Hi Nathan,
thanks for you prompt reply.
Hello Luis @fraguada and Andy @AndyPayne,
I’m trying to set and get values to/from a headless Grasshopper with rhino.inside and cpython. Here is my current code, adapted from the examples above (here and here). It’s a dummy example - the GH file contains some simple components (Addition, Line, Integer, Number) for which I try to set or retrieve data (internalized or computed).
Setting inputs in “Addition” component seems to work (no errors). But to retrieve data, I struggle to get values and geometry out of the IGH_Goo
objects: e.g. CastTo(Grasshopper.Kernel.Types.GH_Number()
and CastTo(Rhino.Geometry.NurbsCurve())
return success: False
and values are zero.
What is the proper way of doing this?
Also, as a newbie to GH SDK, I am not sure if the GH solution has run properly at all (whether I should expected it to run correctly with this code).
The files to reproduce: inside_addition_mix.gh inside_addition_mix.py

#WIP with python3.7, Rhino 7 on Windows10
import os
import random
import rhinoinside
rhinoinside.load()
import Rhino #any difference to "Rhino = rhinoinside.Rhino" ?
#Start grasshopper in "headless" mode
pluginObject = Rhino.RhinoApp.GetPlugInObject("Grasshopper")
if pluginObject: pluginObject.RunHeadless()
import Grasshopper
from Grasshopper.Kernel import GH_SolutionMode
from Grasshopper.Kernel.Data import GH_Path
from Grasshopper.Kernel.Types import GH_Number
currentpath = os.path.dirname(__file__)
filename = "inside_addition_mix.gh"
ghfile = os.path.join(currentpath, filename)
if not os.path.exists(ghfile): print("This file does not exists:", ghfile)
ghdocIO = Grasshopper.Kernel.GH_DocumentIO()
ghdocIO.Open(ghfile)
ghdoc = ghdocIO.Document
ghdoc.Enabled = True
#ghdoc.ExpireSolution() #needed?
for obj in ghdoc.Objects:
#Example 1: Set input values A and B to an "Addition" component and retrieve the Result.
if obj.NickName == "Addition":
print("* GH component: ", obj.NickName, obj.Name, obj.Category, type(obj))
component = Grasshopper.Kernel.IGH_Component(obj)
for inp in component.Params.Input:
inp.VolatileData.Clear()
n = float(random.randint(0, 100))
ghn = GH_Number(n)
inp.AddVolatileData(GH_Path(0), 0, GH_Number(n))
print(f"\tSet input {inp.NickName} to {ghn}")
component.ComputeData() #needed?
#ghdoc.NewSolution(True, GH_SolutionMode.Silent) #needed?
for outp in component.Params.Output:
outp.CollectData() #needed?
outp.ComputeData() #needed?
print(f"\tGet output {outp.NickName}")
pathcount = outp.VolatileData.PathCount
for idx in range(pathcount):
b = outp.VolatileData.get_Branch(idx)
for item in b:
#type(item): Grasshopper.Kernel.Types.IGH_Goo
success, number = item.CastTo(Grasshopper.Kernel.Types.GH_Number())
print("\t\titem:", type(item), "-->", success, number, number.Value)
# Example 2: Get a value stored in a component of a Category "Params"
if obj.NickName in ("InternalizedInteger" , "AdditionResult"):
print("* GH component: ", obj.NickName, obj.Name, obj.Category, type(obj))
param = Grasshopper.Kernel.IGH_Param(obj)
param.CollectData()
param.ComputeData()
for item in param.VolatileData.AllData(True):
success, number = item.CastTo(Grasshopper.Kernel.Types.GH_Number())
print("\t\titem:", type(item), "-->", success, number, number.Value)
# Example 3: Retrieve a geometric object (a line):
if obj.NickName == "InternalizedLine":
print("* GH component: ", obj.NickName, obj.Name, obj.Category, type(obj))
param = Grasshopper.Kernel.IGH_Param(obj)
param.CollectData()
param.ComputeData()
for item in param.VolatileData.AllData(True):
#success, line = item.CastTo(Rhino.Geometry.Line()) #!!! TypeError: No method matches given arguments for Line..ctor: ()
success, line = item.CastTo(Rhino.Geometry.NurbsCurve())
print("\t\titem:", type(item), "-->", success, line)
print("\t\t",line.PointAtStart, line.PointAtEnd) #should be [1,1,0] and [2,2,0]
Many thanks for any nudge or hint 