Problems with layer list order

Hello,
I am having a problem with the order of the layer list. All madCAM toolpaths are saved in layers, and it is the layer order that determines the order of the tool paths when post processing and simulating. I have tried several workarounds by adding fake layers and redraw to get the layer list updated, but nothing seems to work. Below is the code that I use.

            Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;

            // Get a reference to the layer table
            layers = new Rhino.DocObjects.Layer[0];
            layers = (Rhino.DocObjects.Layer[])ResizeArray(layers, doc.Layers.Count);

            int i = 0;
            foreach (Rhino.DocObjects.Layer layer in doc.Layers)
                if (layer.IsVisible)
                    if (IsToolpathLayer(layer))
                    {
                        layers[i] = layer;
                        i = i + 1;
                    }

            layers = (Rhino.DocObjects.Layer[])ResizeArray(layers, i);
            QuickSortLayers(ref layers, 0, i - 1);  //layers[i].SortIndex order

            //foreach (Rhino.DocObjects.Layer layer in layers)
                //Rhino.RhinoApp.Write("Name=" + layer.Name + ";    ");

The only way to get the layerlist updated is to manually move one layer up and then down in the layers dialog and it has to be a layer that is above the last layer for making the list updated. Would it be possible to make a command for refreshing the layer list?

Thanks,
Joakim

My experience is that layer management from code is like stabbing yourself in the eye with a fork sometimes :smile:

Have you tried the CommitChanges() method on the layers you want to re-order? For things like switching on/off visibility, locking etc. this is mandatory - changes to layers will not be propagated otherwise.

Also, see this topic

http://discourse.mcneel.com/t/arrange-layers-through-sdk/

I am not trying to reorder the layer list, I am just trying to get the correct SortIndexes from each layer in the layertable so that I can get the same order as layers are kept in the layer dialog. I have tried to set visibility on and off, add fake layers, enable redraw on and off, but nothing seems to work for refreshing the layer list.

Thanks,
Joakim

You should be able to refresh the layer dialog’s list of layer by doing this:

doc.RedrawEnabled = true;

Let me know if you find otherwise.

Hi Joakim,
We would be more than happy to write a sample for you or add another function to RhinoCommon, we’re just a little confused with what you are trying to do. Could you provide a few more details on what you are trying to accomplish?
Thanks,
-Steve

I’m going to chirp in here as a madCAM user:

The layer order in madCAM is very important as the toolpaths are simulated and post-processed dependent on the order that they appear in the list. When they don’t appear correctly in the layer list, things get ugly in a hurry. Finish paths are post-processed before roughing paths, and this can lead to a lot of damage to tooling, workpiece and machine.

This is a new phenomenon in V5. In V4 the layers always appeared in the correct order.

All Joakim is attempting to do is to make sure, without any doubt, that the layers appear on the layer list in the correct order that they are created and/or the correct order that they are moved to.

Does this help, or just cause more confusion?

Dan

To get the same order as layers are kept in the Rhino layer dialog, I am using the “SortIndex” from each layer in the Rhino layer table. This is working perfect as long as the “Sortindex” from each layer in the Rhino layer table is correct.

My problem is that the sortindexes seems to be out of order compared to the Rhino layer dialog in some cases.

I have noticed that it is possible to refresh the Rhino layer list and get correct sortindexes if manually moving one layer up and down in the Rhino layer dialog.

I am trying to find a solution to refesh the Rhino layer list from Rhinocommon, but I have not been able to find anything that works so far. Below is what I have tried, but nothing works for me.

                   // Work around to update the layer list.
                    Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;
                    int napplayer = doc.Layers.Find(Mc.appstr, true);
                    if (napplayer >= 0)
                    {
                        doc.Views.RedrawEnabled = false;
                        Rhino.DocObjects.Layer fakelayer = new Rhino.DocObjects.Layer();
                        Rhino.DocObjects.Layer app_layer = doc.Layers[napplayer];
                        fakelayer.ParentLayerId = app_layer.Id;
                        int nlayer = doc.Layers.Add(fakelayer);
                        doc.Layers.Delete(nlayer, true);
                        doc.Views.RedrawEnabled = true;
                    }

Thanks,

Joakim

Hi Joakim,

If I were to build a list of layers sorted in the order in which they appear in the ui, I would do something like this:

List<KeyValuePair<int, int>> sortList = new List<KeyValuePair<int, int>>(doc.Layers.Count);

foreach (Rhino.DocObjects.Layer layer in doc.Layers)
{
  if (!layer.IsDeleted)
    sortList.Add(new KeyValuePair<int, int>(layer.LayerIndex, layer.SortIndex));
}

