I haven’t tried this with Clusters, with a heavy workload or with anything complicated yet, but thanks to your code, I’ve been able to ‘remotely’ run an external component in Grasshopper, from an Iron Python 2 one. So thanks very much!
It feels safer to store external components in separate files. But all of those must be opened first, and the one with the controller only opened afterwards.
import os
import Grasshopper
import rhinoscriptsyntax as rs
def GH_doc_components(doc):
return {component.NickName : component
for component in doc.Objects
}
def set_data_on(param, val):
param.ClearData()
param.AddVolatileData(Grasshopper.Kernel.Data.GH_Path(0), 0, val)
def get_data_from(param):
return Grasshopper.DataTree[object](param.VolatileData).Branch(0)[0]
class MyComponent(Grasshopper.Kernel.GH_ScriptInstance):
def __init__(self):
# This component must be re-initialised
# after the component to be run remotely has been placed.
# or e.g. set this to run last by selecting it and pressing
# Ctrl+B
self.GH_Doc = ghdoc.Component.Attributes.DocObject.OnPingDocument()
self.GH_Doc_components = GH_doc_components(self.GH_Doc)
self.all_docs_comps = {
os.path.splitext(os.path.basename(doc.FilePath))[0] : (doc, GH_doc_components(doc))
for doc in Grasshopper.Instances.DocumentServer.GetEnumerator()
}
def RunScript(self, x, y, comp_name, gh_doc_name):
x = x or 10
y = y or 37
comp_name = comp_name or '1000*x + y'
if gh_doc_name is None:
doc, comps = self.GH_Doc, self.GH_Doc_components
else:
gh_doc_name = os.path.splitext(gh_doc_name)[0]
doc, comps = self.all_docs_comps[gh_doc_name]
comp = comps[comp_name]
set_data_on(comp.Params.Input[0], x)
set_data_on(comp.Params.Input[1], y)
comp.ExpireSolution(False)
comp.CollectData()
comp.ComputeData()
a = get_data_from(comp.Params.Output[0])
print(a)
return a
remotely_call_another_component.gh (12.7 KB)
another_gh_doc.gh (3.6 KB)