Exemple #1
0
MStatus TCC::compute(const MPlug& plug, MDataBlock& data)

{
    MStatus stat;

    if (plug == aOutputMesh) {
        /* Get time */
        int subdivRes = data.inputValue(aRes, &stat).asInt();
        int subdivRefRes = data.inputValue(aRefRes, &stat).asInt();
        float lineThickness = data.inputValue(aLineThickness, &stat).asFloat();

        MDataHandle inMeshHandle = data.inputValue( aInputMesh, &stat ); McheckErr(stat,"ERROR getting attribute");
        MObject inMeshObj = inMeshHandle.asMesh();
        MFnMesh inMeshFn(inMeshObj);
        
        MIntArray nFV, F;
        inMeshFn.getVertices(nFV, F);
        
        MIntArray nFVc = MFnIntArrayData( data.inputValue( anFVc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray Fc   = MFnIntArrayData( data.inputValue( aFc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        
        MIntArray pole = MFnIntArrayData( data.inputValue( aPole ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray corner = MFnIntArrayData( data.inputValue( aCorner ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray T    = MFnIntArrayData( data.inputValue( aT ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray eqc  = MFnIntArrayData( data.inputValue( aEqc ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MDoubleArray itv  = MFnDoubleArrayData( data.inputValue( aItv ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");
        MIntArray err  = MFnIntArrayData( data.inputValue( aErr ).data() ).array(&stat); McheckErr(stat,"ERROR getting attr");

        TCCData tccData(nFV, F, nFVc, Fc, pole, corner, T, eqc, itv, err);

        /* Get output object */
        MDataHandle outMeshHandle = data.outputValue(aOutputMesh, &stat); McheckErr(stat, "ERROR getting attribute\n");

        if (validTopology(tccData))
        {
            stat = createSubdividedMesh(subdivRes, subdivRefRes, inMeshFn, tccData, outMeshHandle, lineThickness, stat);
        } 
        else 
        {
            outMeshHandle.setMObject(inMeshObj);
            
            MFnMesh outMeshFn(outMeshHandle.asMesh());
            
            stat = setErrorColors(outMeshFn, tccData);
        }
        
        data.setClean( plug );
    } else
        return MS::kUnknownParameter;

    return stat;
}
MStatus  matrixFromPolygon::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	//MFnDependencyNode thisNode( thisMObject() );
	//cout << thisNode.name() << ", start" << endl;

	if( plug == aOutputMatrix )
	{
		MDataHandle  hInputMesh = data.inputValue( aInputMesh, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		MDataHandle  hInputMeshMatrix = data.inputValue( aInputMeshMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		MDataHandle  hPolygonIndex = data.inputValue( aPolygonIndex, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		MDataHandle  hU = data.inputValue( aU, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		MDataHandle  hV = data.inputValue( aV, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );
		MDataHandle  hOutputMatrix = data.outputValue( aOutputMatrix, &status );
		CHECK_MSTATUS_AND_RETURN_IT( status );

		MMatrix outMatrix;
		getMatrixByPoints( outMatrix, hPolygonIndex.asInt(), hU.asDouble(), hV.asDouble(), hInputMesh.asMesh() );

		outMatrix *= hInputMeshMatrix.asMatrix();

		hOutputMatrix.set( outMatrix );

		data.setClean( plug );
	}
	//cout << thisNode.name() << ", end" << endl;

	return MS::kSuccess;
}
Exemple #3
0
MStatus SargassoNode::compute( const MPlug& plug, MDataBlock& block )
{	
	MStatus stat;
	if(!m_isInitd) return stat;
    
    if(plug == constraintRotateX || 
        plug == constraintRotateY ||
        plug == constraintRotateZ ||
        plug == constraintTranslateX || 
        plug == constraintTranslateY ||
        plug == constraintTranslateZ) {
         // AHelper::Info<MString>("ov child", plug.name());
         // AHelper::Info<unsigned>("ov id", plug.parent().logicalIndex());
         unsigned iobject = plug.parent().logicalIndex();
         if(iobject > m_numObjects-1) {
             MGlobal::displayInfo("n constraint is out of bound");
             return MS::kSuccess;
         }
         
         if(iobject == 0 && plug == constraintRotateX) {
             MDataHandle hm = block.inputValue(atargetMesh);
             updateShape(hm.asMesh());
         }
		 
		 if(plug == constraintRotateX)
			updateSpace(block, iobject);
                  
         MDataHandle hout = block.outputValue(plug, &stat);
             
         if(plug == constraintTranslateX) {
             hout.set(m_solvedT.x);
         }
         else if(plug == constraintTranslateY) {
             hout.set(m_solvedT.y);
         }
         else if(plug == constraintTranslateZ) {
             hout.set(m_solvedT.z);
         }
         else if(plug == constraintRotateX) {
             hout.set(m_rot[0]);
         }
         else if(plug == constraintRotateY) {
             hout.set(m_rot[1]);
         }
         else if(plug == constraintRotateZ) {
             hout.set(m_rot[2]);
         }
         block.setClean( plug );
    }
	else
		return MS::kUnknownParameter;

	return MS::kSuccess;
}
void MayaGeoAttribute::transferValueFromMaya(MPlug &plug, MDataBlock &data){
	MDataHandle dataHandle = data.inputValue(plug);
	MFnMesh meshFn(dataHandle.asMesh());
	
	MFloatPointArray mayaPoints;
	meshFn.getPoints(mayaPoints);
	
	// collect points
	std::vector<Imath::V3f> coralPoints;
	for(int i = 0; i < mayaPoints.length(); ++i){
		MFloatPoint* mayaPoint = &mayaPoints[i];
		coralPoints.push_back(Imath::V3f(mayaPoint->x, mayaPoint->y, mayaPoint->z));
	}
	
	// collect faces
	int numPolys =  meshFn.numPolygons();
	std::vector<std::vector<int> > coralFaces(numPolys);
	for(int polyId = 0; polyId < numPolys; ++polyId){
		MIntArray mayaVertexList;
		meshFn.getPolygonVertices(polyId, mayaVertexList);
		
		int polyPoints = mayaVertexList.length();
		std::vector<int> coralFace(polyPoints);
		for(int i = 0; i < polyPoints; ++i){
			int pointId = mayaVertexList[i];
			coralFace[i] = pointId;
		}
		
		coralFaces[polyId] = coralFace;
	}
	
	// create coral geo
	coral::Geo *coralGeo = outValue();
	
	if(coralGeo->hasSameTopology(coralFaces)){
		coralGeo->setPoints(coralPoints);
	}
	else{
		coralGeo->build(coralPoints, coralFaces);
	}
	
	valueChanged();
}
Exemple #5
0
MStatus sgMeshIntersect::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	if( m_isDirtyMeshMatrix )
	{
		MDataHandle hInputMeshMatrix = data.inputValue( aInputMeshMatrix );
		m_mtxMesh    = hInputMeshMatrix.asMatrix();
		m_mtxInvMesh = m_mtxMesh.inverse();
	}

	if( m_isDirtyMesh )
	{
		MDataHandle hInputMesh = data.inputValue( aInputMesh );
		m_fnMesh.setObject( hInputMesh.asMesh() );
	}

	if( m_isDirtyPointDest )
	{
		MDataHandle hPointDest   = data.inputValue( aPointDest );
		m_pointDest   = MPoint( hPointDest.asVector() ) * m_mtxInvMesh;
	}

	if( m_isDirtyPointSrc )
	{
		MDataHandle hPointSource = data.inputValue( aPointSource );
		m_pointSource = MPoint( hPointSource.asVector() ) * m_mtxInvMesh;
	}

	m_rayDirection = m_pointDest - m_pointSource;

	m_fnMesh.intersect( m_pointSource, m_rayDirection, m_pointsIntersect, &status );
	if( !status ) return MS::kSuccess;

	MDataHandle hParentInverse = data.inputValue( aParentInverseMatrix );
	m_mtxParentInverse = hParentInverse.asMatrix();

	MDataHandle hOutPoint = data.outputValue( aOutPoint );
	hOutPoint.setMVector( m_pointsIntersect[0]*m_mtxMesh*m_mtxParentInverse );

	return MS::kSuccess;
}
Exemple #6
0
//----------------------------------------------------------------------------
MStatus		BPT_InsertVtx::compute(const MPlug& plug, MDataBlock& data)
//----------------------------------------------------------------------------
{
	
	
//	FactoryWerte setzen
//	(hier ueueberall eventuell noch MCheck nutzen fueuer Debug wenn nueuetig)
	MStatus status;
	
		MDataHandle stateHandle = data.outputValue(state);
		
		if(stateHandle.asShort() == 1)
		{
			MDataHandle inMeshHandle = data.inputValue(IVinMesh);
			MDataHandle outMeshHandle = data.outputValue(IVoutMesh);

//			inMesh direkt an outMesh und MObject mesh an factory geben
			outMeshHandle.set(inMeshHandle.asMesh());
			outMeshHandle.setClean();
		}
		else
		{
			if( (plug == IVoutMesh) )
			{

				if(meshDirty)
				{
					MPRINT("COMPLETE COMPUTE!!!!!!!!!!!!!!!!!!!!!!!!!!!")

					status = doCompleteCompute(data);

					INVIS(cout<<"MeshDirty ist "<<meshDirty<<endl;)
						meshDirty = false;
					INVIS(cout<<"--------------------------------"<<endl;)

						MFnDependencyNode depNodeFn(thisMObject());

					INVIS(cout<<"---------------"<<endl;)
						INVIS(cout<<depNodeFn.name().asChar()<<endl;)
Exemple #7
0
//----------------------------------------------------------------------------
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;

}
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;
}
Exemple #9
0
void TestDeformer::initVertMapping(MDataBlock& data,
                          MItGeometry& iter,
                          const MMatrix& localToWorldMatrix,
                          unsigned int mIndex)
{
    MStatus status;


    MArrayDataHandle vertMapOutArrayData = data.outputArrayValue( vert_map, &status );
    CHECK_MSTATUS( status );

    // use vertMapOutArrayBuilder to modify vertMapOutArrayData
    iter.reset();
    int count = iter.count();
    MArrayDataBuilder vertMapOutArrayBuilder( vert_map, count, &status );
    CHECK_MSTATUS( status );


    MPointArray allPts;// world vertex position of the driven mesh
    allPts.clear();

    // walk through the driven mesh
    /// copy MItGeometry's vertex to vertMapOutArrayData
    int i = 0;
    while( !iter.isDone(&status) )
    {
        CHECK_MSTATUS( status );

        MDataHandle initIndexDataHnd = vertMapOutArrayBuilder.addElement( i, &status );
        CHECK_MSTATUS( status );

        int negIndex = -1;

        initIndexDataHnd.setInt( negIndex );
        initIndexDataHnd.setClean();

        // append a vertex position(world coordination) to allPts
        CHECK_MSTATUS(allPts.append( iter.position() * localToWorldMatrix ));
        i = i+1;
        iter.next();
    }
    CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));




    /// Append more vertex from each driver mesh to vertMapOutArrayData
    MArrayDataHandle meshAttrHandle = data.inputArrayValue( driver_mesh, &status );
    CHECK_MSTATUS( status );

    int numMeshes = meshAttrHandle.elementCount();
    __debug("%s(), numMeshes=%d", __FUNCTION__, numMeshes);

    CHECK_MSTATUS(meshAttrHandle.jumpToElement(0));
    for( int meshIndex=0; meshIndex < numMeshes; ++meshIndex )
    {
        __debug("%s(), meshIndex=%d", __FUNCTION__, meshIndex);

        MDataHandle currentMesh = meshAttrHandle.inputValue(&status);
        CHECK_MSTATUS(status);

        MObject meshMobj = currentMesh.asMesh();
        __debug("%s(), meshMobj.apiTypeStr()=%s", __FUNCTION__, meshMobj.apiTypeStr());

        __debugMeshInfo(__FUNCTION__, meshMobj);
        {
            _initVertMapping_on_one_mesh(meshMobj, vertMapOutArrayBuilder, allPts);// Note: vertMapOutArrayBuilder is updated in this function!
            //CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));
        }

        if( !meshAttrHandle.next() )
        {
            break;
        }
    }// for (mesh
    CHECK_MSTATUS(vertMapOutArrayData.set( vertMapOutArrayBuilder ));



}
Exemple #10
0
MStatus TestDeformer::deform(MDataBlock& data,
                          MItGeometry& iter,
                          const MMatrix& localToWorldMatrix,
                          unsigned int mIndex)
{
    MStatus status;

    // get the current node state
    short initialized_mapping = data.inputValue( initialized_data, &status).asShort();
    CHECK_MSTATUS(status);
    __debug("%s(), initialized_mapping=%d, mIndex=%d", __FUNCTION__, initialized_mapping, mIndex);

    if( initialized_mapping == 1 )
    {
        initVertMapping(data, iter, localToWorldMatrix, mIndex);

        // set initialized_data to 2 automatically. User don't have to set it manully.
        MObject tObj  =  thisMObject();
        MPlug setInitMode = MPlug( tObj, initialized_data  );
        setInitMode.setShort( 2 );
        // and sync initialized_mapping from initialized_data
        // so, the code section:
        //     if (initialized_mapping == 2)
        //     {
        //         ...
        //     }
        // will be executed when this deform() function is called next time.
        initialized_mapping = data.inputValue( initialized_data, &status ).asShort();
        CHECK_MSTATUS(status);
    }

    if( initialized_mapping == 2 )
    {
        envelope = MPxDeformerNode::envelope;
        MDataHandle envelopeHandle = data.inputValue( envelope, &status );
        CHECK_MSTATUS( status );

        MArrayDataHandle vertMapArrayData  = data.inputArrayValue( vert_map, &status  );
        CHECK_MSTATUS( status );

        MArrayDataHandle meshAttrHandle = data.inputArrayValue( driver_mesh, &status );
        CHECK_MSTATUS( status );


        /// 1. init tempOutputPts to zero points
        MPointArray tempOutputPts;
        iter.reset();
        while( !iter.isDone(&status) )
        {
            CHECK_MSTATUS(tempOutputPts.append(MPoint(0, 0, 0)));
            CHECK_MSTATUS(iter.next());
        }
        assert(tempOutputPts.length() == iter.count());


        /// 2. set tempOutputPts to deform values which comes from each driver mesh
        iter.reset();

        int numMeshes = meshAttrHandle.elementCount();
        __debug("%s(), numMeshes=%d", __FUNCTION__, numMeshes);

        CHECK_MSTATUS(meshAttrHandle.jumpToElement(0));
        // for each driver mesh
        for( int count=0; count < numMeshes; ++count )
        {
            __debug("%s(), count=%d", __FUNCTION__, count);

            // for one driver mesh: currentMesh
            MDataHandle currentMesh = meshAttrHandle.inputValue(&status);
            CHECK_MSTATUS( status );
            MObject meshMobj = currentMesh.asMesh();
            __debugMeshInfo(__FUNCTION__, meshMobj);

            // accumulate deform values of currentMesh to tempOutputPts
            _deform_on_one_mesh(data, iter, localToWorldMatrix, mIndex,
                                meshMobj,
                                envelopeHandle, vertMapArrayData, tempOutputPts );


            if( !meshAttrHandle.next() )
            {
                break;
            }

        }// for each driver mesh


        /// 3. add deform value to this geometry(driven mesh)
        int i = 0;
        iter.reset();
        while( !iter.isDone(&status) )
        {
            MPoint p = iter.position(MSpace::kObject, &status);
            CHECK_MSTATUS(status);

            // add the deform value to this vertex
            CHECK_MSTATUS(iter.setPosition( p + tempOutputPts[i]/numMeshes ));

            CHECK_MSTATUS(iter.next());
            ++i;
        }
        assert(tempOutputPts.length() == iter.count());
    }// if

	return( MS::kSuccess );
}
Exemple #11
0
MStatus  retargetLocator::compute( const MPlug& plug, MDataBlock& data )
{
	MStatus status;

	MDataHandle hDiscMatrix = data.inputValue( aDiscMatrix );
	MDataHandle hDiscAxis = data.inputValue( aDiscAxis );
	MDataHandle hDiscAngle = data.inputValue( aDiscAngle );
	MDataHandle hDiscDivision = data.inputValue( aDiscDivision );
	MDataHandle hDiscOffset = data.inputValue( aDiscOffset );
	MDataHandle hDiscSize = data.inputValue( aDiscSize );
	MDataHandle hDiscActiveColor = data.inputValue( aDiscActiveColor );
	MDataHandle hDiscLeadColor = data.inputValue( aDiscLeadColor );
	MDataHandle hDiscDefaultColor = data.inputValue( aDiscDefaultColor );
	MDataHandle hDiscFillAlpha = data.inputValue( aDiscFillAlpha );
	MDataHandle hDiscLineAlpha = data.inputValue( aDiscLineAlpha );

	discAxis = hDiscAxis.asInt();
	discDivision = hDiscDivision.asInt();
	discAngle = hDiscAngle.asDouble();
	discSize = hDiscSize.asVector();
	discOffset = hDiscOffset.asVector();
	discActiveColor = hDiscActiveColor.asFloat3();
	discLeadColor = hDiscLeadColor.asFloat3();
	discDefaultColor = hDiscDefaultColor.asFloat3();
	discFillAlpha = hDiscFillAlpha.asFloat();
	discLineAlpha = hDiscLineAlpha.asFloat();

	MArrayDataHandle hArrArrow = data.inputArrayValue( aArrow );
	arrowNum = hArrArrow.elementCount();

	inheritMatrix.setLength( arrowNum );
	aimMatrix.setLength( arrowNum );
	inputMeshObj.setLength( arrowNum );
	startSize.setLength( arrowNum );
	size.setLength( arrowNum );
	activeColor.setLength( arrowNum );
	leadColor.setLength( arrowNum );
	defaultColor.setLength( arrowNum );
	fillAlpha.setLength( arrowNum );
	lineAlpha.setLength( arrowNum );
	offset.setLength( arrowNum );

	for( int i =0; i < arrowNum; i++ )
	{
		MDataHandle hArrow = hArrArrow.inputValue();

		MDataHandle hInheritMatrix = hArrow.child( aInheritMatrix );
		MDataHandle hAimMatrix = hArrow.child( aAimMatrix );
		MDataHandle hInputMesh = hArrow.child( aInputMesh );
		MDataHandle hStartSize = hArrow.child( aStartSize );
		MDataHandle hSize = hArrow.child( aSize );
		MDataHandle hActiveColor = hArrow.child( aActiveColor );
		MDataHandle hLeadColor = hArrow.child( aLeadColor );
		MDataHandle hDefaultColor = hArrow.child( aDefaultColor );
		MDataHandle hFillAlpha = hArrow.child( aFillAlpha );
		MDataHandle hLineAlpha = hArrow.child( aLineAlpha );
		MDataHandle hOffset = hArrow.child( aOffset );

		inheritMatrix[i] = hInheritMatrix.asBool();
		aimMatrix[i] = hAimMatrix.asMatrix()*hDiscMatrix.asMatrix().inverse();
		inputMeshObj[i] = hInputMesh.asMesh();
		startSize[i] = hStartSize.asFloat();
		size[i] = hSize.asFloat();
		activeColor[i] = hActiveColor.asFloat3();
		leadColor[i] = hLeadColor.asFloat3();
		defaultColor[i] = hDefaultColor.asFloat3();
		fillAlpha[i] = hFillAlpha.asFloat();
		lineAlpha[i] = hLineAlpha.asFloat();
		offset[i] = hOffset.asVector();

		hArrArrow.next();
	}

	MDataHandle hOutput = data.outputValue( aOutput );
	hOutput.set( 1.0 );
	data.setClean( plug );

	return MS::kSuccess;
}
/*! Compute function, gets the input surface, determines what type it is and calls the appropriate conversion function
    Encapsulates an cowpointer to the body into the naiadBodyData type and outputs it */
MStatus NBuddySurfaceToBodyNode::compute( const MPlug& plug, MDataBlock& data )
{
    MStatus status;
    if (plug == _outBody)
    {
        //Get the body name
        MDataHandle bodyNameHndl = data.inputValue( _bodyName, &status );
        MString bodyName = bodyNameHndl.asString();

        //Create the MFnPluginData for the naiadBody
        MFnPluginData dataFn;
        dataFn.create( MTypeId( naiadBodyData::id ), &status);
        NM_CheckMStatus( status, "Failed to create naiadBodyData in MFnPluginData");

        //Get subdivision info from plugs so better approximations of meshes can be done
        int divisions = data.inputValue( _subDivide, &status ).asBool();
	
        //Getting genericAttribute handle containing the surface and pick the correct conversion function
        MObject meshObj;
        MDataHandle inSurfaceHdl = data.inputValue( _inSurface, &status );
        if (inSurfaceHdl.type() == MFnData::kNurbsSurface)
        {
            MFnNurbsSurface nurbsFn(inSurfaceHdl.asNurbsSurface());

            // Create the data holder for the tesselated mesh
            MFnMeshData dataCreator;
            MObject newOutputData = dataCreator.create(&status);

            //Setup the tesselation parameters
            MTesselationParams tParams;
            tParams.setOutputType( MTesselationParams::kTriangles );
            tParams.setFormatType( MTesselationParams::kGeneralFormat );
            tParams.setUIsoparmType( MTesselationParams::kSpanEquiSpaced );
            tParams.setVIsoparmType( MTesselationParams::kSpanEquiSpaced );
            tParams.setUNumber( divisions+1 );
            tParams.setVNumber( divisions+1 );

            // Tesselate and get the returned mesh
            meshObj = nurbsFn.tesselate( tParams, newOutputData, &status );
            NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate nurbs surface to poly");
        }
        else if (inSurfaceHdl.type() == MFnData::kMesh)
        {
            meshObj = inSurfaceHdl.asMesh();

            if ( divisions > 0 )
            {
                MFnMeshData dataCreator;
                MObject newOutputData = dataCreator.create(&status);

                MFnMesh meshFn(meshObj);
                MIntArray faceIds;
                for ( unsigned int i(0); i < meshFn.numPolygons(); ++i )
                    faceIds.append(i);

                meshFn.subdivideFaces( faceIds , divisions );
            }
        }
        else if (inSurfaceHdl.type() == MFnData::kSubdSurface)
        {
            // Create the subd function set so we can tesselate
            MFnSubd subDfn(inSurfaceHdl.asSubdSurface());

            // Create the data holder for the tesselated mesh
            MFnMeshData dataCreator;
            MObject newOutputData = dataCreator.create(&status);

            // Tesselate the subD surface
            meshObj = subDfn.tesselate(true, 1 , divisions , newOutputData, &status );
            NM_CheckMStatus( status, "NBuddySurfaceToBodyNode::compute Failed to tesselate SubD surface to poly");
        }
        else
            return status ;

	//Get the handle for the input transform
        MDataHandle inTransformHdl = data.inputValue( _inTransform, &status );
	NM_CheckMStatus( status, "Failed to get inTransform handle");

	MDataHandle useTransformHdl = data.inputValue( _useTransform, &status);
	NM_CheckMStatus( status, "Failed to get worldSpaceHdl ");
	bool useTransform = useTransformHdl.asBool();

        //Get a new naiadBodyData
        naiadBodyData * newBodyData = (naiadBodyData*)dataFn.data( &status );
        NM_CheckMStatus( status, "Failed to get naiadBodyData handle from MFnPluginData");

        try {
            newBodyData->nBody = mayaMeshToNaiadBody( meshObj, std::string(bodyName.asChar()), useTransform, inTransformHdl.asMatrix() );
        }
        catch(std::exception& ex) {
            NM_ExceptionPlugDisplayError("NBuddySurfaceToBodyNode::compute ", plug, ex );
        }

        //Give the data to the output handle and set it clean
        MDataHandle bodyDataHnd = data.outputValue( _outBody, &status );
        NM_CheckMStatus( status, "Failed to get outputData handle for outBody");
        bodyDataHnd.set( newBodyData );
        data.setClean( plug );
    }

    return status;
}
Exemple #13
0
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;
}
Exemple #14
0
MStatus mapBlendShape::deform(MDataBlock& data, 
							  MItGeometry& itGeo, 
							  const MMatrix& localToWorldMatrix, 
							  unsigned int geomIndex)
{
    MStatus status;

	// get the blendMesh 
	MDataHandle hBlendMesh = data.inputValue( aBlendMesh, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );
    MObject oBlendMesh = hBlendMesh.asMesh();
    if (oBlendMesh.isNull())
    {
        return MS::kSuccess;
    }

	MFnMesh fnMesh( oBlendMesh, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );
    MPointArray blendPoints;
    fnMesh.getPoints( blendPoints );

	// get the dirty flags for the input and blendMap
	bool inputGeomClean = data.isClean(inputGeom, &status);
	bool blendMapClean  = data.isClean(aBlendMap, &status);

	if (!blendMapClean) {
		lumValues.reserve(itGeo.count());
	}
	
	MDoubleArray uCoords, vCoords;
	MVectorArray resultColors;
	MDoubleArray resultAlphas;

	uCoords.setLength(1);
	vCoords.setLength(1);

	bool hasTextureNode;
	bool useBlendMap = data.inputValue(aUseBlendMap).asBool();
	float blendMapMultiplier = data.inputValue(aBlendMapMultiplier).asFloat();

	if (blendMapMultiplier<=0.0) {
		useBlendMap = false;
	}

	if (useBlendMap) {
		hasTextureNode = MDynamicsUtil::hasValidDynamics2dTexture(thisMObject(), aBlendMap);
	}

	float env = data.inputValue(envelope).asFloat();
    MPoint point;
	float2 uvPoint;
    float w, lum;

    for ( ; !itGeo.isDone(); itGeo.next() )
    {
		lum = 1.0;

		if (useBlendMap) {
			if (!blendMapClean) {
				fnMesh.getUVAtPoint(blendPoints[itGeo.index()], uvPoint);

				if (hasTextureNode) {
					uCoords[0] = uvPoint[0];
					vCoords[0] = uvPoint[1];
					MDynamicsUtil::evalDynamics2dTexture(thisMObject(), aBlendMap, uCoords, vCoords, &resultColors, &resultAlphas);
					lum = float(resultColors[0][0]);
				}
				lumValues[itGeo.index()] = lum;
			} else {
				lum = lumValues[itGeo.index()];
			}
		}

        point = itGeo.position();
        w = weightValue( data, geomIndex, itGeo.index() );
        point += (blendPoints[itGeo.index()] - point) * env * w * lum * blendMapMultiplier;
        itGeo.setPosition( point );
    }

	return MS::kSuccess;
}
Exemple #15
0
MStatus splitUVNode::compute( const MPlug& plug, MDataBlock& data )
//
//	Description:
//		This method computes the value of the given output plug based
//		on the values of the input attributes.
//
//	Arguments:
//		plug - the plug to compute
//		data - object that provides access to the attributes for this node
//
{
	MStatus status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes - stored as short)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// Check which output attribute we have been asked to 
		// compute. If this node doesn't know how to compute it, 
		// we must return MS::kUnknownParameter
		// 
		if (plug == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Now, we get the value of the uvList and use it to perform
			// the operation on this mesh
			//
			MDataHandle inputUVs = data.inputValue( uvList, &status);
			MCheckStatus(status,"ERROR getting uvList"); 
			
			// Copy the inMesh to the outMesh, and now you can
			// perform operations in-place on the outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			// Retrieve the UV list from the component list.
			//
			// Note, we use a component list to store the components
			// because it is more compact memory wise. (ie. comp[81:85]
			// is smaller than comp[81], comp[82],...,comp[85])
			//
			MObject compList = inputUVs.data();
			MFnComponentListData compListFn( compList );

			unsigned i;
			int j;
			MIntArray uvIds;

			for( i = 0; i < compListFn.length(); i++ )
			{
				MObject comp = compListFn[i];
				if( comp.apiType() == MFn::kMeshMapComponent )
				{
					MFnSingleIndexedComponent uvComp( comp );
					for( j = 0; j < uvComp.elementCount(); j++ )
					{
						int uvId = uvComp.element(j);
						uvIds.append( uvId );
					}
				}
			}

			// Set the mesh object and uvList on the factory
			//
			fSplitUVFactory.setMesh( mesh );
			fSplitUVFactory.setUVIds( uvIds );

			// Now, perform the splitUV
			//
			status = fSplitUVFactory.doIt();

			// Mark the output mesh as clean
			//
			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
Exemple #16
0
MStatus meshOpNode::compute( const MPlug& plug, MDataBlock& data )
//
//	Description:
//		This method computes the value of the given output plug based
//		on the values of the input attributes.
//
//	Arguments:
//		plug - the plug to compute
//		data - object that provides access to the attributes for this node
//
{
	MStatus status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// Check which output attribute we have been asked to 
		// compute. If this node doesn't know how to compute it, 
		// we must return MS::kUnknownParameter
		// 
		if (plug == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Now, we get the value of the component list and the operation
			// type and use it to perform the mesh operation on this mesh
			//
			MDataHandle inputIDs = data.inputValue( cpList, &status);
			MCheckStatus(status,"ERROR getting componentList"); 
			
			MDataHandle opTypeData = data.inputValue( opType, &status);
			MCheckStatus(status,"ERROR getting opType"); 

			// Copy the inMesh to the outMesh, so you can
			// perform operations directly on outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			// Retrieve the ID list from the component list.
			//
			// Note, we use a component list to store the components
			// because it is more compact memory wise. (ie. comp[81:85]
			// is smaller than comp[81], comp[82],...,comp[85])
			//
			MObject compList = inputIDs.data();
			MFnComponentListData compListFn( compList );

			// Get what operation is requested and 
			// what type of component is expected for this operation.
			MeshOperation operationType = (MeshOperation) opTypeData.asShort();
			MFn::Type componentType =
				meshOpFty::getExpectedComponentType(operationType);

			unsigned i;
			int j;
			MIntArray cpIds;

			for( i = 0; i < compListFn.length(); i++ )
			{
				MObject comp = compListFn[i];
				if( comp.apiType() == componentType )
				{
					MFnSingleIndexedComponent siComp( comp );
					for( j = 0; j < siComp.elementCount(); j++ )
						cpIds.append( siComp.element(j) );
				}
			}

			// Set the mesh object and component List on the factory
			//
			fmeshOpFactory.setMesh( mesh );
			fmeshOpFactory.setComponentList( compList );
			fmeshOpFactory.setComponentIDs( cpIds );
			fmeshOpFactory.setMeshOperation( operationType );

			// Now, perform the meshOp
			//
			status = fmeshOpFactory.doIt();

			// Mark the output mesh as clean
			//
			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
MStatus resetVtxRemapNode::compute( const MPlug& plug, MDataBlock& data )
//
//	Description:
//		This method computes the value of the given output plug based
//		on the values of the input attributes.
//
//	Arguments:
//		plug - the plug to compute
//		data - object that provides access to the attributes for this node
//
{
	MStatus status = MS::kSuccess;
 
	MDataHandle stateData = data.outputValue( state, &status );
	MCheckStatus( status, "ERROR getting state" );

	// Check for the HasNoEffect/PassThrough flag on the node.
	//
	// (stateData is an enumeration standard in all depend nodes - stored as short)
	// 
	// (0 = Normal)
	// (1 = HasNoEffect/PassThrough)
	// (2 = Blocking)
	// ...
	//
	if( stateData.asShort() == 1 )
	{
		MDataHandle inputData = data.inputValue( inMesh, &status );
		MCheckStatus(status,"ERROR getting inMesh");

		MDataHandle outputData = data.outputValue( outMesh, &status );
		MCheckStatus(status,"ERROR getting outMesh");

		// Simply redirect the inMesh to the outMesh for the PassThrough effect
		//
		outputData.set(inputData.asMesh());
	}
	else
	{
		// Check which output attribute we have been asked to 
		// compute. If this node doesn't know how to compute it, 
		// we must return MS::kUnknownParameter
		// 
		if (plug == outMesh)
		{
			MDataHandle inputData = data.inputValue( inMesh, &status );
			MCheckStatus(status,"ERROR getting inMesh");

			MDataHandle outputData = data.outputValue( outMesh, &status );
			MCheckStatus(status,"ERROR getting outMesh"); 

			// Copy the inMesh to the outMesh, and now you can
			// perform operations in-place on the outMesh
			//
			outputData.set(inputData.asMesh());
			MObject mesh = outputData.asMesh();

			fresetVtxRemapFactory.setMesh( mesh );

			status = fresetVtxRemapFactory.doIt();

			outputData.setClean();
		}
		else
		{
			status = MS::kUnknownParameter;
		}
	}

	return status;
}
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;
}
Exemple #19
0
MStatus fishVizNode::compute( const MPlug& plug, MDataBlock& data )
{    
    MStatus status;
	
	MObject arbitaryMesh = data.inputValue(aInMesh).asMesh();

	MDoubleArray ptc_time_offset;
	MDoubleArray ptc_amplitude;
	MDoubleArray ptc_bend;
	MDoubleArray ptc_scale;
	MDoubleArray masses;
	
	MString cacheName = data.inputValue(acachename, &status).asString();
	MTime currentTime = data.inputValue(atime, &status).asTime();
	cacheName = cacheName+"."+250*int(currentTime.value())+".pdc";
	
	pdcFile* fpdc = new pdcFile();
	if(fpdc->load(cacheName.asChar())==1)
	{
		//MGlobal::displayInfo(MString("FishViz loaded cache file: ")+cacheName);
		fpdc->readPositions(ptc_positions, ptc_velocities, ptc_ups, ptc_views, ptc_time_offset, ptc_amplitude, ptc_bend, ptc_scale, masses);
	}
	else MGlobal::displayWarning(MString("FishViz cannot open cache file: ")+cacheName);
	
	if(currentTime.value()!=int(currentTime.value())) 
	{
		float delta_t = currentTime.value()-int(currentTime.value());
		
		
		for(int i=0; i<fpdc->getParticleCount(); i++)
		{
			ptc_positions[i] += ptc_velocities[i]*delta_t/24.0f;
		}
	}
	
	delete fpdc;
	
	double flapping = zGetDoubleAttr(data, aFlapping);
	double bending= zGetDoubleAttr(data, aBending);
	double oscillate= zGetDoubleAttr(data, aOscillate);
	double length = zGetDoubleAttr(data, aLength);
	m_fish_length = length;
	double frequency = zGetDoubleAttr(data, aFrequency);
	unsigned num_bones = zGetIntAttr(data, aNBone);
	
	unsigned int nptc = ptc_positions.length();
	MPointArray vertices;
	MATRIX44F mat44, mat_bone;
	XYZ vert, front, up, side;
	MDataHandle outputHandle = data.outputValue(outMesh, &status);
	zCheckStatus(status, "ERROR getting polygon data handle\n");
	if(m_num_fish != nptc || m_num_bone != num_bones)
	{
		m_num_bone = num_bones;
		m_num_fish = nptc;
		unsigned int vertex_count;
		unsigned int face_count;
		MIntArray pcounts;
		MIntArray pconnect;
		
		
		
		unsigned  inmeshnv, inmeshnp;
		MPointArray pinmesh;
		MIntArray count_inmesh;
		MIntArray connect_inmesh;
		zWorks::extractMeshParams(arbitaryMesh, inmeshnv, inmeshnp, pinmesh, count_inmesh, connect_inmesh);
		vertex_count = inmeshnv * nptc;
		face_count = inmeshnp * nptc;
		
		for(unsigned int i=0; i<nptc; i++)
		{
			
			// calculate the bone transformations
			poseBones(length, num_bones, ptc_time_offset[i], frequency, ptc_amplitude[i], ptc_bend[i], flapping, bending, oscillate);
			
			front.x = ptc_views[i].x;
			front.y = ptc_views[i].y;
			front.z = ptc_views[i].z;
			up.x = ptc_ups[i].x;
			up.y = ptc_ups[i].y;
			up.z = ptc_ups[i].z;
			
			side = front.cross(up);
			side.normalize();
			
			up = side.cross(front);
			up.normalize();
			
			mat44.setIdentity();
			mat44.setOrientations(side, up, front);
			mat44.scale(ptc_scale[i]);
			mat44.setTranslation(ptc_positions[i].x, ptc_positions[i].y, ptc_positions[i].z);
			
			for(unsigned int j=0; j<inmeshnv; j++)
			{
				vert.x = pinmesh[j].x;
				vert.y = pinmesh[j].y;
				vert.z = pinmesh[j].z;
				
				int bone_id;
				if(vert.z>0) bone_id = 0;
				else if(-vert.z>length)  bone_id = num_bones-1;
				else bone_id = int(-vert.z/length*(num_bones-1));
				
				mat_bone = m_pBone->getBoneById(bone_id);
				vert.z -= -length/(num_bones-1)*bone_id;
				
				mat_bone.transform(vert);
				mat44.transform(vert);
				
				vertices.append(MPoint(vert.x, vert.y, vert.z));
			}
			for(unsigned int j=0; j<inmeshnp; j++)
			{
				pcounts.append(count_inmesh[j]);
			}
		}
		
		int acc=0;
		for(unsigned int i=0; i<nptc; i++)
		{
			for(unsigned int j=0; j<connect_inmesh.length(); j++)
			{
				pconnect.append(connect_inmesh[j]+acc);
			}
			acc += inmeshnv;
		}
		
		
		MObject m_mesh = outputHandle.asMesh();
		
		
		MFnMeshData dataCreator;
		MObject newOutputData = dataCreator.create(&status);
		zCheckStatusNR(status, "ERROR creating outputData");
		
		MFnMesh meshFn;
		m_mesh= meshFn.create(
		  vertex_count,				// number of vertices
		  face_count,		// number of polygons
		  vertices,			// The points
		  pcounts,			// # of vertex for each poly
		  pconnect,			// Vertices index for each poly
		  newOutputData,      // Dependency graph data object
		  &status
		  );
		
		zCheckStatusNR(status, "ERROE creating mesh");
		
		// Update surface 
		//
		outputHandle.set(newOutputData);
		
		
	}
	else
	{
		
		MObject m_mesh = outputHandle.asMesh();
		MFnMesh meshFn(m_mesh);

		unsigned  inmeshnv, inmeshnp;
		MPointArray pinmesh;
		MIntArray count_inmesh;
		MIntArray connect_inmesh;
		zWorks::extractMeshParams(arbitaryMesh, inmeshnv, inmeshnp, pinmesh, count_inmesh, connect_inmesh);
		vertices.setLength(nptc*inmeshnv);
		int acc=0;
		for(unsigned int i=0; i<nptc; i++)
		{
			// calculate the bone transformations
			poseBones(length, num_bones, ptc_time_offset[i], frequency, ptc_amplitude[i], ptc_bend[i], flapping, bending, oscillate);
			
			front.x = ptc_views[i].x;
			front.y = ptc_views[i].y;
			front.z = ptc_views[i].z;
			up.x = ptc_ups[i].x;
			up.y = ptc_ups[i].y;
			up.z = ptc_ups[i].z;
			
			side = front.cross(up);
			side.normalize();
			
			up = side.cross(front);
			up.normalize();
			
			mat44.setIdentity();
			mat44.setOrientations(side, up, front);
			mat44.scale(ptc_scale[i]);
			mat44.setTranslation(ptc_positions[i].x, ptc_positions[i].y, ptc_positions[i].z);
			
			for(unsigned int j=0; j<inmeshnv; j++)
			{
				vert.x = pinmesh[j].x;
				vert.y = pinmesh[j].y;
				vert.z = pinmesh[j].z;
				
				int bone_id;
				if(vert.z>0) bone_id = 0;
				else if(-vert.z>length)  bone_id = num_bones-1;
				else bone_id = int(-vert.z/length*(num_bones-1));
				
				mat_bone = m_pBone->getBoneById(bone_id);
				vert.z -= -length/(num_bones-1)*bone_id;
				
				mat_bone.transform(vert);
				mat44.transform(vert);
				
				vertices[j+acc] = MPoint(vert.x, vert.y, vert.z);
			}
			acc += inmeshnv;
		}
		
		meshFn.setPoints(vertices);
		outputHandle.set(meshFn.object());
		
		
		
	}
	//delete fmat;
	data.setClean( plug );
	
	
	return MS::kSuccess;
}
Exemple #20
0
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;
}
Exemple #21
0
MStatus TCC::createSubdividedMesh(int sdRes, int sdRefRes, MFnMesh &srcMesh, TCCData &tccData, MDataHandle outMeshHandle, float lineThickness, MStatus& stat)
{   
    HDS hds;
    bool shouldCreateUVs = true;
    
    size_t nV = srcMesh.numVertices();
    size_t nF = srcMesh.numPolygons();
    size_t nIHE = tccData.F.length();
    
    bool consistentSizes= (tccData.pole.length()==nV) && (tccData.T.length()==nIHE) && (tccData.itv.length()==nIHE) & (tccData.corner.length()==nV);
    
    if ((nV==0)||(nF==0)||(!consistentSizes)) return MS::kFailure;

    MFloatArray uArray, vArray, sc_uArray, sc_vArray;
    MIntArray uvIdx;
    if (shouldCreateUVs)
    {
        createUVset(tccData, sdRes, uArray, vArray, sc_uArray, sc_vArray, uvIdx, lineThickness);
    }
    
    
    MFloatPointArray points;
    srcMesh.getPoints(points);
    
    store_in_hds(hds, points, tccData.nFV, tccData.F);     // convert to HDS

    finalize_HDS(hds);
    size_t nHE = hds.nHE();

    hds.T.setDims(1, nHE);
    hds.itv.setDims(1, nHE);
    hds.corner.setDims(1, nV);
    
    // interior halfedge tags
    for (size_t k=0; k<nV; k++) 
    {
        hds.corner[k] = tccData.corner[k];
    }

    // interior halfedge tags
    for (size_t k=0; k<nIHE; k++) 
    {
        hds.T[k] = tccData.T[k];
        hds.itv[k] = tccData.itv[k];
    }
    
    // border halfedge tags
    for (size_t k=nIHE; k<nHE; k++) 
    {
        hds.T[k] = false;
        hds.itv[k] = hds.itv[hds.twin[k]];
    }
        
    TCC_MAX::subdivide(hds, sdRes);
    
    if (sdRefRes>0)
    {
        HDS hds2;
        copy_HDS(hds, hds2);
        TCC_MAX::subdivide(hds2, sdRefRes);
        memcpy(&hds.V[0], &hds2.V[0], hds.V.size() * sizeof(double));
    }
    

    
    MObject outMeshObj = outMeshHandle.asMesh();
    MFnMesh outMeshFn(outMeshObj);
    
    // if no topology change necessary, just update points!
    if ( (outMeshFn.numFaceVertices() == hds.nIHE()) && (outMeshFn.numPolygons() == hds.nF()) )
    {
        size_t nV   = hds.nV();
        points.setLength(nV);
        for (size_t k=0; k<nV; k++) 
        {
            points[k](0) = hds.V[3*k+0];
            points[k](1) = hds.V[3*k+1];
            points[k](2) = hds.V[3*k+2];
        }
        stat = outMeshFn.setPoints(points); McheckErr(stat, "ERROR creating outputData");
        
        if (shouldCreateUVs)
        {
            MString uvSet = "UnitPatchUVs";
            MString sc_uvSet = "ScaledPatchUVs";
            stat = outMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
            stat = outMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        }
        
        return MS::kSuccess;
    }

    
    // Have to update connectivity and geometry

    load_from_hds(hds, points, tccData.nFV, tccData.F);

    nV = points.length();
    nF = tccData.nFV.length();
    
    MFnMeshData dataCreator;
    MObject newOutputData = dataCreator.create(&stat); McheckErr(stat, "ERROR creating outputData");
    MFnMesh newOutMeshFn;
    
    MObject newMesh;
    
    newMesh = newOutMeshFn.create(nV, nF, points, tccData.nFV, tccData.F, newOutputData, &stat); McheckErr(stat, "ERROR in MFnMesh.create\n");

    if (shouldCreateUVs)
    {
        MString uvSet = "UnitPatchUVs";
        MString sc_uvSet = "ScaledPatchUVs";
        
        uvSet = newOutMeshFn.createUVSetDataMeshWithName(uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&uvSet);
        stat = newOutMeshFn.setUVs(uArray, vArray, &uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &uvSet); McheckErr(stat, "ERROR assigning UVs");
        
        sc_uvSet = newOutMeshFn.createUVSetDataMeshWithName(sc_uvSet, &stat); McheckErr(stat, "ERROR creating UVset");
        stat = newOutMeshFn.clearUVs(&sc_uvSet);
        stat = newOutMeshFn.setUVs(sc_uArray, sc_vArray, &sc_uvSet); McheckErr(stat, "ERROR setting UVs");
        stat = newOutMeshFn.assignUVs(tccData.nFV, uvIdx, &sc_uvSet); McheckErr(stat, "ERROR assigning UVs");
    }
    
    
    if (stat == MS::kSuccess)
    {
        outMeshHandle.set(newOutputData);
    }
    
    
    return MS::kSuccess;
}
Exemple #22
0
MStatus sgBulgeDeformer::deform(MDataBlock& dataBlock, MItGeometry& iter, const MMatrix& mtx, unsigned int index)
{
	MStatus status;

	float bulgeWeight = dataBlock.inputValue(aBulgeWeight).asFloat();
	double bulgeRadius = dataBlock.inputValue(aBulgeRadius).asDouble();

	MArrayDataHandle hArrInputs = dataBlock.inputArrayValue(aBulgeInputs);

	MPointArray allPositions;
	iter.allPositions(allPositions);

	if (mem_resetElements)
	{
		unsigned int elementCount = hArrInputs.elementCount();
		mem_meshInfosInner.resize(mem_maxLogicalIndex);
		mem_meshInfosOuter.resize(mem_maxLogicalIndex);

		for (unsigned int i = 0; i < elementCount; i++, hArrInputs.next())
		{
			MDataHandle hInput = hArrInputs.inputValue();
			MDataHandle hMatrix = hInput.child(aMatrix);
			MDataHandle hMesh   = hInput.child(aMesh);

			MMatrix mtxMesh = hMatrix.asMatrix();
			MObject oMesh   = hMesh.asMesh();

			MFnMeshData meshDataInner, meshDataOuter;
			MObject oMeshInner = meshDataInner.create();
			MObject oMeshOuter = meshDataOuter.create();
			MFnMesh fnMesh;
			fnMesh.copy(oMesh, oMeshInner);
			fnMesh.copy(oMesh, oMeshOuter);

			sgMeshInfo* newMeshInfoInner = new sgMeshInfo(oMeshInner, hMatrix.asMatrix());
			sgMeshInfo* newMeshInfoOuter = new sgMeshInfo(oMeshOuter, hMatrix.asMatrix());

			mem_meshInfosInner[hArrInputs.elementIndex()] = newMeshInfoInner;
			mem_meshInfosOuter[hArrInputs.elementIndex()] = newMeshInfoOuter;
		}
	}
	
	for (unsigned int i = 0; i < elementCount; i++)
	{
		mem_meshInfosInner[i]->setBulge(bulgeWeight, MSpace::kWorld );
	}
	
	MFloatArray weightList;
	weightList.setLength(allPositions.length());
	for (unsigned int i = 0; i < weightList.length(); i++)
		weightList[i] = 0.0f;
	MMatrixArray inputMeshMatrixInverses;
	inputMeshMatrixInverses.setLength(elementCount);
	for (unsigned int i = 0; i < elementCount; i++)
	{
		inputMeshMatrixInverses[i] = mem_meshInfosInner[i]->matrix();
	}

	for (unsigned int i = 0; i < allPositions.length(); i++)
	{
		float resultWeight = 0;
		for (unsigned int infoIndex = 0; infoIndex < elementCount; infoIndex++)
		{
			MPoint localPoint = allPositions[i] * mtx* inputMeshMatrixInverses[infoIndex];
			MPoint innerPoint = mem_meshInfosInner[infoIndex]->getClosestPoint(localPoint);
			MPoint outerPoint = mem_meshInfosOuter[infoIndex]->getClosestPoint(localPoint);
			MVector innerVector = innerPoint - localPoint;
			MVector outerVector = outerPoint - localPoint;

			if (innerVector * outerVector < 0)
			{
				double innerLength = innerVector.length();
				double outerLength = outerVector.length();
				double allLength = innerLength + outerLength;

				float numerator = float( innerLength * outerLength );
				float denominator = float( pow(allLength / 2.0, 2) );

				resultWeight = numerator / denominator;
			}
		}
		weightList[i] = resultWeight;
	}

	for (unsigned int i = 0; i < allPositions.length(); i++)
	{
		allPositions[i] += weightList[i] * MVector(0, 1, 0);
	}
	
	iter.setAllPositions(allPositions);

	return MS::kSuccess;
}
MStatus updateTCCDataNode::compute( const MPlug& plug, MDataBlock& data )
//
//    Description:
//        This method computes the value of the given output plug based
//        on the values of the input attributes.
//
//    Arguments:
//        plug - the plug to compute
//        data - object that provides access to the attributes for this node
//
{
    MStatus status = MS::kSuccess;
 
    MDataHandle stateData = data.outputValue( state, &status );
    MCheckStatus( status, "ERROR getting state" );

    // Check for the HasNoEffect/PassThrough flag on the node.
    //
    // (stateData is an enumeration standard in all depend nodes - stored as short)
    // 
    // (0 = Normal)
    // (1 = HasNoEffect/PassThrough)
    // (2 = Blocking)
    // ...
    //
    if( stateData.asShort() == 1 )
    {
        MDataHandle inputData = data.inputValue( inMesh, &status );
        MCheckStatus(status,"ERROR getting inMesh");

        MDataHandle outputData = data.outputValue( outMesh, &status );
        MCheckStatus(status,"ERROR getting outMesh");

        // Simply redirect the inMesh to the outMesh for the PassThrough effect
        //
        outputData.set(inputData.asMesh());
    }
    else
    {
        // Check which output attribute we have been asked to 
        // compute. If this node doesn't know how to compute it, 
        // we must return MS::kUnknownParameter
        // 
        if (plug == outMesh)
        {
            MDataHandle inputData = data.inputValue( inMesh, &status );
            MCheckStatus(status,"ERROR getting inMesh");

            MDataHandle outputData = data.outputValue( outMesh, &status );
            MCheckStatus(status,"ERROR getting outMesh"); 

            MIntArray vR = MFnIntArrayData( data.inputValue( vtxRemap ).data() ).array(&status);
            MCheckStatus(status,"ERROR getting vtxRemap");
            
            MIntArray pO = MFnIntArrayData( data.inputValue( polyOrder ).data() ).array(&status);
            MCheckStatus(status,"ERROR getting polyOrder");

            MIntArray cS = MFnIntArrayData( data.inputValue( cShift ).data() ).array(&status);
            MCheckStatus(status,"ERROR getting cShift");
            
            MIntArray dnFV = MFnIntArrayData( data.inputValue( delta_nFV ).data() ).array(&status);
            MCheckStatus(status,"ERROR getting deltanFV");

            MIntArray dF = MFnIntArrayData( data.inputValue( delta_F ).data() ).array(&status);
            MCheckStatus(status,"ERROR getting deltaF");
            
            int nVtx = data.inputValue( nV ).asInt();
            MCheckStatus(status,"ERROR getting nV");
            
            // Copy the inMesh to the outMesh, and now you can
            // perform operations in-place on the outMesh
            //
            outputData.set(inputData.asMesh());
            MObject mesh = outputData.asMesh();
            
            fupdateTCCDataFactory.setMesh( mesh );
            fupdateTCCDataFactory.setVtxRemap( vR );
            fupdateTCCDataFactory.setPolyOrder( pO );
            fupdateTCCDataFactory.setCShift( cS );
            fupdateTCCDataFactory.setDelta_nFV( dnFV );
            fupdateTCCDataFactory.setDelta_F( dF );
            fupdateTCCDataFactory.setnV( nVtx );

            // Now, perform the updateTCCData
            //
            status = fupdateTCCDataFactory.doIt();

            // Mark the output mesh as clean
            //
            outputData.setClean();
        }
        else
        {
            status = MS::kUnknownParameter;
        }
    }

    return status;
}
MStatus sseDeformer::compute(const MPlug& plug, MDataBlock& data)
{
    MStatus status;
    if (plug.attribute() != outputGeom) {
        printf("Ignoring requested plug\n");
        return status;
    }
    unsigned int index = plug.logicalIndex();
    MObject thisNode = this->thisMObject();

    // get input value
    MPlug inPlug(thisNode,input);
    inPlug.selectAncestorLogicalIndex(index,input);
    MDataHandle hInput = data.inputValue(inPlug, &status);
    MCheckStatus(status, "ERROR getting input mesh\n");

    // get the input geometry
    MDataHandle inputData = hInput.child(inputGeom);
    if (inputData.type() != MFnData::kMesh) {
        printf("Incorrect input geometry type\n");
        return MStatus::kFailure;
    }

    MObject iSurf = inputData.asMesh() ;
    MFnMesh inMesh;
    inMesh.setObject( iSurf ) ;

    MDataHandle outputData = data.outputValue(plug);
    outputData.copy(inputData);
    if (outputData.type() != MFnData::kMesh) {
        printf("Incorrect output mesh type\n");
        return MStatus::kFailure;
    }

    MObject oSurf = outputData.asMesh() ;
    if(oSurf.isNull()) {
        printf("Output surface is NULL\n");
        return MStatus::kFailure;
    }

    MFnMesh outMesh;
    outMesh.setObject( oSurf ) ;
    MCheckStatus(status, "ERROR setting points\n");

    // get all points at once for demo purposes. Really should get points from the current group using iterator
    MFloatPointArray pts;
    outMesh.getPoints(pts);

    int nPoints = pts.length();

    MDataHandle envData = data.inputValue(envelope, &status);
    float env = envData.asFloat();

    MDataHandle sseData = data.inputValue(sseEnabled, &status);
    bool sseEnabled = (bool) sseData.asBool();

    // NOTE: Using MTimer and possibly other classes disables
    // autovectorization with Intel <=10.1 compiler on OSX and Linux!!
    // Must compile this function with -fno-exceptions on OSX and
    // Linux to guarantee autovectorization is done. Use -fvec_report2
    // to check for vectorization status messages with Intel compiler.
    MTimer timer;
    timer.beginTimer();

    if(sseEnabled) {

        // Innter loop will autovectorize. Around 3x faster than the
        // loop below it. It would be faster if first element was
        // guaranteed to be aligned on 16 byte boundary.
        for(int i=0; i<nPoints; i++) {
            float* ptPtr = &pts[i].x;
            for(int j=0; j<4; j++) {
                ptPtr[j] = env * (cosf(ptPtr[j]) * sinf(ptPtr[j]) * tanf(ptPtr[j]));
            }
        }

    } else {

        // This inner loop will not autovectorize.
        for(int i=0; i<nPoints; i++) {
            MFloatPoint& pt = pts[i];
            for(int j=0; j<3; j++) {
                pt[j] = env * (cosf(pt[j]) * sinf(pt[j]) * tanf(pt[j]));
            }

        }
    }

    timer.endTimer();
    if(sseEnabled) {
        printf("SSE enabled, runtime %f\n", timer.elapsedTime());
    } else {
        printf("SSE disabled, runtime %f\n", timer.elapsedTime());
    }

    outMesh.setPoints(pts);

    return status;
}
MStatus inverseSkinCluster::deform(MDataBlock& data,
	MItGeometry& itGeo,
	const MMatrix& localToWorldMatrix,
	unsigned int geomIndex)
{
	MStatus status;

	MMatrix geomMatrix;
	bool updateSkinInfo;

	MDataHandle hInMesh = data.inputValue( aInMesh, &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );
	MObject oInMesh = hInMesh.asMesh();
	if( oInMesh.isNull() )
		return MS::kFailure;
	MFnMesh inMesh = oInMesh;
	inMesh.getPoints( m_meshPoints );

	if( originalMeshUpdated )
	{
		itGeo.allPositions( pTaskData->basePoints );
		originalMeshUpdated = false;
	}

	MDataHandle hGeomMatrix = data.inputValue( aGeomMatrix );
	geomMatrix = hGeomMatrix.asMatrix();

	MDataHandle hUpdateWeightList = data.inputValue( aUpdateWeightList );
	updateSkinInfo = hUpdateWeightList.asBool();

	MDataHandle hEnvelop = data.inputValue( envelope );
	envelopValue = hEnvelop.asFloat();

	pTaskData->envelop = envelopValue;
	pTaskData->invEnv  = 1.0f - envelopValue;
	pTaskData->beforePoints = m_meshPoints;

	if( updateSkinInfo )
	{	
		MDataHandle hUpdateSkinInfoOutput = data.outputValue( aUpdateWeightList );
		hUpdateSkinInfoOutput.set( false );
		weightListUpdated = false;
	}

	if( logicalIndexArray.length() == 0 )
		updateLogicalIndexArray();

	MDataHandle hUpdateMatrix = data.inputValue( aUpdateMatrix );

	if( hUpdateMatrix.asBool() )
	{
		matrixAttrUpdated = false;
		matrixInfoUpdated = false;
	}

	MArrayDataHandle hArrMatrix = data.inputArrayValue( aMatrix );
	MArrayDataHandle hArrBindPreMatrix = data.inputArrayValue( aBindPreMatrix );
	updateMatrixAttribute( hArrMatrix, hArrBindPreMatrix );

	if( !matrixInfoUpdated )
	{
		updateMatrixInfo( hArrMatrix, hArrBindPreMatrix );
	}

	if( !weightListUpdated )
	{
		pTaskData->afterPoints.setLength( m_meshPoints.length() );
		pTaskData->envPoints.setLength( m_meshPoints.length() );

		updateWeightList();
	}

	if( !matrixInfoUpdated || !weightListUpdated )
	{
		if( pSkinInfo->weightsArray.size() > 0 )
			getWeightedMatrices( geomMatrix );
		else
			return MS::kFailure;

		matrixInfoUpdated = true;
		weightListUpdated = true;
	}

	if( envelopValue )
	{
		setThread();
		MThreadPool::newParallelRegion( parallelCompute, pThread );
		endThread();

		itGeo.setAllPositions( pTaskData->envPoints );
	}
	else
	{
		itGeo.setAllPositions( pTaskData->basePoints );
	}

	return MS::kSuccess;
}