sortList.Sort(
    delegate(KeyValuePair<int, int> firstPair,
    KeyValuePair<int, int> nextPair)
    {
      return firstPair.Value.CompareTo(nextPair.Value);
    }
);

foreach (KeyValuePair<int, int> pair in sortList)
  RhinoApp.WriteLine("Name = {0}, LayerIndex = {1}, SortIndex = {2}", doc.Layers[pair.Key].Name, pair.Key, pair.Value);

The above code does not take into account whether or not the layer list has been filtered in any way.

A layer’s sort index should always be in sync with the ui. If it is not, then it is a bug. If you can provide a reproducible way for the above code to not match what is visible in the ui, then let us know so we can get it on the list of things to fix.

@stevebaer @dale This seems the correct thread to report a bug in the layerlist order when saving as dxf or dwg. The testing shown in the image was carried out with the attached file:

  1. The attached file, created in V5 with layers randomly arranged
  2. Save as dxf (2004 natural) and open that dxf in V5 and the layers become randomised
  3. Save as dwg (2004 natural) and open that dwg in V5 and the layers are randomised, but differently to the dxf
  4. Open the saved dwg (or dxf) in Acad 2007 and the layers are alphanumerically arranged
  5. Save the file while in Acad, then reopen in V5 and the layers are randomised in the same order as 3

V5 - Layer List To Dxf.3dm(183.1 KB)

I don’t believe there are any problems here.

Unlike Rhino, AutoCAD does not allow you to reorder layers. Thus, whenever you open a DWG or DXF file in AutoCAD, it will always appear sorted.

Also, if you open the 3DM file and then SaveAs both DWG and DXF without closing the 3DM file, you will see that the layers from the DWG and DXF file appear in the same order when opened in Rhino.

My guess is that Rhino saves layers to DWG and DXF files in the order in which they appear in the layer table. There is no reason to write layers in sorted order as, again, AutoCAD does not track a layer’s sort order.

Thanks for the explanation Dale, I’d forgotten that AutoCAD maintains sorted layers - I used to prefix layers with numbers in Acad to maintain some assemblance of order and grouping, the Rhino system is so… much better.

To modify my query, when an Acad created .dwg, is opened in Rhino, is the layer list arranged according to a sort index applied in Acad as opposed to the way they are displayed in Acad?

Secondly, keeping Autocad out of it, in the dxf example above (1 and 2), the unsorted original list becomes re-ordered, yet still unsorted, when exported as a dxf.

Is this expected behaviour, I am curious now, that in files I send off for cnc cutting, the layers are probably displaying in a different order than intended when opened in 3rd party software? I’ve never had feedback from cnc-cutters over this, but reading @DanBayn comments above, this could be problematic.

Thanks for the code Dale, but I am sorry, I still get incorrect layers sort index.
Below is the code I now use:

Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;

doc.Views.RedrawEnabled = false;
doc.Views.RedrawEnabled = true;
doc.Views.Redraw();

List<KeyValuePair<int, int>> sortList = new List<KeyValuePair<int, int>>(doc.Layers.Count);

foreach (Rhino.DocObjects.Layer layer in doc.Layers)
{
  if (!layer.IsDeleted)
    sortList.Add(new KeyValuePair<int, int>(layer.LayerIndex, layer.SortIndex));
}

sortList.Sort(
  delegate(KeyValuePair<int, int> firstPair,
               KeyValuePair<int, int> nextPair)
               {
                 return firstPair.Value.CompareTo(nextPair.Value);
               }
  );

RhinoApp.WriteLine("---------------- Layer order --------------------------------------------");
foreach (KeyValuePair<int, int> pair in sortList)
  if (IsToolpathLayer(doc.Layers[pair.Key]))
    RhinoApp.WriteLine("Toolpath Name = {0}, LayerIndex = {1}, SortIndex = {2}", doc.Layers[pair.Key].Name, pair.Key, pair.Value);
  else
    RhinoApp.WriteLine("Name = {0}, LayerIndex = {1}, SortIndex = {2}", doc.Layers[pair.Key].Name, pair.Key, pair.Value);

The ui layers looks like this when open the model:

…and the layer order i get.

---------------- Layer order --------------------------------------------

