Example #1
0
XSIPLUGINCALLBACK CStatus nest_LatticeDeform_Evaluate( ICENodeContext& in_ctxt )
{
   // The current output port being evaluated...
   ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

   switch( out_portID )
   {
      case Array_ID_OUT_Result:
      {
         siICENodeDataType dataType;
         siICENodeStructureType struType;
         siICENodeContextType contType;
         in_ctxt.GetPortInfo(Lattice_ID_IN_Point,dataType,struType,contType);
			
         // get all of the data that is the same for any structure
         CDataArrayVector3f SubdivData( in_ctxt, Lattice_ID_IN_Subdivision );
         CDataArrayVector3f StepData( in_ctxt, Lattice_ID_IN_Step );
         CDataArray2DVector3f ReferenceData( in_ctxt, Lattice_ID_IN_Reference );
         CDataArray2DVector3f CurrentData( in_ctxt, Lattice_ID_IN_Current );
         CDataArray2DVector3f::Accessor ReferenceDataSub = ReferenceData[0];
         CDataArray2DVector3f::Accessor CurrentDataSub = CurrentData[0];

         // define the things we need to calculate
         long subdiv[3];
         subdiv[0] = long(floor(SubdivData[0].GetX()));
         subdiv[1] = long(floor(SubdivData[0].GetY()));
         subdiv[2] = long(floor(SubdivData[0].GetZ()));
         long subdiv1[3];
         subdiv1[0] = subdiv[0]+1;
         subdiv1[1] = subdiv[1]+1;
         subdiv1[2] = subdiv[2]+1;
         float step[3];
         step[0] = 1.0f / StepData[0].GetX();
         step[1] = 1.0f / StepData[0].GetY();
         step[2] = 1.0f / StepData[0].GetZ();
			float steplength = StepData[0].GetLength();
         long indexX[8];
         long indexY[8];
         long indexZ[8];
         long index[8];
         long lastIndex[3];
			lastIndex[0] = -1;
			lastIndex[1] = -1;
			lastIndex[2] = -1;
			CVector3f posCp;
			CVector3f pos;
         CVector3f diff[8];
         CVector3f motion[8];
         CVector3f motionScl[8];
			CVector3f deform;
         float weight[8];
			float xyz0[3];
			float xyz1[3];
			float weightSum;
         
         if(struType == siICENodeStructureSingle)
         {
            // two behaviours based on the datatype...
            // Get the output port array ...
            CDataArrayVector3f outData( in_ctxt );
   
            // Get the input data buffers for each port
            CDataArrayVector3f PointData( in_ctxt, Lattice_ID_IN_Point );

            // iterate each subset!
            CIndexSet IndexSet( in_ctxt );
            for(CIndexSet::Iterator it = IndexSet.Begin(); it.HasNext(); it.Next())
            {
               // first let's find the index inside the box!
					posCp.Set(PointData[it].GetX(),PointData[it].GetY(),PointData[it].GetZ());
					
					// substract the lowest corner
					pos.Sub(posCp,ReferenceDataSub[0]);
					pos.Set(pos.GetX() * step[0], pos.GetY() * step[1], pos.GetZ() * step[2]);
					xyz0[0] = pos.GetX() - floor(pos.GetX());
					xyz0[1] = pos.GetY() - floor(pos.GetY());
					xyz0[2] = pos.GetZ() - floor(pos.GetZ());

					xyz1[0] = 1.0 - xyz0[0];
					xyz1[1] = 1.0 - xyz0[1];
					xyz1[2] = 1.0 - xyz0[2];
					
					// calculate the indices (decomposed)
					indexX[0] = clampl(long(floor(pos.GetX())),0,subdiv[0]);
					indexY[0] = clampl(long(floor(pos.GetY())),0,subdiv[1]);
					indexZ[0] = clampl(long(floor(pos.GetZ())),0,subdiv[2]);
					
					if(lastIndex[0] != indexX[0] || lastIndex[1] != indexY[0] || lastIndex[2] != indexZ[0])
					{
						indexX[1] = clampl(indexX[0]+1	,0,subdiv[0]);
						indexY[1] = clampl(indexY[0]	,0,subdiv[1]);
						indexZ[1] = clampl(indexZ[0]	,0,subdiv[2]);
	
						indexX[2] = clampl(indexX[0]+1	,0,subdiv[0]);
						indexY[2] = clampl(indexY[0]+1	,0,subdiv[1]);
						indexZ[2] = clampl(indexZ[0]	,0,subdiv[2]);
	
						indexX[3] = clampl(indexX[0]+1	,0,subdiv[0]);
						indexY[3] = clampl(indexY[0]	,0,subdiv[1]);
						indexZ[3] = clampl(indexZ[0]+1	,0,subdiv[2]);
	
						indexX[4] = clampl(indexX[0]+1	,0,subdiv[0]);
						indexY[4] = clampl(indexY[0]+1	,0,subdiv[1]);
						indexZ[4] = clampl(indexZ[0]+1	,0,subdiv[2]);
						
						indexX[5] = clampl(indexX[0]	,0,subdiv[0]);
						indexY[5] = clampl(indexY[0]+1	,0,subdiv[1]);
						indexZ[5] = clampl(indexZ[0]	,0,subdiv[2]);
	
						indexX[6] = clampl(indexX[0]	,0,subdiv[0]);
						indexY[6] = clampl(indexY[0]	,0,subdiv[1]);
						indexZ[6] = clampl(indexZ[0]+1	,0,subdiv[2]);
	
						indexX[7] = clampl(indexX[0]	,0,subdiv[0]);
						indexY[7] = clampl(indexY[0]+1	,0,subdiv[1]);
						indexZ[7] = clampl(indexZ[0]+1	,0,subdiv[2]);
						
						for(int i=0;i<8;i++)
						{
							// compose the indices!
							index[i] = compose(indexX[i],indexY[i],indexZ[i],subdiv1[1],subdiv1[2]);
							
							// calculate the motions
							motion[i].Sub(CurrentDataSub[index[i]],ReferenceDataSub[index[i]]);
						}
					}
					else
					{
						// for performance, remember the last used index
						lastIndex[0] = indexX[0];
						lastIndex[1] = indexY[0];
						lastIndex[2] = indexZ[0];
					}

					// compute the weights
					weight[0] = xyz1[0] * xyz1[1] * xyz1[2];
					weight[1] = xyz0[0] * xyz1[1] * xyz1[2];
					weight[2] = xyz0[0] * xyz0[1] * xyz1[2];
					weight[3] = xyz0[0] * xyz1[1] * xyz0[2];
					weight[4] = xyz0[0] * xyz0[1] * xyz0[2];
					weight[5] = xyz1[0] * xyz0[1] * xyz1[2];
					weight[6] = xyz1[0] * xyz1[1] * xyz0[2];
					weight[7] = xyz1[0] * xyz0[1] * xyz0[2];

					// sum up all weighted motions
					deform.SetNull();
					for(int i=0;i<8;i++)
					{
						motionScl[i].Scale(weight[i],motion[i]);
						deform.AddInPlace(motionScl[i]);
					}
					
					// output the deformed position
					outData[it] = deform;
            }
         }
			else
         {
            // two behaviours based on the datatype...
            // Get the output port array ...
            CDataArray2DVector3f outData( in_ctxt );
   
            // Get the input data buffers for each port
            CDataArray2DVector3f PointData( in_ctxt, Lattice_ID_IN_Point );

            // iterate each subset!
            CIndexSet IndexSet( in_ctxt );
            for(CIndexSet::Iterator it = IndexSet.Begin(); it.HasNext(); it.Next())
            {
		         CDataArray2DVector3f::Accessor PointDataSub = PointData[it];
					long subCount = PointDataSub.GetCount();
					Application().LogMessage(CString((LONG)subCount));
					outData.Resize(it,subCount);
					for(long k=0;k<subCount;k++)
					{
						// first let's find the index inside the box!
						posCp.Set(PointDataSub[k].GetX(),PointDataSub[k].GetY(),PointDataSub[k].GetZ());
						
						// substract the lowest corner
						pos.Sub(posCp,ReferenceDataSub[0]);
						pos.Set(pos.GetX() * step[0], pos.GetY() * step[1], pos.GetZ() * step[2]);
						xyz0[0] = pos.GetX() - floor(pos.GetX());
						xyz0[1] = pos.GetY() - floor(pos.GetY());
						xyz0[2] = pos.GetZ() - floor(pos.GetZ());
	
						xyz1[0] = 1.0 - xyz0[0];
						xyz1[1] = 1.0 - xyz0[1];
						xyz1[2] = 1.0 - xyz0[2];
						
						// calculate the indices (decomposed)
						indexX[0] = clampl(long(floor(pos.GetX())),0,subdiv[0]);
						indexY[0] = clampl(long(floor(pos.GetY())),0,subdiv[1]);
						indexZ[0] = clampl(long(floor(pos.GetZ())),0,subdiv[2]);
						
						if(lastIndex[0] != indexX[0] || lastIndex[1] != indexY[0] || lastIndex[2] != indexZ[0])
						{
							indexX[1] = clampl(indexX[0]+1	,0,subdiv[0]);
							indexY[1] = clampl(indexY[0]	,0,subdiv[1]);
							indexZ[1] = clampl(indexZ[0]	,0,subdiv[2]);
		
							indexX[2] = clampl(indexX[0]+1	,0,subdiv[0]);
							indexY[2] = clampl(indexY[0]+1	,0,subdiv[1]);
							indexZ[2] = clampl(indexZ[0]	,0,subdiv[2]);
		
							indexX[3] = clampl(indexX[0]+1	,0,subdiv[0]);
							indexY[3] = clampl(indexY[0]	,0,subdiv[1]);
							indexZ[3] = clampl(indexZ[0]+1	,0,subdiv[2]);
		
							indexX[4] = clampl(indexX[0]+1	,0,subdiv[0]);
							indexY[4] = clampl(indexY[0]+1	,0,subdiv[1]);
							indexZ[4] = clampl(indexZ[0]+1	,0,subdiv[2]);
							
							indexX[5] = clampl(indexX[0]	,0,subdiv[0]);
							indexY[5] = clampl(indexY[0]+1	,0,subdiv[1]);
							indexZ[5] = clampl(indexZ[0]	,0,subdiv[2]);
		
							indexX[6] = clampl(indexX[0]	,0,subdiv[0]);
							indexY[6] = clampl(indexY[0]	,0,subdiv[1]);
							indexZ[6] = clampl(indexZ[0]+1	,0,subdiv[2]);
		
							indexX[7] = clampl(indexX[0]	,0,subdiv[0]);
							indexY[7] = clampl(indexY[0]+1	,0,subdiv[1]);
							indexZ[7] = clampl(indexZ[0]+1	,0,subdiv[2]);
							
							for(int i=0;i<8;i++)
							{
								// compose the indices!
								index[i] = compose(indexX[i],indexY[i],indexZ[i],subdiv1[1],subdiv1[2]);
								
								// calculate the motions
								motion[i].Sub(CurrentDataSub[index[i]],ReferenceDataSub[index[i]]);
							}
						}
						else
						{
							// for performance, remember the last used index
							lastIndex[0] = indexX[0];
							lastIndex[1] = indexY[0];
							lastIndex[2] = indexZ[0];
						}
	
						// compute the weights
						weight[0] = xyz1[0] * xyz1[1] * xyz1[2];
						weight[1] = xyz0[0] * xyz1[1] * xyz1[2];
						weight[2] = xyz0[0] * xyz0[1] * xyz1[2];
						weight[3] = xyz0[0] * xyz1[1] * xyz0[2];
						weight[4] = xyz0[0] * xyz0[1] * xyz0[2];
						weight[5] = xyz1[0] * xyz0[1] * xyz1[2];
						weight[6] = xyz1[0] * xyz1[1] * xyz0[2];
						weight[7] = xyz1[0] * xyz0[1] * xyz0[2];
	
						// sum up all weighted motions
						deform.SetNull();
						for(int i=0;i<8;i++)
						{
							motionScl[i].Scale(weight[i],motion[i]);
							deform.AddInPlace(motionScl[i]);
						}
						
						// output the deformed position
						outData[it][k] = deform;
					}
				}
         }
      }
      break;

      // Other output ports...

   };

   return CStatus::OK;
}