Grand. I’ve got this working for my own purposes (automated testing of a plug-in), and have pacakged it, and put it on PyPi as Cheetah_GH, but make no promises how robust it is yet.
Basically, if you’ve already got a component placed, you can find all the components on the canvas using:
GH_DOC = ghdoc.Component.Attributes.DocObject.OnPingDocument()
GH_DOC_COMPONENTS = {component.NickName : component
for component in doc.Objects
}
Place Domain, Random and (Colour) Gradient components manually to test this.
References to them can be found via their visible names, if you turn off view icons (their .NickName
attributes), e.g.:
GHRandomComponent = GH_DOC_COMPONENTS['Random']
GHGradientComponent = GH_DOC_COMPONENTS['Gradient']
GHDomainComponent = GH_DOC_COMPONENTS['Dom']
These can be run via something like:
domain_retvals = run_comp(GHDomainComponent, A=L0, B=L1)
random_retvals = run_comp(GHRandomComponent, R = domain_retvals['I'], N=N, S = random_int(0, 250000))
gradient_retvals = run_comp(GHGradientComponent, L0=L0, L1=L1, t = random_retvals['nums'])
where I defined run_comp
as:
def run_comp(comp, **kwargs):
comp.ClearData()
# comp.ExpireSolution(False)
for param in comp.Params.Input:
if param.NickName in kwargs:
set_data_on(param, kwargs[param.NickName])
comp.CollectData()
comp.ComputeData()
return {param.NickName : get_data_from(param)
for param in comp.Params.Output
}
def set_data_on(param, val, type_ = str):
param.ClearData()
# "and isinstance(val, Grasshopper.DataTree[object])""
# mimicks Grasshopper support for passing a list into a Tree access param
if (param.Access == Grasshopper.Kernel.GH_ParamAccess.tree
and isinstance(val, Grasshopper.DataTree[object])):
#
gh_struct = DataTree_to_GH_Struct(val, type_)
param.AddVolatileDataTree(gh_struct)
elif isinstance(val, (list, tuple)):
for i, item in enumerate(val):
param.AddVolatileData(Grasshopper.Kernel.Data.GH_Path(0), i, item)
else:
param.AddVolatileData(Grasshopper.Kernel.Data.GH_Path(0), 0, val)
and
def get_data_from(param):
if param.Access == Grasshopper.Kernel.GH_ParamAccess.tree:
# return param.VolatileData
return GH_Struct_to_DataTree(param.VolatileData)
data_tree = Grasshopper.DataTree[object](param.VolatileData)
if data_tree.DataCount >= 1: # Alternative: param.VolatileDataCount >= 1
return [convert_GH_type_to_Python_type(x) for x in data_tree.AllData()]
else:
branch = data_tree.Branch(0)
return branch[0] if branch else None
raise NotImplementedError('Unsupported Param.Access value %s. '
+'Supported: item, list and tree. '
% param.Access
)
It was fiddly, but I did get this to work for input params in Item, List and Tree mode.
There are two more functions called from there, so it’s probably easiest just refer to, or import the library: