MStatus DDConvexHullUtils::generateMayaHull(MObject &output, const MObject &input, const DDConvexHullUtils::hullOpts &hullOptions) { // Convert the input mobject to mfnmesh if (!input.hasFn(MFn::kMesh)) { return MStatus::kInvalidParameter; } MFnMesh inputMesh(input); // Allocate an array for the vertices and fill it with the data extracted // from the input mesh uint numInputVerts = inputMesh.numVertices(); if (!numInputVerts) { return MStatus::kFailure; } MPointArray points; inputMesh.getPoints(points); return generateMayaHull(output, points, hullOptions); }
bool retargetLocator::drawArrowPolygon( MMatrix aimMatrix, MColor cuColor,float fillAlpha, float lineAlpha, int index ) { MStatus status; MFnMesh inputMesh( inputMeshObj[index], &status ); if( !status ) return false; float indexedSize = size[index]; float startIndexedSize = startSize[ index ]; MPointArray* polygonPoints = getPolygonPoints( inputMesh ); if( indexedSize > 0 ) { glColor4f( cuColor.r, cuColor.g, cuColor.b, lineAlpha ); for( int polygonId=0; polygonId< polygonNum ; polygonId++ ) { glBegin( GL_LINE_LOOP ); MPointArray& cuPolygonPoints = polygonPoints[polygonId]; for( unsigned int i=0; i < cuPolygonPoints.length(); i++ ) { MPoint cuPoint = cuPolygonPoints[i]*indexedSize*aimMatrix; bbox.expand( cuPoint ); glVertex3f( (float)cuPoint.x, (float)cuPoint.y, (float)cuPoint.z ); } glEnd(); } glColor4f( cuColor.r, cuColor.g, cuColor.b, fillAlpha ); for( int polygonId=0; polygonId< polygonNum ; polygonId++ ) { glBegin( GL_POLYGON ); MPointArray& cuPolygonPoints = polygonPoints[polygonId]; for( unsigned int i=0; i< cuPolygonPoints.length(); i++ ) { MPoint cuPoint = cuPolygonPoints[i]*indexedSize*aimMatrix; glVertex3f( (float)cuPoint.x, (float)cuPoint.y, (float)cuPoint.z ); } glEnd(); } } MVector offsetPosition( offset[index].x, offset[index].y, offset[index].z ); if( startIndexedSize > 0 ) { glColor4f( cuColor.r, cuColor.g, cuColor.b, lineAlpha ); for( int polygonId=0; polygonId< polygonNum ; polygonId++ ) { glBegin( GL_LINE_LOOP ); MPointArray& cuPolygonPoints = polygonPoints[polygonId]; for( unsigned int i=0; i < cuPolygonPoints.length(); i++ ) { MPoint cuPoint = cuPolygonPoints[i]*startIndexedSize+offsetPosition; bbox.expand( cuPoint ); glVertex3f( (float)cuPoint.x, (float)cuPoint.y, (float)cuPoint.z ); } glEnd(); } glColor4f( cuColor.r, cuColor.g, cuColor.b, fillAlpha ); for( int polygonId=0; polygonId< polygonNum ; polygonId++ ) { glBegin( GL_POLYGON ); MPointArray& cuPolygonPoints = polygonPoints[polygonId]; for( unsigned int i=0; i< cuPolygonPoints.length(); i++ ) { MPoint cuPoint = cuPolygonPoints[i]*startIndexedSize+offsetPosition; glVertex3f( (float)cuPoint.x, (float)cuPoint.y, (float)cuPoint.z ); } glEnd(); } } delete []polygonPoints; return true; }
MStatus testNpassiveNode::compute(const MPlug &plug, MDataBlock &data) { MStatus stat; if ( plug == currentState ) { // get old positions and numVerts // if num verts is different, reset topo and zero velocity // if num verts is the same, compute new velocity int ii,jj; // initialize MnCloth MObject inMeshObj = data.inputValue(inputGeom).asMesh(); MFnMesh inputMesh(inMeshObj); unsigned int numVerts = 0; numVerts = inputMesh.numVertices(); unsigned int prevNumVerts; fNObject.getNumVertices(prevNumVerts); if(numVerts != prevNumVerts) { int numPolygons = inputMesh.numPolygons(); int * faceVertCounts = new int[numPolygons]; int facesArrayLength = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); faceVertCounts[ii] = verts.length(); facesArrayLength += verts.length(); } int * faces = new int[facesArrayLength]; int currIndex = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); for(jj=0;jj<(int)verts.length();jj++) { faces[currIndex++] = verts[jj]; } } int numEdges = inputMesh.numEdges(); int * edges = new int[2*numEdges]; currIndex = 0; for(ii=0;ii<numEdges;ii++) { int2 edge; inputMesh.getEdgeVertices(ii,edge); edges[currIndex++] = edge[0]; edges[currIndex++] = edge[1]; } // When you are doing the initialization, the first call must to be setTopology(). All other // calls must come after this. fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges ); delete[] faceVertCounts; delete[] faces; delete[] edges; MFloatPointArray vertexArray; inputMesh.getPoints(vertexArray, MSpace::kWorld); fNObject.setPositions(vertexArray,true); MFloatPointArray velocitiesArray; velocitiesArray.setLength(numVerts); for(ii=0;ii<(int)numVerts;ii++) { velocitiesArray[ii].x = 0.0f; velocitiesArray[ii].y = 0.0f; velocitiesArray[ii].z = 0.0f; velocitiesArray[ii].w = 0.0f; } fNObject.setVelocities(velocitiesArray); } else { MFloatPointArray vertexArray; MFloatPointArray prevVertexArray; inputMesh.getPoints(vertexArray, MSpace::kWorld); fNObject.getPositions(prevVertexArray); // you may want to get the playback rate for the dt // double dt = MAnimControl::playbackBy() \ 24.0; // or get the real dt by caching the last eval time double dt = 1.0/24.0; MFloatPointArray velocitiesArray; velocitiesArray.setLength(numVerts); for(ii=0;ii<(int)numVerts;ii++) { velocitiesArray[ii].x = (float)( (vertexArray[ii].x - prevVertexArray[ii].x)/dt); velocitiesArray[ii].y = (float)( (vertexArray[ii].y - prevVertexArray[ii].y)/dt); velocitiesArray[ii].z = (float)( (vertexArray[ii].x - prevVertexArray[ii].z)/dt); velocitiesArray[ii].w = 0.0f; } fNObject.setVelocities(velocitiesArray); fNObject.setPositions(vertexArray,true); } // in real life, you'd get these attribute values each frame and set them fNObject.setThickness(0.1f); fNObject.setBounce(0.0f); fNObject.setFriction(0.1f); fNObject.setCollisionFlags(true, true, true); MFnNObjectData outputData; MObject mayaNObjectData = outputData.create(); outputData.setObject(mayaNObjectData); outputData.setObjectPtr(&fNObject); outputData.setCached(false); MDataHandle currStateOutputHandle = data.outputValue(currentState); currStateOutputHandle.set(outputData.object()); } if ( plug == startState ) { int ii,jj; // initialize MnCloth MObject inMeshObj = data.inputValue(inputGeom).asMesh(); MFnMesh inputMesh(inMeshObj); int numPolygons = inputMesh.numPolygons(); int * faceVertCounts = new int[numPolygons]; int facesArrayLength = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); faceVertCounts[ii] = verts.length(); facesArrayLength += verts.length(); } int * faces = new int[facesArrayLength]; int currIndex = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); for(jj=0;jj<(int)verts.length();jj++) { faces[currIndex++] = verts[jj]; } } int numEdges = inputMesh.numEdges(); int * edges = new int[2*numEdges]; currIndex = 0; for(ii=0;ii<numEdges;ii++) { int2 edge; inputMesh.getEdgeVertices(ii,edge); edges[currIndex++] = edge[0]; edges[currIndex++] = edge[1]; } // When you are doing the initialization, the first call must to be setTopology(). All other // calls must come after this. fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges ); delete[] faceVertCounts; delete[] faces; delete[] edges; unsigned int numVerts = 0; numVerts = inputMesh.numVertices(); MFloatPointArray vertexArray; inputMesh.getPoints(vertexArray, MSpace::kWorld); fNObject.setPositions(vertexArray,true); MFloatPointArray velocitiesArray; velocitiesArray.setLength(numVerts); for(ii=0;ii<(int)numVerts;ii++) { velocitiesArray[ii].x = 0.0f; velocitiesArray[ii].y = 0.0f; velocitiesArray[ii].z = 0.0f; velocitiesArray[ii].w = 0.0f; } fNObject.setVelocities(velocitiesArray); fNObject.setThickness(0.1f); fNObject.setBounce(0.0f); fNObject.setFriction(0.1f); fNObject.setCollisionFlags(true, true, true); MFnNObjectData outputData; MObject mayaNObjectData = outputData.create(); outputData.setObject(mayaNObjectData); outputData.setObjectPtr(&fNObject); outputData.setCached(false); MDataHandle startStateOutputHandle = data.outputValue(startState); startStateOutputHandle.set(outputData.object()); } else { stat = MS::kUnknownParameter; } return stat; }
MStatus testNobjectNode::compute(const MPlug &plug, MDataBlock &data) { MStatus stat; if ( plug == outputGeom ) { MObject inMeshObj = data.inputValue(inputGeom).asMesh(); cerr<<"pull on outputGeom\n"; MFnMeshData meshDataFn; MFnMesh inputMesh(inMeshObj); MObject newMeshObj = meshDataFn.create(); MFnMesh newMeshFn; newMeshFn.copy( inMeshObj, newMeshObj ); //get the value of the currentTime so it can correctly dirty the //startState, currentState. data.inputValue(currentTime).asTime(); // pull on next state. This will cause the solver to pull on either // the startState or the currentState, depending on the time of solve. // When we return the state to the solver, it will do the solve and update // The N Object data directly. MObject nextNObj = data.inputValue(nextState).data(); MFloatPointArray pts; //At this point the N Object's internal state should have been updated //by the solver. Read it out and set the output mesh. fNObject.getPositions(pts); if(pts.length() == (unsigned int) inputMesh.numVertices()) { newMeshFn.setPoints(pts); } newMeshFn.setObject( newMeshObj ); data.outputValue(outputGeom).set(newMeshObj); data.setClean(plug); } if ( plug == currentState ) { MFnNObjectData outputData; MObject mayaNObjectData = outputData.create(); outputData.setObject(mayaNObjectData); outputData.setObjectPtr(&fNObject); outputData.setCached(false); MDataHandle currStateOutputHandle = data.outputValue(currentState); currStateOutputHandle.set(outputData.object()); cerr<<"pull on currentState\n"; } if ( plug == startState ) { int ii,jj; // initialize MnCloth MObject inMeshObj = data.inputValue(inputGeom).asMesh(); MFnMesh inputMesh(inMeshObj); int numPolygons = inputMesh.numPolygons(); int * faceVertCounts = new int[numPolygons]; int facesArrayLength = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); faceVertCounts[ii] = verts.length(); facesArrayLength += verts.length(); } int * faces = new int[facesArrayLength]; int currIndex = 0; for(ii=0;ii<numPolygons;ii++) { MIntArray verts; inputMesh.getPolygonVertices(ii,verts); for(jj=0;jj<(int)verts.length();jj++) { faces[currIndex++] = verts[jj]; } } int numEdges = inputMesh.numEdges(); int * edges = new int[2*numEdges]; currIndex = 0; for(ii=0;ii<numEdges;ii++) { int2 edge; inputMesh.getEdgeVertices(ii,edge); edges[currIndex++] = edge[0]; edges[currIndex++] = edge[1]; } // When you are doing the initialization, the first call must to be setTopology(). All other // calls must come after this. fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges ); delete[] faceVertCounts; delete[] faces; delete[] edges; unsigned int numVerts = 0; numVerts = inputMesh.numVertices(); MFloatPointArray vertexArray; inputMesh.getPoints(vertexArray); fNObject.setPositions(vertexArray,true); MFloatPointArray velocitiesArray; velocitiesArray.setLength(numVerts); for(ii=0;ii<(int)numVerts;ii++) { velocitiesArray[ii].x = 0.0f; velocitiesArray[ii].y = 0.0f; velocitiesArray[ii].z = 0.0f; velocitiesArray[ii].w = 0.0f; } fNObject.setVelocities(velocitiesArray); fNObject.setThickness(0.05f); fNObject.setInverseMass(1.0f); fNObject.setBounce(0.0f); fNObject.setFriction(0.1f); fNObject.setDamping(0.0f); fNObject.setBendResistance(0.0f); fNObject.setMaxIterations(100); fNObject.setMaxSelfCollisionIterations(100); fNObject.setStretchAndCompressionResistance(20.0f,10.0f); fNObject.setSelfCollisionFlags(false); fNObject.setCollisionFlags(true); MFnNObjectData outputData; MObject mayaNObjectData = outputData.create(); outputData.setObject(mayaNObjectData); outputData.setObjectPtr(&fNObject); outputData.setCached(false); MDataHandle startStateOutputHandle = data.outputValue(startState); startStateOutputHandle.set(outputData.object()); cerr<<"pull on startState\n"; } else { stat = MS::kUnknownParameter; } return stat; }