Softimage SDK Programmer's Guide > Customizing Softimage using the SDK > Custom ICENodes > Registering a Custom ICENode >

# Registration Example

This example demonstrates how to define and register an ICENode with two input ports and two output ports:

    #include <xsi_application.h>
    #include <xsi_mdnodecontext.h>
    #include <xsi_mdnodedef.h>
    #include <xsi_pluginregistrar.h>
    #include <xsi_status.h>
    #include <xsi_factory.h>
    #include <xsi_math.h>
    #include <xsi_vector3f.h>
    #include <xsi_indexset.h>
    #include <xsi_dataarray.h>

    using namespace XSI;
    using namespace MATH;

    // user defined IDs
    enum IDs
    {
    	// groups
    	IdGr_In,

    	// ports
    	IdPort_InPos = 100,
    	IdPort_OutX,
    	IdPort_InValue,
    	IdPort_OutY,

    	// maps
    	typemapid = 200,
    	structmapid,
    	contextmapid,

    	UndefinedID = ULONG_MAX
    };

    XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
    {
    	in_reg.PutAuthor(L"Softimage");
    	in_reg.PutName(L"ICENode registration sample plugin");
    	in_reg.PutVersion(1,0);

    	Application app ;

    	// Creates an ICENodeDef object from the factory
    	Factory factory = app.GetFactory();
    	ICENodeDef nodeOpDef = Application().GetFactory().CreateICENodeDef( in_name );

    	// Set the threading model to multi-threading (default)
    	CStatus st;
    	st = nodeOpDef.PutThreadingModel( siICENodeMultiThreading );
    	st.AssertSucceeded( ) ;

    	// Create the input port
    	st = nodeOpDef.AddPortGroup( IdGr_In );
    	st.AssertSucceeded( ) ;

    	// Create the input port of type Vector3f per vertex
    	siICENodeDataType nDataType = siICENodeDataVector3;
    	siICENodeStructureType nStructType = siICENodePortStructureSingle;
    	siICENodeContextType nContextType = siICENodeEvaluationContextComponent0D;

    	// constraint maps are not used for data and structure types, set them with the default ID
    	IDs typemapValue = UndefinedID;
    	IDs structmapValue = UndefinedID
    	IDs contextmapValue = contextmapid;

    	st = nodeOpDef.AddInputPort(
    		IdPort_InPos, // input port index
    		IdGr_In, // index of group to add port to
    		nDataType, // data type for port
    		nStructType, // structure type for port
    		nContextType, // context type for port
    		L"vector", // port name
    		L"vector", // port scripting name
    		MATH::CVector3f(1.0, 1.0, 1.0), // default value
    		typemapValue, // data type constraint
    		structmapValue, // structure type constraint
    		contextmapValue			// context type constraint
    	);
    	st.AssertSucceeded( ) ;

    	// Create the input port of type Long with a 'wildcard' context
    	nDataType = siICENodePortDataLong;
    	nStructType = siICENodePortStructureSingle;
    	nContextType = siICENodeEvaluationContextAny;

    	st = nodeOpDef.AddInputPort(
    		IdPort_InValue, // input port index
    		IdGr_In, // index of group to add port to
    		nDataType, // data type for port
    		nStructType, // structure type for port
    		nContextType, // context type for port
    		L"InValue", // port name
    		L"InValue", // port scripting name
    		55L, // default value
    		typemapValue, // data type constraint
    		structmapValue, // structure type constraint
    		contextmapValue		// context type constraint
    	);
    	st.AssertSucceeded( ) ;

    	// Create 2 float output ports
    	nDataType = siICENodePortDataFloat;

    	// Note: IdPort_InPos and IdPort_inValue are context constrained by the output ports,
    	// if one of the output port context is set to siICENodeContextSingleton at
    	// connection time, these ports will also be set to siICENodeContextSingleton
    	// (and vice-versa)

    	st = nodeOpDef.AddOutputPort(
    		IdPort_OutX, // output port index
    		nDataType, // data type for port
    		nStructType, // structure type for port
    		nContextType, // context type for port
    		L"x", // port name
    		L"x", // port scripting name
    		typemapValue, // data type constraint
    		structmapValue, // structure type constraint
    		contextmapValue		// context type constraint
    	);
    	st.AssertSucceeded( ) ;

    	st = nodeOpDef.AddOutputPort(
    		IdPort_OutY, // output port index
    		nDataType, // data type for port
    		nStructType, // structure type for port
    		nContextType, // context type for port
    		L"y", // port name
    		L"y", // port scripting name
    		typemapValue, // data type constraint
    		structmapValue, // structure type constraint
    		contextmapValue		// context type constraint
    	);
    	st.AssertSucceeded( ) ;

    	// Register the new ICENode and add it to the Custom ICENode category
    	PluginItem nodeItem = in_reg.RegisterICENode(nodeOpDef);
    	nodeItem.PutCategories(L"Custom ICENode Sample");

    	return CStatus::OK;
    }