-
Notifications
You must be signed in to change notification settings - Fork 1
Zero Touch Plugin Development
This page outlines the process of developing a custom Dynamo node in C# using the "Zero Touch" interface
An example Visual Studio 2012 project can be found here: https://github.com/hlp/ZeroTouchEssentials
In most cases, C# static methods and Classes can be imported without modification. If your library only needs to call functions, and not construct new objects, this can be achieved very easily with static methods. When Dynamo loads your DLL, it will strip off the namespace of your classes, and expose all static methods as nodes. For instance, we can create a node that takes a single number and multiplies it by 2 as follows:
namespace ZeroTouchExample
{
public class ZeroTouchExample
{
public static double MultByTwo(double inputNumber)
{
return inputNumber * 2.0;
}
}
}
A node will appear in the Dynamo menu called "MultByTwo" in the "ZeroTouchExample" category. It will have one input, called "inputNumber".
Accepting multiple inputs into a node is easy: just specify multiple parameters to your C# function. Returning multiple values from a node requires slightly more work. First step is to reference "ProtoInterface.dll" in your project, found in the Dynamo install location, and add "using Autodesk.DesignScript.Runtime;" to the top of your C# script. The second step is to add the "MultiReturn" attribute to your function. It should contain an array of strings, containing the names of the output ports. Your function should then return a Dictionary<string, object> containing the returned values. The keys to your dictionary should match the parameter names in your attribute. For example:
using Autodesk.DesignScript.Runtime;
namespace ZeroTouchExample
{
public class ZeroTouchExample
{
[MultiReturn(new[] { "add", "mult" })]
public static Dictionary<string, object> ReturnMultiExample(double a, double b)
{
return new Dictionary<string, object>
{
{ "add", (a + b) },
{ "mult", (a * b) }
};
}
}
}
This creates a new node that outputs two doubles, "add" and "mult" containing the addition and multiplication of the two input numbers.
Dynamo doesn't have a "new" keyword, so objects need to be constructed via static constructors. Dynamo uses the "By" prefix to indicate a static method is a constructor, and while this it is optional, using "By" will help your library better fit into the existing Dynamo style.
namespace ZeroTouchExample
{
public class MyLine
{
private double _x1;
private double _y1;
private double _x2;
private double _y2;
public static MyLine ByStartPointEndPoint(double x1, double y1, double x2, double y2)
{
_x1 = x1;
_y1 = y1;
_x2 = x2;
_y2 = y2;
}
public double Length()
{
return Math.sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
}
}
}
Dynamo libraries can also use native Dynamo geometry types as inputs, and create new geometry as outputs. The first step is to reference both "ProtoGeometry.dll" and "ProtoInterface.dll" in your project, and include "using Autodesk.DesignScript.Interfaces;" and "using Autodesk.DesignScript.Geometry;" in the top of your C# file. Dynamo geometry objects are then used like any other passed object to your functions. For example, we can clean up our MyLine example above by using Dynamo's native geometry types:
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Geometry;
namespace ZeroTouchExample
{
public class MyLine
{
private Autodesk.DesignScript.Geometry.Point _p1;
private Autodesk.DesignScript.Geometry.Point _p2;
public static MyLine ByStartPointEndPoint(Autodesk.DesignScript.Geometry.Point p1, Autodesk.DesignScript.Geometry.Point p2)
{
_p1 = p1;
_p2 = p2;
}
public double Length()
{
return Math.sqrt(Math.Pow(_p2.X- _p1.X, 2) + Math.Pow(_p2.Y - _p1.Y, 2));
}
}
}
It's best practice to add documentation to your Dynamo nodes. This is done through XML documentation tags. The main documentation for your node should be in the "
Control over how your node appears in the Dynamo search results is similarly controlled through the "..." XML documentation tag. This tag should contain a comma-separated list of search terms that, if matched, will cause your node to appear in search results.
We can add documentation an search to our original example as follows:
namespace ZeroTouchExample
{
public class ZeroTouchExample
{
/// <summary>
/// This is an example node demonstrating how to use the Zero Touch import mechanism.
/// It returns the input number multiplied by 2.
/// </summary>
/// <param name="inputNumber">Number that will get multiplied by 2</param>
/// <search>
/// example, multiply, math
/// </search>
public static double MultByTwo(double inputNumber)
{
return inputNumber * 2.0;
}
}
}