void MayaObject::getMeshData(MPointArray& points, MFloatVectorArray& normals) { MStatus stat; MObject meshObject = this->mobject; MMeshSmoothOptions options; MFnMesh tmpMesh(this->mobject); MFnMeshData meshData; MObject dataObject; MObject smoothedObj; // create smooth mesh if needed if (tmpMesh.findPlug("displaySmoothMesh").asBool()) { stat = tmpMesh.getSmoothMeshDisplayOptions(options); if (stat) { if (!tmpMesh.findPlug("useSmoothPreviewForRender", false, &stat).asBool()) { //Logging::debug(MString("useSmoothPreviewForRender turned off")); int smoothLevel = tmpMesh.findPlug("renderSmoothLevel", false, &stat).asInt(); options.setDivisions(smoothLevel); } if (options.divisions() > 0) { dataObject = meshData.create(); smoothedObj = tmpMesh.generateSmoothMesh(dataObject, &options, &stat); if (stat) { meshObject = smoothedObj; } } } } MFnMesh meshFn(meshObject, &stat); if (!stat) { MString error = stat.errorString(); Logging::error(error); } meshFn.getPoints(points); meshFn.getNormals(normals, MSpace::kObject); }
void MayaObject::getMeshData(MPointArray& points, MFloatVectorArray& normals, MFloatArray& uArray, MFloatArray& vArray, MIntArray& triPointIndices, MIntArray& triNormalIndices, MIntArray& triUvIndices, MIntArray& triMatIndices) { MStatus stat; MObject meshObject = this->mobject; MMeshSmoothOptions options; MFnMesh tmpMesh(this->mobject, &stat); MFnMeshData meshData; MObject dataObject; MObject smoothedObj; // create smooth mesh if needed if (tmpMesh.findPlug("displaySmoothMesh").asBool()) { stat = tmpMesh.getSmoothMeshDisplayOptions(options); if (stat) { if (!tmpMesh.findPlug("useSmoothPreviewForRender", false, &stat).asBool()) { //Logging::debug(MString("useSmoothPreviewForRender turned off")); int smoothLevel = tmpMesh.findPlug("renderSmoothLevel", false, &stat).asInt(); options.setDivisions(smoothLevel); } if (options.divisions() > 0) { dataObject = meshData.create(); smoothedObj = tmpMesh.generateSmoothMesh(dataObject, &options, &stat); if (stat) { meshObject = smoothedObj; } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); meshFn.getPoints(points); meshFn.getNormals(normals, MSpace::kObject); meshFn.getUVs(uArray, vArray); uint numVertices = points.length(); uint numNormals = normals.length(); uint numUvs = uArray.length(); //Logging::debug(MString("numVertices ") + numVertices); //Logging::debug(MString("numNormals ") + numNormals); //Logging::debug(MString("numUvs ") + numUvs); // some meshes may have no uv's // to avoid problems I add a default uv coordinate if (numUvs == 0) { Logging::warning(MString("Object has no uv's: ") + this->shortName); uArray.append(0.0); vArray.append(0.0); } for (uint nid = 0; nid < numNormals; nid++) { if (normals[nid].length() < 0.1f) Logging::warning(MString("Malformed normal in ") + this->shortName); } MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; for (faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); int perFaceShadingGroup = 0; if (this->perFaceAssignments.length() > 0) perFaceShadingGroup = this->perFaceAssignments[faceId]; MIntArray faceUVIndices; faceNormalIds.clear(); for (uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; if (numUvs == 0) { faceUVIndices.append(0); } else{ faceIt.getUVIndex(vtxId, uvIndex); //if (uvIndex > uArray.length()) // Logging::info(MString("-----------------> UV Problem!!! uvIndex ") + uvIndex + " > uvArray in object " + this->shortName); faceUVIndices.append(uvIndex); } } for (int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for (uint triVtxId = 0; triVtxId < 3; triVtxId++) { for (uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if (faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; triPointIndices.append(vtxId0); triPointIndices.append(vtxId1); triPointIndices.append(vtxId2); triNormalIndices.append(normalId0); triNormalIndices.append(normalId1); triNormalIndices.append(normalId2); triUvIndices.append(uvId0); triUvIndices.append(uvId1); triUvIndices.append(uvId2); triMatIndices.append(perFaceShadingGroup); //Logging::debug(MString("vtxIds ") + vtxId0 + " " + vtxId1 + " " + vtxId2); //Logging::debug(MString("nIds ") + normalId0 + " " + normalId1 + " " + normalId2); //Logging::debug(MString("uvIds ") + uvId0 + " " + uvId1 + " " + uvId2); } } }
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MIntArray& perFaceAssignments, MObjectArray& shadingGroups, bool needsPerFaceInfo=true) { // if obj is a light, simply return the mobject if (shapeObjectDP.node().hasFn(MFn::kLight)) { perFaceAssignments.clear(); shadingGroups.clear(); shadingGroups.append(shapeObjectDP.node()); return true; } if (shapeObjectDP.node().hasFn(MFn::kMesh)) { // Find the Shading Engines Connected to the SourceNode MFnMesh meshFn(shapeObjectDP.node()); perFaceAssignments.clear(); shadingGroups.clear(); MObjectArray comps; // this one seems to be extremly much faster if we need no per face informations. // e.g. for a sphere with 90000 faces, the non per face method needs 0.05 sec. whereas the // method with per face info needs about 20 sec. if (!needsPerFaceInfo) { meshFn.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), shadingGroups, comps, true); return true; } meshFn.getConnectedShaders(shapeObjectDP.instanceNumber(), shadingGroups, perFaceAssignments); if (!meshFn.findPlug("displaySmoothMesh").asBool()) return true; MIntArray indices; indices = perFaceAssignments; int subdivs = 0; int multiplier = 0; if (meshFn.findPlug("displaySmoothMesh").asBool()) { MMeshSmoothOptions options; MStatus status = meshFn.getSmoothMeshDisplayOptions(options); if (status) { if (!meshFn.findPlug("useSmoothPreviewForRender", false, &status).asBool()) { int smoothLevel = meshFn.findPlug("renderSmoothLevel", false, &status).asInt(); options.setDivisions(smoothLevel); } subdivs = options.divisions(); if (subdivs > 0) multiplier = static_cast<int> (pow(4.0f, (subdivs - 1))); } } if (multiplier > 0) perFaceAssignments.clear(); for (unsigned int i = 0; i < indices.length(); i++) { int subdivisions = multiplier * meshFn.polygonVertexCount(i); int index = 0 > indices[i] ? 0 : indices[i]; // non assigned has -1, but we want 0 perFaceAssignments.append(index); // simply replicate the index for all subdiv faces for (int k = 0; k < subdivisions - 1; k++) perFaceAssignments.append(index); } return true; } if (shapeObjectDP.node().hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MObject instObjGroupsAttr; if (shapeObjectDP.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbs(shapeObjectDP.node()); instObjGroupsAttr = fnNurbs.attribute("instObjGroups"); } if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MFnParticleSystem fnPart(shapeObjectDP.node()); instObjGroupsAttr = fnPart.attribute("instObjGroups"); } MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr); // Get the instance that our node is referring to; // In other words get the Plug for instObjGroups[intanceNumber]; MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber()); // Find the ShadingGroup plugs that we are connected to as Source MPlugArray SGPlugArray; instPlugElem.connectedTo(SGPlugArray, false, true); perFaceAssignments.clear(); shadingGroups.clear(); // Loop through each ShadingGroup Plug for (unsigned int i=0; i < SGPlugArray.length(); ++i) { shadingGroups.append(SGPlugArray[i].node()); return true; } } return false; }