Using the NodeInCode namespace

ghpython
rhinocommon
ghpythonlib
grasshopper
nodeincode

(Giulio Piacentino) #1

As some noticed some time ago, we have been working on NodeInCode functionality.

The goal was to make this functionality more understandable: with warnings that could give useful suggestions, stable: also when used with multi-threading, and more robust to cases where third-party libraries would not cooperate.

While at it, we decided to allow every .Net language, to access this functionality. Some of you noticed a while back, when we were actively changing this most weeks: Rhino.NodeInCode namespace?

Now it’s time to explain how NodeInCode works.

1. Finding a loaded Grasshopper component.

All components that are loaded (with a minimal set of exceptions^) can be found. You just need to know their full name. If the component names comes from a library, then the library names is pre-pended, with an underscore _ as separator. The exact spelling of the library depends from the AssemblyName of the GHA. If you are having issues finding what it exactly is, you can just query all dynamic names like this:

A = Rhino.NodeInCode.Components.NodeInCodeFunctions.GetDynamicMemberNames();
node-in-code-dynamic-names.gh (13.9 KB)

2. Evaluating a component

Any component that can be found can then be evaluated.

node-in-code.gh (7.8 KB)

The same is also possible outside of Grasshopper, for example,

node-in-code.py (539 Bytes)

The only catch is that, at present, there is no way to switch components that have special settings to any alternative. For example,

no-conversion

3. .Net delegates (“function pointers”)

Some developers are used to directly evaluating a method without going through an “Evaluate” function. Especially when writing functional code in .Net, it might be beneficial to get directly a delegate.

This is also supported, in a few different flavors. The flavor mostly deal with how warnings are issues, thereby making it simpler to develop and then possibly switch to a more warning-tolerant system^^. The ComponentFunctionInfo has Delegate, DelegateNoWarnings, DelegateTree and DelegateTreeNoWarnings properties, returning the appropriate type of result.

Delegates are returned in the form of a Func<object,object,...> generic instance. Because of this, the number of inputs needs to match exactly the amount of inputs of the component. This is in contrast with the Evaluate() method, where Optional inputs at the bottom of a component can just be omitted.

node-in-code-delegates.gh (11.9 KB)

Notes

^ at present you cannot find: scripting components themselves, GHPY compiled components, params and third-party add-ons components that have names consisting of only non-ASCII characters.

^^ please note that DynamicInvoke() will wrap exceptions within TargetInvocationExceptions. You can retrieve the inner exception with the InnerException property. You can get Grasshopper to visualize the exception by writing:

try
{
  B = ((Delegate) y).DynamicInvoke(new object[]{"1,1,0", "2,3,0", "-2,3,0"}, "World XY", "1.1,2,0", null);
}
catch (TargetInvocationException tex)
{
  throw tex.InnerException;
}

Rhino.NodeInCode namespace?
(Giulio Piacentino) #2

A post was split to a new topic: Asynchronous issues with NodeInCode