// Propagate objectGroups from inMesh to subdivided outMesh // Note: Currently only supporting facet groups (for per-facet shading) MStatus createSmoothMesh_objectGroups(const MFnMeshData &inMeshDat, int subdivisionLevel, MFnMeshData &newMeshDat) { MStatus returnStatus; int facesPerBaseFace = (int)(pow(4.0f, subdivisionLevel)); MIntArray newCompElems; for(unsigned int gi=0; gi < inMeshDat.objectGroupCount(); gi++) { unsigned int compId = inMeshDat.objectGroup(gi, &returnStatus); MCHECKERR(returnStatus, "cannot get objectGroup() comp ID."); MFn::Type compType = inMeshDat.objectGroupType(compId, &returnStatus); MCHECKERR(returnStatus, "cannot get objectGroupType()."); // get elements from inMesh objectGroupComponent MIntArray compElems; MFnSingleIndexedComponent compFn(inMeshDat.objectGroupComponent(compId), &returnStatus ); MCHECKERR(returnStatus, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent()."); compFn.getElements(compElems); // Only supporting kMeshPolygonComponent ObjectGroups at this time // Skip the other types if (compType == MFn::kMeshPolygonComponent) { // convert/populate newCompElems from compElems of inMesh // (with new face indices) to outMesh newCompElems.setLength( compElems.length() * facesPerBaseFace ); for (unsigned int i=0; i < compElems.length(); i++) { int startElemIndex = i * facesPerBaseFace; int startElemValue = compElems[i] * facesPerBaseFace; for (int j=0; j < facesPerBaseFace; j++) { newCompElems[startElemIndex+j] = startElemValue+j; } } // create comp createComp(newMeshDat, compType, compId, newCompElems); } } return MS::kSuccess; }
// Propagate objectGroups from inMesh to subdivided outMesh // Note: Currently only supporting facet groups (for per-facet shading) MStatus createSmoothMesh_objectGroups( MFnMesh const & inMeshFn, MFnMeshData const & inMeshDat, MFnMeshData &newMeshDat, int level, int numSubfaces ) { MStatus status; MIntArray newCompElems; std::vector<unsigned int> offsets; // mapping of offsets for subdivided faces for(unsigned int gi=0; gi<inMeshDat.objectGroupCount(); gi++) { unsigned int compId = inMeshDat.objectGroup(gi, &status); MCHECKERR(status, "cannot get objectGroup() comp ID."); MFn::Type compType = inMeshDat.objectGroupType(compId, &status); MCHECKERR(status, "cannot get objectGroupType()."); // Only supporting kMeshPolygonComponent ObjectGroups at this time // Skip the other types if (compType == MFn::kMeshPolygonComponent) { // get elements from inMesh objectGroupComponent MIntArray compElems; MFnSingleIndexedComponent compFn( inMeshDat.objectGroupComponent(compId), &status ); MCHECKERR(status, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent()."); compFn.getElements(compElems); if (compElems.length()==0) { continue; } // over-allocation to maximum possible length newCompElems.setLength( numSubfaces ); if (offsets.empty()) { // lazy population of the subface offsets table int nfaces = inMeshFn.numPolygons(); offsets.resize(nfaces); for (int i=0, count=0; i<nfaces; ++i) { int nverts = inMeshFn.polygonVertexCount(i), nsubfaces = computeNumSubfaces(nverts, level); offsets[i] = count; count+=nsubfaces; } } unsigned int idx = 0; // convert/populate newCompElems from compElems of inMesh // (with new face indices) to outMesh for (unsigned int i=0; i < compElems.length(); i++) { int nverts = inMeshFn.polygonVertexCount(compElems[i]), nsubfaces = computeNumSubfaces(nverts, level); unsigned int subFaceOffset = offsets[compElems[i]]; for (int j=0; j<nsubfaces; ++j) { newCompElems[idx++] = subFaceOffset++; } } // resize to actual length newCompElems.setLength( idx ); // create comp createComp(newMeshDat, compType, compId, newCompElems); } } return MS::kSuccess; }