Speedy Selection of Layer and Sublayer Objects: Custom Script Example

The issue is that in Rhino, it’s not possible to select an object by double-clicking a layer.

I use the middle mouse button to focus on the selected object. This is helpful because navigating to the group object, surface, curve, or point is significantly faster. But how can we combine both methods?

So, when I press the middle mouse button…

The idea is that 
    if there is something selected
     	Then, Zoom selected
    Else
	Run a custom script
	    That looks at the selected layer
	    selects the objects in it,
	    and Zoom selected

To do so, I consulted ChatGPT4. After some introductions, friendly banter, and discussions, we created this code.

Option Explicit

'Script version 3
'Script was written by Alan Mattanó and co-authored by ChatGPT4, with thanks to Jeremy5 and Michael Vollrath
'Script copyright - use as you wish
'Script date: Tuesday, July 18, 2023, 11:37 AM

Call CustomZoomSelected()

Sub CustomZoomSelected()
	Dim arrSelectedObjects
	arrSelectedObjects = Rhino.SelectedObjects(True, True)
	If IsArray(arrSelectedObjects) Then
		Rhino.Command("_Zoom _Selected")
	Else
		Call SelectObjectsOnCurrentLayerAndSublayers()
		arrSelectedObjects = Rhino.SelectedObjects()
		If IsArray(arrSelectedObjects) Then Rhino.Command("_Zoom _Selected")
	End If
End Sub


Sub SelectObjectsOnCurrentLayerAndSublayers()
	Dim strCurrentLayer
	strCurrentLayer = Rhino.CurrentLayer()
	SelectObjectsOnLayerAndChildren(strCurrentLayer)
End Sub

Sub SelectObjectsOnLayerAndChildren(strLayer)
	Dim arrObjects
	arrObjects = Rhino.ObjectsByLayer(strLayer)
	If Not IsNull(arrObjects) Then Rhino.SelectObjects(arrObjects)
	Dim arrChildLayers
	arrChildLayers = Rhino.LayerChildren(strLayer)
	If Not IsNull(arrChildLayers) Then
		Dim strChildLayer
		For Each strChildLayer In arrChildLayers
			SelectObjectsOnLayerAndChildren(strChildLayer)
		Next
	End If
End Sub

To use this code, you need to:

  • Go to Tools > RhinoScript > Edit. This will open the built-in RhinoScript Editor.
  • Paste the script into the editor.

  • Save As ‘CustomZoomSelected’. I’m new to scripting, so I can’t provide much help here. I usually designate a specific place on my drive to store all these files.
  • Now, we need to execute this script. Close the current window.
  • Navigate to Tools > Options.
  • Within the Options dialog, proceed to Rhino Options > Keyboard.
  • Look for the key you wish to assign this function to in the list of keys. My personal preference is to use the middle mouse button. To do this, navigate through Mouse > MMB > Run this Macro:
  • In the Command column adjacent to the key, enter this Macro:
    • -Runscript (CustomZoomSelected).
  • Click [ OK ] to confirm and close the Options dialog.

Now, whenever you press the assigned function key or MMB in Rhino, it will either zoom to the selected object (if any are selected) or select all objects on the currently active working layer and zoom to them.

This will select ‘Pallet 03’, not the highlighted ‘PushBroom’."

image

Last Tutorial: Clarifying Rhino 7 Cycles PBR Normal: It’s OpenGL!

2 Likes

The code in the thread was updated to Vr2. A bug was fixed.

So in the first version,
The Rhino.LayerChildren function in RhinoScript returns the immediate child layers of a specified parent layer. It was selecting the direct children sublayer only and not all of its children’s sublayers.

The new code (Vr2):
We want child layers of child layers down to any level of nesting. You would need to use a recursive function to get all nested sublayers. A function that calls itself to deal with hierarchical or nested data structures.

The old code (Vr1) was:

Option Explicit

'Script Vr1
'Script written by Alan Mattano, co-author ChatGPT4
'Script copyrighted do whatever you want
'Script version Tuesday, July 11, 2023 8:28:10 PM

Call CustomZoomSelected()

Sub CustomZoomSelected()
	Rhino.Command("_Zoom _Selected")
	Dim arrSelectedObjects
	arrSelectedObjects = Rhino.SelectedObjects()
	If IsArray(arrSelectedObjects) Then
		Rhino.Print("Zoom done!")
	Else
		Call SelectObjectsOnCurrentLayerAndSublayers2()
		arrSelectedObjects = Rhino.SelectedObjects()
		If IsArray(arrSelectedObjects) Then Rhino.Command("_Zoom _Selected")
	End If
End Sub


Sub SelectObjectsOnCurrentLayerAndSublayers2()
	Dim strCurrentLayer, arrLayers, strLayer
	strCurrentLayer = Rhino.CurrentLayer()
	arrLayers = Rhino.LayerChildren(strCurrentLayer)
	If IsNull(arrLayers) Then
		arrLayers = Array(strCurrentLayer)
	Else
		ReDim Preserve arrLayers(UBound(arrLayers)+1)
		arrLayers(UBound(arrLayers)) = strCurrentLayer
	End If
	For Each strLayer In arrLayers
		Dim arrObjects
		arrObjects = Rhino.ObjectsByLayer(strLayer)
		If Not IsNull(arrObjects) Then Rhino.SelectObjects(arrObjects)
	Next
End Sub

The script will only be available in the Rhino sessions where it’s loaded, so if you restart Rhino, you will need to reload the script.

There is a way to make scripts persistent across Rhino sessions by using a Rhino startup script.

Remember, you need to be careful with startup scripts, because if there’s an error in the script, it could cause problems when Rhino starts. Always test your scripts before adding them as startup scripts.

To ensure that your custom scripts are always available, no matter which Rhino file you’re working on the following:

  • Save the script in a .rvb file as described in the earlier responses. like C:\DoNotMove\Rhino-Setup\RhinoScript\ …filename.rvb
  • Open Rhino and go to Tools > Options. And go to Rhino Options > RhinoScript.
  • In the RhinoScript options, you’ll see a list of ‘Startup Scripts’. Click on NEW

  • Click the Add button and browse to the location of your .rvb file.
  • Select the .rvb file and click Open.
  • Click OK to close the Options dialog.