Iterating Over Port Data

 
 
 

Given the following ICENode ports:

nodeOpDef.AddInputPort( ID_Port0, ID_Group0, siICENodePortDataLong, siICENodePortStructureSingle, siICENodeEvaluationContextAny, L"Port_0", L"Port_0" );
nodeOpDef.AddInputPort( ID_Port1, ID_Group0, siICENodeDataVector3, siICENodePortStructureSingle, siICENodeEvaluationContextAny, L"Port_1", L"Port_1" );
nodeOpDef.AddInputPort( ID_Port2, ID_Group0, siICENodePortDataFloat, siICENodePortStructureArray, siICENodeEvaluationContextAny, L"Port_2", L"Port_2" );
nodeOpDef.AddOutputPort( ID_OutPort0, siICENodeDataVector3, siICENodePortStructureSingle, siICENodeEvaluationContextAny, L"OutPort_0", L"OutPort_0" );
nodeOpDef.AddOutputPort( ID_OutPort1, siICENodePortDataFloat, siICENodePortStructureArray, siICENodeEvaluationContextAny, L"OutPort_1", L"OutPort_1" );
nodeOpDef.AddOutputPort( ID_OutPort2, siICENodePortDataLong, siICENodePortStructureSingle, siICENodeEvaluationContextAny, L"OutPort_2", L"OutPort_2" );

The next block demonstrates how to iterate over the port data defined above and how to filter out elements:

XSIPLUGINCALLBACK CStatus SampleNode_Evaluate( ICENodeContext& in_ctxt )
{
	// Switch over the output port being evaluated
	ULONG outportID = in_ctxt.GetEvaluatedOutputPortID( );
	
	// Create the index set
	CIndexSet indexSet( in_ctxt );
	switch ( outportID )
	{
		// This section demonstrates a regular array iteration
		case ID_OutPort0:
		{
			// Get the data from port 0 and port 1
			CDataArrayLong port0( in_ctxt, ID_Port0 );
			CDataArrayVector3f port1( in_ctxt, ID_Port1 );
			
			// Get the output array
			CDataArrayVector3 outPort0( in_ctxt );
			
			// Now fill the output array 
			for( CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{	
				ULONG nIndex = it;
				XSI::MATH::CVector3f v3f( port1[ nIndex ] );
				outPort0[ nIndex ].Set( v3f.GetY(), port0[ nIndex ] * v3f.GetZ(), v3f.GetX() );
			}
		}
		break;

		// This section demonstrates how to iterate over a 2D array
		case ID_OutPort1:
		{
			// Get the 2D array from port 2
			CDataArray2DFloat port2( in_ctxt, ID_Port2 );
						
			// Get the output 2D array
			CDataArray2DFloat outPort1( in_ctxt );
			
			// The first loop iterates normally on outPort1 
			for( CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{	
				// Now we use the Accessor class to allocate the output buffer and to iterate over the sub-array of outPort1
				CDataArray2DFloat::Accessor floatAccessor = port2[it];	
				
				CDataArray2DFloat::Accessor outAccessor = outPort1.Resize( it, floatAccessor.GetCount( ) );

				for (ULONG i=0; i<floatAccessor.GetCount( ); i++)
				{	
					// Set the output 2D array
					outAccessor[i] = floatAccessor[i];
				}							
			}
		}
		break;

		// This section demonstrates how to filter out element items 
		case ID_OutPort2:
		{
			// Get the data from port 0
			CDataArrayLong port0( in_ctxt, ID_Port0 );
			
			// Get the output array
			CDataArrayLong outPort2( in_ctxt );
			
			for( CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); /* do not call it.Next() here as it could increment the iterator twice! */ )
			{
				outPort2[ it ] = port0[ it ];
				
				if ( port0[ it ] < 10 )
				{
					// Filter out elements of port 0 below 10
					it.Remove( );
					
					// Important: Remove() will increment the iterator position by itself
				}
				else
				{	
					// Nothing to filter out, go to next item
					it.Next( );
				}
			}
		}
		break;	
	};

	return CStatus::OK;
}

Creative Commons License Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License