I have an object preselected. Then I do:
-_SelLayer _Pick
My previously selected object is still selected.
I hit enter.
The selection does not change. I still have the initially selected object selected, but no other objects of the layer got selected. If I select the object inside the command, the other objects of the layer get selected as expected.
I would like the preselected object being used for the -_SelLayer _Pick. Can I adjust the macro to do so or is this not possible?
Seems like this may not be possible - looks like a bug or an oversight…
Here is both a VB rhinoscript and a Python script (in case you’re on Mac) that do what you want…
–Mitch
Option Explicit
Call SelLayerEx()
Sub SelLayerEx()
Dim objs, obj
Rhino.UnselectAllObjects()
objs = Rhino.GetObjects("Select objects",,, True)
If Not IsArray(objs) Then Exit Sub
Call Rhino.EnableRedraw(False)
For Each obj In objs
Call Rhino.ObjectsByLayer(Rhino.ObjectLayer(obj), True)
Next
Call Rhino.EnableRedraw(True)
End Sub
import rhinoscriptsyntax as rs
def SelLayerEx():
rs.UnselectAllObjects()
objs = rs.GetObjects("Select objects",preselect=True)
if not objs: return
rs.EnableRedraw(False)
for obj in objs:
rs.ObjectsByLayer(rs.ObjectLayer(obj), True)
SelLayerEx()
I don’t know - I’ve never used scripts in that way… I just have a tendency to integrate all the functions in the script itself. So you are trying to hide all other objects except those on selected layers? That’s just another couple of lines in the script. --Mitch
import rhinoscriptsyntax as rs
def SelLayerInvHide():
rs.UnselectAllObjects()
objs = rs.GetObjects("Select objects",preselect=True)
if not objs: return
rs.EnableRedraw(False)
for obj in objs:
rs.ObjectsByLayer(rs.ObjectLayer(obj), True)
toHide=rs.InvertSelectedObjects()
if toHide: rs.HideObjects(toHide)
SelLayerInvHide()
Thanks a lot for adding to the script. I was starting to like macros to make quick aliases. I would have used the MitchSelLayer in around 8 macros. I think I have to go back to scripting due to the limitations of macros to work in combination with scripts.
Hi Mitch, Silvano - this is probably by design, since it allows you to add specific layers’ objects to your current selection - I guess, absent another command line option, the right way is a matter of context- hard to win.
@pascal@dale May the dash command with objects preselected be adjusted to complete without an additional _Enter? This seems like many other commands behave.
Current command flow:
Select objects in view
-_SelLayer _Pick
Hit enter
Wished for command flow:
Select objects in view
-_SelLayer _Pick → completes
I know this can be done with a script (see below). I am asking, because I need a version for my students that works without installing anything.
For others, that look for a solution that also stays within the space you are in, you can use the following script to achieve this.
#! python 3
"""
Select objects on the layers of the selected objects. Allows preselect.
The selection stays inside the active view. In model space only model objects
are picked up, in a layout only the objects sitting on that page. With a
detail view active the command works in model space and objects outside the
detail window stay unselected (avoids accidental deletions of invisible objects).
"""
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc
def filter_space(view):
if isinstance(view, Rhino.Display.RhinoPageView):
if view.ActiveViewport.Id != view.MainViewport.Id:
# A detail is active, it shows model space
return Rhino.DocObjects.ActiveSpace.ModelSpace
return Rhino.DocObjects.ActiveSpace.PageSpace
return Rhino.DocObjects.ActiveSpace.ModelSpace
def detail_viewport(view):
if not isinstance(view, Rhino.Display.RhinoPageView):
return None
if view.ActiveViewport.Id == view.MainViewport.Id:
return None
return view.ActiveViewport
def objects_of_view(obj_ids, view):
space = filter_space(view)
page_id = None
if space == Rhino.DocObjects.ActiveSpace.PageSpace:
# Page space objects carry the id of the layout they sit on
page_id = view.MainViewport.Id
viewport = detail_viewport(view)
res_objs = []
for obj_id in obj_ids:
obj = sc.doc.Objects.FindId(obj_id)
if not obj:
continue
if obj.Attributes.Space != space:
continue
if page_id and obj.Attributes.ViewportId != page_id:
continue
if viewport:
# Only what the detail camera looks at
bbox = obj.Geometry.GetBoundingBox(True)
if not bbox.IsValid:
continue
if not viewport.IsVisible(bbox):
continue
res_objs.append(obj_id)
return res_objs
def main():
objs = rs.GetObjects("Select objects", preselect=True)
if not objs:
return
rs.EnableRedraw(False)
layers = [rs.ObjectLayer(o) for o in objs]
layers = set(layers)
# Get objects by layer
res_objs = []
for lay in layers:
if lay is not None:
sel_objs = rs.ObjectsByLayer(lay, False)
if sel_objs:
res_objs.extend(sel_objs)
# Keep the objects of the active view only
view = sc.doc.Views.ActiveView
if view:
res_objs = objects_of_view(res_objs, view)
# Select
rs.UnselectAllObjects()
rs.SelectObjects(res_objs)
rs.EnableRedraw(True)
if __name__ == "__main__":
main()