コード例 #1
0
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data)
{
	MStatus stat;
	
	if( plug == deformed)
	{
		MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus);
		McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n");

		MDataHandle restShapeData = data.inputValue(restShape, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restElementsData = data.inputValue(restElements, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle timeData = data.inputValue(time, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus);
		McheckErr(returnStatus, "Error getting outputMesh data handle\n");
		
		MMatrix twmat = tetWorldMatrixData.asMatrix();
		MObject rs = restShapeData.asMesh();
		double t = timeData.asDouble();

		MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus);
		McheckErr(returnStatus, "Error getting poissonRatio data handle\n");

		MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus);
		McheckErr(returnStatus, "Error getting youngsmodulus data handle\n");

		MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus);
		McheckErr(returnStatus, "Error getting objectDensity data handle\n");

		MDataHandle frictionData = data.inputValue(friction, &returnStatus);
		McheckErr(returnStatus, "Error getting friction data handle\n");

		MDataHandle restitutionData = data.inputValue(restitution, &returnStatus);
		McheckErr(returnStatus, "Error getting restitution data handle\n");

		MDataHandle dampingData = data.inputValue(damping, &returnStatus);
		McheckErr(returnStatus, "Error getting damping data handle\n");

		MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus);
		McheckErr(returnStatus, "Error getting user supplied dt data handle\n");


		MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus);
		McheckErr(returnStatus, "Error getting user integrationTypeData\n");

		MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceModelTypeData\n");

		MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceApplicationTime\n");
	
		MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceReleasedTime\n");

		MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIncrementTime\n");

		MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStartTime\n");

		MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStopTime\n");

		MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");	

		MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MTime currentTime, maxTime;
		currentTime = MAnimControl::currentTime();
		maxTime = MAnimControl::maxTime();
					
		if (currentTime == MAnimControl::minTime())
		{
			// retrive restVertices and restElements
			sTime=0;

			MFnDoubleArrayData restVertArrayData(restVerticesData.data());
			MDoubleArray verts = restVertArrayData.array();
			int vertArrayLen = verts.length();
			double *vertArray = new double[vertArrayLen];
			verts.get(vertArray);

			for(int v=0;v<vertArrayLen;v=v+3)
			{
				MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat;
				vertArray[v] = mpoint.x;
				vertArray[v+1] = mpoint.y;
				vertArray[v+2] = mpoint.z;
			}

			MFnIntArrayData restEleArrayData(restElementsData.data());
			MIntArray ele = restEleArrayData.array();
			int eleArrayLen = ele.length();
			int *eleArray = new int[eleArrayLen];
			ele.get(eleArray);

			MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data());
			MIntArray sv = selectedConstraintVertsArrayData.array();

			// building selectedConstraintVerts
			vector<int> selectedConstraintVertIndices;
			for (int i = 0 ; i < sv.length() ; i++)
			{
				selectedConstraintVertIndices.push_back(sv[i]);
			}
			MGlobal::displayInfo("!!!!!");
			//std::string tmp=std::to_string((long double)selectedConstraintVertIndices.size());
			//MGlobal::displayInfo(MString(tmp.c_str()));
			//std::cout<<currentConstriant<<" up"<<std::endl;
			for(int i=0;i<constraintIndex[currentConstriant].size();i++){
				if(domainParentIndex[currentConstriant]==-1)
					selectedConstraintVertIndices.push_back(constraintIndex[currentConstriant][i]);
				//std::cout<<constraintIndex[currentConstriant][i]<<std::endl;
			}
			//std::cout<<currentConstriant<<" up"<<std::endl;

			/*for(int i=0;i<10;i++){
				selectedConstraintVertIndices.push_back(i+1);
			}*/

			MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data());
			MIntArray sf = selectedForceVertsArrayData.array();

			vector<int> selectedForceVertIndices;
			for (int i = 0 ; i < sf.length() ; i++)
			{
				selectedForceVertIndices.push_back(sf[i]);
			}


			// temporarily create force direction vector
			double *forceDir = forceDirectionData.asDouble3();

	
			vector<double> dir;
			dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]);

			prevDeformed = 0;
			double youngsModulusDouble = youngsModulusData.asDouble();
			double poissonRatioDouble = poissonRatioData.asDouble();
			double objectDensityDouble = objectDensityData.asDouble();
			double frictionDouble = frictionData.asDouble();
			double restitutionDouble = restitutionData.asDouble();
			double dampingDouble = dampingData.asDouble();
			double userSuppliedDtDouble = userSuppliedDtData.asDouble();
			double forceMagnitudeDouble = forceMagnitudeData.asDouble();
			int fAppT = forceApplicationTimeData.asInt();
			int fReleasedT = forceReleasedTimeData.asInt();
			int fIncT = forceIncrementTimeData.asInt();
			int fStartT = forceStartTimeData.asInt();
			int fStopT = forceStopTimeData.asInt();
			int integrationTypeInt = integrationTypeData.asShort();
			int forceModelTypeInt = forceModelTypeData.asShort();

			bool useSuppliedForceBool = useSuppliedForceData.asBool();
			bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool();

			double contactKs = contactKsData.asDouble();
			double contactKd = contactKdData.asDouble();

			if( sm)
			{
				delete sm;
			}
			sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble,
				frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt);
			sm->setContactAttributes(contactKs,contactKd);
			if (useSuppliedConstraintsBool)
				sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices);
			else
			{
				vector<int> empty;
				sm->initialize("",userSuppliedDtDouble, empty);
			}
			
			if (useSuppliedForceBool)
				sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT);

			std::vector<int> childList=fdg.GetDomainChild(currentConstriant);
			if(childList.size()!=0){//not the root
				for(int i=0;i<childList.size();i++){
					int childIndex=-1;
					for(int j=0;j<fdomain_list.size();j++){
						if(fdomain_list[j]->index==childList[i]){
							childIndex=j;
						}
					}//j
					glm::dvec3 oldPos=glm::dvec3(0,0,0);
					for(int j=0;j<parentConstraintIndex[childIndex].size();j++){
						int index=3*parentConstraintIndex[childIndex][j];
						oldPos.x+=sm->m_vertices[index];
						oldPos.y+=sm->m_vertices[index+1];
						oldPos.z+=sm->m_vertices[index+2];
					}
					oldPos=oldPos*(1.0/parentConstraintIndex[childIndex].size());
					parentLastPosOld[childIndex]=oldPos;
					parentLastPosNew[childIndex]=oldPos;
				}//i
			}
			domainID=currentConstriant;
			currentConstriant++;
			if(currentConstriant==fdomain_list.size()) currentConstriant=0;
		}

		else
		{
			std::vector<int> childList=fdg.GetDomainChild(domainID);
			if(childList.size()!=0){//not the root
				for(int i=0;i<childList.size();i++){
					int childIndex=-1;
					for(int j=0;j<fdomain_list.size();j++){
						if(fdomain_list[j]->index==childList[i]){
							childIndex=j;
						}
					}//j
					glm::dvec3 newPos=glm::dvec3(0,0,0);
					for(int j=0;j<parentConstraintIndex[childIndex].size();j++){
						int index=3*parentConstraintIndex[childIndex][j];
						newPos.x+=sm->m_vertices[index];
						newPos.y+=sm->m_vertices[index+1];
						newPos.z+=sm->m_vertices[index+2];
					}
					//std::cout<<newPos.x<<","<<newPos.y<<","<<newPos.z<<std::endl;
					newPos=newPos*(1.0/parentConstraintIndex[childIndex].size());
					parentLastPosOld[childIndex]=parentLastPosNew[childIndex];
					parentLastPosNew[childIndex]=newPos;
				}//i
			}
			//update the parents' fixed point moving distance
			std::vector<float> pos;
			int num=0;
			if(domainParentIndex[domainID]!=-1){//has parent
				for(int i=0;i<constraintIndex[domainID].size();i++){
					int index=3*constraintIndex[domainID][i];
					pos.push_back(sm->m_vertices[index]);
					pos.push_back(sm->m_vertices[index+1]);
					pos.push_back(sm->m_vertices[index+2]);
				}
			}
			sm->update(sTime);
			sTime++;
			if(domainParentIndex[domainID]!=-1){//has parent
				//std::cout<<sm->numOfVertices<<std::endl;
				for(int i=0;i<constraintIndex[domainID].size();i++){
					int index=3*constraintIndex[domainID][i];
					if(index>3*sm->numOfVertices) std::cout<<index-3*sm->numOfVertices<<"big "<<currentConstriant<<std::endl;
					glm::dvec3 movePos=parentLastPosNew[domainID]-parentLastPosOld[domainID];
					//std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<std::endl;
					sm->m_vertices[index]=pos[num++]+movePos.x;
					sm->m_vertices[index+1]=pos[num++]+movePos.y;
					sm->m_vertices[index+2]=pos[num++]+movePos.z;
					//std::cout<<sm->m_vertices[index]<<","<<sm->m_vertices[index+1]<<","<<sm->m_vertices[index+2]<<"end"<<std::endl;
					//std::cout<<constraintIndex[domainID][i]<<std::endl;
				}
			}
		}

		MFnMesh surfFn(rs,&stat);
		McheckErr( stat, "compute - MFnMesh error" );

		MFnMeshData ouputMeshDataCreator;
		MObject oMesh = ouputMeshDataCreator.create(&stat);
		buildOutputMesh(surfFn, sm->m_vertices,oMesh);
		outputMeshData.set(oMesh);
		data.setClean(plug);

	}

	else
		stat = MS::kUnknownParameter;

	return stat;
}
コード例 #2
0
ファイル: BPT_insertVtxNode.cpp プロジェクト: Byron/bsuite
//---------------------------------------------------------------------------------------------------
bool	BPT_InsertVtx::setInternalValue ( const MPlug & plug, const MDataHandle & dataHandle)
//---------------------------------------------------------------------------------------------------
{ 

//	cout<<"War hier, plug war "<<plug.info()<<endl;


	if(plug == IVslide)
	{
		int isLimited;
		
		MFnDependencyNode depFn(plug.node());
		depFn.findPlug( "sll" ).getValue( isLimited );


		if( isLimited )
		{//limits setzen, wenn gewueuenscht
			
			double value = dataHandle.asDouble();
			
	//		cout<<value<<endl;

			if(value > 1.0)
				value = 1.0;

			if(value < 0.0)
				value = 0.0;
			
			//Das muss hier einfach sein, um limits dynamisch zu setzen je nach userwunsch
			 const_cast<MDataHandle&>(dataHandle).set(value);
		}

	}
	else if( plug == IVcount )
	{
		int value = dataHandle.asInt();
		
		if(value != lastCount)
		{//count hat sich nicht verueuendert, also outHandle sueueubern und raus hier
			meshDirty = true;
			lastCount = value;	
		}
		
	}
	else if( plug == IVspin )
	{
		int value = dataHandle.asInt();
/*
		MFnIntArrayData arrayData;
		MPlug optionPlug(thisMObject(), options);	//dieser wert kann gefahrlos geholt werden, da er das outmesh nicht beeinflusst
		
		MObject data;
		optionsPlug.getValue(data);
		arrayData.setObject(data);

		if(!(arrayData.array())[9])
		{//wenn civ nicht gesetzt ist, dann macht dieser Wert keinen sinn



		}
*/
		
		if(value != lastSpin)
		{
			meshDirty = true;
			lastSpin = value;
		}

	}

	
	// Sich jetzt um die STE internals kuemmern
	//
	//

	STE_CHECK_INTERNALS( IV,dataHandle );

	

	if(plug==IVinMesh)
		meshDirty = true; 
	
	return MPxNode::setInternalValue (plug, dataHandle);
}
コード例 #3
0
ファイル: BPT_insertVtxNode.cpp プロジェクト: Byron/bsuite
//----------------------------------------------------------------------------
MStatus		BPT_InsertVtx::doCompleteCompute( MDataBlock& data )
//----------------------------------------------------------------------------
{

				SPEED("Berechne EdgeSplit neu: ");

				MStatus status;

				MPRINT("MACHE KOMPLETTE BERECHNUNG")



				MDataHandle inMeshHandle = data.inputValue(IVinMesh);
				MDataHandle outMeshHandle = data.outputValue(IVoutMesh);


					//splitCount setzen
				
				MDataHandle countHandle	= data.inputValue(IVcount);			
				fIVfty.setCount(countHandle.asInt());
			
				

				MDataHandle spinHandle = data.inputValue(IVspin);

				fIVfty.setSpin(spinHandle.asInt());
				

				int initialVtxCount;	//wird spueueter benueuetigt, um das ValidIndicesArray gleich in der rictigen grueueueuee zu erstellen und zu schreiben


				//gleich zu beginn muss der MeshPath initialisiert werden, damit der MeshPath an die fty ueuebergeben werden kann
				// Dies geschieht besser durch die STE - sie ist darauf ausgelegt
				softTransformationEngine::gatherAttributeObjects(thisMObject());
				softTransformationEngine::saveMeshPathes();

				

				fIVfty.setMeshPath(meshPath);
				
				
			
				MDataHandle	rHandle = data.inputValue(IVslideRelative);
				fIVfty.setRelative(rHandle.asInt());
				
				
				MDataHandle nRelativeHandle = data.inputValue(IVnormalRelative);
				fIVfty.setNormalRelative(nRelativeHandle.asInt());
				
				
				//selection setzen
				MFnIntArrayData		intDataArray;	
				
				MDataHandle arrayHandle = data.inputValue(IVselEdgeIDs);
				intDataArray.setObject(arrayHandle.data());
				
				fIVfty.setEdgeIDs( intDataArray.array() );

				arrayHandle = data.inputValue(IVselVertIDs);
				intDataArray.setObject(arrayHandle.data());

				fIVfty.setVertIDs(intDataArray.array());
				

				//				optionen holen
				
				arrayHandle = data.inputValue(IVoptions);
				intDataArray.setObject(arrayHandle.data());
				MIntArray optionsArray(intDataArray.array());
				

				fIVfty.setOptions(optionsArray);
				
				
				
				
				MDataHandle slideHandle = data.inputValue(IVslide);
				fIVfty.setSlide(slideHandle.asDouble());

				
				//whichSide attribute wird nur fueuer SLide selbst verwendet und kann nicht bereits beim command gestetzt werden
				
				


				MObject inMeshRef = inMeshHandle.asMesh();
				fIVfty.setMesh(inMeshRef);


				MFnMesh meshFn(inMeshHandle.asMesh());
				initialVtxCount = meshFn.numVertices();
				

				

				//ACTION
				try
				{
					status = fIVfty.doIt();
				}
				
				catch(...)
				{
					MGlobal::displayError(" An unknown, severe, error occoured.\nIf it happens again in this situation, please write a bug report.\nPlease undo the operation and save your work!");
					return MS::kUnknownParameter;
				}

				
				MObject newOutMesh = fIVfty.getMesh();

				
				outMeshHandle.set(newOutMesh);

				
				// ---------------------
				// SOFT TRANSFORMATION
				// ---------------------
				// VtxSet setzen - hier reicht es, wenn er einfach die neuen Vtx nimmt


				softTransformationEngine::setVtxSet(data);

		

				//------------SELECTION ROUTINE----------------------


			
				//nur wenn sich spin nicht verueuendert hat, darf ne neue selection gemacht werden - dies wird auch von der IV berueuecksichtigt
				//die selection wird nur noch einmal ausgefueuehrt, weshalb scriptJobInitiated nicht mehr gesetzt wird vom scriptjob
				if( optionsArray[6] && !scriptJobInitated && !(meshPath.apiType() == MFn::kInvalid) )
				{
						
						//auf jeden Fall erstmal die neuen Vertizen holen, damit die anderen prozeduren auch darauf arbeiten kueuennen

						//alles neuen Vertces sollen gewueuehlt werden, also einfach alle Indices eintragen vom initialVtxCount
						//bis zum jetzigen VtxCount
						MIntArray validEdges, validFaces;
						componentConverter CC(newOutMesh);

						int i = 0;


						meshFn.setObject(newOutMesh);
						int newCount = meshFn.numVertices();
						
						validIndices.clear();
						validIndices.setLength(newCount - initialVtxCount);
						
						

						for(; initialVtxCount < newCount; initialVtxCount++)
							validIndices[i++] = initialVtxCount;
						
						

					
					if(optionsArray[6] == 1 || optionsArray[6] == 2) //select edges
					{
						
						CC.getContainedEdges(validIndices,validEdges);
					}


					BPT_Helpers helper;


					if(optionsArray[6] == 2) //select Faces
					{
						CC.getConnectedFaces(validEdges,validFaces);

						//jetzt kann gleich alles beendet werden, da hiernach keine componente mehr kommt, in die man faces umwandeln mueuesste
						validIndices.clear();
						validIndices.append(2);

						
						helper.addIntArrayToLHS(validIndices,validFaces);

					}

					if(optionsArray[6] == 1)
					{//edges fertigmachen
						
						validIndices.clear();
						validIndices.append(1);

						helper.addIntArrayToLHS(validIndices,validEdges);

					}
					else if(optionsArray[6] == 5)
						validIndices.insert(3,0);


					//component Mode umschalten bei bedarf
					if(optionsArray[5])
					{
						MSelectionMask::SelectionType type = MSelectionMask::kSelectMeshVerts;
						
						if(optionsArray[6] == 5)
						{
							type = MSelectionMask::kSelectMeshVerts;
						}
						else if(optionsArray[6] == 2)
						{
							type = MSelectionMask::kSelectMeshFaces;
						}
						else if(optionsArray[6] == 1)
						{
							type = MSelectionMask::kSelectMeshEdges;
						}
						
						
						MSelectionMask mask(type);
						
						
						MGlobal:: setComponentSelectionMask(mask);
					}


					eID = MEventMessage::addEventCallback("idle",IV_makeSelection,this);

					scriptJobInitated = true;

				}
				else
				{//ansonsten muss die SelectionList neu aufgebaut werden, allerdings ohne komponenten
					//diese Aktion solte auch nur einmal ausgefueuehrt werden

					//gegenwueuertige selection holen
					MSelectionList currentList;
					MSelectionList newList;
					MGlobal::getActiveSelectionList(currentList);

					//durch die Liste iterieren und Komponenten Filtern
					MItSelectionList selIter(currentList);
					MObject currentObj;
					for( ; !selIter.isDone();selIter.next() )
					{
						
						selIter.getDependNode(currentObj);
						
						newList.add(currentObj);
					}

					MGlobal::setActiveSelectionList(newList, MGlobal::kAddToList);


		


				}


				



				return status;

}
コード例 #4
0
ファイル: pnTrianglesNode.cpp プロジェクト: DimondTheCat/xray
bool pnTriangles::setInternalValue( const MPlug &plug, const MDataHandle &dh ) 
//
// Description:
//		Set internally cached values when attribute changes
//
{
   if( plug == pnTriangles::attrSubdivisions ) 
	{
		fSubdivisions = dh.asInt();

		// Make sure we don't go above the maximum allowed by 
		// the extension
		if (fSubdivisions > fMaxTessellationLevel)
			fSubdivisions = fMaxTessellationLevel;
		return true;
    }
	else if ( plug == pnTriangles::attrColored)
	{
		if (dh.asBool() == true)
			fNumColors = 1;
		else
			fNumColors = 0;
		return true;
	}
	else if ( plug == pnTriangles::attrWireframe)
	{
		if (dh.asBool() == true)
			fWireframe = 1;
		else
			fWireframe = 0;
		return true;
	}
	else if ( plug == pnTriangles::attrTextured)
	{
		if (dh.asBool() == true)
			fNumTextureCoords = 1;
		else
			fNumTextureCoords = 0;
		return true;
	}
	else if ( plug == pnTriangles::attrNormalMode )
	{
		if (dh.asInt() == 0)
			fNormalMode = kNormalLinear;
		else
			fNormalMode = kNormalQuadratic;
		return true;
	}
	else if ( plug == pnTriangles::attrPointMode )
	{
		if (dh.asInt() == 0)
			fPointMode = kPointLinear;
		else
			fPointMode = kPointCubic;
		return true;
	}
	else if ( plug == pnTriangles::attrEnableVertexProgram )
	{
		if (dh.asBool() == true)
		{
			if (fExtensionSupported[kVertexShaderEXT])
				fTestVertexProgram = 1;
			else
				fTestVertexProgram = 0;
		}
		else
			fTestVertexProgram = 0;

		return true;
	}
	else if ( plug == pnTriangles::attrEnablePixelProgram )
	{
#ifdef _FRAGMENT_PROGRAM_READY_
		if (dh.asBool() == true)
			if (fExtensionSupported[kFragmentShaderEXT])
				fTestFragmentProgram = 1;
			else
				fTestFragmentProgram = 0;
		else
			fTestFragmentProgram = 0;
#else
		fTestFragmentProgram = 0;
#endif
		return true;
	}
    return false;
}
コード例 #5
0
MStatus LSSolverNode::compute(const MPlug& plug, MDataBlock& data)
{
	MStatus stat;
	
	if( plug == deformed)
	{
		MDataHandle tetWorldMatrixData = data.inputValue(tetWorldMatrix, &returnStatus);
		McheckErr(returnStatus, "Error getting tetWorldMatrix data handle\n");

		MDataHandle restShapeData = data.inputValue(restShape, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restVerticesData = data.inputValue(restVertices, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle restElementsData = data.inputValue(restElements, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedConstraintVertsData = data.inputValue(selectedConstraintVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle selectedForceVertsData = data.inputValue(selectedForceVerts, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle timeData = data.inputValue(time, &returnStatus);
		McheckErr(returnStatus, "Error getting step data handle\n");

		MDataHandle outputMeshData = data.outputValue(deformed, &returnStatus);
		McheckErr(returnStatus, "Error getting outputMesh data handle\n");
		
		MMatrix twmat = tetWorldMatrixData.asMatrix();
		MObject rs = restShapeData.asMesh();
		double t = timeData.asDouble();

		MDataHandle poissonRatioData = data.inputValue(poissonRatio, &returnStatus);
		McheckErr(returnStatus, "Error getting poissonRatio data handle\n");

		MDataHandle youngsModulusData = data.inputValue(youngsModulus, &returnStatus);
		McheckErr(returnStatus, "Error getting youngsmodulus data handle\n");

		MDataHandle objectDensityData = data.inputValue(objectDensity, &returnStatus);
		McheckErr(returnStatus, "Error getting objectDensity data handle\n");

		MDataHandle frictionData = data.inputValue(friction, &returnStatus);
		McheckErr(returnStatus, "Error getting friction data handle\n");

		MDataHandle restitutionData = data.inputValue(restitution, &returnStatus);
		McheckErr(returnStatus, "Error getting restitution data handle\n");

		MDataHandle dampingData = data.inputValue(damping, &returnStatus);
		McheckErr(returnStatus, "Error getting damping data handle\n");

		MDataHandle userSuppliedDtData = data.inputValue(userSuppliedDt, &returnStatus);
		McheckErr(returnStatus, "Error getting user supplied dt data handle\n");


		MDataHandle integrationTypeData = data.inputValue(integrationType, &returnStatus);
		McheckErr(returnStatus, "Error getting user integrationTypeData\n");

		MDataHandle forceModelTypeData = data.inputValue(forceModelType, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceModelTypeData\n");

		MDataHandle forceApplicationTimeData = data.inputValue(forceApplicationTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceApplicationTime\n");
	
		MDataHandle forceReleasedTimeData = data.inputValue(forceReleasedTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceReleasedTime\n");

		MDataHandle forceIncrementTimeData = data.inputValue(forceIncrementTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIncrementTime\n");

		MDataHandle forceStartTimeData = data.inputValue(forceStartTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStartTime\n");

		MDataHandle forceStopTimeData = data.inputValue(forceStopTime, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceStopTime\n");

		MDataHandle forceMagnitudeData = data.inputValue(forceMagnitude, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedForceData = data.inputValue(useSuppliedForce, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle useSuppliedConstraintsData = data.inputValue(useSuppliedConstraints, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceIdleTime\n");

		MDataHandle forceDirectionData = data.inputValue(forceDirection, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MDataHandle contactKsData = data.inputValue(contactKs, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");	

		MDataHandle contactKdData = data.inputValue(contactKd, &returnStatus);
		McheckErr(returnStatus, "Error getting user forceDirection\n");

		MTime currentTime, maxTime;
		currentTime = MAnimControl::currentTime();
		maxTime = MAnimControl::maxTime();
					
		if (currentTime == MAnimControl::minTime())
		{
			// retrive restVertices and restElements
			MFnDoubleArrayData restVertArrayData(restVerticesData.data());
			MDoubleArray verts = restVertArrayData.array();
			int vertArrayLen = verts.length();
			double *vertArray = new double[vertArrayLen];
			verts.get(vertArray);

			for(int v=0;v<vertArrayLen;v=v+3)
			{
				MPoint mpoint = MPoint(vertArray[v],vertArray[v+1],vertArray[v+2])*twmat;
				vertArray[v] = mpoint.x;
				vertArray[v+1] = mpoint.y;
				vertArray[v+2] = mpoint.z;
			}

			MFnIntArrayData restEleArrayData(restElementsData.data());
			MIntArray ele = restEleArrayData.array();
			int eleArrayLen = ele.length();
			int *eleArray = new int[eleArrayLen];
			ele.get(eleArray);

			MFnIntArrayData selectedConstraintVertsArrayData(selectedConstraintVertsData.data());
			MIntArray sv = selectedConstraintVertsArrayData.array();

			// building selectedConstraintVerts
			vector<int> selectedConstraintVertIndices;
			for (int i = 0 ; i < sv.length() ; i++)
			{
				selectedConstraintVertIndices.push_back(sv[i]);
			}

			MFnIntArrayData selectedForceVertsArrayData(selectedForceVertsData.data());
			MIntArray sf = selectedForceVertsArrayData.array();

			vector<int> selectedForceVertIndices;
			for (int i = 0 ; i < sf.length() ; i++)
			{
				selectedForceVertIndices.push_back(sf[i]);
			}


			// temporarily create force direction vector
			double *forceDir = forceDirectionData.asDouble3();

	
			vector<double> dir;
			dir.push_back(forceDir[0]); dir.push_back(forceDir[1]);dir.push_back(forceDir[2]);

			prevDeformed = 0;
			double youngsModulusDouble = youngsModulusData.asDouble();
			double poissonRatioDouble = poissonRatioData.asDouble();
			double objectDensityDouble = objectDensityData.asDouble();
			double frictionDouble = frictionData.asDouble();
			double restitutionDouble = restitutionData.asDouble();
			double dampingDouble = dampingData.asDouble();
			double userSuppliedDtDouble = userSuppliedDtData.asDouble();
			double forceMagnitudeDouble = forceMagnitudeData.asDouble();
			int fAppT = forceApplicationTimeData.asInt();
			int fReleasedT = forceReleasedTimeData.asInt();
			int fIncT = forceIncrementTimeData.asInt();
			int fStartT = forceStartTimeData.asInt();
			int fStopT = forceStopTimeData.asInt();
			int integrationTypeInt = integrationTypeData.asShort();
			int forceModelTypeInt = forceModelTypeData.asShort();

			bool useSuppliedForceBool = useSuppliedForceData.asBool();
			bool useSuppliedConstraintsBool = useSuppliedConstraintsData.asBool();

			double contactKs = contactKsData.asDouble();
			double contactKd = contactKdData.asDouble();

			if( sm)
			{
				delete sm;
			}
			sm = new SoftBodySim(youngsModulusDouble,poissonRatioDouble,objectDensityDouble,
				frictionDouble,restitutionDouble,dampingDouble, eleArrayLen, eleArray, vertArrayLen, vertArray,integrationTypeInt,forceModelTypeInt);
			sm->setContactAttributes(contactKs,contactKd);
			if (useSuppliedConstraintsBool)
				sm->initialize("",userSuppliedDtDouble, selectedConstraintVertIndices);
			else
			{
				vector<int> empty;
				sm->initialize("",userSuppliedDtDouble, empty);
			}
			
			if (useSuppliedForceBool)
				sm->setUserForceAttributes(forceMagnitudeDouble, dir,selectedForceVertIndices,fAppT,fReleasedT,fIncT,fStartT,fStopT);
		}

		else
		{
			sm->update();
		}

		MFnMesh surfFn(rs,&stat);
		McheckErr( stat, "compute - MFnMesh error" );

		MFnMeshData ouputMeshDataCreator;
		MObject oMesh = ouputMeshDataCreator.create(&stat);
		buildOutputMesh(surfFn, sm->m_vertices,oMesh);
		outputMeshData.set(oMesh);
		data.setClean(plug);

	}

	else
		stat = MS::kUnknownParameter;

	return stat;
}
コード例 #6
0
ファイル: PtexColorNode.cpp プロジェクト: Mankua/PtexShaders
MStatus PtexColorNode::compute(const MPlug& plug, MDataBlock& block) 
{
    if( ( plug != aOutColor ) && ( plug.parent() != aOutColor ) )
	{
		return MS::kUnknownParameter;
	}
	
	if ( m_ptex_cache == NULL )
	{
		m_ptex_cache = PtexCache::create( 0, 1024 * 1024 );
	}

	if ( m_ptex_cache && m_ptex_texture == 0 )
	{
		MDataHandle fileNameHnd = block.inputValue( aPtexFileName );
		MDataHandle filterTypeHnd = block.inputValue( aPtexFilterType );

		MString fileNameStr = fileNameHnd.asString();
		int filterTypeValue = filterTypeHnd.asInt();

		const float &filterSize = block.inputValue( aPtexFilterSize ).asFloat();

		if ( fileNameStr.length() )
		{
			Ptex::String error;
			m_ptex_texture = m_ptex_cache->get( fileNameStr.asChar(), error );
		}
		
		if ( m_ptex_texture == 0 )
		{
			MDataHandle outColorHandle = block.outputValue( aOutColor );
			MFloatVector& outColor = outColorHandle.asFloatVector();
			outColor.x = 1.0f;
			outColor.y = 0.0f;
			outColor.z = 1.0f;
			return MS::kSuccess;
		}

		m_ptex_num_channels = m_ptex_texture->numChannels();

		PtexFilter::FilterType ptexFilterType = PtexFilter::f_point;

		switch ( filterTypeValue )
		{
			case 0:   ptexFilterType = PtexFilter::f_point;        break;
			case 1:   ptexFilterType = PtexFilter::f_bilinear;     break;
			case 2:   ptexFilterType = PtexFilter::f_box;          break;
			case 3:   ptexFilterType = PtexFilter::f_gaussian;     break;
			case 4:   ptexFilterType = PtexFilter::f_bicubic;      break;
			case 5:   ptexFilterType = PtexFilter::f_bspline;      break;
			case 6:   ptexFilterType = PtexFilter::f_catmullrom;   break;
			case 7:   ptexFilterType = PtexFilter::f_mitchell;     break;
		}

		PtexFilter::Options opts( ptexFilterType, 0, filterSize );
		m_ptex_filter = PtexFilter::getFilter( m_ptex_texture, opts );
	}

	const float2 &uv  = block.inputValue( aUVPos  ).asFloat2();
	const float2 &duv = block.inputValue( aUVSize ).asFloat2();

	int f = (int)uv[ 0 ];

	float u = uv[ 0 ] - (float)f;
	float v = uv[ 1 ];

	float result[4];
	
	m_critical_section.lock();
	m_ptex_filter->eval( result, 0, m_ptex_num_channels, f, u, v, duv[ 0 ], 0, 0, duv[ 1 ] );
	m_critical_section.unlock();
	
	// set ouput color attribute
	MFloatVector resultColor( result[ 0 ], result[ 1 ], result[ 2 ] );
	MDataHandle outColorHandle = block.outputValue( aOutColor );
	MFloatVector& outColor = outColorHandle.asFloatVector();
	outColor = resultColor;
	outColorHandle.setClean();

	return MS::kSuccess;
}
コード例 #7
0
MStatus NBuddyEMPSaverNode::compute( const MPlug& plug, MDataBlock& data )
{
    MStatus status;
    if (plug == _outTrigger)
    {
	MDataHandle outputPathHdl = data.inputValue( _empOutputPath, &status );
        NM_CheckMStatus( status, "Failed to get the output path handle");
	MString outputPath = outputPathHdl.asString();

       	// Get the input time
	MDataHandle timeHdl = data.inputValue( _time, &status );
	NM_CheckMStatus( status, "Failed to get time handle");
	MTime time = timeHdl.asTime();

        // Get the frame padding
        MDataHandle framePaddingHdl = data.inputValue( _framePadding, &status );
        NM_CheckMStatus( status, "Failed to get the framePadding handle");
        int numPad = framePaddingHdl.asInt();

      // Get the frame padding
        MDataHandle timeStepHdl = data.inputValue( _timeStep, &status );
        NM_CheckMStatus( status, "Failed to get the timeStep handle");
        int timeStep = timeStepHdl.asInt();
  
        // Get the time in frames
        int frameNr = (int)floor( time.as( time.uiUnit() ) );

        //Create the writer, givin it the time index in seconds
        Nb::EmpWriter* writer = 
            new Nb::EmpWriter( 
                "",
                outputPath.asChar(),       // absolute fullpath of emp
                frameNr,                   // frame
                timeStep,                  // timestep
                numPad,                    // zero-padding                
                time.as( MTime::kSeconds ) // emp timestamp
                );

        // Then get the inputBodies
        MArrayDataHandle inBodyArrayData = data.inputArrayValue( _inBodies, &status );
        NM_CheckMStatus( status, "Failed to create get inBodyArrayData handle");

        // Loop the input in the inBody multi plug
        unsigned int numBodies = inBodyArrayData.elementCount();
        if ( numBodies > 0 )
        {
            //Jump to the first element in the array
            inBodyArrayData.jumpToArrayElement(0);

            //Loop all the body inputs and add them to the empWriter
            for ( unsigned int i(0); i < numBodies; ++i)
            {
                MDataHandle bodyDataHnd = inBodyArrayData.inputValue( &status );
                MFnPluginData dataFn(bodyDataHnd.data());

                //Get naiad body from datatype
                naiadBodyData * bodyData = (naiadBodyData*)dataFn.data( &status );
                if ( bodyData && bodyData->nBody() )
                {
                    //Add body to writer
                    try{
                        Nb::String channels("*.*");
                        writer->write(bodyData->nBody(),channels);
                    }
                    catch(std::exception& e) {
                        std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl;
                    }
                }
                else
                    std::cerr << "NBuddyEMPSaverNode::compute() :: No body in input " << inBodyArrayData.elementIndex() << std::endl;

                //Next body in the input multi
                inBodyArrayData.next();
            }
        }

        try{
            writer->close();
            // Get rid of the writer object
            delete writer;
        }
        catch(std::exception& e) {
            std::cerr << "NBuddyEMPSaverNode::compute() " << e.what() << std::endl;
        }

        //Set the output to be clean indicating that we have saved out the file
        MDataHandle outTriggerHnd = data.outputValue( _outTrigger, &status );
        outTriggerHnd.set(true);
        data.setClean( plug );
    }

    return status;
}
コード例 #8
0
ファイル: snapMeshDeformer.cpp プロジェクト: dams31/maya
MStatus snapDeformer::deform(MDataBlock &data, MItGeometry &iter, const MMatrix &mat, unsigned int multiIndex) {
	MStatus stat;


    //lets see if we need to do anything
	MDataHandle DataHandle = data.inputValue(envelope, &stat);
	float env = DataHandle.asFloat();
	if (env == 0)
		return stat;
    DataHandle = data.inputValue(weight, &stat);
	const float weight = DataHandle.asFloat();
    if (weight == 0)
		return stat;
    
    env = (env*weight);


	//space target
	DataHandle = data.inputValue(space, &stat);
    int SpaceInt = DataHandle.asInt();

    //space source
	DataHandle = data.inputValue(spaceSource, &stat);
    int SpaceSourceInt = DataHandle.asInt();

    //pointlist
    MArrayDataHandle pointArrayHandle = data.inputArrayValue(pointList);


	//snapMesh
	MFnMesh	SnapMesh;
	DataHandle = data.inputValue(snapMesh, &stat);
    if (!stat)
        return Err(stat,"Can't get mesh to snap to");
    MObject SnapMeshObj = DataHandle.asMesh();
    SnapMesh.setObject(SnapMeshObj);
    MPointArray snapPoints;
    if (SpaceSourceInt==0)
        SnapMesh.getPoints(snapPoints, MSpace::kWorld);
    else
        SnapMesh.getPoints(snapPoints, MSpace::kObject);
    


    iter.reset();
    for ( ; !iter.isDone(); iter.next()) 	{
        //check for painted weights
        float currEnv = env * weightValue(data, multiIndex, iter.index());

        //get point to snap to
        unsigned int index;
        stat = pointArrayHandle.jumpToElement(iter.index());
        if (!stat)
            index = 0;
        else {
            DataHandle = pointArrayHandle.outputValue();
            index = DataHandle.asInt();
        }

        if (index != -1) {
            //calc point location
            MPoint currPoint;
            if (snapPoints.length() > index)
                currPoint = snapPoints[index];

            if (SpaceInt == 0)
                currPoint *= mat.inverse();

            if (currEnv !=1)
            {
                MPoint p = (currPoint- iter.position());
                currPoint = iter.position() + (p*currEnv);
            }


            //set point location
            iter.setPosition(currPoint);
        }
            
            
    }

    return stat;
}
コード例 #9
0
ファイル: PtexUVNode.cpp プロジェクト: Mankua/PtexShaders
MStatus PtexUVNode::compute( const MPlug &plug, MDataBlock &data )
{
	MStatus stat;
	bool hasNoEffect = false;
	
	MDataHandle inMeshHnd = data.inputValue( inMesh );
	MDataHandle outMeshHnd = data.outputValue( outMesh );
	 
	MDataHandle stateHnd = data.inputValue( state );
	int state = stateHnd.asInt();

	if( state == 1 ) // No Effect/Pass through
		hasNoEffect = true;
		
	if( !hasNoEffect && plug == outMesh )
	{
	    MObject inMeshData = inMeshHnd.asMesh();
				
		if( !hasNoEffect )
		{
			MFnMeshData meshDataFn;
			MObject newMeshData = meshDataFn.create();
			MFnMesh inMeshFn( inMeshData );
			inMeshFn.copy( inMeshData, newMeshData );
			
			MFnMesh meshFn( newMeshData );
			MPointArray pts;
			meshFn.getPoints( pts );

			MStringArray uvSetNames;
			meshFn.getUVSetNames( uvSetNames );
			unsigned int defaultUvSetCount = (unsigned int)uvSetNames.length();

			int num_faces = meshFn.numPolygons();

			MIntArray uvCounts;
			uvCounts.setLength( num_faces );

			for ( int i_f = 0; i_f < num_faces; i_f++ )
			{
				int deg = meshFn.polygonVertexCount( i_f );
				uvCounts[ i_f ] = deg;

				if ( deg != 4 )
				{
					return MS::kFailure;
				}
			}

			MIntArray uvIds;
			uvIds.setLength( 4 * num_faces );

			if ( defaultUvSetCount == 1 )
			{
				int currentUVCount = meshFn.numUVs( uvSetNames[0] );

				MFloatArray us, vs; 
				us.setLength( 4 * num_faces ); 
				vs.setLength( 4 * num_faces );

				for ( int i_f = 0; i_f < num_faces; i_f++ )
				{
					float f = (float)i_f;

					uvIds[ 4 * i_f + 0 ] = 4 * i_f + 0;
					uvIds[ 4 * i_f + 1 ] = 4 * i_f + 1;
					uvIds[ 4 * i_f + 2 ] = 4 * i_f + 2;
					uvIds[ 4 * i_f + 3 ] = 4 * i_f + 3;

					us[ 4 * i_f + 0 ] = (float)i_f;         vs[ 4 * i_f + 0 ] = 0.0f;
					us[ 4 * i_f + 1 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 1 ] = 0.0f;
					us[ 4 * i_f + 2 ] = (float)i_f + 1.0f;  vs[ 4 * i_f + 2 ] = 1.0f;
					us[ 4 * i_f + 3 ] = (float)i_f;         vs[ 4 * i_f + 3 ] = 1.0f;
				}

				stat = meshFn.setUVs( us, vs, &uvSetNames[0] );
				stat = meshFn.assignUVs( uvCounts, uvIds, &uvSetNames[0] );
			}

			meshFn.updateSurface();
			meshFn.syncObject();

			outMeshHnd.set( newMeshData );
		}	
	}
	else 
		return MS::kUnknownParameter;

	if( hasNoEffect )
		outMeshHnd.set( inMeshHnd.asMesh() );
	
	data.setClean( plug );

	return stat;
}
コード例 #10
0
ファイル: hwPhongShader.cpp プロジェクト: OpenXRay/xray
/* virtual */
bool hwPhongShader::setInternalValueInContext( const MPlug &plug, 
											   const MDataHandle &handle,
											   MDGContext & )
{
	bool handledAttribute = false;
	if (plug == aColor)
	{
		handledAttribute = true;
		float3 & val = handle.asFloat3();
		if (val[0] != mAmbientColor[0] || 
			val[1] != mAmbientColor[1] || 
			val[2] != mAmbientColor[2])
		{
			mAmbientColor[0] = val[0];
			mAmbientColor[1] = val[1];
			mAmbientColor[2] = val[2];
			mAttributesChanged = true;
		}
	}
	else if (plug == aDiffuseColor)
	{
		handledAttribute = true;
		float3 & val = handle.asFloat3();
		if (val[0] != mDiffuseColor[0] || 
			val[1] != mDiffuseColor[1] || 
			val[2] != mDiffuseColor[2])
		{
			mDiffuseColor[0] = val[0];
			mDiffuseColor[1] = val[1];
			mDiffuseColor[2] = val[2];
			mAttributesChanged = true;
		}
	}
	else if (plug == aSpecularColor)
	{
		handledAttribute = true;
		float3 & val = handle.asFloat3();
		if (val[0] != mSpecularColor[0] || 
			val[1] != mSpecularColor[1] || 
			val[2] != mSpecularColor[2])
		{
			mSpecularColor[0] = val[0];
			mSpecularColor[1] = val[1];
			mSpecularColor[2] = val[2];
			mAttributesChanged = true;
		}
	}
	else if (plug == aShininess)
	{
		handledAttribute = true;
		float3 & val = handle.asFloat3();
		if (val[0] != mShininess[0] || 
			val[1] != mShininess[1] || 
			val[2] != mShininess[2])
		{
			mShininess[0] = val[0];
			mShininess[1] = val[1];
			mShininess[2] = val[2];
			mAttributesChanged = true;
		}
	}
	else if (plug == aGeometryShape)
	{
		handledAttribute = true;
		mGeometryShape = handle.asInt();
	}

	return handledAttribute;
}
コード例 #11
0
ファイル: HRBFNode.cpp プロジェクト: ArtisticCoding/HRBF-Skin
MStatus
HRBFSkinCluster::deform( MDataBlock& block,
                      MItGeometry& iter,
                      const MMatrix& m,
                      unsigned int multiIndex)
//
// Method: deform1
//
// Description:   Deforms the point with a simple smooth skinning algorithm
//
// Arguments:
//   block      : the datablock of the node
//   iter       : an iterator for the geometry to be deformed
//   m          : matrix to transform the point into world space
//   multiIndex : the index of the geometry that we are deforming
//
//
{
	MStatus returnStatus;

	// get HRBF status
	MDataHandle HRBFstatusData = block.inputValue(rebuildHRBF, &returnStatus);
	McheckErr(returnStatus, "Error getting rebuildHRBF handle\n");
	int rebuildHRBFStatusNow = HRBFstatusData.asInt();
	// handle signaling to the rest of deform that HRBFs must be rebuild
	bool signalRebuildHRBF = false;
	signalRebuildHRBF = (rebuildHRBFStatus != rebuildHRBFStatusNow);
	MMatrixArray bindTFs; // store just the bind transforms in here.
	MMatrixArray boneTFs; // ALWAYS store just the bone transforms in here.

	// get HRBF export status
	MDataHandle exportCompositionData = block.inputValue(exportComposition, &returnStatus);
	McheckErr(returnStatus, "Error getting exportComposition handle\n");
	int exportCompositionStatusNow = exportCompositionData.asInt();

	MDataHandle HRBFExportSamplesData = block.inputValue(exportHRBFSamples, &returnStatus);
	McheckErr(returnStatus, "Error getting exportHRBFSamples handle\n");
	std::string exportHRBFSamplesStatusNow = HRBFExportSamplesData.asString().asChar();

	MDataHandle HRBFExportValuesData = block.inputValue(exportHRBFValues, &returnStatus);
	McheckErr(returnStatus, "Error getting exportHRBFValues handle\n");
	std::string exportHRBFValuesStatusNow = HRBFExportValuesData.asString().asChar();

	// get skinning type
	MDataHandle useDQData = block.inputValue(useDQ, &returnStatus);
	McheckErr(returnStatus, "Error getting useDQ handle\n");
	int useDQNow = useDQData.asInt();

	// determine if we're using HRBF
	MDataHandle useHRBFData = block.inputValue(useHRBF, &returnStatus);
	McheckErr(returnStatus, "Error getting useHRBFData handle\n");
	int useHRBFnow = useHRBFData.asInt();

	// get envelope because why not
	MDataHandle envData = block.inputValue(envelope, &returnStatus);
	float env = envData.asFloat();

	// get point in space for evaluating HRBF
	MDataHandle checkHRBFAtData = block.inputValue(checkHRBFAt, &returnStatus);
	McheckErr(returnStatus, "Error getting useDQ handle\n");
	double* data = checkHRBFAtData.asDouble3();

	// get the influence transforms
	//
	MArrayDataHandle transformsHandle = block.inputArrayValue( matrix ); // tell block what we want
	int numTransforms = transformsHandle.elementCount();
	if ( numTransforms == 0 ) { // no transforms, no problems
		return MS::kSuccess;
	}
	MMatrixArray transforms; // fetch transform matrices -> actual joint matrices
	for ( int i=0; i<numTransforms; ++i ) {
		MMatrix worldTF = MFnMatrixData(transformsHandle.inputValue().data()).matrix();
		transforms.append(worldTF);
		boneTFs.append(worldTF);
		transformsHandle.next();
	}
	// inclusive matrices inverse of the driving transform at time of bind
	// matrices for transforming vertices to joint local space
	MArrayDataHandle bindHandle = block.inputArrayValue( bindPreMatrix ); // tell block what we want
	if ( bindHandle.elementCount() > 0 ) {
		for ( int i=0; i<numTransforms; ++i ) {
			MMatrix bind = MFnMatrixData(bindHandle.inputValue().data()).matrix();
			transforms[i] = bind * transforms[i];
			bindHandle.next();
			if (signalRebuildHRBF) bindTFs.append(bind);
		}
	}

	MArrayDataHandle weightListHandle = block.inputArrayValue(weightList);
	if (weightListHandle.elementCount() == 0) {
		// no weights - nothing to do
		std::cout << "no weights!" << std::endl;
		//rebuildHRBFStatus = rebuildHRBFStatusNow - 1; // HRBFs will need to rebuilt no matter what
		return MS::kSuccess;
	}

	// print HRBF samples if requested
	if (exportHRBFSamplesStatusNow != exportHRBFSamplesStatus) {
		std::cout << "instructed to export HRBF samples: " << exportHRBFSamplesStatusNow.c_str() << std::endl;
		exportHRBFSamplesStatus = exportHRBFSamplesStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugSamplesToConsole(exportHRBFSamplesStatus);
	}

	// print HRBF values if requested
	if (exportHRBFValuesStatusNow != exportHRBFValuesStatus) {
		std::cout << "instructed to export HRBF values: " << exportHRBFValuesStatusNow.c_str() << std::endl;
		exportHRBFValuesStatus = exportHRBFValuesStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugValuesToConsole(exportHRBFValuesStatus);
	}

	// print HRBF composition if requested
	if (exportCompositionStatusNow != exportCompositionStatus) {
		std::cout << "instructed to export HRBF composition." << std::endl;
		exportCompositionStatus = exportCompositionStatusNow;
		// TODO: handle exporting HRBFs to the text file format
		hrbfMan->debugCompositionToConsole(boneTFs, numTransforms);
	}

	// check the HRBF value if the new point is significantly different
	MPoint checkHRBFHereNow(data[0], data[1], data[2]);
	if ((checkHRBFHereNow - checkHRBFHere).length() > 0.0001) {
		if (hrbfMan->m_HRBFs.size() == numTransforms) {
			std::cout << "checking HRBF at x:" << data[0] << " y: " << data[1] << " z: " << data[2] << std::endl;
			hrbfMan->compose(boneTFs);
			float val = 0.0f;
			float dx = 0.0f;
			float dy = 0.0f;
			float dz = 0.0f;
			float grad = 0.0f;

			hrbfMan->mf_vals->trilinear(data[0], data[1], data[2], val);
			hrbfMan->mf_gradX->trilinear(data[0], data[1], data[2], dx);
			hrbfMan->mf_gradY->trilinear(data[0], data[1], data[2], dy);
			hrbfMan->mf_gradZ->trilinear(data[0], data[1], data[2], dz);
			hrbfMan->mf_gradMag->trilinear(data[0], data[1], data[2], grad);
			std::cout << "val: " << val << " dx: " << dx << " dy: " << dy << " dz: " << dz << " grad: " << grad << std::endl;
			checkHRBFHere = checkHRBFHereNow;
		}
	}

	// rebuild HRBFs if needed
	if (signalRebuildHRBF) {
		std::cout << "instructed to rebuild HRBFs" << std::endl;
		rebuildHRBFStatus = rebuildHRBFStatusNow;

		MArrayDataHandle parentIDCsHandle = block.inputArrayValue(jointParentIdcs); // tell block what we want
		std::vector<int> jointParentIndices(numTransforms);
		if (parentIDCsHandle.elementCount() > 0) {
			for (int i = 0; i<numTransforms; ++i) {
				jointParentIndices[i] = parentIDCsHandle.inputValue().asInt();
				parentIDCsHandle.next();
			}
		}

		MArrayDataHandle jointNamesHandle = block.inputArrayValue(jointNames); // tell block what we want
		std::vector<std::string> jointNames(numTransforms);
		if (jointNamesHandle.elementCount() > 0) {
			for (int i = 0; i<numTransforms; ++i) {
				jointNames[i] = jointNamesHandle.inputValue().asString().asChar();
				jointNamesHandle.next();
			}
		}

		// debug
		//std::cout << "got joint hierarchy info! it's:" << std::endl;
		//for (int i = 0; i < numTransforms; ++i) {
		//	std::cout << i << ": " << jointNames[i].c_str() << " : " << jointParentIndices[i] << std::endl;
		//}
		std::cout << "rebuilding HRBFs... " << std::endl;
		hrbfMan->buildHRBFs(jointParentIndices, jointNames, bindTFs, boneTFs, 
			weightListHandle, iter, weights);
		std::cout << "done rebuilding!" << std::endl;
		weightListHandle.jumpToElement(0); // reset this, it's an iterator. trust me.
		iter.reset(); // reset this iterator so we can go do normal skinning
	}


	// perform traditional skinning
	if (useDQNow != 0) {
		returnStatus = skinDQ(transforms, numTransforms, weightListHandle, iter);
	}
	else {
		returnStatus = skinLB(transforms, numTransforms, weightListHandle, iter);
	}

	// do HRBF corrections
	if (useHRBFnow != 0) {
		if (hrbfMan->m_HRBFs.size() == numTransforms) {
			hrbfMan->compose(boneTFs);
			iter.reset();
			hrbfMan->correct(iter);
		}
	}

	return returnStatus;
}
コード例 #12
0
ファイル: vxCacheDeformer.cpp プロジェクト: saggita/makoto
MStatus vxCacheDeformer::deform( MDataBlock& block,
				MItGeometry& iter,
				const MMatrix& m,
				unsigned int multiIndex)
{
	MStatus returnStatus;
	
	MDataHandle envData = block.inputValue(envelope,&returnStatus);
	float env = envData.asFloat();
	if(env == 0) return returnStatus;
	
	double time = block.inputValue( frame ).asTime().value();
	
	MDataHandle inPathData = block.inputValue( path );
	MString str_path =  inPathData.asString();
	
	MDataHandle inMinFrmData = block.inputValue( aminframe );
	int minfrm = inMinFrmData.asInt();
	
	MDataHandle inMaxFrmData = block.inputValue( amaxframe );
	MDataHandle inFrmStepData = block.inputValue( aframestep );
	int frmstep = inFrmStepData.asInt();
	
	if( time < minfrm )
		time = minfrm;
		
	int frame_lo = minfrm + int(time-minfrm)/frmstep*frmstep;
	int frame_hi = frame_lo+frmstep;
	
	if( strlen( str_path.asChar() ) > 0 ) 
	{
	
		char filename[256];
		sprintf( filename, "%s.%d.mcf", str_path.asChar(), frame_lo );
	
		FMCFMesh mesh;
		if(mesh.load(filename) != 1)
		{
			MGlobal::displayError( MString("Failed to open file: ") + filename );
			return MS::kFailure;
		}
		
		int lo_n_vertex = mesh.getNumVertex();
		
		vertexArray.clear();
		vertexFArray.clear();
		
		XYZ tp;
		for(unsigned int i = 0; i < mesh.getNumVertex(); i++) {
			mesh.getVertex(tp, i);
			vertexArray.append( MPoint( tp.x, tp.y, tp.z ) );
		}

		if( time > frame_lo ) 
		{
			sprintf( filename, "%s.%d.mcf", str_path.asChar(), frame_hi );

			if(mesh.load(filename) != 1) MGlobal::displayError( MString("Failed to open file: ") + filename );

			else if(mesh.getNumVertex() == lo_n_vertex)
			{
				XYZ tp;
				for(unsigned int i = 0; i < mesh.getNumVertex(); i++) 
				{
					mesh.getVertex(tp, i);
					vertexFArray.append( MPoint( tp.x, tp.y, tp.z ) );
				}
				
				double alpha = double(time-frame_lo) / (double)frmstep;

				for(unsigned int i = 0; i < mesh.getNumVertex(); i++) {
					
					vertexArray[i] = vertexArray[i] + ( vertexFArray[i] - vertexArray[i] )*alpha;
					
				}
			}
		}

		// iterate through each point in the geometry
		//
		for ( ; !iter.isDone(); iter.next()) 
		{
			MPoint pt = iter.position();
			pt = pt + (vertexArray[iter.index()] - pt)*env;
			iter.setPosition(pt);
		}
	}
	
	return returnStatus;
}