What class/method does Grasshopper use when picking objects from rhino as command option


I would like to understand how command options work and what is possible there. Assume I want to create a surface from curves or points. How can I set command option that prompts the user to select objects?

I assume it’s this one :

AddOptionEnumSelectionList[T](self: GetBaseClass, englishOptionName: str, enumSelection: IEnumerable[T], listCurrentIndex: int) -> int

Could somebody give me short example how to use it?

Is this a Rhino developer question, rather than a Grasshopper developer one?

The code you pasted rings no bells for me. If you want to use the Rhino command line (and viewports) to prompt people to specify values or select objects, you must typically create a ‘getter’, then set its properties, populate it with options and perhaps specify a few filtering delegates. You can find the getters in the Rhino.Input and Rhino.Input.Custom namespaces.

Rhino.Input.RhinoGet offers a bunch of standard getter operations that do not allow you to get really creative, but they are easy to use.

Rhino.Input.Custom.GetObject is the class you want to use if your getter involves the user picking an existing object (or objects) from the Rhino document.

1 Like

Sorry, my bad I forgot to attach the screenshots. from GH.

It is I suppose both Grasshopper and Rhino question, assuming you can call same function from GH_Python



Sadly I didn’t see how I can add Rhino+Grasshopper when starting the thread that’s why I put scripts,rhinocommon,python and rhino6 as tags

Thanks, @DavidRutten, I’ll take a look.

Those “set” options come from the way you register input parameters in a grasshopper plug-in project.

Maybe you can investigate what pManager does

@piac do you know if it makes sense to create custom parameters in python and override the ‘set one’ and ‘set multiple’ items?

This is at least in part outside the scope of the project, because:

  • the SDK/compilation support was added in order to allow GH_Component classes to be compiled
  • all geometry types in Rhino should be already handled by Grasshopper natively, when that is possible

Yet, the GhPython loader mechanism is not looking specifically for custom parameters, and all instantiation happens in components setup, so they are intrinsically entirely possible.

Once compiled with the instructions at: Tutorial: creating a Grasshopper component with the Python GHPY compiler (step 2.5), this file will provide a sample of an overridden brep picker:

custompickingpython.py (2.8 KB)

from ghpythonlib.componentbase import dotnetcompiledcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg

class ParamBrepPick(Grasshopper.Kernel.Parameters.Param_Brep):
    # use a line like the one below here to see require signature
    # Grasshopper.Kernel.Parameters.Param_Brep.Prompt_Singular(
    def Prompt_Singular(self, result):
        #result is  System.Runtime.CompilerServices.StrongBox[Brep]
            g1 = Rhino.Input.RhinoGet.GetOneObject("Personal brep selection", False, Rhino.DocObjects.ObjectType.Brep)
            if g1[0] == Rhino.Input.GetResult.Object:
                geometry = g1[1].Geometry()
                if isinstance(geometry, Rhino.Geometry.Brep):
                    # use a line like the one below here to see require signature
                    # Rhino.Geometry.Brep.
                    result.Value = Grasshopper.Kernel.Types.GH_Brep(g1[1].ObjectId)
                return Grasshopper.Kernel.GH_GetterResult.success
        except Exception as ex:
            System.Windows.Forms.MessageBox.Show(ex, "Error in picking code")
        return Grasshopper.Kernel.GH_GetterResult.cancel

class PreviewEx(component):
    def __new__(cls):
        instance = Grasshopper.Kernel.GH_Component.__new__(cls,
            "Pick", "PickEx", """Component to pick something off Rhino""", "Pick", "Pick")
        return instance
    def get_ComponentGuid(self):
        return System.Guid("ae9ec8cd-f30d-48fc-9c89-04820b652268")
    def SetUpParam(self, p, name, nickname, description):
        p.Name = name
        p.NickName = nickname
        p.Description = description
        p.Optional = True
    def RegisterInputParams(self, pManager):
        p = ParamBrepPick()
        self.SetUpParam(p, "t", "t", "Pick one brep")
        p.Access = Grasshopper.Kernel.GH_ParamAccess.item
    def RegisterOutputParams(self, pManager):
        p = Grasshopper.Kernel.Parameters.Param_GenericObject()
        self.SetUpParam(p, "a", "a", "Pick one result.")
    def SolveInstance(self, DA):
        p0 = self.marshal.GetInput(DA, 0)
        result = self.RunScript(p0)
    def RunScript(self, t):
        return t

class AssemblyInfo(GhPython.Assemblies.PythonAssemblyInfo):
    def get_AssemblyName(self):
        return "pickingsample"
    def get_AssemblyDescription(self):
        return """A picking sample"""

    def get_AssemblyVersion(self):
        return "0.1"

    def get_AuthorName(self):
        return "giulio@mcneel.com"
    def get_Id(self):
        return System.Guid("66c54542-da0d-478d-a5a4-5dc0fc173feb")

So, this is possible, yet I do not think it is entirely useful except maybe for some corner cases. In general, I think this type of Grasshopper-SDK-related work is better suited to a strongly-typed language such as C#.



Giulio Piacentino
for Robert McNeel & Associates


:smiley: now after programming a bit more I understand how valuable your answer was back then.

1 Like