static RPI_NodeInfo ninfo = { { "CircleRamp", // node name "Circleramp", // menu name "Silicon Grail", // author "v0.1" // version "", // help URL "" // icon name }, CircleRampInit, // initialize node CircleRampShutDown, // shut down node NULL, // parameter changed NULL, // input changed CircleRampGetRegion, // return result region CircleRampGetFullSize, // return full size CircleRampGetRange, // return frame range NULL, // return errors CircleRampExec, // node execute NULL, // input label NULL, // output label NULL, // viewer label NULL, // viewer outputs 0, // min inputs 0, // max inputs 1, // min outputs 1, // max outputs CPI_FALSE // can add more inputs }
static RPI_NodeInfo ninfo = { ... 3, 3, 1, 1, CPI_FALSE }
static RPI_NodeInfo ninfo = { ... 1, 3, 1, 1, CPI_FALSE }Which means 1 required input and up to 3 total inputs.
static RPI_NodeInfo ninfo = { ... 1, 1, 1, 1, CPI_TRUE }When the "growable" flag is set to true, the value for the maximum number of inputs is ignored by RAYZ. However, the minimum value may still be used to enforce a minumum number of inputs. The node will be drawn with 'minimum' connectors, plus one more, which is the "growable" one. When that extra one is connected, another will grow. RAYZ will generate a user error for nodes which do not have their minimum input count all connected.
For example, a node which is specified like this:
static RPI_NodeInfo ninfo = { ... 3, 3, 1, 1, CPI_TRUE }will be drawn with 4 inputs, and until the first 3 are connected, RAYZ will show a user error with a message that says "Input image is not connected."
For example, this routine defines labels for a 2-input node. The labels are printed in the status line, when the user mouses over the connector. The connectors themselves are labeled with the first letter of the label string.
const char * SimpleInputLabel( CPI_Uint32 input) { static const char input1[] = {"foreground image"}; static const char input2[] = {"background image"}; if ( input == 0 ) return input1; else return input2; }
The resulting node would look like this: | ![]() |
Then each output usually has several output viewers, or views. These are called views because they may only be (in many cases) viewed in an Image Viewer. They cannot be piped downstream to another node.
By default, a node has 1 output. Also by default, it has 1 viewer for each input, plus one for the output. Those viewers allow the user to see each of the node's inputs, plus (of course) the result of the node's operations.
To see this, drop a simple filter node, such as Blur, onto the RAYZ worksheet. Then go to the top line of the Image Viewer, and look at the menu labeled "Source". This allows the user to choose the view to be displayed in the viewer. By default, this is set to "Output", which is the result of the node's processing. But notice that it can be set to "Input Image". For a multi-input node, such as Ultimatte PFG, each connected input results in another entry in the Source menu.
static RPI_NodeInfo ninfo = { { "CircleRamp", // node name "Circleramp", // menu name "Silicon Grail", // author "v0.1" // version "", // help URL "" // icon name }, CircleRampInit, // initialize node CircleRampShutDown, // shut down node NULL, // parameter changed NULL, // input changed CircleRampGetRegion, // return result region CircleRampGetFullSize, // return full size CircleRampGetRange, // return frame range NULL, // return errors CircleRampExec, // node execute NULL, // input label NULL, // output label NULL, // viewer label NULL, // viewer outputs 0, // min inputs 0, // max inputs 2, // min outputs 2, // max outputs CPI_FALSE // can add more inputs }(In fact, in RAYZ 1.0, the 'max outputs' value is ignored, but is there for future expansion)
To label these outputs for the user, you define a node output label function, which is analogous to the one for input labels (see above). This routine takes an output number (starting from 0) and returns a string which labels it. This label is printed in the status line when the user places the mouse over the output connector.
The plugin programmer knows which output is being requested from the value being passed into the GetRegion and Exec routines. The plugin ChannelSplit.C shows how this works, and should be used as a reference for doing this.
// the number returned is the number of extra viewer outputs your // are making available to the user. There are at least 2 by default // already (see above). CPI_Uint32 NewNodeViewerOut( CPI_Uint32 nodeOutput ) { return 1; } // return a label for each of the extra viewers you have added. // You cannot relabel the default viewers, just the one(s) you have // added. const char * NewNodeViewerLabel( CPI_Uint32 nodeOutput, CPI_Uint32 whichViewer ) { static const char view1[] = {"sparkle matte"}; // assuming only one output, 1 extra viewer (which is number 0) if ( whichViewer == 0 ) return view1; } // note these routines are declared in the structure static RPI_NodeInfo ninfo = { { "newnode", // node name "New Node", // menu name "Silicon Grail", // author "v0.1" // version "", // help URL "" // icon name }, NewNodeInit, // initialize node NewNodeShutDown, // shut down node NULL, // parameter changed NULL, // input changed NewNodeGetRegion, // return result region NewNodeGetFullSize, // return full size NewNodeGetRange, // return frame range NULL, // return errors NewNodeExec, // node execute NULL, // input label NULL, // output label NewNodeViewerLabel, // viewer label NewNodeViewerOut, // viewer outputs 0, // min inputs 0, // max inputs 2, // min outputs 2, // max outputs CPI_FALSE // can add more inputs }