Ejemplo n.º 1
0
SICALLBACK MOM_AddToCluster_Evaluate( ICENodeContext& in_ctxt )
{
	// The current output port being evaluated...
   ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

   if(gSimulation == NULL)
      return CStatus::OK;

	switch( out_portID )
	{
		case ID_OUT_base:
		{
         CDataArrayLong baseData( in_ctxt, ID_IN_base );
         CDataArrayLong idData( in_ctxt, ID_IN_id );
         CDataArrayLong clusterData( in_ctxt, ID_IN_cluster );
         rbdID rbd_ID,cluster_ID;
         CIndexSet indexSet( in_ctxt );

			// Get the output port array ...
			CDataArrayLong outData( in_ctxt );

			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            cluster_ID.primary = rbd_ID.primary;
            cluster_ID.secondary = (int)(clusterData.IsConstant() ? clusterData[0] : clusterData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            btRigidBodyReference * clusterRef = gSimulation->GetRigidBody(cluster_ID);

            if(bodyRef != NULL && clusterRef != NULL)
            {
               bodyRef->AddToCluster(clusterRef);
            }
            outData[it] = rbd_ID.primary;
			}
         break;
		}
	};

	return CStatus::OK;
}
Ejemplo n.º 2
0
CStatus VDB_Node_FBM::Evaluate(ICENodeContext& ctxt)
{
   Application().LogMessage(L"[VDB_Node_FBM] Evaluate");

   CDataArrayCustomType inVDBGridPort(ctxt, kInVDBGrid);

   // The current output port being evaluated...
   ULONG evaluatedPort = ctxt.GetEvaluatedOutputPortID();

   switch (evaluatedPort)
   {
      case kOutVDBGrid:
      {
         CDataArrayCustomType output(ctxt);
         CIndexSet indexSet(ctxt);

         for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
         {
            //Application().LogMessage(L"[VDB_Node_FBM] iterator index = " + CValue(it.GetIndex()).GetAsText());

            ULONG inDataSize;
            VDB_Primitive* inVDBPrim;
            inVDBGridPort.GetData(it, (const CDataArrayCustomType::TData**)&inVDBPrim, inDataSize);
            if (!inDataSize)
            {
               Application().LogMessage(L"[VDB_Node_FBM] data size is invalid!", siErrorMsg);
               return CStatus::OK;
            }
            Application().LogMessage(L"[VDB_Node_FBM] previous data size = " + CValue(inDataSize).GetAsText());

            openvdb::GridBase::Ptr grid = inVDBPrim->GetGridPtr();
            openvdb::FloatGrid::Ptr outputGrid;
            outputGrid = openvdb::gridPtrCast<openvdb::FloatGrid>(grid);
            //openvdb::math::Transform::Ptr transform = outputGrid->getTransform();
            
            CDataArrayLong octaves(ctxt, kOctaves);
            CDataArrayFloat lacunarity(ctxt, kLacunarity);
            CDataArrayFloat gain(ctxt, kGain);

            for (openvdb::FloatGrid::ValueOnIter iter = outputGrid->beginValueOn(); iter; ++iter)
            {
               if (iter.isVoxelValue())
               {
                  openvdb::Coord coord = iter.getCoord();
                  openvdb::Vec3d vec = outputGrid->indexToWorld(coord);
                  double result;
                  double p[3] = {vec.x(), vec.y(), vec.z()};
                  SeExpr::FBM<3,1,false>(p, &result, double(octaves[0]), double(lacunarity[0]), double(gain[0]));
                  Application().LogMessage(CValue(vec.x()).GetAsText() + "," + CValue(vec.y()).GetAsText() + "," + CValue(vec.z()).GetAsText(), siVerboseMsg);
                  Application().LogMessage(CValue(.5*result+.5).GetAsText(), siVerboseMsg);
                  iter.setValue(*iter + 1.0f * result);
               }
            }

            VDB_Primitive* outVDBPrim = (VDB_Primitive*)output.Resize(it, sizeof(VDB_Primitive));
            ::memcpy(outVDBPrim, inVDBPrim, inDataSize);

            Application().LogMessage(L"[VDB_Node_FBM] memcpy succeeded");
            Application().LogMessage(L"[VDB_Node_FBM] grid type is " + CString(inVDBPrim->GetTypeName()));
         }
         break;
      }
      default:
         break;
   };

   return CStatus::OK;
}
Ejemplo n.º 3
0
SICALLBACK MOM_GetAttributes_Evaluate( ICENodeContext& in_ctxt )
{
	// The current output port being evaluated...
   ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );
   CDataArrayLong baseData( in_ctxt, ID_IN_base );
   CDataArrayLong idData( in_ctxt, ID_IN_id );
   rbdID rbd_ID;
   CIndexSet indexSet( in_ctxt );

   if(gSimulation == NULL)
      return CStatus::OK;

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

         // get the index set iterator
         btTransform bodyTransform;
         btVector3 bodyPos;
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               bodyRef->body->getMotionState()->getWorldTransform(bodyTransform);
               bodyPos = bodyTransform.getOrigin();
               outData[it] = CVector3f(bodyPos.getX(),bodyPos.getY(),bodyPos.getZ());
            }
			}
         break;
		}
		case ID_OUT_orientation :
		{
			// Get the output port array ...
			CDataArrayVector3f outData( in_ctxt );

         // get the index set iterator
         btTransform bodyTransform;
         btQuaternion bodyRot;
			CRotation rot;
			CVector3 angles;
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               bodyTransform = bodyRef->GetWorldTransform();
               bodyRot = bodyTransform.getRotation();
               rot.SetFromQuaternion(CQuaternion(bodyRot.getW(),bodyRot.getX(),bodyRot.getY(),bodyRot.getZ()));
               angles = rot.GetXYZAngles();
               outData[it].Set(RadiansToDegrees(angles.GetX()),RadiansToDegrees(angles.GetY()),RadiansToDegrees(angles.GetZ()));
            }
			}
         break;
		}
		case ID_OUT_linvelocity:
		{
			// Get the output port array ...
			CDataArrayVector3f outData( in_ctxt );

         // get the index set iterator
         btVector3 linvel;
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               linvel = bodyRef->body->getLinearVelocity();
               outData[it].Set(linvel.getX(),linvel.getY(),linvel.getZ());
            }
			}
         break;
		}
		case ID_OUT_angvelocity:
		{
			// Get the output port array ...
			CDataArrayVector3f outData( in_ctxt );

         // get the index set iterator
         btVector3 angvel;
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               angvel = bodyRef->body->getAngularVelocity();
               outData[it].Set(angvel.getX(),angvel.getY(),angvel.getZ());
            }
			}
         break;
		}
		case ID_OUT_state:
		{
			// Get the output port array ...
			CDataArrayLong outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               outData[it] = 0;
               if(bodyRef->body->getActivationState() == WANTS_DEACTIVATION)
                  outData[it] = 1;
               else if(bodyRef->body->getActivationState() == DISABLE_SIMULATION)
                  outData[it] = 2;
            }
			}
         break;
		}
		case ID_OUT_mass:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = 1.0f / bodyRef->body->getInvMass();
			}
         break;
		}
		case ID_OUT_bounce:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getRestitution();
			}
         break;
		}
		case ID_OUT_friction:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getFriction();
			}
         break;
		}
		case ID_OUT_lindamping:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getLinearDamping();
			}
         break;
		}
		case ID_OUT_angdamping:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getAngularDamping();
			}
         break;
		}
		case ID_OUT_lintreshold:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getLinearSleepingThreshold();
			}
         break;
		}
		case ID_OUT_angtreshold:
		{
			// Get the output port array ...
			CDataArrayFloat outData( in_ctxt );

         // get the index set iterator
			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
               outData[it] = bodyRef->body->getAngularSleepingThreshold();
			}
         break;
		}
	};

	return CStatus::OK;
}
Ejemplo n.º 4
0
SICALLBACK MOM_SetAttributes_Evaluate( ICENodeContext& in_ctxt )
{
	// The current output port being evaluated...
   ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

   if(gSimulation == NULL)
      return CStatus::OK;

	switch( out_portID )
	{
		case ID_OUT_base:
		{
         CDataArrayLong baseData( in_ctxt, ID_IN_base );
         CDataArrayLong idData( in_ctxt, ID_IN_id );
         rbdID rbd_ID;
         CIndexSet indexSet( in_ctxt );

			// Get the output port array ...
			CDataArrayLong outData( in_ctxt );

			// get all of the input SET data!
			CDataArrayBool setPosData( in_ctxt, ID_IN_set_position);
			CDataArrayBool setRotData( in_ctxt, ID_IN_set_orientation);
			CDataArrayBool setLinvelData( in_ctxt, ID_IN_set_linvelocity);
			CDataArrayBool setAngvelData( in_ctxt, ID_IN_set_angvelocity);
			CDataArrayBool setStateData( in_ctxt, ID_IN_set_state);
			CDataArrayBool setMassData( in_ctxt, ID_IN_set_mass);
			CDataArrayBool setBounceData( in_ctxt, ID_IN_set_bounce);
			CDataArrayBool setFrictionData( in_ctxt, ID_IN_set_friction);
			CDataArrayBool setLindampData( in_ctxt, ID_IN_set_lindamping);
			CDataArrayBool setAngdampData( in_ctxt, ID_IN_set_angdamping);
			CDataArrayBool setLintreshData( in_ctxt, ID_IN_set_lintreshold);
			CDataArrayBool setAngtreshData( in_ctxt, ID_IN_set_angtreshold);

			// get all of the input data!
			CDataArrayVector3f posData( in_ctxt, ID_IN_position);
			CDataArrayVector3f rotData( in_ctxt, ID_IN_orientation);
			CDataArrayVector3f linvelData( in_ctxt, ID_IN_linvelocity);
			CDataArrayVector3f angvelData( in_ctxt, ID_IN_angvelocity);
			CDataArrayLong stateData( in_ctxt, ID_IN_state);
			CDataArrayFloat massData( in_ctxt, ID_IN_mass);
			CDataArrayFloat bounceData( in_ctxt, ID_IN_bounce);
			CDataArrayFloat frictionData( in_ctxt, ID_IN_friction);
			CDataArrayFloat lindampData( in_ctxt, ID_IN_lindamping);
			CDataArrayFloat angdampData( in_ctxt, ID_IN_angdamping);
			CDataArrayFloat lintreshData( in_ctxt, ID_IN_lintreshold);
			CDataArrayFloat angtreshData( in_ctxt, ID_IN_angtreshold);

         // get the index set iterator
         btTransform bodyTransform;
         CVector3f bodyPos,linvel,angvel;
         btQuaternion bodyRot;
			CRotation rot;
			CQuaternion quat;
			CVector3f anglesf;
			CVector3 angles;

			for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
			{
            rbd_ID.primary = (int)(baseData.IsConstant() ? baseData[0] : baseData[it]);
            rbd_ID.secondary = (int)(idData.IsConstant() ? idData[0] : idData[it]);
            btRigidBodyReference * bodyRef = gSimulation->GetRigidBody(rbd_ID);
            if(bodyRef != NULL)
            {
               // take care of the positions
               if((setPosData.IsConstant() ? setPosData[0] : setPosData[it]) == true)
               {
                  bodyPos = posData.IsConstant() ? posData[0] : posData[it];
                  bodyTransform = bodyRef->GetWorldTransform();
                  bodyTransform.setOrigin(btVector3(bodyPos.GetX(),bodyPos.GetY(),bodyPos.GetZ()));
                  bodyRef->SetWorldTransform(bodyTransform);
               }
               // take care of the orientations
               if((setRotData.IsConstant() ? setRotData[0] : setRotData[it]) == true)
               {
                  anglesf = rotData.IsConstant() ? rotData[0] : rotData[it];
                  rot.SetFromXYZAngles(DegreesToRadians(anglesf.GetX()),DegreesToRadians(anglesf.GetY()),DegreesToRadians(anglesf.GetZ()));
                  quat = rot.GetQuaternion();
                  bodyTransform = bodyRef->GetWorldTransform();
                  bodyTransform.setRotation(btQuaternion(quat.GetX(),quat.GetY(),quat.GetZ(),quat.GetW()));
                  bodyRef->SetWorldTransform(bodyTransform);
               }
               // take care of the linear velocity
               if((setLinvelData.IsConstant() ? setLinvelData[0] : setLinvelData[it]) == true)
               {
                  linvel = linvelData.IsConstant() ? linvelData[0] : linvelData[it];
                  bodyRef->body->setLinearVelocity(btVector3(linvel.GetX(),linvel.GetY(),linvel.GetZ()));
               }
               // take care of the angular velocity
               if((setAngvelData.IsConstant() ? setAngvelData[0] : setAngvelData[it]) == true)
               {
                  angvel = angvelData.IsConstant() ? angvelData[0] : angvelData[it];
                  bodyRef->body->setAngularVelocity(btVector3(angvel.GetX(),angvel.GetY(),angvel.GetZ()));
               }
               // take care of the state
               if((setStateData.IsConstant() ? setStateData[0] : setStateData[it]) == true)
               {
                  int state = stateData.IsConstant() ? stateData[0] : stateData[it];
                  if(state == 0)
                     bodyRef->body->forceActivationState(ACTIVE_TAG);
                  else if(state == 1)
                     bodyRef->body->forceActivationState(ISLAND_SLEEPING);
                  else if(state == 2)
                     bodyRef->body->forceActivationState(DISABLE_SIMULATION);
               }
               // take care of the mass
               if((setMassData.IsConstant() ? setMassData[0] : setMassData[it]) == true)
               {
                  // compute the inertia
                  bodyRef->mass = massData.IsConstant() ? massData[0] : massData[it];
                  btVector3 inertia(0,0,0);
                  if(bodyRef->mass > 0.0f)
                     bodyRef->body->getCollisionShape()->calculateLocalInertia(bodyRef->mass,inertia);
                  bodyRef->body->setMassProps(bodyRef->mass,inertia);
               }
               // take care of the bounce
               if((setBounceData.IsConstant() ? setBounceData[0] : setBounceData[it]) == true)
               {
                  bodyRef->body->setRestitution(bounceData.IsConstant() ? bounceData[0] : bounceData[it]);
               }
               // take care of the friction
               if((setFrictionData.IsConstant() ? setFrictionData[0] : setFrictionData[it]) == true)
               {
                  bodyRef->body->setFriction(frictionData.IsConstant() ? frictionData[0] : frictionData[it]);
               }
               // take care of the linear damping
               if((setLindampData.IsConstant() ? setLindampData[0] : setLindampData[it]) == true)
               {
                  float angdamp = bodyRef->body->getAngularDamping();
                  bodyRef->body->setDamping(lindampData.IsConstant() ? lindampData[0] : lindampData[it],angdamp);
               }
               // take care of the angular damping
               if((setAngdampData.IsConstant() ? setAngdampData[0] : setAngdampData[it]) == true)
               {
                  float lindamp = bodyRef->body->getLinearDamping();
                  bodyRef->body->setDamping(lindamp,angdampData.IsConstant() ? angdampData[0] : angdampData[it]);
               }
               // take care of the linear treshold
               if((setLintreshData.IsConstant() ? setLintreshData[0] : setLintreshData[it]) == true)
               {
                  float angtresh = bodyRef->body->getAngularSleepingThreshold();
                  bodyRef->body->setSleepingThresholds(lintreshData.IsConstant() ? lintreshData[0] : lintreshData[it],angtresh);
               }
               // take care of the angular treshold
               if((setAngtreshData.IsConstant() ? setAngtreshData[0] : setAngtreshData[it]) == true)
               {
                  float lintresh = bodyRef->body->getLinearSleepingThreshold();
                  bodyRef->body->setSleepingThresholds(lintresh,angtreshData.IsConstant() ? angtreshData[0] : angtreshData[it]);
               }
            }
            outData[it] = rbd_ID.primary;
			}
         break;
		}
	};

	return CStatus::OK;
}
CStatus VDB_Node_VolumeToMesh::Evaluate(ICENodeContext& ctxt)
{
   Application().LogMessage(L"[VDB_Node_VolumeToMesh] Evaluate");

   if (!m_isValid) return CStatus::OK;

   // The current output port being evaluated...
   ULONG evaluatedPort = ctxt.GetEvaluatedOutputPortID();
   
   switch (evaluatedPort)
   {
      case kPointArray:
      {
         CDataArray2DVector3f output(ctxt);
         CDataArray2DVector3f::Accessor iter;
         iter = output.Resize(0, (ULONG)m_points.size());
         CIndexSet::Iterator index = CIndexSet(ctxt).Begin();

         for (size_t i=0; i<m_points.size(); ++i, index.Next())
         {
            openvdb::math::Vec3s pnt = m_points[i];
            iter[index] = CVector3f(pnt.x(), pnt.y(), pnt.z());
         }
         break;
      }
      case kPolygonArray:
      {
         CDataArray2DLong output(ctxt);
         CDataArray2DLong::Accessor iter = output.Resize(0, m_polygonArraySize);
         CIndexSet::Iterator index = CIndexSet(ctxt).Begin();
         
         // quads
         for (size_t q=0; q<m_quads.size(); ++q)
         {
            const openvdb::Vec4I& quad = m_quads[q];
            iter[index] = quad.w(); index.Next();
            iter[index] = quad.z(); index.Next();
            iter[index] = quad.y(); index.Next();
            iter[index] = quad.x(); index.Next();
            // end of quad
            iter[index] = -1; index.Next();
         }

         // triangles
         for (size_t t=0; t<m_triangles.size(); ++t)
         {
            const openvdb::Vec3I& triangle = m_triangles[t];
            iter[index] = triangle.z(); index.Next();
            iter[index] = triangle.y(); index.Next();
            iter[index] = triangle.x(); index.Next();
            // end of triangle
            iter[index] = -1; index.Next();
         }
         break;
      }
      default:
         break;
   };
   
   return CStatus::OK;
}
Ejemplo n.º 6
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;
}