Name = 01 Block, LayerIndex = 0, SortIndex = 0
Name = 02 Surfaces, LayerIndex = 1, SortIndex = 1
Name = madCAM, LayerIndex = 2, SortIndex = 2
Name = Clipping Planes, LayerIndex = 3, SortIndex = 3
Name = Box-region, LayerIndex = 4, SortIndex = 4
Name = 36_T14_Ø50.8r1.6_finish_bullnose_alum, LayerIndex = 5, SortIndex = 5
Name = 40_T8_Ø10_finish_ballnose_alum, LayerIndex = 6, SortIndex = 6
Toolpath Name = Z_Levels_40_T8_Ø10_finish_ballnose_alum Group:3, LayerIndex = 7, SortIndex = 7
Toolpath Name = Roughing_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:0, LayerIndex = 8, SortIndex = 8
Toolpath Name = Roughing_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:1, LayerIndex = 9, SortIndex = 9
Toolpath Name = Planar_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:0, LayerIndex = 10, SortIndex = 10

Layer number 7 should be the last toolpath, but it goes as the first toolpath. If I manually move layer number 5 down in the ui list and then up again, it seems like the layer list becomes correct and the sortindexes syncs with the ui as it should.

Below is what I get after manually moving a layer in the list.

---------------- Layer order --------------------------------------------

Name = 01 Block, LayerIndex = 0, SortIndex = 0
Name = 02 Surfaces, LayerIndex = 1, SortIndex = 1
Name = madCAM, LayerIndex = 2, SortIndex = 2
Name = Clipping Planes, LayerIndex = 3, SortIndex = 3
Name = Box-region, LayerIndex = 4, SortIndex = 4
Name = 36_T14_Ø50.8r1.6_finish_bullnose_alum, LayerIndex = 5, SortIndex = 5
Toolpath Name = Roughing_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:0, LayerIndex = 8, SortIndex = 6
Toolpath Name = Roughing_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:1, LayerIndex = 9, SortIndex = 7
Toolpath Name = Planar_36_T14_Ø50.8r1.6_finish_bullnose_alum Group:0, LayerIndex = 10, SortIndex = 8
Name = 40_T8_Ø10_finish_ballnose_alum, LayerIndex = 6, SortIndex = 9
Toolpath Name = Z_Levels_40_T8_Ø10_finish_ballnose_alum Group:3, LayerIndex = 7, SortIndex = 10

Thanks,

Joakim

@dale, any thoughts on the original issue Joakim posted? It’s just a matter of time before someone doesn’t notice the layer order and ends up smashing something expensive. Can you take another look at the layer sort index and see if you can find a problem with it? I would think that Joakim can provide more code samples if you need. He is just as eager as I am to get this resolved.

Thanks,

Dan

Dan, its pretty hard to fix something that I cannot repeat. I’ve never seen a model that repeats the report behavior. Until I get a model, source code and/or a procedure that I can use to replicate the issue, I’m not sure how to help.

Yeah, it’s the repeatability that’s the tough thing here. I had a file saved that gave me this problem, and I was about to send it to you, but it’s working fine now. I’ll ask Joakim if he has something he can repeat.

Thanks, and have a great weekend,

Dan

Hi Dale,

Here is a file that can repeat the issue. However, don’t save the file or the issue will disappear. Perhaps there is a clue in that. This was a file I sent to Joakim a while ago but I’ve resaved mine, so that’s why I couldn’t repeat it.

kuverta-1.3dm(443.7 KB)

As for samples of source code for madCAM, I don’t have access to that.

Dan

Hi Dale,

madCAM saves tool paths as regular curves in Rhino. You can test with the following code without having madCAM installed.

Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc;

doc.Views.RedrawEnabled = false;
doc.Views.RedrawEnabled = true;
doc.Views.Redraw();

List<KeyValuePair<int, int>> sortList = new List<KeyValuePair<int, int>>(doc.Layers.Count);

foreach (Rhino.DocObjects.Layer layer in doc.Layers)
{
if (!layer.IsDeleted)
sortList.Add(new KeyValuePair<int, int>(layer.LayerIndex, layer.SortIndex));
}

sortList.Sort(
delegate(KeyValuePair<int, int> firstPair,
KeyValuePair<int, int> nextPair)
{
return firstPair.Value.CompareTo(nextPair.Value);
}
);

foreach (KeyValuePair<int, int> pair in sortList)
RhinoApp.WriteLine(“Name = {0}, LayerIndex = {1}, SortIndex = {2}”, doc.Layers[pair.Key].Name, pair.Key, pair.Value);

Thanks,

Joakim

Hi Joakim,

I’ve made a small change to Rhino 5 SR6 that might fix this. When a release candidate is available, try the code you posted above and see if it works more consistent.

Thank you!