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); }
MObject createSubD(double iFrame, SubDAndColors & iNode, MObject & iParent) { Alembic::AbcGeom::ISubDSchema schema = iNode.mMesh.getSchema(); Alembic::AbcCoreAbstract::index_t index, ceilIndex; getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); Alembic::AbcGeom::ISubDSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); MString name(iNode.mMesh.getName().c_str()); MFnMesh fnMesh; MFloatPointArray pointArray; Alembic::Abc::P3fArraySamplePtr emptyPtr; fillPoints(pointArray, samp.getPositions(), emptyPtr, 0.0); fillTopology(fnMesh, iParent, pointArray, samp.getFaceIndices(), samp.getFaceCounts()); fnMesh.setName(iNode.mMesh.getName().c_str()); setInitialShadingGroup(fnMesh.partialPathName()); MObject obj = fnMesh.object(); setUVs(iFrame, fnMesh, schema.getUVsParam()); setColors(iFrame, fnMesh, iNode.mC3s, iNode.mC4s, true); // add the mFn-specific attributes to fnMesh node MFnNumericAttribute numAttr; MString attrName("SubDivisionMesh"); MObject attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, 1); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); if (samp.getInterpolateBoundary() > 0) { attrName = MString("interpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingInterpolateBoundary() > 0) { attrName = MString("faceVaryingInterpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingPropagateCorners() > 0) { attrName = MString("faceVaryingPropagateCorners"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingPropagateCorners()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } #if MAYA_API_VERSION >= 201100 Alembic::Abc::Int32ArraySamplePtr holes = samp.getHoles(); if (holes && !holes->size() == 0) { unsigned int numHoles = (unsigned int)holes->size(); MUintArray holeData(numHoles); for (unsigned int i = 0; i < numHoles; ++i) { holeData[i] = (*holes)[i]; } if (fnMesh.setInvisibleFaces(holeData) != MS::kSuccess) { MString warn = "Failed to set holes on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } #endif Alembic::Abc::FloatArraySamplePtr creases = samp.getCreaseSharpnesses(); if (creases && !creases->size() == 0) { Alembic::Abc::Int32ArraySamplePtr indices = samp.getCreaseIndices(); Alembic::Abc::Int32ArraySamplePtr lengths = samp.getCreaseLengths(); std::size_t numLengths = lengths->size(); MUintArray edgeIds; MDoubleArray creaseData; std::size_t curIndex = 0; // curIndex incremented here to move on to the next crease length for (std::size_t i = 0; i < numLengths; ++i, ++curIndex) { std::size_t len = (*lengths)[i] - 1; float creaseSharpness = (*creases)[i]; // curIndex incremented here to go between all the edges that make // up a given length for (std::size_t j = 0; j < len; ++j, ++curIndex) { Alembic::Util::int32_t vertA = (*indices)[curIndex]; Alembic::Util::int32_t vertB = (*indices)[curIndex+1]; MItMeshVertex itv(obj); int prev; itv.setIndex(vertA, prev); MIntArray edges; itv.getConnectedEdges(edges); std::size_t numEdges = edges.length(); for (unsigned int k = 0; k < numEdges; ++k) { int oppVert = -1; itv.getOppositeVertex(oppVert, edges[k]); if (oppVert == vertB) { creaseData.append(creaseSharpness); edgeIds.append(edges[k]); break; } } } } if (fnMesh.setCreaseEdges(edgeIds, creaseData) != MS::kSuccess) { MString warn = "Failed to set creases on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } Alembic::Abc::FloatArraySamplePtr corners = samp.getCornerSharpnesses(); if (corners && !corners->size() == 0) { Alembic::Abc::Int32ArraySamplePtr cornerVerts = samp.getCornerIndices(); unsigned int numCorners = static_cast<unsigned int>(corners->size()); MUintArray vertIds(numCorners); MDoubleArray cornerData(numCorners); for (unsigned int i = 0; i < numCorners; ++i) { cornerData[i] = (*corners)[i]; vertIds[i] = (*cornerVerts)[i]; } if (fnMesh.setCreaseVertices(vertIds, cornerData) != MS::kSuccess) { MString warn = "Failed to set corners on: "; warn += iNode.mMesh.getName().c_str(); printWarning(warn); } } return obj; }
MObject createSubD(double iFrame, SubDAndFriends & iNode, MObject & iParent) { Alembic::AbcGeom::ISubDSchema schema = iNode.mMesh.getSchema(); Alembic::AbcCoreAbstract::index_t index, ceilIndex; getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); Alembic::AbcGeom::ISubDSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); MString name(iNode.mMesh.getName().c_str()); MFnMesh fnMesh; MFloatPointArray pointArray; Alembic::Abc::P3fArraySamplePtr emptyPtr; fillPoints(pointArray, samp.getPositions(), emptyPtr, 0.0); fillTopology(fnMesh, iParent, pointArray, samp.getFaceIndices(), samp.getFaceCounts()); fnMesh.setName(iNode.mMesh.getName().c_str()); setInitialShadingGroup(fnMesh.partialPathName()); MObject obj = fnMesh.object(); setColorsAndUVs(iFrame, fnMesh, schema.getUVsParam(), iNode.mV2s, iNode.mC3s, iNode.mC4s, true); // add the mFn-specific attributes to fnMesh node MFnNumericAttribute numAttr; MString attrName("SubDivisionMesh"); MObject attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, 1); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); if (samp.getInterpolateBoundary() > 0) { attrName = MString("interpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingInterpolateBoundary() > 0) { attrName = MString("faceVaryingInterpolateBoundary"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingInterpolateBoundary()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } if (samp.getFaceVaryingPropagateCorners() > 0) { attrName = MString("faceVaryingPropagateCorners"); attrObj = numAttr.create(attrName, attrName, MFnNumericData::kBoolean, samp.getFaceVaryingPropagateCorners()); numAttr.setKeyable(true); numAttr.setHidden(false); fnMesh.addAttribute(attrObj, MFnDependencyNode::kLocalDynamicAttr); } fillCreasesCornersAndHoles(fnMesh, iNode, samp); return obj; }