RhinoIO.Net File3DM.Layers.IndexOf always returns -1


#1

Hello,

I’m saving OpenNurbs files from my application and I want to be selective of which layer i’m exporting. Since I won’t be exporting all layers, I need to change the objects individual attribute.LayerIndex, because it won’t be the same in the resulting 3DM file.

When i’m adding the layers to the File3dm.Layers collection using:
file3DM.Layers.Add(rhinoLayer);

It returns no index, so I tried doing this right after:
int index = file3DM.Layers.IndexOf(rhinoLayer);

but index is always -1.

I tried to do file3DM.Polish() but it still returns -1. I could iterate the collection and find the index myself, but I was wondering if there’s something i’m missing to assign the added layers index?

Thanks

Alex


(Dale Fugier) #2

Hi Alex,

File3DM.Layers is just a generic collection. So, you will want to make sure to set the layer index yourself (Layer.LayerIndex) before adding to the collection.

Does this help?


#3

Hello Dale,

Unfortunately this doesn’t work. If I set the rhinoLayer.LayerIndex before adding/inserting it to the collection, the collection returns an exception:
{“Index was outside the bounds of the array.”}

I’m counting the layers as i’m adding them to the collection starting from the file3DM.Layers.Count and it works fine.

Thanks for your help.

Alex


(Dale Fugier) #4

This seems to work:

int[] indices = {5, 4, 3, 2, 1, 0};

var f = new Rhino.FileIO.File3dm();
foreach (var idx in indices)
{
  var layer = new Rhino.DocObjects.Layer
  {
    Name = idx.ToString(), 
    LayerIndex = idx
  };
  f.Layers.Add(layer);
}

Perhaps I don’t have enough details?


#5

It seems to work when adding them, but try to access the collection after. Like this:

        int[] indices = { 5, 4, 3, 2, 1, 0 };

        var f = new Rhino.FileIO.File3dm();
        foreach (var idx in indices)
        {
            var layer = new Rhino.DocObjects.Layer
            {
                Name = idx.ToString(),
                LayerIndex = idx
            };
            f.Layers.Add(layer);
        }

        foreach (Layer layer in f.Layers)
        {
            string layerName = layer.Name;
        }

(Dale Fugier) #6

Hi Alex,

The reason for the “index out of range exception” is not because the layer indices are incorrect. It is because the layer has not been assigned an ID, which is usually done by Rhino when the file is read. So, an updated example will look like this:

var file = new Rhino.FileIO.File3dm();

string[] names = {"Zero", "One", "Two", "Three", "Four", "Five"};
foreach (var name in names)
{
  var layer = new Rhino.DocObjects.Layer();
  layer.Name = name;
  layer.Id = Guid.NewGuid();
  file.Layers.Add(layer);
}

foreach (var layer in file.Layers)
{
  var name = layer.Name;
  var index = layer.LayerIndex;
  // TODO...
}

I also verified that Layers.Add will assign Layer.LayerIndex automatically. Sorry for the miss information.


#7

Hello Dale,

Thanks for looking into this. It seems to work perfectly now.

I have a last question regarding this. Is it normal that the original layer object is not updated and instead a new layer instance is created when adding to the Layers collection? For example:

        File3dm file = new Rhino.FileIO.File3dm();

        Layer layer = new Rhino.DocObjects.Layer();
        layer.Name = "MyInstance";
        layer.Id = Guid.NewGuid();
        file.Layers.Add(layer);

        int layerIndex = layer.LayerIndex; // this is still and will always be -1

        foreach (Layer addedLayer in file.Layers)
        {
            int index = addedLayer.LayerIndex; // this will be 0...
            Assert.IsTrue(addedLayer == layer); // this will fail
        }

Thanks

Alex


(Dale Fugier) #8

With the .NET version of openNURBS, yes. Keep on mind that openNURBS .NET is just a wrapper around our C++ toolkit - it is not a pure .NET implementation. When you add a layer, you are really adding a layer on the C++ side. Thus, your .NET properties are copied. So if you iterate the layer table, a new layer will be returned.


#9

Ok. This is what I thought. Thanks! Alex