Custom input GetObject() infinite while loop


#1

using: rhino python

hello, I am trying to have a user select a series of mesh edges, and after each selection run a function which uses the selected mesh edge index. The idea is to let the user select either single edges or chains of edges associated with a single edge. Thus the code should ask the user to select an edge, with the options of making it a chain or leaving it alone.

I found this example for getting a point with command line options in the rhinocommon docs. With the ‘break’ statement removed (as I did below) one can set any number of points, with options:

import Rhino
import scriptcontext

def CommandLineOptions():
  
  gp = Rhino.Input.Custom.GetPoint() #if this is changed to GetObject() rhino gets stuck.
  gp.SetCommandPrompt("GetPoint with options")

  # set up the options
  intOption = Rhino.Input.Custom.OptionInteger(1, 1, 99)
  dblOption = Rhino.Input.Custom.OptionDouble(2.2, 0, 99.9)
  boolOption = Rhino.Input.Custom.OptionToggle(False, "Off", "On")
  listValues = "Item0", "Item1", "Item2", "Item3", "Item4"

  gp.AddOptionInteger("Integer", intOption)
  gp.AddOptionDouble("Double", dblOption)
  gp.AddOptionToggle("Boolean", boolOption)
  listIndex = 3
  opList = gp.AddOptionList("List", listValues, listIndex)
  gp.Get()
  while True:
    get_rc = gp.Get()
    if gp.CommandResult()!=Rhino.Commands.Result.Success:
        return gp.CommandResult()
    if get_rc==Rhino.Input.GetResult.Point:
        point = gp.Point()
        scriptcontext.doc.Objects.AddPoint(point)
        scriptcontext.doc.Views.Redraw()
        print "Command line option values are"
        print " Integer =", intOption.CurrentValue
        print " Double =", dblOption.CurrentValue
        print " Boolean =", boolOption.CurrentValue
        print " List =", listValues[listIndex]
    elif get_rc==Rhino.Input.GetResult.Option:
        if gp.OptionIndex()==opList:
          listIndex = gp.Option().CurrentListOptionIndex
        continue
    #break #I removed this so that one can pick any number of points
  return Rhino.Commands.Result.Success


if __name__ == "__main__":
    CommandLineOptions()

this is basically exactly what I want to be able to do, but for meshEdges. I would have the loop break if a user presses ‘enter’ or ‘esc.’ Unfortunately, if I change the above code to use Rhino.Input.Custom.GetObject() in place of Rhino.Input.Custom.GetPoint(), rhino stops responding. I have tried playing around with Dispose() but that does not seem to help.

Alternatively, is it possible to use GetMultiple(), but tag each selection with input from the command line options? Or is there a better way of doing this? why is this happening?
thanks in advance!


(Menno Deij - van Rijswijk) #2

I’m not intimately familiar with the Python syntax, but it looks an awful lot like the C# stuff I write.

Two things I notice: First, if you want to select multiple objects, why not do GetMultiple

GetObject go = Rhino.Input.Custom.GetObject();
while True:
    get_rc = go.GetMultiple(<min>,<max>)
    objects = go.Objects()
    etc. etc

The second thing is: once you select an object, it stays selected and you shoot through

gp.Get()

with the selected object, getting you into an infinite loop like you describe.
The solution is to unselect all objects after each while iteration. I’m not sure how to do this in Python; in C# it is

RhinoDoc.ActiveDoc.Objects.UnselectAll(true);

#3

Your second suggestion worked! this makes a lot of sense.
in rhino python: (using scriptcontext)

scriptcontext.doc.Objects.UnselectAll()

the GetMultiple() is also a good solution, but in this case I want a function to be called each time a user picks an edge.
thanks so much!