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

# Code

The ICENode registration and Evaluate callback code is generated by default. Several check box options are offered to let you generate more code to suit your needs.

## BeginEvaluate callback

Generates the skeleton code for the optional BeginEvaluate callback.

## EndEvaluate callback

Generates the skeleton code for the optional EndEvaluate callback.

## Init callback

Generates the skeleton code for the optional Init callback.

## Term callback

Generates the skeleton code for the optional Term callback.

## Add Sample Code

Adds extra code to get you started for each function. This includes helpful comments explaining how to code the blocks.

## Add Debug Trace

Inserts a call to print the location at the beginning of each function. For example:

    Application().LogMessage(L"MyCustomICENode_EndEvaluate called",siVerboseMsg);

## Generate Code button

The wizard will generate code that looks similar to the following snippet:

    // My Custom ICENode Plugin
    // Initial code generated by Softimage SDK Wizard
    // Executed Fri May 15 21:24:29 EDT 2009 by greena
    //
    //
    // Tip: You need to compile the generated code before you can load the plug-in.
    // After you compile the plug-in, you can load it by clicking Update All in the Plugin Manager.
    #include <xsi_application.h>
    #include <xsi_context.h>
    #include <xsi_pluginregistrar.h>
    #include <xsi_status.h>

    #include <xsi_icenodecontext.h>
    #include <xsi_icenodedef.h>
    #include <xsi_command.h>
    #include <xsi_factory.h>
    #include <xsi_longarray.h>
    #include <xsi_doublearray.h>
    #include <xsi_math.h>
    #include <xsi_vector2f.h>
    #include <xsi_vector3f.h>
    #include <xsi_vector4f.h>
    #include <xsi_matrix3f.h>
    #include <xsi_matrix4f.h>
    #include <xsi_rotationf.h>
    #include <xsi_quaternionf.h>
    #include <xsi_color4f.h>
    #include <xsi_shape.h>
    #include <xsi_icegeometry.h>
    #include <xsi_iceportstate.h>
    #include <xsi_indexset.h>
    #include <xsi_dataarray.h>
    #include <xsi_dataarray2D.h>

    // Defines port, group and map identifiers used for registering the ICENode
    enum IDs
    {
    	ID_IN_InPort = 0,
    	ID_IN_InPort2 = 1,
    	ID_G_100 = 100,
    	ID_OUT_OutPort = 200,
    	ID_TYPE_CNS = 400,
    	ID_STRUCT_CNS,
    	ID_CTXT_CNS,
    	ID_UNDEF = ULONG_MAX
    };

    XSI::CStatus RegisterMyCustomICENode( XSI::PluginRegistrar& in_reg );
    using namespace XSI;

    XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
    {
    	in_reg.PutAuthor(L"greena");
    	in_reg.PutName(L"My Custom ICENode Plugin");
    	in_reg.PutVersion(1,0);

    	RegisterMyCustomICENode( in_reg );

    	//RegistrationInsertionPoint - do not remove this line

    	return CStatus::OK;
    }

    XSIPLUGINCALLBACK CStatus XSIUnloadPlugin( const PluginRegistrar& in_reg )
    {
    	CString strPluginName;
    	strPluginName = in_reg.GetName();
    	Application().LogMessage(strPluginName + L" has been unloaded.",siVerboseMsg);
    	return CStatus::OK;
    }

    CStatus RegisterMyCustomICENode( PluginRegistrar& in_reg )
    {
    	ICENodeDef nodeDef;
    	nodeDef = Application().GetFactory().CreateICENodeDef(L"MyCustomICENode",L"My Custom ICENode");
    	CStatus st;

    	st = nodeDef.PutColor(154,188,102);
    	st.AssertSucceeded( ) ;

    	// Add custom types definition.
    	st = nodeDef.DefineCustomType(L"MyCustomDataType",L"MyCustomDataType",L"MyCustomDataType",255,8,255);
    	st.AssertSucceeded( ) ;

    	// Add input ports and groups.
    	st = nodeDef.AddPortGroup(ID_G_100);
    	st.AssertSucceeded( ) ;

    	st = nodeDef.AddInputPort(ID_IN_InPort,ID_G_100,siICENodeDataFloat,siICENodeStructureSingle,siICENodeContextSingleton,L"InPort",L"InPort",1.0f,ID_UNDEF,ID_UNDEF,ID_CTXT_CNS);
    	st.AssertSucceeded( ) ;

    	st = nodeDef.AddInputPort(ID_IN_InPort2,undefined,siICENodeDataFloat,siICENodeStructureArray,siICENodeContextAny,L"InPort2",L"InPort2",1.0f,ID_UNDEF,ID_UNDEF,ID_CTXT_CNS);
    	st.AssertSucceeded( ) ;

    	// Add output ports.
    	CStringArray OutPortCustomType(1);
    	OutPortCustomType[0] = L"MyCustomDataType";

    	st = nodeDef.AddOutputPort(ID_OUT_OutPort,siICENodeDataCustomType,OutPortCustomType,siICENodeStructureSingle,siICENodeContextAny,L"OutPort",L"OutPort",ID_UNDEF,ID_UNDEF,ID_CTXT_CNS);
    	st.AssertSucceeded( ) ;

    	PluginItem nodeItem = in_reg.RegisterICENode(nodeDef);
    	nodeItem.PutCategories(L"Custom ICENode");

    	return CStatus::OK;
    }

    XSIPLUGINCALLBACK CStatus MyCustomICENode_Evaluate( ICENodeContext& in_ctxt )
    {
    	// The current output port being evaluated...
    	ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

    	switch( out_portID )
    	{
    		case ID_OUT_OutPort :
    		{
    			// Get the output port array ...
    			CDataArrayCustomType outData( in_ctxt );

     			// Get the input data buffers for each port
    			CDataArrayFloat InPortData( in_ctxt, ID_IN_InPort );
    			CDataArray2DFloat InPort2Data( in_ctxt, ID_IN_InPort2 );

     			// We need a CIndexSet to iterate over the data
    			CIndexSet indexSet( in_ctxt );
    			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
    			{
    				// Add code to set output port...
    				Application().LogMessage( CString( InPortData[it] ) );
    				CDataArray2DFloat::Accessor InPort2SubArray = InPort2Data[it];
    				for (ULONG i=0; i<InPort2SubArray.GetCount( ); i++)
    				{
    					Application().LogMessage( CString( InPort2SubArray[i] ) );
    				}

    			}
    		}
    		break;

    		// Other output ports...
    	};

    	return CStatus::OK;
    }