Is it possible to create a keyboard shortcut that will Expand All Layers in the Layers Menu? Also one for Collapse All Layers?
Regards,
Terry.
Is it possible to create a keyboard shortcut that will Expand All Layers in the Layers Menu? Also one for Collapse All Layers?
Regards,
Terry.
Hi Terry- not directly that I know of but a macro using this python will do it, if that helps:
import scriptcontext as sc
for layer in sc.doc.Layers:
layer.IsExpanded=True
for example
_-RunPythonScript (
import scriptcontext as sc
for layer in sc.doc.Layers:
layer.IsExpanded=False
)
Does that help?
-Pascal
On a similar note, I kind of use the layers panel like a feature tree and sometimes it gets a bit bloated and long. Is there a way to collapse all layers except the currently active or currently selected layer(s)?
Pascal ,
This works fine.
ExpandAllLayers is stored in my Scripts directory and contains:
from scriptcontext import doc
doc.Views.RedrawEnabled = False
for layer in doc.Layers:
layer.IsExpanded = True
doc.Views.RedrawEnabled = True
while CollapseAllLayers contains:
from scriptcontext import doc
doc.Views.RedrawEnabled = False
for layer in doc.Layers:
layer.IsExpanded = False
doc.Views.RedrawEnabled = True
ExpandAllLayers.py (148 Bytes)
CollapseAllLayers.py (149 Bytes)
My keyboard shortcuts now look like:
Thanks for the quick response.
Regards,
Terry.
How does Rhino determine if the layer you want to keep open is the Currently Active or Selected Layer? Do you want to collapse all layers with no Visible layers selected? The following script will do that. I stored it in my Scripts folder as CollapseNotVisibleLayers.
from scriptcontext import doc
doc.Views.RedrawEnabled = False
for layer in doc.Layers:
if not layer.IsVisible:
layer.IsExpanded = False
doc.Views.RedrawEnabled = True
Here is a file for this:
CollapseNotVisibleLayers.py (176 Bytes)
And my keyboard shortcuts now look like this:
Here is one example of my Layers menu before pushing F8:
Regards,
Terry.
Hi Terry,
Thanks for sharing! Actually that’s even better than what I was imagining.
Your implementation made me realize that I only select layers that I would want to work on, which are usually the only layers visible with all others hidden.
The reason I made the distinction between currently active or selected layers was just to provide two separate options, so I wouldn’t want a script that would have to make that distinction.
And in retrospect, collapsing all but the active layer would actually be counterproductive since I’m often working on multiple interdependent layers, so I wouldn’t want those collapsed anyway.
But a script that could collapse all but the selected layers (and I guess their parent layers for it to work?) would be nice.
If the selected layer is the one highlighted in Blue, what is an active layer? How can it be detected? Is an active layer one with objects or one which is expanded?
I see that Rhino recognizes a Current layer which is the one with the check mark in the Current column.
So far I have not found a way to detect a layer highlighted in Blue.
Oh a simple misunderstanding then: by active layer, I meant what you refer to as the current layer, which is probably the more suitable way to refer to it as.
As for the selected layer highlighted in blue, that’s unfortunate, maybe Rhino devs could expose it in RhinoCommon?
Vince,
Here is a script that collapses all layers except the current layer.
from scriptcontext import doc
doc.Views.RedrawEnabled = False
# Get full name of current layer.
current_name = doc.Layers.CurrentLayer.FullPath
# Collapse layers that do not share part of current layer full name.
for layer in doc.Layers:
full_path = layer.FullPath
if full_path:
# Collapse layer if its name is not in the beginning of current's.
if current_name.find(full_path) != 0:
layer.IsExpanded = False
# If layer name is in the beggining of current's, do more checks.
else:
lc = len(current_name)
lf = len(full_path)
# If layer name is the same length as current's or
# it fills a hierarchy of current, then do not collapse it.
if not (lf == lc or (lc > lf and current_name[lf] == ":")):
layer.IsExpanded = False
doc.Views.RedrawEnabled = True
Here is a file for this:
CollapseNotCurrentLayers.py (801 Bytes)
Regards,
Terry.
You can get a list of selected layers, here is a sample code:
import Rhino
import rhinoscriptsyntax as rs
selectedLayers = Rhino.RhinoDoc.ActiveDoc.Layers.GetSelected() # get the currently selected layers
for l in selectedLayers[1]: # array of indices of selected layers
lname = Rhino.RhinoDoc.ActiveDoc.Layers.FindIndex(l) # use index to find layername
print lname.Name #layername property
Maybe it can be implemented to help with not collapsing the selected layers as well in your case.
Hi Terry - the LayerTable can help-
https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.tables.layertable/getselected
Ooops, too late.
-Pascal
Thanks for the help.
Here is a script that will collapse all but the selected layers (layers highlighted in Blue):
from scriptcontext import doc
doc.Views.RedrawEnabled = False
# Get the currently selected layers
selectedLayers = doc.Layers.GetSelected()
# Get full name for all layers.
names = [layer.FullPath for layer in doc.Layers]
# Get full name of selected layers.
selected_names = [names[l] for l in selectedLayers[1]]
# Collect index of layers that share part of selected layer name.
i = 0; ok = set()
for full_path in names:
if full_path:
for selected_name in selected_names:
if selected_name.find(full_path) == 0:
ls = len(selected_name); lf = len(full_path)
if lf == ls or (ls > lf and selected_name[lf] == ":"):
ok.add(i)
i += 1
# Collapse layers that do not share part of selected layer name.
for j in range(i):
if j not in ok: doc.Layers[j].IsExpanded = False
doc.Views.RedrawEnabled = True
Here is a file for this:
CollapseNotSelectedLayers.py (834 Bytes)
Here is a sample .3dm file you can use to exercise the script:
SeveralLayers.3dm (4.1 MB)
Here is an example using the sample file.
Regards,
Terry.
I’m a bit confused by Pascal’s response here but, assuming I’m reading the date of the question correctly (June 7th, 2024), it is very definitely possible to Expand or Collapse all layers without adding a Macro: (in Rhino 7) in the Layers panel, just click on the Tools dropdown (the hammer icon) & select ‘Collapse All’ or ‘Expand All’ (with undo available immediately afterwards, Ctrl+Z)
My original goal was to create a 1 keystroke method for faster expand/collapse of the layers. I replaced some of my rarely used function keys with calls to the macros. So now it requires no mouse moves to control the expand/collapse of the layer menu. Now it is faster for two reasons: (1) No mouse movement (2) The macro toggles off redraw until all changes have been made. This makes a noticable difference when I have dozens of layers in use.
Vince wanted additional functionality and I created some more macros for that. Pascal comments helped this effort.
Regards,
Terry.
I didn’t mean any offense Terry - thank you to you and Pascal for sharing your scripts. But I think my confusion is still relevant as a Rhino user that ended up on this thread having looked (unsuccessfully) in Rhino for methodologies to efficiently navigate complex layer trees - I couldn’t find anything in menus or toolbars or the command line or Help and when I came to this thread I misunderstood your question and Pascal’s response to mean that there is no native way in Rhino to bulk collapse or expand layers and that a user-side macro was necessary. Going further, my questions/requests for @Pascal/McNeel/other users would be:
• can/should something be added in the help files so that if a user types ‘Nested Layers Management’ or ‘Expand/Collapse Layers’ into the Help search bar, they are pointed (far more directly) to:
• can/should the above 4 commands also be discoverable in the command line? (Rhino is a command-line oriented software. It’s normally reasonable to assume that if you start typing what you are looking for in the command line (e.g. ‘layer…’), something will come up)
• Is there an existing way for the user to 1. Save their existing layer tree state (‘SaveLayerTree’), 2. Radically change their layer tree state (for example, with Expand or Collapse All), 3. Do an intermediate action, 4. Revert to the Layer Tree State they had at step 1 (‘RestoreLayerTree’)? If not, can this be implemented, for example by either creating the commands/macros necessary for steps 1 & 4, or by adding ‘Layer Tree State’ as a parameter & check box in Layer State Manager? Being able to do steps 1 & 4 with minimal clicks is something that I would find very useful, but I’m not aware that they are currently even possible - any help appreciated.
Hi @Jack_Brown,
You can also expand and collapse by pressing the + and - keys, respectively.
Sure - I’ve logged your wish.
https://mcneel.myjetbrains.com/youtrack/issue/RH-83351
The Layer State Manager already saves a layer’s expanded/collapsed state. It just does not restore it. I’ve added that to the pile (too).
https://mcneel.myjetbrains.com/youtrack/issue/RH-83352
Thanks,
– Dale
Here are macros for saving and restoring the layer tree:
from scriptcontext import doc
from rhinoscriptsyntax import SetDocumentUserText
doc.Views.RedrawEnabled = False
# Save state of all valid layers.
for layer in doc.Layers:
if layer.IsValid:
SetDocumentUserText(str(layer.Index), str(layer.IsExpanded))
doc.Views.RedrawEnabled = True
SaveLayerTree.py (290 Bytes)
from scriptcontext import doc
from rhinoscriptsyntax import GetDocumentUserText
doc.Views.RedrawEnabled = False
# Restore state of all valid layers.
for layer in doc.Layers:
if layer.IsValid:
layer.IsExpanded = GetDocumentUserText(str(layer.Index)) == "True"
doc.Views.RedrawEnabled = True
RestoreLayerTree.py (303 Bytes)
The information is stored in the document so it will exist across closing and opening of the document.
Let me know if this helps.
Regards,
Terry.
Thanks Terry, very much appreciated - have done some quick testing and both scripts are working well during and between sessions.
Good to hear that the scripts are working.
I have a few questions for you:
(1) Do you want the visibility of each layer also saved and restored?
(2) Do you want the selection (highlighted in blue) of each layer also saved and restored?
I have (1) working. But for (2), I am still trying to figure out how to select a layer using rhinoscriptsyntax.
I know how to store the state of selected layers, but how to select a layer during restore of the layer tree is a mystery.
Regards,
Terry.
Hi Terry. Absolutely, having layer visibility saved and restored would be great (while the highlighted selection doesn’t seem so critical). I’ve thought about this more, though, and what would also be great is if the Expanded/Collapsed checkbox can be added to the Layer State Manager soon - @dale , if you’re out there, any idea on how long this might take? - This is how I see it (for architectural design):
Say you’ve got multiple Layer States saved including (for e.g.), 1. Electrical - All Levels, 2. Carpentry - All Levels, …(others)… 6. Carpentry/Electrical Conflicts - Level 3. If you do each save with Visibility & Layer Tree optimised then you have a VERY efficient tool for moving back & forth through different design focuses BUT most of that efficiency is lost if you can’t include the Expanded/Collapsed state of the layers in the save/restore. Any thoughts?