Save objects to file with rhino3dmio C#

Hello there,

I’m trying to write geometric objects to a .3dm file using C# in a custom application that is not a Rhino plugin and not related to a running instance of Rhino.
As I understood rhino3dmio is meant for exactly that purpose, but I couldn’t really get my head around it.
I’m using the rhino3dmio nuget package for desktop applications.
I did find this Python related thread: Write 3dm file
And this C++ example: https://developer.rhino3d.com/guides/cpp/archiving-curves-to-a-file/
I tried to adapt the latter to C# and my code looks like this:

public bool SaveAsFile(List<GeometryBase> geom) //geom contains Breps and Curves
{
    BinaryArchiveFile a = new BinaryArchiveFile("filename.3dm", BinaryArchiveMode.Write3dm);
    a.Open();

    if (!a.Writer.BeginWrite3dmChunk((uint)TypeCode.Byte, 1, 0)) return false;

    foreach (GeometryBase g in geom)
        a.Writer.WriteGeometry(g);

    if (!a.Writer.EndWrite3dmChunk()) return false;

    a.Close();

    return true;
}

The code compiles, works and I get a file that has an appropriate size.
However when I try to open the file with Rhino, I receive the error:

filename.3dm is not a Rhino m_archive

I tried different options for TypeCode as I wasn’t sure which one to chose, but that didn’t help. Where did I go wrong?

Best
Ben

Hi @benjamin.felbrich,

To write 3dm files, use a File3dm object. For example:

static void Main(string[] args)
{
  var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
  var filename = Path.Combine(path, "TestBenjamin.3dm");

  using (var file = new File3dm())
  {
    var layer = new Layer { Name = "Default", Color = Color.Black };
    file.AllLayers.Add(layer);

    var layer_index = file.AllLayers.Count - 1;
    var attributes = new ObjectAttributes { LayerIndex = layer_index };

    for (var x = 0; x < 100; x++)
    {
      var line_curve = new LineCurve(new Point3d(x, 0, 0), new Point3d(x, 1, 0));
      if (line_curve.IsValid)
        file.Objects.AddCurve(line_curve, attributes);
    }

    file.Write(filename, 6);
  }
}

– Dale

Thanks a lot Dale!
It works like a charm.
I’m guessing there’s no way to fetch the serialization or binary stream that file.Write() uses to possibly reroute it? Say if I wanted to send my file to a network but avoid writing it to my local drive first?

Hi @benjamin.felbrich,

The filename variable and point to a network path. Or am I missing something?

– Dale

Hi, but if i don’t know the type object, can be a Line, Curve, Rectangle, brep,… whatever

Just use “add” how you do when adding objects to the current doc.

Rhino.FileIO.File3dmObjectTable

– Dale