Regular Custom ICENode

 
 
 

Most custom ICENodes are regular ICENodes processed in multi-threading mode. Data and structure types define the port data type that gets propagated through other ICENodes and context types specify the connection compatibility of custom node ports with other ICENode ports. Mixing context types together is supported for both input and output ports but must follow this rule:

Important

Softimage will log an error at registration time if the above rule is not met, in which case the ICENode registration will be aborted.

Tip

See the CustomVector3ToScalar Example for an example of how to create a regular ICENode.

Example: Custom ICENode Using Mixed Context Types:

enum IDs
{
	ID_IN_SINGLETON = 0,
	ID_IN_COMPONENT0D = 1,
	ID_IN_SINGLETON_OR_COMPONENT0D = 2,
	ID_G_100 = 100,
	ID_OUT_FLOAT_ARRAY = 200,
	ID_OUT_VECTOR3F_ARRAY = 201,
	ID_TYPE_CNS = 400,
	ID_STRUCT_CNS,
	ID_CTXT_CNS,
	ID_UNDEF = ULONG_MAX
};
 
XSI::CStatus MixedContextSample_Register( XSI::PluginRegistrar& in_reg );
 
XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
{
	in_reg.PutAuthor(L"Softimage");
	in_reg.PutName(L"MixedContextSample Plugin");
	in_reg.PutVersion(1,0);

	MixedContextSample_Register( in_reg );

	return CStatus::OK;
}
 
CStatus MixedContextSample_Register( PluginRegistrar& in_reg )
{
	ICENodeDef nodeDef;
	nodeDef = Application().GetFactory().CreateICENodeDef(L"MixedContextSample");
	CStatus st;

	st = nodeDef.AddPortGroup( ID_G_100 );
	st.AssertSucceeded();

	// This port is a single integer.
	st = nodeDef.AddInputPort( ID_IN_SINGLETON, 
		ID_G_100,
		siICENodeDataLong,
		siICENodeStructureSingle,
		siICENodeContextSingleton,
		L"int_singleton", L"int_singleton",
		1L,
		ID_UNDEF, ID_UNDEF, ID_UNDEF );
	st.AssertSucceeded( ) ;

	// Array of positions port.
	st = nodeDef.AddInputPort( ID_IN_COMPONENT0D, 
		ID_G_100,
		siICENodeDataVector3,
		siICENodeStructureSingle,
		siICENodeContextSingleton | siICENodeContextComponent0D,
		L"C0D", L"C0D",
		MATH::CVector3f(1.0,1.0,1.0),
		ID_UNDEF, ID_UNDEF, ID_CTXT_CNS );
	st.AssertSucceeded( ) ;

	// A single float or an array of floats matching the positions array count above.
	st = nodeDef.AddInputPort( ID_IN_SINGLETON_OR_COMPONENT0D, 
		ID_G_100,
		siICENodeDataFloat,
		siICENodeStructureSingle,
		siICENodeContextSingleton | siICENodeContextComponent0D,
		L"Singleton_or_C0D", L"Singleton_or_C0D",
		1.0f,
		ID_UNDEF, ID_UNDEF, ID_CTXT_CNS );
	st.AssertSucceeded( ) ;
	
	// Port to output an array of float values
	st = nodeDef.AddOutputPort( ID_OUT_FLOAT_ARRAY, 
		siICENodeDataFloat,
		siICENodeStructureArray,
		siICENodeContextSingleton | siICENodeContextComponent0D,
		L"OutFloatArray", L"OutFloatArray",
		ID_UNDEF, ID_UNDEF, ID_CTXT_CNS );
	st.AssertSucceeded( ) ;
	
	// Port to output an array of CVector3f values
	st = nodeDef.AddOutputPort( ID_OUT_VECTOR3F_ARRAY, 
		siICENodeDataVector3,
		siICENodeStructureSingle,
		siICENodeContextSingleton | siICENodeContextComponent0D,
		L"OutVector3fArray", L"OutVector3fArray",
		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 MixedContextSample_Evaluate( ICENodeContext& in_ctxt )
{
	switch( (ULONG)in_ctxt.GetEvaluatedOutputPortID() )
	{
		case ID_OUT_FLOAT_ARRAY :
		{
			CDataArrayLong a_count( in_ctxt, ID_IN_SINGLETON );
			LONG count = a_count[0];
			CDataArray2DFloat aa_out( in_ctxt );
			CDataArray2DFloat::Accessor a_out = aa_out.Resize( 0, count );
			for( ULONG i = 0; i < a_out.GetCount(); ++i ) 
			{
				a_out[i] = (float)i;
			}	
		}
		break;
		
		case ID_OUT_VECTOR3F_ARRAY :
		{
			CIndexSet indexSet( in_ctxt );
			CDataArrayVector3f v3fArray( in_ctxt, ID_IN_COMPONENT0D );
			CDataArrayFloat fArray( in_ctxt, ID_IN_SINGLETON_OR_COMPONENT0D );	
			float fFact = fArray[0];
			MATH::CVector3f v3f( fFact, fFact*2.0, -fFact );
			CDataArrayVector3f outVector3f( in_ctxt );
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{ 
				fFact *= 1.1;
				v3f.ScaleInPlace( fFact );
				outVector3f[it] = v3f;
			}
		}
		break;
	};
	
	return CStatus::OK;
}