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?
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);
}
}
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?