Hi McNeel and other experts
Do you know the best way to programmatically create a RhinoCodePluginGH component (Rhino 8 C# and Python script components)?
I have these aspects in mind:
- creating a new script component instance
- setting the inputs & outputs parameters, with type hints and persistent data
- setting the source code & ensuring that the
RunScript
method signature matches the inputs & outputs
In my experimentation so far, for Rhino 7, this works well:
- a new instance is created through
Activator.CreateInstance
- set up inputs & outputs by
- creating
Param_ScriptVariable
objects - assigning objects to
Param_ScriptVariable.TypeHint
to set the type, and - adding them via
Params.RegisterInputParam
andParams.RegisterOutputParam
.
- creating
- to set the source code using,
- for C#: the
ScriptSource.ScriptCode
,ScriptSource.AdditionalCode
andScriptSource.UsingCode
properties, - and for Python, the
Code
property
- for C#: the
However for Rhino 8:
- I could actually set the inputs and outputs the same way using the legacy registration, but somehow it ends up with the
RunScript
signature seemingly not respecting the type hints, not reflecting these inputs/outputs, so it doesn’t work. Intriguingly, when I look at the XML for the component instance created this way, theConverterData
chunk (needed for Rhino 8 it seems) isn’t there - there seems to be no source code property, although I find that serialising it to XML, using
XDocument
to parse and find theScript
chunk, encoding the code to base64 and assigning it to theText
item before deserialising it into a component instance, seems to work - except for theRunScript
signature of course - but this does feel a little ‘hacky’
Is there a better way to do it? There might be no public API for it but if anyone can share the next best thing, the next most reliable mechanism, I’d much appreciate it. Is there a plan at McNeel to offer a sanctioned way to do this at some point?
I did actually fid one way that seems to work for Rhino 8, fulfilling all my requirements: I have a template script component (that I load from file or have stored as static content) which has one of every type of input, and I just clone the parameters and add them to a newly created instance, before setting the source code using the XML method. The types are then respected & reflected in the RunScript
signature, and it works.
Any thoughts on this?