Specifying location of layer in layer dialog using Rhinoscript

We are using Rhinoscript to create top-level layers based on user inputs. We end up with many layers and these new layers are being created at the very bottom of the layer dialog. We also have a lot of miscellaenous layers because we are bringing in external objects so it is not convenient to force the user to reposition the layer after it is created. Is there a way to allow the user to select which layer to create the new layer under, e.g. using a list box?

In the process of creating this topic, I had an idea for a solution but didnā€™t know if it would work. After posting I went and tried it and turns out it works.

The solution I found was to specify the layer to create the new layer under as the parent layer, then subsequently unparent the new layer. This puts the new layer under the child layers of the specified ā€œparentā€ layer.

If anyone has a more elegant way of doing this, please let me know!

2 Likes

WOW, i think you just solved a problem I had for two years! I will try this method, even if it seem like a hack/workaround.

http://discourse.mcneel.com/t/sort-the-layer-order-from-code-can-this-be-done/3303

Glad it helps! I did run into an issue where unparenting the layer causes it to shoot to the bottom sometimes but not others. I managed to alleviate it if I run redraw from the command line but not if I run it in Rhinoscript. Still playing around to see what will fix it.

I have narrowed down the issue to having to have the layer dialog window selected before running ā€œSetRedrawOnā€ either from the command line or Rhinoscript, then unparenting the layer. Before I create another topic, is there a way to set the layer dialog as active using Rhinoscript?

Using this trick, Iā€™m able to do something to INSERT a layer before another layer:

        Dim currentLayer As Layer = MyPlugin.PushStepLayer(selectedStepNumber)
        Dim newlayer As Layer = MyPlugin.AddStepLayer(selectedStepNumber)
        newlayer.ParentLayerId = currentLayer.Id
        newlayer.CommitChanges()
        newlayer.ParentLayerId = Guid.Empty
        newlayer.CommitChanges()

        currentLayer.ParentLayerId = newlayer.Id
        currentLayer.CommitChanges()
        currentLayer.ParentLayerId = Guid.Empty
        currentLayer.CommitChanges()

But this removes my user string attached to the currentLayer.

2 Likes

I suppose you could work around this problem by reading the user-string before you do this ā€œtrickā€, and setting it again afterwards. Iā€™m going to try this in my plug-in, to see if I can insert a layer at a given position, thanks for the suggestion!

I can confirm this approach as working. I was finally able to do this as follows:

Guid idOfTrueParent; // the parent layer - can be Guid.Empty if the newly added layer has no parent
Guid idOfLayerAbove; // determined elsewhere, the new layer must come under the layer with this Id.
Layer l = new Layer();
l.Name = "New Layer";
l.ParentLayerId = idOfLayerAbove;
int newLayerIndex = doc.Layers.Add(l);
if (newLayerIndex < 0) return; // addition not successful....
Layer fromDoc = doc.Layers[newLayerIndex];
fromDoc.ParentLayerId = idOfTrueParent;
fromDoc.CommitChanges();

// woohoo - it's working :-)

Anyway, thanks again. This forum is great.

1 Like

Hi @menno, @yck011522,

Sorry for reviving 3 year old topic, but do you it would be possible to use the same trick to insert a new layer at the top of the child layers list? For example:

image

What would be the id of the layer above in the case of ā€˜child2ā€™ layer?
Trying with ā€œParentā€ id, just creates the new ā€œchild2ā€ layer at the very bottom of the list.

I donā€™t think so

Thank you Menno.
I created a dummy layer at the beginning, which then makes it possible to insert ā€œchild2ā€.