Tutorial: creating a Grasshopper component with the Python GHPY compiler

6 posts were split to a new topic: Problems loading GHPY assembly

Hi, Giulio. Happy New Year. Thanks for your toturial, that’s very helpful.
But there is a error that troubles me a lot and I can’t figure out why. Here is the code:

from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

class MyComponent(component):
    def RunScript(self, crv_id):
        sc.doc = Rhino.RhinoDoc.ActiveDoc
        crv_o = sc.doc.Objects.Find(crv_id)
        a = crv_o.Attributes.Name
        sc.doc = ghdoc
        return a

Compiling this code follow your tutorial, I got a new GH component without any error. But when I put this component into canvas and loaded input it get red and says:

Solution exception: global name “ghdoc” is not defined.

Do you know why? Can’t run correctly after compiling into GH component. But this code runs OK before the final step.

I have change “ghdoc” into GhPython.DocReplacement.GrasshopperDocument() and solved this problem. I hope I’m not disturbing you.

1 Like

Thanks, this is reported at RH-43345.

Hi,Giulio Piacentino.
Is user have to install IronPython to load ghpy files as GH plug-in into Rhino?
And can Rhino5 support ghpy files?

Hi Giulio!
Following your tutorial 1. Compiling a single component in an assembly with the wizard
I have a Runtime error


and the compile did not work
GHPython%20compilatin%20error
could you tell me how to fix it? why the name ‘component’ is not defined, is not defined already in line 18 ?
classs MyComponent(component):

Thanks in advance!

The import part should not be within the triple-quotes. Pay attention to that! @andresobregonlopez

Hi @piac,

I use this code below often to dynamically add/remove inputs. Is there a way to translate this functionality within the compiled component?

   # automnatically set the right input names and types (when using + icon) 
    numInputs = ghenv.Component.Params.Input.Count
    accessList = ghenv.Component.Params.Input[0].Access.list
    accessItem = ghenv.Component.Params.Input[0].Access.item
    typeFloat = GhPython.Component.NewFloatHint()
    typeBool = gh.Parameters.Hints.GH_BooleanHint_CS()
    
    for input in range(numInputs):
        access = accessList
        typeHint = typeString   
        if input == 0: inputName = 'width'; access = accessItem; typeHint = typeFloat
        elif input == 1: inputName = 'thickness'; access = accessItem; typeHint = typeFloat
        elif input == 2: inputName = 'spacing'; access = accessItem; typeHint = typeFloat
        elif input == 3: inputName = 'rotation'; access = accessItem; typeHint = typeFloat
        elif input == 4: inputName = 'offsetFromWall'; access = accessItem; typeHint = typeFloat
        elif input == 5: inputName = 'verticalOrientation' ; access = accessItem; typeHint = typeBool   
        else: continue
        
        ghenv.Component.Params.Input[input].NickName = inputName
        ghenv.Component.Params.Input[input].Name = inputName
        ghenv.Component.Params.Input[input].Access = access
        ghenv.Component.Params.Input[input].TypeHint = typeHint
    ghenv.Component.Attributes.Owner.OnPingDocument()

Hi @sgaray

if you are doing this from an event handler, then it should be fine. Never do this within a solution.

Just keep in mind that you’ll need to use standard Grasshopper input parameters, not Hint-based scripting parameters. Compile a sample component with the Hints that you need, then choose to copy the code. It will show exactly what types are expected.

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

@piac
I was doing it from the solution itself, will follow your suggestion.Thanks!

A post was split to a new topic: Problems creating GHPY files

2 posts were split to a new topic: Documentation strings not used in GH_Component SDK mode

A post was split to a new topic: clr.AddReference() for compile GHPYs

@piac,

Can the other sections of the compiling window be defined from inside the code?

image

Thanks

They cannot, sorry.

If you compile often or more than a single component, you must compile all components on your own using clr.CompileModules(). Do not ship dozens of components in single GHPYs, because the loading time for each single GHPY is quite long (it does not take almost any longer to load 1 to 10 components in the same file).

1 Like

QQ%E6%88%AA%E5%9B%BE20190126222010
I like this battery. How is this battery code written??

Sorry, I’m not sure what you mean from your post.
But if you are wondering about the name tag above the component, that probably comes from the Bifocals plugin.

@piac, I was wondering if you could clarify this please? Is setting node properties like this fine in the initial lines of a uncompiled GhPyton node?

Hi Anton,

nice blog!

I think I need to see a sample of your code to understand what you ask. General, registering inputs and outputs should be done from the methods that are meant for that:

and:

This will ensure that the methods get called only when Grasshopper needs them. When you copy the compilable code, the boilerplate generator creates these methods for you, using similar inputs as the ‘Hints’ options you chose for the scripting components. Because of the intricacies of the Grasshopper SDK, a Hint is not a Param by itself, so there is a translation.

You can also change the network topology or the solution properties (tree, list, ecc) from other methods. This may or may not have unintended consequences. Especially bad is if you change them while the solution runs. If you do this, you might be getting two results: if you do that from the SolveInstance method, you might stack overflow, as solving will call your method that will call solve that will call your method…

The other option, if you change these from another thread, is that you may not see any results or the solver may crash. So, in few words: do not change the network topology, solution properties (locked, etc) or options (list, tree access, longest list, etc) while the solution runs.