void CXRayObjectExport:: CreateSMGEdgeAttrs ( MFnMesh& fnMesh ) { int numPolygons = fnMesh.numPolygons(); for ( int pid=0; pid<numPolygons; pid++ ) { MIntArray vertexList; fnMesh.getPolygonVertices( pid, vertexList ); int vcount = vertexList.length(); if(vcount!=3) Msg( "poly vertex count not equel 3(is not a tri) vertex count = %d", vcount ); for ( int vid=0; vid<vcount;vid++ ) { int a = vertexList[vid]; int b = vertexList[ vid==(vcount-1) ? 0 : vid+1 ]; SXREdgeInfoPtr elem = findEdgeInfo( a, b ); if ( NULL != elem ) { set_edge_smooth_flag( polySmoothingGroups[pid], vid, elem->smooth ); } } } }
MObject MG_poseReader::makePlane(const MVector& p1,const MVector& p2,const MVector& p3){ MFnMesh meshFn; MPoint p1p (p1); MPoint p2p (p2); MPoint p3p (p3); MPointArray pArray; pArray.append(p1p); pArray.append(p2p); pArray.append(p3p); MIntArray polyCount; polyCount.append(3); MIntArray polyConnect; polyConnect.append(0); polyConnect.append(1); polyConnect.append(2); MFnMeshData data; MObject polyData = data.create(); MStatus stat; meshFn.create(3,1,pArray,polyCount,polyConnect,polyData,&stat); return polyData; }
// grab the current mesh and setup the polygon sets void Mesh::SetMesh(const MDagPath &dPath) { MObjectArray fPolygonSets; MObjectArray fPolygonComponents; MDagPath dagPath(dPath); polySets.clear(); MFnMesh fMesh = MFnMesh(dagPath); //Have to make the path include the shape below it so that //we can determine if the underlying shape node is instanced. //By default, dag paths only include transform nodes. dagPath.extendToShape(); //If the shape is instanced then we need to determine which instance this path refers to. int instanceNum = 0; if (dagPath.isInstanced()) instanceNum = dagPath.instanceNumber(); //Get the connected sets and members - these will be used to determine texturing of different faces if (!fMesh.getConnectedSetsAndMembers(instanceNum, fPolygonSets, fPolygonComponents, true)) { MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers"); return; } unsigned int setCount = fPolygonSets.length(); if (setCount > 1) setCount--; for (unsigned int i=0; i < setCount; i++) polySets.push_back(PolygonSet(dagPath, fPolygonComponents[i], fPolygonSets[i])); }
void SoftBodyNode::createHelperMesh(MFnMesh &mayaMesh, std::vector<int> &triIndices, std::vector<float> &triVertices, MSpace::Space space) { MFloatPointArray ptArray; mayaMesh.getPoints(ptArray, space); // append vertex locations (x, y, z) into "flattened array" for(int i = 0; i < ptArray.length(); i++) { MFloatPoint pt; pt = ptArray[i]; pt.cartesianize(); triVertices.push_back(pt.x); triVertices.push_back(pt.y); triVertices.push_back(pt.z); } std::cout << std::endl; // create vector of triangle indices MIntArray tCounts; MIntArray tVerts; mayaMesh.getTriangles(tCounts, tVerts); triIndices.resize(tVerts.length()); for(int i = 0; i < tVerts.length(); i ++) { triIndices[i] = tVerts[i]; } }
// Reference: OSD shape_utils.h:: applyTags() "crease" static float getCreaseEdges(MFnMesh const & inMeshFn, Descriptor & outDesc) { MUintArray tEdgeIds; MDoubleArray tCreaseData; float maxCreaseValue = 0.0f; if (inMeshFn.getCreaseEdges(tEdgeIds, tCreaseData)) { assert( tEdgeIds.length() == tCreaseData.length() ); int ncreases = tEdgeIds.length(); int * vertPairs = new int[ncreases*2]; float * weights = new float[ncreases]; int2 edgeVerts; for (unsigned int j=0; j < tEdgeIds.length(); j++) { assert( tCreaseData[j] >= 0.0 ); inMeshFn.getEdgeVertices(tEdgeIds[j], edgeVerts); vertPairs[j*2 ] = edgeVerts[0]; vertPairs[j*2+1] = edgeVerts[1]; weights[j] = float(tCreaseData[j]); maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue); } outDesc.numCreases = ncreases; outDesc.creaseVertexIndexPairs = vertPairs; outDesc.creaseWeights = weights; } return maxCreaseValue; }
void SGToolContext::toolOnSetup(MEvent& evt) { MStatus status; SGPermit permit; SGKey::initializeKeys(); SGMouse::initializeButtons(); SGMesh::getSelection(SGToolCondition::option.symInfo); SGSelection::sels.initialize(SGMesh::pMesh); M3dView activeView = M3dView().active3dView(); manip = (SGManip*)SGManip::newManipulator(Names::manipName, m_oManip); if (!manip) sgPrintf("manip is null"); this->addManipulator(m_oManip); toolWidget = new SGWidget(MQtUtil::mainWindow()); toolWidget->startEvent(); this->setCursor( MCursor::editCursor ); if ( SGMesh::pMesh->dagPath.node().isNull() ) { //MGlobal::displayWarning("Select mesh first"); } else { MFnMesh fnMesh = SGMesh::pMesh->dagPath; MFnDagNode dagNode = fnMesh.parent(0); char buffer[128]; sprintf(buffer, "maintainActiveChangeSelectMode %s", dagNode.partialPathName().asChar() ); MGlobal::executeCommand(buffer); } SGMarkingMenu::menu.setDefaultMenu(); SGToolCondition::toolIsOn = true; }
int Triangulation( MFnMesh &mfnMesh, MIntArray &triangleCount, MIntArray &triangleList, MIntArray &triangleNList, MIntArray &triangleUVList, MIntArray &vertexCount, MIntArray &vertexList, MIntArray &normalList, MIntArray &uvIds) { int poly_idx_offset = 0; int tri_idx_offset = 0; for (int i = 0; i < mfnMesh.numPolygons(); ++i) { for (int j = 0; j < triangleCount[i]; ++j) { for (unsigned int k = 0; k < 3; ++k) { int v_idx = triangleList[tri_idx_offset + j * 3 + k]; int match = -1; int l = 0; while (match < 0 && l < vertexCount[i]) { if (vertexList[poly_idx_offset + l] == v_idx) match = l; ++l; } triangleNList[tri_idx_offset + j * 3 + k] = normalList[poly_idx_offset + match]; int id = 0; if (uvIds.length() != 0) mfnMesh.getPolygonUVid(i, match, id); triangleUVList[tri_idx_offset + j * 3 + k] = id; } } poly_idx_offset += vertexCount[i]; tri_idx_offset += 3 * triangleCount[i]; } return tri_idx_offset; }
MObject animCube::createMesh(const MTime& time, MObject& outData, MStatus& stat) { int numVertices, frame; float cubeSize; MFloatPointArray points; MFnMesh meshFS; // Scale the cube on the frame number, wrap every 10 frames. frame = (int)time.as( MTime::kFilm ); if (frame == 0) frame = 1; cubeSize = 0.5f * (float)( frame % 10); const int numFaces = 6; numVertices = 8; const int numFaceConnects = 24; MFloatPoint vtx_1( -cubeSize, -cubeSize, -cubeSize ); MFloatPoint vtx_2( cubeSize, -cubeSize, -cubeSize ); MFloatPoint vtx_3( cubeSize, -cubeSize, cubeSize ); MFloatPoint vtx_4( -cubeSize, -cubeSize, cubeSize ); MFloatPoint vtx_5( -cubeSize, cubeSize, -cubeSize ); MFloatPoint vtx_6( -cubeSize, cubeSize, cubeSize ); MFloatPoint vtx_7( cubeSize, cubeSize, cubeSize ); MFloatPoint vtx_8( cubeSize, cubeSize, -cubeSize ); points.append( vtx_1 ); points.append( vtx_2 ); points.append( vtx_3 ); points.append( vtx_4 ); points.append( vtx_5 ); points.append( vtx_6 ); points.append( vtx_7 ); points.append( vtx_8 ); // Set up an array containing the number of vertices // for each of the 6 cube faces (4 verticies per face) // int face_counts[numFaces] = { 4, 4, 4, 4, 4, 4 }; MIntArray faceCounts( face_counts, numFaces ); // Set up and array to assign vertices from points to each face // int face_connects[ numFaceConnects ] = { 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }; MIntArray faceConnects( face_connects, numFaceConnects ); MObject newMesh = meshFS.create(numVertices, numFaces, points, faceCounts, faceConnects, outData, &stat); return newMesh; }
// -------------------------------------------------------- void GeometryPolygonExporter::exportPolygonSources ( MFnMesh& fnMesh, const String& meshId, MStringArray& uvSetNames, MStringArray& colorSetNames, Sources* polygonSources, Sources* vertexSources, const bool hasFaceVertexNorms ) { // Initialize the members mMeshId = meshId; mUvSetNames = uvSetNames; mPolygonSources = polygonSources; mVertexSources = vertexSources; mHasFaceVertexNormals = hasFaceVertexNorms; mColorSetNames = colorSetNames; // If triangulation is requested, verify that it is // feasible by checking with all the mesh polygons if ( ExportOptions::exportTriangles() ) { triangulated = true; for ( MItMeshPolygon polyIt ( fnMesh.object() ); triangulated && !polyIt.isDone(); polyIt.next() ) { triangulated = polyIt.hasValidTriangulation(); } } // If we have a hole in a polygon, we can't write a <polylist>. // Either we write <polygons> with holes or we write triangles. // Get hole information from the mesh node. // The format for the holes information is explained in the MFnMesh documentation. MStatus status; fnMesh.getHoles ( mHoleInfoArray, mHoleVertexArray, &status ); holeCount = ( status != MStatus::kSuccess ) ? 0 : ( mHoleInfoArray.length() / 3 ); // Find how many shaders are used by this instance of the mesh. // Each instance may apply a number of different materials to different faces. // We can use the getConnectedShaders member function of MFnMesh to find out // this shader information for each instance. mShaders.clear(); mShaderIndices.clear(); fnMesh.getConnectedShaders ( 0, mShaders, mShaderIndices ); // Find the polygons that correspond to each materials and export them. uint realShaderCount = ( uint ) mShaders.length(); uint numShaders = ( uint ) std::max ( ( size_t ) 1, ( size_t ) mShaders.length() ); for ( uint shaderPosition=0; shaderPosition<numShaders; ++shaderPosition ) { // Set the current shader position mShaderPosition = shaderPosition; // Export the polygons of the current shader exportShaderPolygons ( fnMesh ); } }
// #### buildUVList // // Face-varying data expects a list of per-face per-vertex // floats. This method reads the UVs from the mesh and // concatenates them into such a list. // MStatus OsdMeshData::buildUVList( MFnMesh& meshFn, std::vector<float>& uvList ) { MStatus status = MS::kSuccess; MItMeshPolygon polyIt( _meshDagPath ); MFloatArray uArray; MFloatArray vArray; // If user hasn't given us a UV set, use the current one MString *uvSetPtr=NULL; if ( _uvSet.numChars() > 0 ) { if (uvSetNameIsValid(meshFn, _uvSet)) { uvSetPtr = &_uvSet; } else { MGlobal::displayWarning(MString("OpenSubdivShader: uvSet \""+_uvSet+"\" does not exist.")); } } else { uvSetPtr = NULL; } // pull UVs from Maya mesh status = meshFn.getUVs( uArray, vArray, uvSetPtr ); MCHECK_RETURN(status, "OpenSubdivShader: Error reading UVs"); if ( uArray.length() == 0 || vArray.length() == 0 ) { MGlobal::displayWarning("OpenSubdivShader: Mesh has no UVs"); return MS::kFailure; } // list of UV values uvList.clear(); uvList.resize( meshFn.numFaceVertices()*2 ); int uvListIdx = 0; // for each face-vertex copy UVs into list, adjusting for renderman orientation for ( polyIt.reset(); !polyIt.isDone(); polyIt.next() ) { int faceIdx = polyIt.index(); unsigned int numPolyVerts = polyIt.polygonVertexCount(); for ( unsigned int faceVertIdx = 0; faceVertIdx < numPolyVerts; faceVertIdx++ ) { int uvIdx; polyIt.getUVIndex( faceVertIdx, uvIdx, uvSetPtr ); // convert maya UV orientation to renderman orientation uvList[ uvListIdx++ ] = uArray[ uvIdx ]; uvList[ uvListIdx++ ] = 1.0f - vArray[ uvIdx ]; } } return status; }
MStatus PluginTestUserOperation::execute(const MHWRender::MDrawContext & drawContext) { //return MStatus::kSuccess; M3dView view; if(M3dView::getM3dViewFromModelPanel(panelName, view) == MStatus::kSuccess) { // Get the current viewport and scale it relative to that // int targetW, targetH; drawContext.getRenderTargetSize(targetW, targetH); // Some user drawing of scene bounding boxes // MDagPath cameraPath; MFnCamera fnCamera; view.getCamera(cameraPath); MMatrix m3dViewProjection, m3dViewModelView; view.projectionMatrix(m3dViewProjection); view.modelViewMatrix(m3dViewModelView); MFloatMatrix m3dFloatViewProjection(m3dViewProjection.matrix); MFloatMatrix m3dFloatViewModelView(m3dViewModelView.matrix); MFloatMatrix viewProjection = m3dFloatViewModelView * m3dFloatViewProjection; SurfaceDrawTraversal traversal; traversal.enableFiltering(true); traversal.setFrustum(cameraPath, targetW, targetH); traversal.traverse(); unsigned int numItems = traversal.numberOfItems(); MFnMesh fnMesh; for (int i = 0; i < numItems; i++) { MDagPath path; traversal.itemPath(i, path); if (path.hasFn(MFn::kMesh)) { fnMesh.setObject(path); MFloatMatrix modelWorld(path.inclusiveMatrix().matrix); MTransformationMatrix transformMatrix; MFloatMatrix modelViewProjection = modelWorld * viewProjection; modelViewProjection = modelViewProjection.transpose(); MIntArray triangleCounts; MIntArray triangleVertices; // This is the index list for all the triangles in the mesh in one big list. Ie. first 3 are for tri 1 etc. Index into getPoints() fnMesh.getTriangles(triangleCounts, triangleVertices); //int indices[100]; //triangleVertices.get(indices); MFloatPointArray vertexArray; //float points[1000][4]; fnMesh.getPoints(vertexArray); //vertexArray.get(points); UserSceneRenderer::get()->render(triangleVertices, vertexArray, modelViewProjection); } } } return MStatus::kSuccess; }
MStatus LSSolverNode::buildOutputMesh(MFnMesh& inputMesh, float* vertices, MObject &outputMesh) { MStatus stat; MPointArray points; unsigned vIndex = 0; int numVertices = inputMesh.numVertices(); for(int i=0; i<numVertices;i++) { double x = vertices[vIndex++]; double y = vertices[vIndex++]; double z = vertices[vIndex++]; //std::cout<<"("<<x<<","<<y<<","<<z<<")"<<endl; MPoint point(x,y,z); points.append(point); } const int numFaces = inputMesh.numPolygons(); int *face_counts = new int[numFaces]; for(int i = 0 ; i < numFaces ; i++) { face_counts[i] = 3; } MIntArray faceCounts( face_counts, numFaces ); // Set up and array to assign vertices from points to each face int numFaceConnects = numFaces * 3; int *face_connects = new int[numFaceConnects]; int faceConnectsIdx = 0; for ( int i=0; i<numFaces; i++ ) { MIntArray polyVerts; inputMesh.getPolygonVertices( i, polyVerts ); int pvc = polyVerts.length(); face_connects[faceConnectsIdx++] = polyVerts[0]; face_connects[faceConnectsIdx++]= polyVerts[1]; face_connects[faceConnectsIdx++] = polyVerts[2]; } MIntArray faceConnects( face_connects, numFaceConnects ); MFnMesh meshFS; MObject newMesh = meshFS.create(numVertices, numFaces, points, faceCounts, faceConnects, outputMesh, &stat); return stat; }
MObject AniMesh::readFrame(const MTime& time,MObject& outData,MStatus& stat) { MFloatPointArray points; MFnMesh meshFS; int frame = (int)time.as( MTime::kFilm ); if (frame == 0) frame = 1; vector<size_t> face_v; vector<double> points_v; char cfilename[256]; sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),frame); //sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0); string filename = string(cfilename); fstream fp; fp.open(filename,ios::in); if (fp) { ImportVrml2 (filename, face_v, points_v); }else{ sprintf(cfilename, "%s%d.vrml",import_prefix.c_str(),0); string filename = string(cfilename); ImportVrml2(filename,face_v,points_v); } size_t numVertices = points_v.size()/3; size_t numFaces = face_v.size()/3; for(vector<double>::const_iterator it = points_v.begin();it != points_v.end();it+=3) { MFloatPoint vtx(*it,*(it+1),*(it+2)); points.append(vtx); } vector<int> face_count; for(int i=0;i<numFaces;i++) { face_count.push_back(3); } MIntArray faceCounts(&face_count[0],numFaces); vector<int> face_connects; face_connects.resize(face_v.size()); for(int i=0;i<face_v.size();++i) { face_connects[i] = face_v[i]; } MIntArray faceConnects( &face_connects[0], face_connects.size() ); MObject newMesh=meshFS.create(numVertices, numFaces,points, faceCounts, faceConnects,outData,&stat); return newMesh; }
IECoreScene::PrimitiveVariable FromMayaMeshConverter::normals() const { MFnMesh fnMesh; const MDagPath *d = dagPath( true ); if( d ) { fnMesh.setObject( *d ); } else { fnMesh.setObject( object() ); } V3fVectorDataPtr normalsData = new V3fVectorData; normalsData->setInterpretation( GeometricData::Normal ); vector<V3f> &normals = normalsData->writable(); normals.reserve( fnMesh.numFaceVertices() ); int numPolygons = fnMesh.numPolygons(); V3f blankVector; if( space() == MSpace::kObject ) { const float* rawNormals = fnMesh.getRawNormals(0); MIntArray normalIds; for( int i=0; i<numPolygons; i++ ) { fnMesh.getFaceNormalIds( i, normalIds ); for( unsigned j=0; j < normalIds.length(); ++j ) { const float* normalIt = rawNormals + 3 * normalIds[j]; normals.push_back( blankVector ); V3f& nn = normals.back(); nn.x = *normalIt++; nn.y = *normalIt++; nn.z = *normalIt; } } } else { MFloatVectorArray faceNormals; for( int i=0; i<numPolygons; i++ ) { fnMesh.getFaceVertexNormals( i, faceNormals, space() ); for( unsigned j=0; j<faceNormals.length(); j++ ) { MFloatVector& n = faceNormals[j]; normals.push_back( blankVector ); V3f& nn = normals.back(); nn.x = n.x; nn.y = n.y; nn.z = n.z; } } } return PrimitiveVariable( PrimitiveVariable::FaceVarying, normalsData ); }
MStatus TCC::setErrorColors(MFnMesh &meshFn, TCCData &tccData) { MStatus stat; if ((tccData.err.length()>0) && (tccData.err.length()==tccData.nFV.length())) { for (size_t k=0; k<tccData.err.length(); k++) { int err = tccData.err[k]; if (err>0) { MColor col(1.0, 1.0, 1.0); switch(err) { case 1: col = MColor(1.0, 0.0, 0.0); break; // bad topology / inconsistent eqc case 2: col = MColor(1.0, 0.0, 1.0); break; // mismatched itv case 3: col = MColor(0.0, 0.0, 1.0); break; // unassigned itvs case 4: col = MColor(0.5, 0.5, 1.0); break; // unassigned T-joint default: break; } stat = meshFn.setFaceColor(col, k); if (stat!=MS::kSuccess) { char bla[] = "bla"; stat.perror(bla); } } } } return stat; }
void CXRayObjectExport:: CreateSMGFacegroups ( MFnMesh& fnMesh ) { // Now call the smoothingAlgorithm to fill in the polySmoothingGroups // table. // Note: we have to traverse ALL polygons to handle the case // of disjoint polygons. // int numPolygons = fnMesh.numPolygons(); nextSmoothingGroup = 1; currSmoothingGroup = 1; for ( int pid=0; pid<numPolygons; pid++ ) { newSmoothingGroup = true; // Check polygon has not already been visited if ( NO_SMOOTHING_GROUP == polySmoothingGroups[pid] ) { if ( !smoothingAlgorithm(pid,fnMesh) ) { // No smooth edges for this polygon so we set // the smoothing group to NO_SMOOTHING_GROUP (off) polySmoothingGroups[pid] = NO_SMOOTHING_GROUP; } } } /* for ( int idx=0; idx<numPolygons; ++idx ) { string128 buff; sprintf (buff,"[%d] smg=%d",idx,polySmoothingGroups[idx]); Msg (buff); } */ }
// once normals are supported in the polyMesh schema, polyMesh will look // different than readSubD void readPoly(double iFrame, MFnMesh & ioMesh, MObject & iParent, Alembic::AbcGeom::IPolyMesh & iNode, bool iInitialized) { Alembic::AbcGeom::IPolyMeshSchema schema = iNode.getSchema(); Alembic::AbcGeom::MeshTopologyVariance ttype = schema.getTopologyVariance(); int64_t index, ceilIndex; double alpha = getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); MFloatPointArray pointArray; Alembic::Abc::V3fArraySamplePtr ceilPoints; // we can just read the points if (ttype != Alembic::AbcGeom::kHeterogenousTopology && iInitialized) { Alembic::Abc::V3fArraySamplePtr points = schema.getPositions().getValue( Alembic::Abc::ISampleSelector(index) ); if (alpha != 0.0) { ceilPoints = schema.getPositions().getValue( Alembic::Abc::ISampleSelector(ceilIndex) ); } fillPoints(pointArray, points, ceilPoints, alpha); ioMesh.setPoints(pointArray, MSpace::kObject); if (schema.getNormals().getNumSamples() > 1) { setPolyNormals(iFrame, ioMesh, schema.getNormals()); } if (schema.getUVs().getNumSamples() > 1) { setUVs(iFrame, ioMesh, schema.getUVs()); } return; } // we need to read the topology Alembic::AbcGeom::IPolyMeshSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); if (alpha != 0.0 && ttype != Alembic::AbcGeom::kHeterogenousTopology) { ceilPoints = schema.getPositions().getValue( Alembic::Abc::ISampleSelector(ceilIndex) ); } fillPoints(pointArray, samp.getPositions(), ceilPoints, alpha); fillTopology(ioMesh, iParent, pointArray, samp.getIndices(), samp.getCounts()); setPolyNormals(iFrame, ioMesh, schema.getNormals()); setUVs(iFrame, ioMesh, schema.getUVs()); }
// Reference: OSD shape_utils.h:: applyTags() "corner" static float getCreaseVertices( MFnMesh const & inMeshFn, Descriptor & outDesc) { MUintArray tVertexIds; MDoubleArray tCreaseData; float maxCreaseValue = 0.0f; if ( inMeshFn.getCreaseVertices(tVertexIds, tCreaseData) ) { assert( tVertexIds.length() == tCreaseData.length() ); int ncorners = tVertexIds.length(); int * verts = new int[ncorners*2]; float * weights = new float[ncorners]; // Has crease vertices for (unsigned int j=0; j < tVertexIds.length(); j++) { assert( tCreaseData[j] >= 0.0 ); verts[j] = tVertexIds[j]; weights[j] = float(tCreaseData[j]); maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue); } outDesc.numCorners = ncorners; outDesc.cornerVertexIndices = verts; outDesc.cornerWeights = weights; } return maxCreaseValue; }
// ---------------------------------------- bool GeometryPolygonExporter::verifyPolygonsForHoles( const MFnMesh &fnMesh ) { // If we want to export triangles, holes aren't of note. if ( triangulated ) return false; // Iterate through all polygons of the current mesh and // verify their polygons for holes. MItMeshPolygon meshPolygonsIter ( fnMesh.object() ); for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() ) { // Is this polygon shaded by this shader? int polyIndex = meshPolygonsIter.index(); uint realShaderCount = ( uint ) mShaders.length(); if ( mShaderPosition < realShaderCount && ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue; if ( mShaderPosition >= realShaderCount && ( mShaderIndices[polyIndex] >= 0 && mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue; // Look for holes in this polygon // ASSUMPTION: Holes are automatically removed by triangulation. // ASSUMPTION: The iterator gives the hole vertices at the end of the enumeration. // ASSUMPTION: Hole vertices are never used as surface vertices or repeated between holes or inside a hole. if ( meshPolygonsIter.isHoled() && !triangulated ) { return true; } } return false; }
// Reference: OSD shape_utils.h:: applyTags() "corner" float applyCreaseVertices( MFnMesh const & inMeshFn, HMesh * hbrMesh ) { MUintArray tVertexIds; MDoubleArray tCreaseData; float maxCreaseValue = 0.0f; if ( inMeshFn.getCreaseVertices(tVertexIds, tCreaseData) ) { assert( tVertexIds.length() == tCreaseData.length() ); // Has crease vertices for (unsigned int j=0; j < tVertexIds.length(); j++) { // Assumption: The OSD vert ids are identical to those of the Maya mesh HVertex * v = hbrMesh->GetVertex( tVertexIds[j] ); if(v) { assert( tCreaseData[j] >= 0.0 ); v->SetSharpness( (float)tCreaseData[j] ); maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue); } else { fprintf(stderr, "warning: cannot find vertex for corner tag (%d)\n", tVertexIds[j] ); } } } return maxCreaseValue; }
PXR_NAMESPACE_OPEN_SCOPE /// "Flattens out" the given \p interpolation onto face-vertexes of the given /// \p meshFn, returning a mapping of the face-vertex indices to data indices. /// Takes into account data authored sparsely if \p assignmentIndices and /// \p unauthoredValuesIndex are specified. static MIntArray _GetMayaFaceVertexAssignmentIds( const MFnMesh& meshFn, const TfToken& interpolation, const VtIntArray& assignmentIndices, const int unauthoredValuesIndex) { MIntArray valueIds(meshFn.numFaceVertices(), -1); MItMeshFaceVertex itFV(meshFn.object()); unsigned int fvi = 0; for (itFV.reset(); !itFV.isDone(); itFV.next(), ++fvi) { int valueId = 0; if (interpolation == UsdGeomTokens->constant) { valueId = 0; } else if (interpolation == UsdGeomTokens->uniform) { valueId = itFV.faceId(); } else if (interpolation == UsdGeomTokens->vertex) { valueId = itFV.vertId(); } else if (interpolation == UsdGeomTokens->faceVarying) { valueId = fvi; } if (static_cast<size_t>(valueId) < assignmentIndices.size()) { // The data is indexed, so consult the indices array for the // correct index into the data. valueId = assignmentIndices[valueId]; if (valueId == unauthoredValuesIndex) { // This component had no authored value, so leave it unassigned. continue; } } valueIds[fvi] = valueId; } return valueIds; }
void SGNormalManipIntersector::build() { MMatrix camMatrix = SGMatrix::getCamMatrix(); MFnMesh fnMesh = SGMesh::pMesh->dagPath; MIntArray selIndices = SGSelection::sels.getSelVtxIndices(); MMatrix worldToView = SGMatrix::getWorldToViewMatrix(camMatrix); int targetIndex = selIndices[0]; MPoint mousePoint(SGMouse::x, SGMouse::y); double closeDist = 100000.0; for (unsigned int i = 0; i < selIndices.length(); i++) { MPoint point, viewPoint; fnMesh.getPoint(selIndices[i], point, MSpace::kWorld); viewPoint = SGMatrix::getViewPointFromWorld(point, camMatrix, &worldToView); double dist = mousePoint.distanceTo(viewPoint); if (dist < closeDist) { closeDist = dist; targetIndex = selIndices[i]; } } if (closeDist > catchDist) { exists = false; return; } fnMesh.getPoint(targetIndex, center, MSpace::kWorld); fnMesh.getVertexNormal(targetIndex, normal, MSpace::kWorld); normal.normalize(); double manipSize = SGMatrix::getManipSizeFromWorldPoint(center, camMatrix); double normalSize = axisSize / manipSize; double coneMatrixSize = coneSize / manipSize; normal *= normalSize; normalLine.setLength(2); normalLine[0] = center; normalLine[1] = center + normal; MMatrix rotMatrix = SGMatrix::getRotateMatrix(MVector(0, 1, 0), normal); rotMatrix *= coneMatrixSize; rotMatrix(3, 0) = normalLine[1].x; rotMatrix(3, 1) = normalLine[1].y; rotMatrix(3, 2) = normalLine[1].z; rotMatrix(3, 3) = 1; coneMatrix = rotMatrix; exists = true; }
// Reference: OSD shape_utils.h:: applyTags() "crease" float applyCreaseEdges(MFnMesh const & inMeshFn, HMesh * hbrMesh) { MStatus returnStatus; MUintArray tEdgeIds; MDoubleArray tCreaseData; float maxCreaseValue = 0.0f; if (inMeshFn.getCreaseEdges(tEdgeIds, tCreaseData)) { assert( tEdgeIds.length() == tCreaseData.length() ); // Has crease edges int2 edgeVerts; for (unsigned int j=0; j < tEdgeIds.length(); j++) { // Get vert ids from maya edge int edgeId = tEdgeIds[j]; returnStatus = inMeshFn.getEdgeVertices(edgeId, edgeVerts); // Assumption: The OSD vert ids are identical to those of the Maya mesh HVertex const * v = hbrMesh->GetVertex( edgeVerts[0] ), * w = hbrMesh->GetVertex( edgeVerts[1] ); HHalfedge * e = 0; if( v and w ) { if( (e = v->GetEdge(w)) == 0) { e = w->GetEdge(v); } if(e) { assert( tCreaseData[j] >= 0.0 ); e->SetSharpness( (float)tCreaseData[j] ); maxCreaseValue = std::max(float(tCreaseData[j]), maxCreaseValue); } else { fprintf(stderr, "warning: cannot find edge for crease tag (%d,%d)\n", edgeVerts[0], edgeVerts[1] ); } } } } return maxCreaseValue; }
bool CacheMeshSampler::addSampleFromMesh(MFnMesh& mesh) { MDagPath dagPath; mesh.getPath(dagPath); MString path = dagPath.fullPathName(); return fAttributeSet.updateAnimatedChannels( fIsAnimated, AttributeSet(mesh, fNeedUVs, fUseBaseTessellation), path); }
// ------------------------------------------------------------ void SceneGraph::addForcedNodes ( const MDagPath& dagPath ) { MFnMesh meshFn ( dagPath ); // Iterate upstream finding all the nodes which affect the mesh. MStatus stat; MPlug plug = meshFn.findPlug ( ATTR_IN_MESH ); if ( plug.isConnected() ) { MItDependencyGraph dependGraphIter ( plug, MFn::kInvalid, MItDependencyGraph::kUpstream, MItDependencyGraph::kDepthFirst, MItDependencyGraph::kPlugLevel, &stat ); if ( stat == MS::kSuccess ) { dependGraphIter.disablePruningOnFilter(); for ( ; ! dependGraphIter.isDone(); dependGraphIter.next() ) { MObject thisNode = dependGraphIter.thisNode(); MFn::Type type = thisNode.apiType(); if ( thisNode.apiType() == MFn::kSkinClusterFilter ) { MFnSkinCluster clusterFn ( thisNode ); MDagPathArray jointPaths; clusterFn.influenceObjects ( jointPaths, &stat ); if ( stat == MS::kSuccess ) { uint count = jointPaths.length(); for ( uint i = 0; i < count; ++i ) appendForcedNodeToList ( jointPaths[i] ); } } else if ( thisNode.apiType() == MFn::kJointCluster ) { MObject joint = DagHelper::getNodeConnectedTo ( thisNode, ATTR_MATRIX ); MDagPath jointPath = MDagPath::getAPathTo ( joint ); appendForcedNodeToList ( jointPath ); } } } } }
void NifTextureConnector::ConnectTexture( MDagPath mesh_path ) { MDGModifier dgModifier; MFnDependencyNode chooserFn; chooserFn.create( "uvChooser", "uvChooser" ); //Connection between the mesh and the uvChooser MFnMesh meshFn; meshFn.setObject(mesh_path); dgModifier.connect( meshFn.findPlug("uvSet")[uvSet].child(0), chooserFn.findPlug("uvSets").elementByLogicalIndex(0) ); //Connections between the uvChooser and the place2dTexture dgModifier.connect( chooserFn.findPlug("outUv"), texturePlacement.findPlug("uvCoord") ); dgModifier.connect( chooserFn.findPlug("outVertexCameraOne"), texturePlacement.findPlug("vertexCameraOne") ); dgModifier.connect( chooserFn.findPlug("outVertexUvOne"), texturePlacement.findPlug("vertexUvOne") ); dgModifier.connect( chooserFn.findPlug("outVertexUvTwo"), texturePlacement.findPlug("vertexUvTwo") ); dgModifier.connect( chooserFn.findPlug("outVertexUvThree"), texturePlacement.findPlug("vertexUvThree") ); dgModifier.doIt(); }
static void makeCubes(std::vector<cube> &cubes, MString &name, MStatus *stat) { MFnMesh fnMesh; MObject result; MFloatPointArray points; MIntArray faceCounts; MIntArray faceConnects; int index_offset = 0; for (std::vector<cube>::iterator cit = cubes.begin(); cit != cubes.end(); ++cit) { point3 diag = cit->diagonal(); float scale = diag.x; point3 pos = cit->start + (diag * .5f); MFloatVector mpos(pos.x, pos.y, pos.z); addCube(scale, mpos, index_offset * (8), points, faceCounts, faceConnects); index_offset += 1; } unsigned int vtx_cnt = points.length(); unsigned int face_cnt = faceCounts.length(); MObject newMesh = fnMesh.create( /* numVertices */ vtx_cnt, /* numFaces */ face_cnt, points, faceCounts, faceConnects, MObject::kNullObj, stat); /* Harden all edges. */ int n_edges = fnMesh.numEdges(stat); for (int i = 0; i < n_edges; ++i) { fnMesh.setEdgeSmoothing(i, false); } fnMesh.cleanupEdgeSmoothing(); /* Must be called after editing edges. */ fnMesh.updateSurface(); /* Assign Shader. */ MSelectionList sel_list; if (!MFAIL(sel_list.add("initialShadingGroup"))) { MObject set_obj; sel_list.getDependNode(0, set_obj); MFnSet set(set_obj); set.addMember(newMesh); } /* Give it a swanky name. */ MFnDagNode parent(fnMesh.parent(0)); name = parent.setName("polyMengerSponge", false, stat); }
//------------------------------ void MaterialExporter::exportConnectedMaterials ( SceneElement* sceneElement ) { // If we have a external reference, we don't need to export the data here. if ( !sceneElement->getIsLocal() ) return; if ( !sceneElement->getIsExportNode () ) return; // Check if it is a mesh object and an export node if ( sceneElement->getType() == SceneElement::MESH ) { MDagPath dagPath = sceneElement->getPath(); // Attach a function set MStatus status; MFnMesh fnMesh ( dagPath.node(), &status ); if ( status != MStatus::kSuccess ) return; // Find how many shaders are used by this instance of the mesh MObjectArray shaders; MIntArray shaderIndices; unsigned instanceNumber = dagPath.instanceNumber(); fnMesh.getConnectedShaders ( instanceNumber, shaders, shaderIndices ); // Find the polygons that correspond to each materials and export them uint realShaderCount = ( uint ) shaders.length(); uint numShaders = ( uint ) std::max ( ( size_t ) 1, ( size_t ) shaders.length() ); for ( uint shaderPosition = 0; shaderPosition < numShaders; ++shaderPosition ) { if ( shaderPosition < realShaderCount ) { // Add shader-specific parameters (TexCoords sets). // Add symbolic name for the material used on this polygon set. MObject shadingEngine = shaders[shaderPosition]; exportMaterial ( shadingEngine ); } } } // recursive call for all the child elements for ( uint i=0; i<sceneElement->getChildCount(); ++i ) { SceneElement* childElement = sceneElement->getChild ( i ); exportConnectedMaterials ( childElement ); } }
void readSubD(double iFrame, MFnMesh & ioMesh, MObject & iParent, SubDAndColors & iNode, bool iInitialized) { Alembic::AbcGeom::ISubDSchema schema = iNode.mMesh.getSchema(); Alembic::AbcGeom::MeshTopologyVariance ttype = schema.getTopologyVariance(); Alembic::AbcCoreAbstract::index_t index, ceilIndex; double alpha = getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); MFloatPointArray pointArray; Alembic::Abc::P3fArraySamplePtr ceilPoints; // we can just read the points if (ttype != Alembic::AbcGeom::kHeterogenousTopology && iInitialized) { Alembic::Abc::P3fArraySamplePtr points = schema.getPositionsProperty( ).getValue(Alembic::Abc::ISampleSelector(index)); if (alpha != 0.0) { ceilPoints = schema.getPositionsProperty().getValue( Alembic::Abc::ISampleSelector(ceilIndex) ); } fillPoints(pointArray, points, ceilPoints, alpha); ioMesh.setPoints(pointArray, MSpace::kObject); if (schema.getUVsParam().getNumSamples() > 1) { setUVs(iFrame, ioMesh, schema.getUVsParam()); } setColors(iFrame, ioMesh, iNode.mC3s, iNode.mC4s, !iInitialized); return; } // we need to read the topology Alembic::AbcGeom::ISubDSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); if (alpha != 0.0 && ttype != Alembic::AbcGeom::kHeterogenousTopology) { ceilPoints = schema.getPositionsProperty().getValue( Alembic::Abc::ISampleSelector(ceilIndex) ); } fillPoints(pointArray, samp.getPositions(), ceilPoints, alpha); fillTopology(ioMesh, iParent, pointArray, samp.getFaceIndices(), samp.getFaceCounts()); setUVs(iFrame, ioMesh, schema.getUVsParam()); setColors(iFrame, ioMesh, iNode.mC3s, iNode.mC4s, !iInitialized); }
void disconnectMesh(MObject & iMeshObject, std::vector<Prop> & iSampledPropList, std::size_t iFirstProp) { MFnMesh fnMesh; fnMesh.setObject(iMeshObject); // disconnect old connection from AlembicNode or some other nodes // to inMesh if one such connection exist MPlug dstPlug = fnMesh.findPlug("inMesh"); disconnectAllPlugsTo(dstPlug); disconnectProps(fnMesh, iSampledPropList, iFirstProp); clearPt(fnMesh); return; }