axa
April 21, 2020, 12:11pm
1
Is there a way of triggering an event every time a new object is added to the selection?
I am trying to write a custom block picker that adds all instances of the block that the user has just picked to the selection, and print how many instances of the block it has found.
My code so far is largely based on this thread:
I think adding the EnablePreSelect(False) like menno suggests plus a couple of small tweaks does what you want:
def TestGetObjects_OptionList():
go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select objects")
go.EnableClearObjectsOnEntry(False);
go.EnableUnselectObjectsOnExit(False);
go.DeselectAllBeforePostSelect = False;
listValues = ["DoThis", "DoThat", "DoNothing"]
opList = go.AddOptionList("List", listValues, 2)
while True:
getResult = go.Get…
Thank you
Are you looking for RhinoDoc.SelectObjects event?
Here you can find a simple implementation in Grasshopper:
[SelectedObjects]
private void RunScript(ref object A)
{
if(!_init)
{
Rhino.RhinoDoc.SelectObjects -= RhinoDocOnSelectObjects;
Rhino.RhinoDoc.SelectObjects += RhinoDocOnSelectObjects;
Rhino.RhinoDoc.DeselectObjects -= RhinoDocOnSelectObjects;
Rhino.RhinoDoc.DeselectObjects += RhinoDocOnSelectObjects;
Rhino.RhinoDoc.DeselectAllObjects -= RhinoDocOnDeselectAllObjects;
Rhino.RhinoDoc.DeselectAllObjects += RhinoDocOnDeselectAllObjects;
_init = tr…
axa
April 21, 2020, 1:39pm
3
Hm, I’m not sure how I would add this to my code. Rhino common is not my forte
def getBlocksWithDirection():
msg = "Select blocks"
go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt(msg)
toggle = Rhino.Input.Custom.OptionToggle(True, '+x', '-y')
go.AddOptionToggle('Arrange', toggle)
go.EnablePreSelect(True, True)
go.GeometryFilter = Rhino.DocObjects.ObjectType.InstanceReference
objs = []
while True:
# https://discourse.mcneel.com/t/get-multiple-objects-plus-list-option/14849/3
get = go.GetMultiple(1, 0)
if get == Rhino.Input.GetResult.Cancel:
return False
elif get == Rhino.Input.GetResult.Option:
continue
elif get == Rhino.Input.GetResult.Object:
ids = [go.Object(i).ObjectId for i in range(go.ObjectCount)]
return (ids, toggle.CurrentValue)
return False
You mean something like this?
import Rhino
def getBlocks():
go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select blocks")
go.OneByOnePostSelect = True
go.GeometryFilter = Rhino.DocObjects.ObjectType.InstanceReference
while True:
go.Get()
if go.CommandResult()!=Rhino.Commands.Result.Success:
return go.CommandResult()
instance = go.Object(0).Object().InstanceDefinition
print "There are {} references of {}".format(instance.GetReferences(0).Count, instance.Name)
go.SetCommandPrompt("Select blocks. Press Enter when done")
if __name__ == "__main__":
getBlocks()
GetBlocks.py (634 Bytes)
import Rhino
from scriptcontext import doc
def getBlocks():
go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select blocks")
go.OneByOnePostSelect = True
go.GeometryFilter = Rhino.DocObjects.ObjectType.InstanceReference
go.DeselectAllBeforePostSelect = False
while True:
go.Get()
if go.CommandResult()!= Rhino.Commands.Result.Success:
return go.CommandResult()
instance = go.Object(0).Object().InstanceDefinition
references = instance.GetReferences(0)
for reference in references:
reference.Select(True)
doc.Views.Redraw()
print "There are {} references of {}".format(references.Count, instance.Name)
go.SetCommandPrompt("Select blocks. Press Enter when done")
if __name__ == "__main__":
getBlocks()
GetBlocks.py (845 Bytes)
2 Likes
axa
April 22, 2020, 10:20am
6
This is amazing, Mahdiyar. Thank you. Please let me ask you one last question:
After selecting the blocks, when I hit Enter or right-click, the return value is Rhino.Commands.Result.Cancel. How would I return all the selected block GUIDs (from user click, and the additional ones)? I also have an OptionToggle, whose state needs to be returned.
Thank you so much