3dm written using FileIO.File3dm cannot be read using Import GH 3dm component

3dmWrite.gh (42.4 KB)

I have written code to export geometries to 3dm.
If I try to open 3dm file created by this component in Rhino, it works fine. Every geometries are there as expected.
But if I try to import the file from GH using import 3dm component, it yields empty result as if nothing is there.
I have used Rhino.FileIO.File3dm.Read(path).Objects.Count property to get a better understanding of this problem and it returned correct number of objects count.
Am I doing something wrong here?

And the L and N inputs are still *?

Can you share the 3dm file which fails to be read?

yes both L and N are *

gh file I have attached have geometries internalized within the geometry container. try button and it will create a 3dm file. that particular file would not be recognized by import 3dm component but will open from rhino. I wll attach the 3dm file anyway.

I am suspecting the following lines :
Rhino.FileIO.File3dm file = new Rhino.FileIO.File3dm();

file.Write(path, 5); // I have tried 6, 0,1,2… all could not be read from GH import 3dm.

testRhinoFile1.3dm (41.5 KB)
testRhinoFile2.3dm (4.4 KB)

Doesn’t work here either. It could well be a bug in the IO import component.
Slightly too tipsy from dinner wine at the moment to investigate, but logged under RH-46981 for when I’m up and running again.

2 Likes

Thanks David. appreciate your response.

Took a while, but the layer index of your objects is all -1. The 3dm file contains a single layer, so I’d expect all the layer indices to be zero. At the moment my import code ignores all objects with an invalid layer index, since I cannot compare the layer name filter. I can change that so that it automatically accepts all unlayered objects, or at least displays a warning for unlayered objects, but I need to talk to the 3dm file format experts first to see how they feel about this.

Thanks @DavidRutten How do I set layer index of an object in c#?
If possible, an example code would be great.

The 3dm experts have told me that a layer index of -1 indicates the default layer in some cases, so technically the 3dm file you’re writing is not considered broken.

However you can assign layers to an object by giving it attributes that have the layer index set: 3dmWriteWithAttributes.gh (62.6 KB)

private void RunScript(bool Write, string Folder, string Filename, List<GeometryBase> Geometry, ref object A)
{
  string file = CreateFilePath(Folder, Filename);
  A = file;

  if (Write)
    Create3dmFile(Geometry, file);
  else
    CreateValidityReport(Geometry, Filename);
}

private static string CreateFilePath(string folder, string name)
{
  var separator = System.IO.Path.DirectorySeparatorChar;
  return string.Format("{0}{1}{2}", folder, separator, name);
}

private void CreateValidityReport(List<GeometryBase> geometry, string name)
{
  Print("Validity report for: " + name);
  Print("{");
  for (int i = 0; i < geometry.Count; i++)
  {
    GeometryBase shape = geometry[i];
    string typename = "an invalid object type!";

    if (shape is Brep)
      typename = "a brep.";
    else if (shape is Curve)
      typename = "a curve.";
    else if (shape is Rhino.Geometry.Point)
      typename = "a point.";

    Print("  Object at [{0}] is {1}", i, typename);
  }
  Print("}");
}
private void Create3dmFile(List<GeometryBase> geometry, string path)
{
  Rhino.FileIO.File3dm file = new Rhino.FileIO.File3dm();
  var layer = new Layer();
  layer.Name = "Default Layer";
  file.AllLayers.Add(layer);

  Print("File write report for: " + path);
  Print("{");
  foreach (var shape in geometry)
  {
    var attributes = new ObjectAttributes();
    attributes.LayerIndex = 0;
    attributes.Name = "Object name";

    if (shape is Brep)
    {
      file.Objects.AddBrep((Brep) shape, attributes);
      Print("  Brep added.");
    }
    else if(shape is Curve)
    {
      file.Objects.AddCurve((Curve) shape, attributes);
      Print("  Curve added.");
    }
    else if(shape is Rhino.Geometry.Point)
    {
      Rhino.Geometry.Point pt = (Rhino.Geometry.Point) shape;
      file.Objects.AddPoint(pt.Location, attributes);
      Print("  Point added.");
    }
    else
      Print("  Object ('{0}') was not of a recognised type.", shape.GetType());
  }
  Print("}");

  file.Write(path, 5);
}