MayaTransformWriter::MayaTransformWriter(double iFrame, MayaTransformWriter & iParent, MDagPath & iDag, uint32_t iTimeIndex, bool iWriteVisibility) { if (iDag.hasFn(MFn::kJoint)) { MFnIkJoint joint(iDag); Alembic::AbcGeom::OXform obj(iParent.getObject(), joint.name().asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp = obj.getProperties(); mAttrs = AttributesWriterPtr(new AttributesWriter(iFrame, cp, joint, iTimeIndex, iWriteVisibility)); pushTransformStack(iFrame, joint); } else { MFnTransform trans(iDag); Alembic::AbcGeom::OXform obj(iParent.getObject(), trans.name().asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp = obj.getProperties(); mAttrs = AttributesWriterPtr(new AttributesWriter(iFrame, cp, trans, iTimeIndex, iWriteVisibility)); pushTransformStack(iFrame, trans); } // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); }
MayaPointPrimitiveWriter::MayaPointPrimitiveWriter( double iFrame, MDagPath & iDag, Alembic::AbcGeom::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) : mIsAnimated(false), mDagPath(iDag) { MFnParticleSystem particle(mDagPath); MString name = particle.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); Alembic::AbcGeom::OPoints obj(iParent, name.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(particle, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, particle, iTimeIndex, iArgs)); MObject object = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(object)) mIsAnimated = true; write(iFrame); }
MayaNurbsSurfaceWriter::MayaNurbsSurfaceWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) : mIsSurfaceAnimated(false), mDagPath(iDag) { MStatus stat; MObject surface = iDag.node(); MFnNurbsSurface nurbs(mDagPath, &stat); if (!stat) { MGlobal::displayError( "MFnNurbsSurface() failed for MayaNurbsSurfaceWriter" ); } MString name = nurbs.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); Alembic::AbcGeom::ONuPatch obj(iParent, name.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(nurbs, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, nurbs, iTimeIndex, iArgs, true)); // for now if it a trim surface, treat it like it's animated if ( iTimeIndex != 0 && (nurbs.isTrimmedSurface() || util::isAnimated(surface)) ) { mIsSurfaceAnimated = true; } if (!mIsSurfaceAnimated || iArgs.setFirstAnimShape) { write(); } }
MayaNurbsCurveWriter::MayaNurbsCurveWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, bool iIsCurveGrp, const JobArgs & iArgs) : mIsAnimated(false), mRootDagPath(iDag), mIsCurveGrp(iIsCurveGrp) { MStatus stat; MFnDependencyNode fnDepNode(iDag.node(), &stat); MString name = fnDepNode.name(); if (mIsCurveGrp) { collectNurbsCurves(mRootDagPath, iArgs.excludeInvisible, mNurbsCurves, mIsAnimated); // if no curves were found bail early if (mNurbsCurves.length() == 0) return; } else { MObject curve = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(curve)) mIsAnimated = true; } name = util::stripNamespaces(name, iArgs.stripNamespace); Alembic::AbcGeom::OCurves obj(iParent, name.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(fnDepNode, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, fnDepNode, iTimeIndex, iArgs)); write(); }
MStatus AlembicHair::Save(double time, unsigned int timeIndex, bool isFirstFrame) { ESS_PROFILE_SCOPE("AlembicHair::Save"); MStatus status; // access the geometry MFnPfxGeometry node(GetRef()); // save the metadata SaveMetaData(this); // save the attributes if (isFirstFrame) { Abc::OCompoundProperty cp; Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(node, *GetJob())) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr( new AttributesWriter(cp, up, GetMyParent(), node, timeIndex, *GetJob()) ); } else { mAttrs->write(); } // prepare the bounding box Abc::Box3d bbox; // check if we have the global cache option const bool globalCache = GetJob()->GetOption(L"exportInGlobalSpace").asInt() > 0; MRenderLineArray mainLines, leafLines, flowerLines; node.getLineData(mainLines, leafLines, flowerLines, true, false, mNumSamples == 0, false, false, mNumSamples == 0, false, true, globalCache); // first we need to count the number of points unsigned int vertexCount = 0; for (unsigned int i = 0; i < (unsigned int)mainLines.length(); i++) { vertexCount += mainLines.renderLine(i, &status).getLine().length(); } mPosVec.resize(vertexCount); unsigned int offset = 0; if (mNumSamples == 0) { mNbVertices.resize((size_t)mainLines.length()); mRadiusVec.resize(vertexCount); mColorVec.resize(vertexCount); for (unsigned int i = 0; i < (unsigned int)mainLines.length(); i++) { const MRenderLine &line = mainLines.renderLine(i, &status); const MVectorArray &positions = line.getLine(); const MDoubleArray &radii = line.getWidth(); const MVectorArray &colors = line.getColor(); const MVectorArray &transparencies = line.getTransparency(); mNbVertices[i] = positions.length(); for (unsigned int j = 0; j < positions.length(); j++) { const MVector &opos = positions[j]; Imath::V3f &ipos = mPosVec[offset]; ipos.x = (float)opos.x; ipos.y = (float)opos.y; ipos.z = (float)opos.z; bbox.extendBy(Imath::V3d(ipos)); mRadiusVec[offset] = (float)radii[j]; const MVector &ocol = colors[j]; Imath::C4f &icol = mColorVec[offset]; icol.r = (float)ocol.x; icol.g = (float)ocol.y; icol.b = (float)ocol.z; icol.a = 1.0f - (float)transparencies[j].x; offset++; } } } else { for (unsigned int i = 0; i < (unsigned int)mainLines.length(); i++) { const MRenderLine &line = mainLines.renderLine(i, &status); const MVectorArray &positions = line.getLine(); for (unsigned int j = 0; j < positions.length(); j++) { const MVector &opos = positions[j]; Imath::V3f &ipos = mPosVec[offset]; ipos.x = (float)opos.x; ipos.y = (float)opos.y; ipos.z = (float)opos.z; bbox.extendBy(Imath::V3d(ipos)); offset++; } } } // store the positions to the samples mSample.setPositions(Abc::P3fArraySample(&mPosVec.front(), mPosVec.size())); mSample.setSelfBounds(bbox); if (mNumSamples == 0) { mSample.setCurvesNumVertices(Abc::Int32ArraySample(mNbVertices)); mSample.setWrap(AbcG::kNonPeriodic); mSample.setType(AbcG::kLinear); mRadiusProperty.set( Abc::FloatArraySample(&mRadiusVec.front(), mRadiusVec.size())); mColorProperty.set( Abc::C4fArraySample(&mColorVec.front(), mColorVec.size())); } // save the sample mSchema.set(mSample); mNumSamples++; return MStatus::kSuccess; }
MayaTransformWriter::MayaTransformWriter(MayaTransformWriter & iParent, MDagPath & iDag, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) { mVerbose = iArgs.verbose; mFilterEulerRotations = iArgs.filterEulerRotations; mJointOrientOpIndex[0] = mJointOrientOpIndex[1] = mJointOrientOpIndex[2] = mRotateOpIndex[0] = mRotateOpIndex[1] = mRotateOpIndex[2] = mRotateAxisOpIndex[0] = mRotateAxisOpIndex[1] = mRotateAxisOpIndex[2] = ~size_t(0); if (iDag.hasFn(MFn::kJoint)) { MFnIkJoint joint(iDag); MString jointName = joint.name(); mName = util::stripNamespaces(jointName, iArgs.stripNamespace); Alembic::AbcGeom::OXform obj(iParent.getObject(), mName.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(joint, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, joint, iTimeIndex, iArgs)); pushTransformStack(joint, iTimeIndex == 0); } else { MFnTransform trans(iDag); MString transName = trans.name(); mName = util::stripNamespaces(transName, iArgs.stripNamespace); Alembic::AbcGeom::OXform obj(iParent.getObject(), mName.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(trans, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, trans, iTimeIndex, iArgs)); pushTransformStack(trans, iTimeIndex == 0); } // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); }
MayaTransformWriter::MayaTransformWriter(Alembic::AbcGeom::OObject & iParent, MDagPath & iDag, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) { mVerbose = iArgs.verbose; mFilterEulerRotations = iArgs.filterEulerRotations; mJointOrientOpIndex[0] = mJointOrientOpIndex[1] = mJointOrientOpIndex[2] = mRotateOpIndex[0] = mRotateOpIndex[1] = mRotateOpIndex[2] = mRotateAxisOpIndex[0] = mRotateAxisOpIndex[1] = mRotateAxisOpIndex[2] = ~size_t(0); if (iDag.hasFn(MFn::kJoint)) { MFnIkJoint joint(iDag); MString jointName = joint.name(); mName = util::stripNamespaces(jointName, iArgs.stripNamespace); Alembic::AbcGeom::OXform obj(iParent, mName.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(joint, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, joint, iTimeIndex, iArgs)); if (!iArgs.worldSpace) { pushTransformStack(joint, iTimeIndex == 0); // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); return; } } else { MFnTransform trans(iDag); MString transName = trans.name(); mName = util::stripNamespaces(transName, iArgs.stripNamespace); Alembic::AbcGeom::OXform obj(iParent, mName.asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(trans, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, trans, iTimeIndex, iArgs)); if (!iArgs.worldSpace) { pushTransformStack(trans, iTimeIndex == 0); // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); return; } } // if we didn't bail early then we need to add all the transform // information at the current node and above // copy the dag path because we'll be popping from it MDagPath dag(iDag); int i; int numPaths = dag.length(); std::vector< MDagPath > dagList; for (i = numPaths - 1; i > -1; i--, dag.pop()) { dagList.push_back(dag); // inheritsTransform exists on both joints and transforms MFnDagNode dagNode(dag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); // if inheritsTransform exists and is set to false, then we // don't need to worry about ancestor nodes above this one if (!inheritPlug.isNull() && !inheritPlug.asBool()) break; } std::vector< MDagPath >::iterator iStart = dagList.begin(); std::vector< MDagPath >::iterator iCur = dagList.end(); iCur--; // now loop backwards over our dagpath list so we push ancestor nodes // first, all the way down to the current node for (; iCur != iStart; iCur--) { // only add it to the stack don't write it yet! if (iCur->hasFn(MFn::kJoint)) { MFnIkJoint joint(*iCur); pushTransformStack(joint, iTimeIndex == 0); } else { MFnTransform trans(*iCur); pushTransformStack(trans, iTimeIndex == 0); } } // finally add any transform info on the final node and write it if (iCur->hasFn(MFn::kJoint)) { MFnIkJoint joint(*iCur); pushTransformStack(joint, iTimeIndex == 0); } else { MFnTransform trans(*iCur); pushTransformStack(trans, iTimeIndex == 0); } // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); }
MayaCameraWriter::MayaCameraWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs) : mIsAnimated(false), mDagPath(iDag), mUseRenderShutter(false), mShutterOpen(0.0), mShutterClose(0.0) { MStatus status = MS::kSuccess; MFnCamera cam(iDag, &status); if (!status) { MGlobal::displayError( "MFnCamera() failed for MayaCameraWriter" ); } MString name = cam.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); Alembic::AbcGeom::OCamera obj(iParent, name.asChar(), iTimeIndex); mSchema = obj.getSchema(); MObject cameraObj = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(cameraObj)) { mIsAnimated = true; } else { iTimeIndex = 0; } MObject renderObj; MSelectionList sel; sel.add("defaultRenderGlobals"); if (!sel.isEmpty()) { sel.getDependNode(0, renderObj); MFnDependencyNode dep(renderObj); MPlug plug = dep.findPlug("motionBlurUseShutter", true); if (plug.asBool()) { MTime sec(1.0, MTime::kSeconds); double val = sec.as(MTime::uiUnit()); mUseRenderShutter = true; plug = dep.findPlug("motionBlurShutterOpen", true); mShutterOpen = plug.asDouble() / val; plug = dep.findPlug("motionBlurShutterClose", true); mShutterClose = plug.asDouble() / val; } } Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(cam, iArgs)) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, cam, iTimeIndex, iArgs, true)); if (!mIsAnimated || iArgs.setFirstAnimShape) { write(); } }
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs, GetMembersMap& gmMap) : mNoNormals(iArgs.noNormals), mWriteUVs(iArgs.writeUVs), mWriteColorSets(iArgs.writeColorSets), mWriteUVSets(iArgs.writeUVSets), mIsGeometryAnimated(false), mDagPath(iDag) { MStatus status = MS::kSuccess; MFnMesh lMesh( mDagPath, &status ); if ( !status ) { MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" ); } // intermediate objects aren't translated MObject surface = iDag.node(); if (iTimeIndex != 0 && util::isAnimated(surface)) { mIsGeometryAnimated = true; } else { iTimeIndex = 0; } std::vector<float> uvs; std::vector<Alembic::Util::uint32_t> indices; std::string uvSetName; MString name = lMesh.name(); name = util::stripNamespaces(name, iArgs.stripNamespace); // check to see if this poly has been tagged as a SubD MPlug plug = lMesh.findPlug("SubDivisionMesh"); if ( !plug.isNull() && plug.asBool() ) { Alembic::AbcGeom::OSubD obj(iParent, name.asChar(), iTimeIndex); mSubDSchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if (mWriteUVs || mWriteUVSets) { getUVs(uvs, indices, uvSetName); if (!uvs.empty()) { if (!uvSetName.empty()) { mSubDSchema.setUVSourceName(uvSetName); } uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope ); uvSamp.setVals(Alembic::AbcGeom::V2fArraySample( (const Imath::V2f *) &uvs.front(), uvs.size() / 2)); if (!indices.empty()) { uvSamp.setIndices(Alembic::Abc::UInt32ArraySample( &indices.front(), indices.size())); } } } Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(lMesh, iArgs)) { cp = mSubDSchema.getArbGeomParams(); up = mSubDSchema.getUserProperties(); } mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh, iTimeIndex, iArgs)); writeSubD(uvSamp); } else { Alembic::AbcGeom::OPolyMesh obj(iParent, name.asChar(), iTimeIndex); mPolySchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if (mWriteUVs || mWriteUVSets) { getUVs(uvs, indices, uvSetName); if (!uvs.empty()) { if (!uvSetName.empty()) { mPolySchema.setUVSourceName(uvSetName); } uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope ); uvSamp.setVals(Alembic::AbcGeom::V2fArraySample( (const Imath::V2f *) &uvs.front(), uvs.size() / 2)); if (!indices.empty()) { uvSamp.setIndices(Alembic::Abc::UInt32ArraySample( &indices.front(), indices.size())); } } } Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(lMesh, iArgs)) { cp = mPolySchema.getArbGeomParams(); up = mPolySchema.getUserProperties(); } // set the rest of the props and write to the writer node mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh, iTimeIndex, iArgs)); writePoly(uvSamp); } if (mWriteColorSets) { MStringArray colorSetNames; lMesh.getColorSetNames(colorSetNames); if (colorSetNames.length() > 0) { // Create the color sets compound prop Alembic::Abc::OCompoundProperty arbParams; if (mPolySchema.valid()) { arbParams = mPolySchema.getArbGeomParams(); } else { arbParams = mSubDSchema.getArbGeomParams(); } std::string currentColorSet = lMesh.currentColorSetName().asChar(); for (unsigned int i=0; i < colorSetNames.length(); ++i) { // Create an array property for each color set std::string colorSetPropName = colorSetNames[i].asChar(); Alembic::AbcCoreAbstract::MetaData md; if (currentColorSet == colorSetPropName) { md.set("mayaColorSet", "1"); } else { md.set("mayaColorSet", "0"); } if (lMesh.getColorRepresentation(colorSetNames[i]) == MFnMesh::kRGB) { Alembic::AbcGeom::OC3fGeomParam colorProp(arbParams, colorSetPropName, true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md); mRGBParams.push_back(colorProp); } else { Alembic::AbcGeom::OC4fGeomParam colorProp(arbParams, colorSetPropName, true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md); mRGBAParams.push_back(colorProp); } } writeColor(); } } if (mWriteUVSets) { MStringArray uvSetNames; lMesh.getUVSetNames(uvSetNames); unsigned int uvSetNamesLen = uvSetNames.length(); if (uvSetNamesLen > 1) { // Create the uv sets compound prop Alembic::Abc::OCompoundProperty arbParams; if (mPolySchema.valid()) { arbParams = mPolySchema.getArbGeomParams(); } else { arbParams = mSubDSchema.getArbGeomParams(); } MString currentUV = lMesh.currentUVSetName(); for (unsigned int i = 0; i < uvSetNamesLen; ++i) { // Create an array property for each uv set MString uvSetPropName = uvSetNames[i]; // the current UV set gets mapped to the primary UVs if (currentUV == uvSetPropName) { continue; } if (uvSetPropName.length() > 0 && lMesh.numUVs(uvSetPropName) > 0) { mUVparams.push_back(Alembic::AbcGeom::OV2fGeomParam( arbParams, uvSetPropName.asChar(), true, Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex)); } } writeUVSets(); } } // write out facesets if(!iArgs.writeFaceSets) return; // get the connected shading engines MObjectArray connSGObjs (getOutConnectedSG(mDagPath)); const unsigned int sgCount = connSGObjs.length(); for (unsigned int i = 0; i < sgCount; ++i) { MObject connSGObj, compObj; connSGObj = connSGObjs[i]; MFnDependencyNode fnDepNode(connSGObj); MString connSgObjName = fnDepNode.name(); // retrive the component MObject status = getSetComponents(mDagPath, connSGObj, gmMap, compObj); if (status != MS::kSuccess) { // for some reason the shading group doesn't represent a face set continue; } // retrieve the face indices MIntArray indices; MFnSingleIndexedComponent compFn; compFn.setObject(compObj); compFn.getElements(indices); const unsigned int numData = indices.length(); // encountered the whole object mapping. skip it. if (numData == 0) continue; std::vector<Alembic::Util::int32_t> faceIndices(numData); for (unsigned int j = 0; j < numData; ++j) { faceIndices[j] = indices[j]; } connSgObjName = util::stripNamespaces(connSgObjName, iArgs.stripNamespace); Alembic::AbcGeom::OFaceSet faceSet; std::string faceSetName(connSgObjName.asChar()); MPlug abcFacesetNamePlug = fnDepNode.findPlug("AbcFacesetName", true); if (!abcFacesetNamePlug.isNull()) { faceSetName = abcFacesetNamePlug.asString().asChar(); } if (mPolySchema.valid()) { if (mPolySchema.hasFaceSet(faceSetName)) { faceSet = mPolySchema.getFaceSet(faceSetName); } else { faceSet = mPolySchema.createFaceSet(faceSetName); } } else { if (mSubDSchema.hasFaceSet(faceSetName)) { faceSet = mSubDSchema.getFaceSet(faceSetName); } else { faceSet = mSubDSchema.createFaceSet(faceSetName); } } Alembic::AbcGeom::OFaceSetSchema::Sample samp; samp.setFaces(Alembic::Abc::Int32ArraySample(faceIndices)); Alembic::AbcGeom::OFaceSetSchema faceSetSchema = faceSet.getSchema(); faceSetSchema.set(samp); faceSetSchema.setFaceExclusivity(Alembic::AbcGeom::kFaceSetExclusive); MFnDependencyNode iNode(connSGObj); Alembic::Abc::OCompoundProperty cp; Alembic::Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(iNode, iArgs)) { cp = faceSetSchema.getArbGeomParams(); up = faceSetSchema.getUserProperties(); } AttributesWriter attrWriter(cp, up, faceSet, iNode, iTimeIndex, iArgs); attrWriter.write(); } }
MStatus AlembicCurves::Save(double time, unsigned int timeIndex, bool isFirstFrame) { ESS_PROFILE_SCOPE("AlembicCurves::Save"); if (this->accumRef.get() != 0) { accumRef->save(GetRef(), time); ++mNumSamples; return MStatus::kSuccess; } // access the geometry MFnNurbsCurve node(GetRef()); // save the metadata SaveMetaData(this); // save the attributes if (isFirstFrame) { Abc::OCompoundProperty cp; Abc::OCompoundProperty up; if (AttributesWriter::hasAnyAttr(node, *GetJob())) { cp = mSchema.getArbGeomParams(); up = mSchema.getUserProperties(); } mAttrs = AttributesWriterPtr( new AttributesWriter(cp, up, GetMyParent(), node, timeIndex, *GetJob()) ); } else { mAttrs->write(); } // prepare the bounding box Abc::Box3d bbox; // check if we have the global cache option const bool globalCache = GetJob()->GetOption(L"exportInGlobalSpace").asInt() > 0; Abc::M44f globalXfo; if (globalCache) { globalXfo = GetGlobalMatrix(GetRef()); } MPointArray positions; node.getCVs(positions); mPosVec.resize(positions.length()); for (unsigned int i = 0; i < positions.length(); i++) { const MPoint &outPos = positions[i]; Imath::V3f &inPos = mPosVec[i]; inPos.x = (float)outPos.x; inPos.y = (float)outPos.y; inPos.z = (float)outPos.z; if (globalCache) { globalXfo.multVecMatrix(inPos, inPos); } bbox.extendBy(inPos); } // store the positions to the samples mSample.setPositions(Abc::P3fArraySample(&mPosVec.front(), mPosVec.size())); mSample.setSelfBounds(bbox); if (mNumSamples == 0) { // knot vector! MDoubleArray knots; node.getKnots(knots); mKnotVec.resize(knots.length()); for (unsigned int i = 0; i < knots.length(); ++i) { mKnotVec[i] = (float)knots[i]; } mKnotVectorProperty.set(Abc::FloatArraySample(mKnotVec)); mNbVertices.push_back(node.numCVs()); mSample.setCurvesNumVertices(Abc::Int32ArraySample(mNbVertices)); if (node.form() == MFnNurbsCurve::kOpen) { mSample.setWrap(AbcG::kNonPeriodic); } else { mSample.setWrap(AbcG::kPeriodic); } if (node.degree() == 3) { mSample.setType(AbcG::kCubic); } else { mSample.setType(AbcG::kLinear); } MPlug widthPlug = node.findPlug("width"); if (!widthPlug.isNull()) { mRadiusVec.push_back(widthPlug.asFloat()); } else { mRadiusVec.push_back(1.0); } mRadiusProperty.set( Abc::FloatArraySample(&mRadiusVec.front(), mRadiusVec.size())); } // save the sample mSchema.set(mSample); mNumSamples++; return MStatus::kSuccess; }
MayaTransformWriter::MayaTransformWriter(double iFrame, Alembic::AbcGeom::OObject & iParent, MDagPath & iDag, uint32_t iTimeIndex, bool iAddWorld, bool iWriteVisibility) { if (iDag.hasFn(MFn::kJoint)) { MFnIkJoint joint(iDag); Alembic::AbcGeom::OXform obj(iParent, joint.name().asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp = obj.getProperties(); mAttrs = AttributesWriterPtr(new AttributesWriter(iFrame, cp, joint, iTimeIndex, iWriteVisibility)); if (!iAddWorld) { pushTransformStack(iFrame, joint); // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); return; } } else { MFnTransform trans(iDag); Alembic::AbcGeom::OXform obj(iParent, trans.name().asChar(), iTimeIndex); mSchema = obj.getSchema(); Alembic::Abc::OCompoundProperty cp = obj.getProperties(); mAttrs = AttributesWriterPtr(new AttributesWriter(iFrame, cp, trans, iTimeIndex, iWriteVisibility)); if (!iAddWorld) { pushTransformStack(iFrame, trans); // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); return; } } // if we didn't bail early then we need to add all the transform // information at the current node and above // copy the dag path because we'll be popping from it MDagPath dag(iDag); int i; int numPaths = dag.length(); std::vector< MDagPath > dagList; for (i = numPaths - 1; i > -1; i--, dag.pop()) { dagList.push_back(dag); // inheritsTransform exists on both joints and transforms MFnDagNode dagNode(dag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); // if inheritsTransform exists and is set to false, then we // don't need to worry about ancestor nodes above this one if (!inheritPlug.isNull() && !inheritPlug.asBool()) break; } std::vector< MDagPath >::iterator iStart = dagList.begin(); std::vector< MDagPath >::iterator iCur = dagList.end(); iCur--; // now loop backwards over our dagpath list so we push ancestor nodes // first, all the way down to the current node for (; iCur != iStart; iCur--) { // only add it to the stack don't write it yet! if (iCur->hasFn(MFn::kJoint)) { MFnIkJoint joint(*iCur); pushTransformStack(iFrame, joint); } else { MFnTransform trans(*iCur); pushTransformStack(iFrame, trans); } } // finally add any transform info on the final node and write it if (iCur->hasFn(MFn::kJoint)) { MFnIkJoint joint(*iCur); pushTransformStack(iFrame, joint); } else { MFnTransform trans(*iCur); pushTransformStack(iFrame, trans); } // need to look at inheritsTransform MFnDagNode dagNode(iDag); MPlug inheritPlug = dagNode.findPlug("inheritsTransform"); if (!inheritPlug.isNull()) { if (util::getSampledType(inheritPlug) != 0) mInheritsPlug = inheritPlug; mSample.setInheritsXforms(inheritPlug.asBool()); } // everything is default, don't write anything if (mSample.getNumOps() == 0 && mSample.getInheritsXforms()) return; mSchema.set(mSample); }