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 APolygonalMesh::computeFaceDrift() { unsigned * dst = faceDrifts(); unsigned * src = faceCounts(); dst[0] = 0; unsigned i = 1; for(;i<numPolygons();i++) dst[i] = dst[i-1] + src[i-1]; }
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; }
static MStatus convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner, std::vector<Vertex> const & refinedVerts, bool hasUVs, std::vector<FVarVertexUV> const & refinedUVs, bool hasColors, std::vector<FVarVertexColor> const & refinedColors, MFnMesh & inMeshFn, MObject newMeshDataObj) { MStatus status; typedef OpenSubdiv::Far::ConstIndexArray IndexArray; int maxlevel = refiner.GetMaxLevel(); OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel); int nfaces = refLastLevel.GetNumFaces(); // Init Maya Data // Face Counts MIntArray faceCounts(nfaces); for (int face=0; face < nfaces; ++face) { faceCounts[face] = 4; } // Face Connects MIntArray faceConnects(nfaces*4); for (int face=0, idx=0; face < nfaces; ++face) { IndexArray fverts = refLastLevel.GetFaceVertices(face); for (int vert=0; vert < fverts.size(); ++vert) { faceConnects[idx++] = fverts[vert]; } } // Points int nverts = refLastLevel.GetNumVertices(); int firstOfLastVert = refiner.GetNumVerticesTotal() - nverts - refiner.GetLevel(0).GetNumVertices(); MFloatPointArray points(nverts); for (int vIt = 0; vIt < nverts; ++vIt) { Vertex const & v = refinedVerts[firstOfLastVert + vIt]; points.set(vIt, v.position[0], v.position[1], v.position[2]); } // Create New Mesh from MFnMesh MFnMesh newMeshFn; MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(), points, faceCounts, faceConnects, newMeshDataObj, &status); MCHECKERR(status, "Cannot create new mesh"); // Get face-varying set names and other info from the inMesh MStringArray uvSetNames; MStringArray colorSetNames; std::vector<int> colorSetChannels; std::vector<MFnMesh::MColorRepresentation> colorSetReps; int totalColorSetChannels = 0; status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels); // Add new UVs back to the mesh if needed if (hasUVs) { MIntArray fvarConnects(faceConnects.length()); int count = 0; for (int f = 0; f < refLastLevel.GetNumFaces(); ++f) { IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELUV); for (int index = 0 ; index < faceIndices.size() ; ++index) { fvarConnects[count++] = faceIndices[index]; } } int nuvs = refLastLevel.GetNumFVarValues(CHANNELUV); int firstOfLastUvs = refiner.GetNumFVarValuesTotal(CHANNELUV) - nuvs - refiner.GetLevel(0).GetNumFVarValues(CHANNELUV); MFloatArray uCoord(nuvs), vCoord(nuvs); for (int uvIt = 0; uvIt < nuvs; ++uvIt) { FVarVertexUV const & uv = refinedUVs[firstOfLastUvs + uvIt]; uCoord[uvIt] = uv.u; vCoord[uvIt] = uv.v; } // Currently, the plugin only supports one UV set int uvSetIndex = 0; if (uvSetIndex > 0) { status = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] ); MCHECKERR(status, "Cannot create UVSet"); } static MString defaultUVName("map1"); MString const * uvname = uvSetIndex==0 ? &defaultUVName : &uvSetNames[uvSetIndex]; status = newMeshFn.setUVs(uCoord, vCoord, uvname); MCHECKERR(status, "Cannot set UVs for set : "+*uvname); status = newMeshFn.assignUVs(faceCounts, fvarConnects, uvname); MCHECKERR(status, "Cannot assign UVs"); } // Add new colors back to the mesh if needed if (hasColors) { int count = 0; MIntArray fvarConnects2(faceConnects.length()); for (int f = 0 ; f < refLastLevel.GetNumFaces(); ++f) { IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELCOLOR); for (int index = 0 ; index < faceIndices.size() ; ++index) { fvarConnects2[count++] = faceIndices[index]; } } int ncols = refLastLevel.GetNumFVarValues(CHANNELCOLOR); int firstOfLastCols = refiner.GetNumFVarValuesTotal(CHANNELCOLOR) - ncols - refiner.GetLevel(0).GetNumFVarValues(CHANNELCOLOR); MColorArray colorArray(ncols); for (int colIt = 0; colIt < ncols; ++colIt) { FVarVertexColor const & c = refinedColors[firstOfLastCols + colIt]; colorArray.set(colIt, c.r, c.g, c.b, c.a); } // Currently, the plugin only supports one color sets int colorSetIndex = 0; // Assign color buffer and map the ids for each face-vertex // API Limitation: Cannot set MColorRepresentation here status = newMeshFn.createColorSetDataMesh( colorSetNames[colorSetIndex]); MCHECKERR(status, "Cannot create ColorSet"); bool isColorClamped = inMeshFn.isColorClamped( colorSetNames[colorSetIndex], &status); MCHECKERR(status, "Can not get Color Clamped "); status = newMeshFn.setIsColorClamped( colorSetNames[colorSetIndex], isColorClamped); MCHECKERR(status, "Can not set Color Clamped : " + isColorClamped); status = newMeshFn.setColors( colorArray, &colorSetNames[colorSetIndex], colorSetReps[colorSetIndex]); MCHECKERR(status, "Can not set Colors"); status = newMeshFn.assignColors( fvarConnects2, &colorSetNames[colorSetIndex]); MCHECKERR(status, "Can not assign Colors"); } return MS::kSuccess; }
MStatus convertOsdFarToMayaMeshData( FMesh const * farMesh, OpenSubdiv::OsdCpuVertexBuffer * vertexBuffer, int subdivisionLevel, MFnMesh const & inMeshFn, MObject newMeshDataObj ) { MStatus returnStatus; // Get sizing data from OSD const OpenSubdiv::FarPatchTables *farPatchTables = farMesh->GetPatchTables(); int numPolygons = farPatchTables->GetNumFaces(); // use the highest level stored in the patch tables const unsigned int *polygonConnects_orig = farPatchTables->GetFaceVertices(); // use the highest level stored in the patch tables const OpenSubdiv::FarSubdivisionTables<OpenSubdiv::OsdVertex> *farSubdivTables = farMesh->GetSubdivisionTables(); unsigned int numVertices = farSubdivTables->GetNumVertices(subdivisionLevel); unsigned int vertexOffset = farSubdivTables->GetFirstVertexOffset(subdivisionLevel); // Init Maya Data MFloatPointArray points(numVertices); MIntArray faceCounts(numPolygons); // number of edges for each polygon. Assume quads (4-edges per face) MIntArray faceConnects(numPolygons*4); // array of vertex ids for all edges. assuming quads // -- Face Counts for (int i=0; i < numPolygons; ++i) { faceCounts[i] = 4; } // -- Face Connects for (unsigned int i=0; i < faceConnects.length(); i++) { faceConnects[i] = polygonConnects_orig[i] - vertexOffset; // adjust vertex indices so that v0 is at index 0 } // -- Points // Number of floats in each vertex. (positions, normals, etc) int numFloatsPerVertex = vertexBuffer->GetNumElements(); assert(numFloatsPerVertex == 3); // assuming only xyz stored for each vertex const float *vertexData = vertexBuffer->BindCpuBuffer(); float *ptrVertexData; for (unsigned int i=0; i < numVertices; i++) { // make sure to offset to the first osd vertex for that subd level unsigned int osdRawVertexIndex = i + vertexOffset; // Lookup the data in the vertexData ptrVertexData = (float *) vertexData + ((osdRawVertexIndex) * numFloatsPerVertex); points.set(i, ptrVertexData[0], ptrVertexData[1], ptrVertexData[2]); } // Create New Mesh from MFnMesh MFnMesh newMeshFn; MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(), points, faceCounts, faceConnects, newMeshDataObj, &returnStatus); MCHECKERR(returnStatus, "Cannot create new mesh"); // Attach UVs (if present) // ASSUMPTION: Only tracking UVs as FVar data. Will need to change this // ASSUMPTION: OSD has a unique UV for each face-vertex int fvarTotalWidth = farMesh->GetTotalFVarWidth(); if (fvarTotalWidth > 0) { // Get face-varying set names and other info from the inMesh MStringArray uvSetNames; MStringArray colorSetNames; std::vector<int> colorSetChannels; std::vector<MFnMesh::MColorRepresentation> colorSetReps; int totalColorSetChannels = 0; returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels); int numUVSets = uvSetNames.length(); int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels; assert(fvarTotalWidth == expectedFvarTotalWidth); const OpenSubdiv::FarPatchTables::FVarDataTable &fvarDataTable = farPatchTables->GetFVarDataTable(); assert(fvarDataTable.size() == expectedFvarTotalWidth*faceConnects.length()); // Create an array of indices to map each face-vert to the UV and ColorSet Data MIntArray fvarConnects(faceConnects.length()); for (unsigned int i=0; i < faceConnects.length(); i++) { fvarConnects[i] = i; } MFloatArray uCoord(faceConnects.length()); MFloatArray vCoord(faceConnects.length()); for (int uvSetIndex=0; uvSetIndex < numUVSets; uvSetIndex++) { for(unsigned int vertid=0; vertid < faceConnects.length(); vertid++) { int fvarItem = vertid*fvarTotalWidth + uvSetIndex*2; // stride per vertex is the fvarTotalWidth uCoord[vertid] = fvarDataTable[fvarItem]; vCoord[vertid] = fvarDataTable[fvarItem+1]; } // Assign UV buffer and map the uvids for each face-vertex if (uvSetIndex != 0) { // assume uvset index 0 is the default UVset, so do not create returnStatus = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] ); } MCHECKERR(returnStatus, "Cannot create UVSet"); newMeshFn.setUVs(uCoord,vCoord, &uvSetNames[uvSetIndex]); newMeshFn.assignUVs(faceCounts, fvarConnects, &uvSetNames[uvSetIndex]); } MColorArray colorArray(faceConnects.length()); int colorSetRelativeStartIndex = numUVSets*2; for (unsigned int colorSetIndex=0; colorSetIndex < colorSetNames.length(); colorSetIndex++) { for(unsigned int vertid=0; vertid < faceConnects.length(); vertid++) { int fvarItem = vertid*fvarTotalWidth + colorSetRelativeStartIndex; if (colorSetChannels[colorSetIndex] == 1) { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem]; colorArray[vertid].b = fvarDataTable[fvarItem]; colorArray[vertid].a = 1.0f; } else if (colorSetChannels[colorSetIndex] == 3) { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem+1]; colorArray[vertid].b = fvarDataTable[fvarItem+2]; colorArray[vertid].a = 1.0f; } else { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem+1]; colorArray[vertid].b = fvarDataTable[fvarItem+2]; colorArray[vertid].a = fvarDataTable[fvarItem+3]; } } // Assign UV buffer and map the uvids for each face-vertex // API Limitation: Cannot set MColorRepresentation here returnStatus = newMeshFn.createColorSetDataMesh(colorSetNames[colorSetIndex]); MCHECKERR(returnStatus, "Cannot create ColorSet"); bool isColorClamped = inMeshFn.isColorClamped(colorSetNames[colorSetIndex], &returnStatus); newMeshFn.setIsColorClamped(colorSetNames[colorSetIndex], isColorClamped); newMeshFn.setColors(colorArray, &colorSetNames[colorSetIndex], colorSetReps[colorSetIndex]); newMeshFn.assignColors(fvarConnects, &colorSetNames[colorSetIndex]); // Increment colorSet start location in fvar buffer colorSetRelativeStartIndex += colorSetChannels[colorSetIndex]; } } return MS::kSuccess; }
unsigned APolygonalMesh::faceCount(unsigned idx) const { return faceCounts()[idx]; }
static void export_alembic_xform_by_buffer(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex) { Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop); Alembic::AbcGeom::OXform xform; if (archive.xform_map.find(renderedBufferIndex) != archive.xform_map.end()) { xform = archive.xform_map[renderedBufferIndex]; } else { xform = Alembic::AbcGeom::OXform(topObj, "xform_" + umbase::UMStringUtil::number_to_string(renderedBufferIndex), archive.timesampling); archive.xform_map[renderedBufferIndex] = xform; } bool isFirstMesh = false; Alembic::AbcGeom::OPolyMesh polyMesh; if (archive.mesh_map.find(renderedBufferIndex) != archive.mesh_map.end()) { polyMesh = archive.mesh_map[renderedBufferIndex]; } else { polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex), archive.timesampling); archive.mesh_map[renderedBufferIndex] = polyMesh; isFirstMesh = true; Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema(); archive.schema_map[renderedBufferIndex] = meshSchema; } Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[renderedBufferIndex]; meshSchema.setTimeSampling(archive.timesampling); std::vector<Alembic::Util::int32_t> faceList; std::vector<Alembic::Util::int32_t> faceCountList; const RenderedBuffer::UVList &uvList = renderedBuffer.uvs; const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies; const RenderedBuffer::NormalList &normalList = renderedBuffer.normals; RenderedBuffer::UVList& temporary_uv = archive.temporary_uv_list; temporary_uv.resize(uvList.size()); RenderedBuffer::NormalList& temporary_normal = archive.temporary_normal_list; temporary_normal.resize(normalList.size()); RenderedBuffer::VertexList& temporary_vertex = archive.temporary_vertex_list; temporary_vertex.resize(vertexList.size()); const int materialSize = static_cast<int>(renderedBuffer.materials.size()); int totalFaceCount = 0; for (int k = 0; k < materialSize; ++k) { RenderedMaterial* material = renderedBuffer.materials.at(k); totalFaceCount += material->surface.faces.size(); } if (archive.surface_size_map.find(renderedBufferIndex) == archive.surface_size_map.end()) { archive.surface_size_map[renderedBufferIndex] = 0; } int& preSurfaceSize = archive.surface_size_map[renderedBufferIndex]; bool isFirstSurface = totalFaceCount != preSurfaceSize; if (!isFirstMesh && isFirstSurface) { return; } preSurfaceSize = totalFaceCount; faceCountList.resize(totalFaceCount); faceList.resize(totalFaceCount * 3); int faceCounter = 0; for (int k = 0; k < materialSize; ++k) { RenderedMaterial* material = renderedBuffer.materials.at(k); const int faceSize = material->surface.faces.size(); for (int n = 0; n < faceSize; ++n) { UMVec3i face = material->surface.faces[n]; faceList[faceCounter * 3 + 0] = (face.x - 1); faceList[faceCounter * 3 + 1] = (face.y - 1); faceList[faceCounter * 3 + 2] = (face.z - 1); faceCountList[faceCounter] = 3; ++faceCounter; } } Alembic::AbcGeom::OPolyMeshSchema::Sample sample; // vertex for (int n = 0, nsize = vertexList.size(); n < nsize; ++n) { temporary_vertex[n].z = -vertexList[n].z; } Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &temporary_vertex.front(), temporary_vertex.size()); sample.setPositions(positions); // face index if (isFirstMesh) { Alembic::Abc::Int32ArraySample faceIndices(faceList); Alembic::Abc::Int32ArraySample faceCounts(faceCountList); sample.setFaceIndices(faceIndices); sample.setFaceCounts(faceCounts); } // UVs if (!uvList.empty() && archive.is_export_uvs) { for (int n = 0, nsize = uvList.size(); n < nsize; ++n) { temporary_uv[n].y = 1.0f - uvList[n].y; } Alembic::AbcGeom::OV2fGeomParam::Sample uvSample; uvSample.setScope(Alembic::AbcGeom::kVertexScope ); uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &temporary_uv.front(), temporary_uv.size())); sample.setUVs(uvSample); } // Normals if (!normalList.empty() && archive.is_export_normals) { for (int n = 0, nsize = normalList.size(); n < nsize; ++n) { temporary_normal[n].z = -normalList[n].z; } Alembic::AbcGeom::ON3fGeomParam::Sample normalSample; normalSample.setScope(Alembic::AbcGeom::kVertexScope ); normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &temporary_normal.front(), temporary_normal.size())); sample.setNormals(normalSample); } meshSchema.set(sample); }
static void export_alembic_xform_by_material_direct(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex) { Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop); for (int k = 0, ksize = static_cast<int>(renderedBuffer.materials.size()); k < ksize; ++k) { Alembic::AbcGeom::OPolyMesh polyMesh; const int key = renderedBufferIndex * 10000 + k; Alembic::AbcGeom::OXform xform; if (archive.xform_map.find(key) != archive.xform_map.end()) { xform = archive.xform_map[key]; } else { xform = Alembic::AbcGeom::OXform(topObj, "xform_" + to_string(renderedBufferIndex) + "_material_" + to_string(k) , archive.timesampling); archive.xform_map[key] = xform; } bool isFirstMesh = false; if (archive.mesh_map.find(key) != archive.mesh_map.end()) { polyMesh = archive.mesh_map[key]; } else { polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex) + "_material_" + to_string(k), archive.timesampling); archive.mesh_map[key] = polyMesh; isFirstMesh = true; Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema(); archive.schema_map[key] = meshSchema; } if (archive.surface_size_map.find(key) == archive.surface_size_map.end()) { archive.surface_size_map[key] = 0; } Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[key]; meshSchema.setTimeSampling(archive.timesampling); Alembic::AbcGeom::OPolyMeshSchema::Sample empty; std::vector<Alembic::Util::int32_t> faceList; std::vector<Alembic::Util::int32_t> faceCountList; const RenderedBuffer::UVList &uvList = renderedBuffer.uvs; const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies; const RenderedBuffer::NormalList &normalList = renderedBuffer.normals; RenderedBuffer::VertexList vertexListByMaterial; RenderedBuffer::UVList uvListByMaterial; RenderedBuffer::NormalList normalListByMaterial; RenderedMaterial* material = renderedBuffer.materials.at(k); const int materialSurfaceSize = static_cast<int>(material->surface.faces.size()); vertexListByMaterial.resize(materialSurfaceSize * 3); faceList.resize(materialSurfaceSize * 3); faceCountList.resize(materialSurfaceSize); if (!uvList.empty()) { uvListByMaterial.resize(materialSurfaceSize * 3); } if (!normalList.empty()) { normalListByMaterial.resize(materialSurfaceSize * 3); } int& preSurfaceSize = archive.surface_size_map[key]; bool isFirstSurface = material->surface.faces.size() != preSurfaceSize; if (!isFirstMesh && isFirstSurface) { continue; } // re assign par material int lastIndex = 0; for (int n = 0; n < materialSurfaceSize; ++n) { UMVec3i face = material->surface.faces[n]; const int f1 = face.x - 1; const int f2 = face.y - 1; const int f3 = face.z - 1; int vi1 = n * 3 + 0; int vi2 = n * 3 + 1; int vi3 = n * 3 + 2; vertexListByMaterial[vi1] = vertexList.at(f1); vertexListByMaterial[vi2] = vertexList.at(f2); vertexListByMaterial[vi3] = vertexList.at(f3); if (!uvList.empty() && archive.is_export_uvs) { uvListByMaterial[vi1] = uvList.at(f1); uvListByMaterial[vi2] = uvList.at(f2); uvListByMaterial[vi3] = uvList.at(f3); } if (!normalList.empty() && archive.is_export_normals) { normalListByMaterial[vi1] = normalList.at(f1); normalListByMaterial[vi2] = normalList.at(f2); normalListByMaterial[vi3] = normalList.at(f3); } faceList[vi1] = vi1; faceList[vi2] = vi2; faceList[vi3] = vi3; faceCountList[n] = 3; } preSurfaceSize = material->surface.faces.size(); for (int n = 0, nsize = vertexListByMaterial.size(); n < nsize; ++n) { vertexListByMaterial[n].z = -vertexListByMaterial[n].z; } Alembic::AbcGeom::OPolyMeshSchema::Sample sample; // vertex Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &vertexListByMaterial.front(), vertexListByMaterial.size()); sample.setPositions(positions); // face index if (isFirstMesh) { Alembic::Abc::Int32ArraySample faceIndices(faceList); Alembic::Abc::Int32ArraySample faceCounts(faceCountList); sample.setFaceIndices(faceIndices); sample.setFaceCounts(faceCounts); } // UVs if (!uvListByMaterial.empty() && archive.is_export_uvs) { for (int n = 0, nsize = uvListByMaterial.size(); n < nsize; ++n) { uvListByMaterial[n].y = 1.0f - uvListByMaterial[n].y; } Alembic::AbcGeom::OV2fGeomParam::Sample uvSample; uvSample.setScope(Alembic::AbcGeom::kVertexScope ); uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &uvListByMaterial.front(), uvListByMaterial.size())); sample.setUVs(uvSample); } // Normals if (!normalListByMaterial.empty() && archive.is_export_normals) { for (int n = 0, nsize = normalListByMaterial.size(); n < nsize; ++n) { normalListByMaterial[n].z = -normalListByMaterial[n].z; } Alembic::AbcGeom::ON3fGeomParam::Sample normalSample; normalSample.setScope(Alembic::AbcGeom::kVertexScope ); normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &normalListByMaterial.front(), normalListByMaterial.size())); sample.setNormals(normalSample); } meshSchema.set(sample); } }
static MStatus convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner, std::vector<Vertex> const & vertexBuffer, MFnMesh const & inMeshFn, MObject newMeshDataObj) { MStatus status; typedef OpenSubdiv::Far::ConstIndexArray IndexArray; int maxlevel = refiner.GetMaxLevel(); OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel); int nfaces = refLastLevel.GetNumFaces(); // Init Maya Data // -- Face Counts MIntArray faceCounts(nfaces); for (int face=0; face < nfaces; ++face) { faceCounts[face] = 4; } // -- Face Connects MIntArray faceConnects(nfaces*4); for (int face=0, idx=0; face < nfaces; ++face) { IndexArray fverts = refLastLevel.GetFaceVertices(face); for (int vert=0; vert < fverts.size(); ++vert) { faceConnects[idx++] = fverts[vert]; } } // -- Points MFloatPointArray points(refLastLevel.GetNumVertices()); Vertex const * v = &vertexBuffer.at(0); for (int level=1; level<=maxlevel; ++level) { int nverts = refiner.GetLevel(level).GetNumVertices(); if (level==maxlevel) { for (int vert=0; vert < nverts; ++vert, ++v) { points.set(vert, v->position[0], v->position[1], v->position[2]); } } else { v += nverts; } } // Create New Mesh from MFnMesh MFnMesh newMeshFn; MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(), points, faceCounts, faceConnects, newMeshDataObj, &status); MCHECKERR(status, "Cannot create new mesh"); int fvarTotalWidth = 0; if (fvarTotalWidth > 0) { // Get face-varying set names and other info from the inMesh MStringArray uvSetNames; MStringArray colorSetNames; std::vector<int> colorSetChannels; std::vector<MFnMesh::MColorRepresentation> colorSetReps; int totalColorSetChannels = 0; status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels); #if defined(DEBUG) or defined(_DEBUG) int numUVSets = uvSetNames.length(); int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels; assert(fvarTotalWidth == expectedFvarTotalWidth); #endif // XXXX fvar stuff here } return MS::kSuccess; }