Grasshopper Automation python - script not waiting

Hello everyone, I am hoping if anyone could help me with a problem I have stumbled upon and tryinf to fix for ca couple of days now.

I am working on a project that consists of automating a series of grasshopper definitions. The python scripts open the grasshopper definitions, places data, sets slider values, gets the final data and places it an another definition and so on…

One of my definitions uses anemone, processes data in a loop and takes quite some time to process.
However, even though the definition hasn’t arrived at the final state, the script keeps on going, placing wrong data in the ouput component and thus breaking the rest of the automation process.

I have spent days trying to find a solution such as trying to schedule a solution, using events to trigger the rest of the code, changing the grasshopper definition to buffer data at some point and so on, but I haven’t made any progress in solving this problem… I have alrady explored a lots of existing topics on the forum attempting to solve the problem.

Could someone look at my code and tell me if there are any possible solutions and how to correct my code? Your help would be very much appreciaited :slight_smile:

Here is my code, before doing any alterations on my side:

Here is where the code is supposed to wait for the grasshopper definition to finish processing

        # Set config sliders
        config_sliders = self.get_sliders(self.config.master_plan_sliders)
        self.set_slider_values(self.config.master_plan_sliders, config_sliders)

        # Place data in input
        self.place_data('COMPONENT_NAME', block_data.main_data)

        # Code keeps on going here before the previous line has finished processing

This is what the def place_data looks like:

    # Get the component object
    # This function returns the component that has a particular nickname
    inputComponent = self.find_by_nickname(component_name)

    # Clear the component data if needed
    if clear_data:
        inputComponent.PersistentData.Clear()
        inputComponent.ExpireSolution(True)

    inputComponent.SetPersistentData(data)
    inputComponent.ExpireSolution(True)

Thank you for your time and attention and looking forward to speaking with you

1 Like

If there’s no good reason for it to be this complicated, with components calling and setting each other, heavily simplify it. Work with Grasshopper, not against it.

Grasshopper definitions can be run from the command line, which can be called from a regular external Python process calling subprocess.run, or even just a batch file. I would just use GhPython components to read the inputs from a file, and connect their outputs to whatever needs them in the GH definition, instead of using .SetPersistentData.

What are you actually running the Python code in, yet another GH definition? That all seems tricky to understand and get to work, even with just the unusual method calls.

Hello James,

Thank you very much for your answer!
Regarding your first part of your answer, I would be very interested in discovering a simplified version on what I have been working on.

The python code I am running is external from rhino. I run an IronPython script from the runpythonscript command line from rhino an the whole automation starts. What do you mean by method calls?

Thank you again for your answer, I hope I answered your questions

What I use to call a GH Definition from the command line (to build the components for a Plug-in) is (you don’t need that start " " outside of a batch file):

start " " "C:\Program Files\Rhino 7\System\Rhino.exe" /nosplash /runscript="-_grasshopper _editor _load _document _open C:\Path\To\Your_Grasshopper_Definition_Name.gh _enter _exit _enterend"

I never imagined interacting with GH Definitions from an external IronPython process, let alone thought was possible.

I’d make the simplest possible GH Definition, e.g. that writes something to a text file, to prove these lines cannot, or actually can set data and recompute the definintion:

    inputComponent.SetPersistentData(data)
    inputComponent.ExpireSolution(True)

Objects in Python and a lot of languages have attributes, which in Python (and in C# and JS), is the name after a . immediates after the object name. If an attribute is not callable, it’s a property. If it is callable it’s a method (if you can put () after it, exactly like a function call) .

In Python modules and functions within them use exactly the same syntax.

I understand the confusion, clearly some things could be unusual as I learned Python by myself on the go.

I know that the code is working properly because when debugging in the python editor, when moving step by step, and waiting for the solution to finish, the code works and everything is set properly. I get unsatisfactory results only when I run the complete python script