Hiding Reference Layers in Layers Tree

Is there any way to prevent a reference layer that is added in plug-in code (not via a worksession) from showing up in the Rhino layers tree even though it is added to the document? A secret layer of sorts?
Thanks, Larry

I can’t recall if I’ve tried this, but have you tried using Layer.IsVisible?
This seems like it should do what you’re asking.

I guess I assumed that this set the visibility of the objects on the layer, like clicking the light bulb next to the layer, rather than hiding the existence of the layer itself. Is that not the case?

Ah yes sorry you’re right. I was looking at this from the wrong angle :blush:.

Why do you want to do that, what are you trying to achieve? There may be other ways to do this, but I don’t think a “secret layer” is an option.

Hi Menno, thanks for your input. Yes, this approach was more for expediency than anything else. We create some reference layers in our plug-in at initialization, that are used for certain pieces of functionality. If someone is not using that functionality, then those layers are technically not needed (and some users have expressed a desire not to have to see them at all in the layers tree in that case or I suppose even when they are needed). The initial approach was to create the layers lazily only when the functionality that requires them is needed. Unfortunately this has wider implications for the code which would require a fair bit of restructuring and then testing. For what seemed like a functionality request with relatively low significance, it seemed a lot easier to offer a way to just let the user hide them from showing up in the layers tree without actually removing them.

Hold your horses, it looks like it is possible with the C++ SDK. Let me see if I can create a useful example.

Also following this thread, we take a very similar approach to @LarryL for our CNC plugin ZebraCut.

We provide the user with a big “clear Layers” which deletes the reference layers whenever they wish.
We also call that routine frequently before large operations. Can share code if helpful

Hi David, thanks for your input. That’s an interesting approach. If the user wants to delete the reference layers but there is useful information on them do you let them or warn them it will delete important info? If you do an operation that requires the reference layers do you just create them again automatically?

Thanks Menno, eager to see what you find.

In the C++ SDK you can apply a layer filter to show any layers that pass the filter. In the command below a small example of what is possible:

Run this once to create a red layer called "Lock+Off to hide me". If you then lock the layer and hide its contents by clicking the lamp to off, and run the command again, the layer will be filtered off the list.

It will reappear when the file is reloaded, or any time Rhino itself applies a filter. This is done when the user sorts the layer table for example, or applied a filter of their own. So you may want to do something when the file is loaded, also listen for layer table events and take action accordingly.

I’m the first to say that this feels a bit like a hack, but it gets you towards where you want to be.

  CRhinoCommand::result RunCommand(const CRhinoCommandContext& context) override
  {
    ON_Color c(255, 0, 0);

    int id = context.m_doc.m_layer_table.AddLayer(L"Lock+Off to hide me", c, true);
    const CRhinoLayer& l = context.m_doc.m_layer_table[id];    

    CRhinoLayerFilter filter(context.m_doc.RuntimeSerialNumber());
    
    unsigned int lock = (unsigned int)CRhinoLayerFilter::FilterType::Unlock;
    unsigned int off = (unsigned int)CRhinoLayerFilter::FilterType::On;
    unsigned int lockAndOff = lock | off;

    filter.SetFilterType((CRhinoLayerFilter::FilterType)lockAndOff);
    filter.SetSortType(CRhinoLayerFilter::SortType::None);
    filter.SortAndCull(false);

    ON_SimpleArray<const CRhinoLayer*> list;
    context.m_doc.m_layer_table.GetSortedList(true, false, list);
    for (int i = 0; i < list.Count(); ++i)
    {
      const CRhinoLayer* l = list[i];
      RhinoApp().Print(L"Layer %d %s\n", i, l->Name());
    }
    
    return success;
  }
2 Likes

Thank you @menno

Yeah we allow users to always delete reference layers - no warnings.

Any information on them should be regenerated afresh during any operation because the users original geometry may have changed.

Thank you @menro that looks interesting - I wonder if Rhino Common provides the same API

RhinoCommon does not provide this AFAICS.

Hi @LarryL,

A layer has a “is visible in UI” property that is not exposed anywhere. This property is runtime only - it is not archived in 3dm files. When layers are filtered, either by using the Layers panel or some C++ class, this property is used.

I can expose this property to RhinoCommon. No guarantees this flag will survive layer filtering, however.

https://mcneel.myjetbrains.com/youtrack/issue/RH-81522

– Dale

3 Likes

Hi @dale, I think this would serve our purpose very nicely, thank you!

1 Like

We too could make use of that new RhinoCommon property. Thanks @dale @menno !