MString getConnectedFileTexturePath(const MString& plugName, MFnDependencyNode& depFn) { MStatus stat; MString path = ""; MPlug plug = depFn.findPlug(plugName, &stat); if (!stat) return path; if (plug.isConnected()) { MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if (!stat) return path; if (parray.length() == 0) return path; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); if (!fileNode.hasFn(MFn::kFileTexture)) { return path; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if (!stat) { return path; } path = ftn.asString(); } return path; }
MString getString(const char *plugName, MFnDependencyNode& dn) { MDGContext ctx = MDGContext::fsNormal; MStatus stat = MS::kSuccess; MPlug plug = dn.findPlug(plugName, &stat); if( !stat ) return ""; return plug.asString(ctx, &stat); }
void Exporter::extractColor(Color& tempcolor, MFnDependencyNode& fn, MString name) { MPlug p; MString r = name; r += "R"; MString g = name; g += "G"; MString b = name; b += "B"; MString a = name; a += "A"; p = fn.findPlug(r.asChar()); p.getValue(tempcolor.r); p = fn.findPlug(g.asChar()); p.getValue(tempcolor.g); p = fn.findPlug(b.asChar()); p.getValue(tempcolor.b); p = fn.findPlug(a.asChar()); p.getValue(tempcolor.a); p = fn.findPlug(name.asChar()); MPlugArray connections; p.connectedTo(connections, true, false); int debug = connections.length(); for (int i = 0; i != connections.length(); ++i) { // if file texture found if (connections[i].node().apiType() == MFn::kFileTexture) { // bind a function set to it .... MFnDependencyNode fnDep(connections[i].node()); // to get the node name tempcolor.texfileInternal = fnDep.name().asChar(); MPlug filename = fnDep.findPlug("ftn"); //sparar hela s�kv�gen till texturen tempcolor.texfileExternal = filename.asString().asChar(); //kopierar texturfiler std::string base_filename = tempcolor.texfileExternal.substr(tempcolor.texfileExternal.find_last_of("/\\") + 1); CopyFile(tempcolor.texfileExternal.c_str(), base_filename.c_str(), false); // stop looping break; } } }
bool getString(MString& plugName, MFnDependencyNode& dn, MString& value) { MDGContext ctx = MDGContext::fsNormal; MStatus stat = MS::kSuccess; bool result = false; MPlug plug = dn.findPlug(plugName, &stat); if( !stat ) return false; value = plug.asString(ctx, &stat); if(stat) return true; return result; }
bool getConnectedFileTexturePath(MString& plugName, MString& nodeName, MString& value, MObject& outFileNode) { MStatus stat; MObject obj = objectFromName(nodeName); if( obj == MObject::kNullObj) return false; MFnDependencyNode depFn(obj); MPlug plug = depFn.findPlug(plugName, &stat); if( !stat ) return false; //MGlobal::displayInfo(MString("is plug connected: ") + plug.name()); if( !plug.isConnected()) { //MGlobal::displayInfo(MString("plug is NOT connected: ") + plug.name()); return false; } MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if( !stat ) return false; if( parray.length() == 0 ) return false; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); std::cout << "filenode: " << getObjectName(fileNode).asChar() << " plug name " << destPlug.name() << "\n"; if( !fileNode.hasFn(MFn::kFileTexture) ) { std::cout << "node is not from type fileTexture.\n"; return false; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if(!stat) { std::cout << "fileTextureName not found at fileTexNode.\n"; return false; } MString fileTextureName = ftn.asString(); std::cout << "fileTextureName value: " << fileTextureName.asChar() <<"\n"; value = fileTextureName; outFileNode = fileNode; return true; }
bool getConnectedFileTexturePath(const MString& plugName, MString& nodeName, MString& value, MObject& outFileNode) { MStatus stat; MObject obj = objectFromName(nodeName); if (obj == MObject::kNullObj) return false; MFnDependencyNode depFn(obj); MPlug plug = depFn.findPlug(plugName, &stat); if (!stat) return false; if (!plug.isConnected()) { return false; } MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if (!stat) return false; if (parray.length() == 0) return false; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); if (!fileNode.hasFn(MFn::kFileTexture)) { return false; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if (!stat) { return false; } MString fileTextureName = ftn.asString(); value = fileTextureName; outFileNode = fileNode; return true; }
void LiveScene::readTags( NameList &tags, int filter ) const { tags.clear(); if ( m_isRoot ) { return; } if( m_dagPath.length() == 0 ) { throw Exception( "IECoreMaya::LiveScene::attributeNames: Dag path no longer exists!" ); } std::set<Name> uniqueTags; // read tags from ieTags attribute: MStatus st; MFnDependencyNode fnNode( m_dagPath.node() ); MPlug tagsPlug = fnNode.findPlug( "ieTags", false, &st ); if( st ) { std::string tagsStr( tagsPlug.asString().asChar() ); boost::tokenizer<boost::char_separator<char> > t( tagsStr, boost::char_separator<char>( " " ) ); for ( boost::tokenizer<boost::char_separator<char> >::iterator it = t.begin(); it != t.end(); ++it ) { uniqueTags.insert( Name( *it ) ); } } // read tags from custom readers: std::vector<CustomTagReader> &tagReaders = customTagReaders(); for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it ) { NameList values; it->m_read( m_dagPath, values, filter ); uniqueTags.insert( values.begin(), values.end() ); } tags.insert( tags.end(), uniqueTags.begin(), uniqueTags.end() ); }
bool PxrUsdMayaWriteUtil::ReadMayaAttribute( const MFnDependencyNode& depNode, const MString& name, std::string* val) { MStatus status; depNode.attribute(name, &status); if (status == MS::kSuccess) { MPlug plug = depNode.findPlug(name); MObject dataObj; if ( (plug.getValue(dataObj) == MS::kSuccess) && (dataObj.hasFn(MFn::kStringData)) ) { (*val) = std::string(plug.asString().asChar()); return true; } } return false; }
static TfToken _GetPrimvarInterpolation(const MFnDependencyNode& depFn, const std::string attrName) { const MPlug scopePlg = depFn.findPlug(MString(attrName.c_str()) + MString(_tokens->abcGeomScopeSuffix.GetText()), true); if (scopePlg.isNull()) { return TfToken(); } const char* scopeText = scopePlg.asString().toLowerCase().asChar(); if (scopeText == _tokens->abcGeomScopeVertex) { return UsdGeomTokens->vertex; } else if (scopeText == _tokens->abcGeomScopeFaceVarying) { return UsdGeomTokens->faceVarying; } else if (scopeText == _tokens->abcGeomScopeUniform) { return UsdGeomTokens->uniform; } else { return UsdGeomTokens->constant; } }
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(); } }
void CScriptedShapeTranslator::RunScripts(AtNode *atNode, unsigned int step, bool update) { std::map<std::string, CScriptedTranslator>::iterator translatorIt; MFnDependencyNode fnNode(GetMayaObject()); translatorIt = gTranslators.find(fnNode.typeName().asChar()); if (translatorIt == gTranslators.end()) { AiMsgError("[mtoa.scriptedTranslators] No command to export node \"%s\" of type %s.", fnNode.name().asChar(), fnNode.typeName().asChar()); return; } MString exportCmd = translatorIt->second.exportCmd; MString cleanupCmd = translatorIt->second.cleanupCmd; MFnDagNode node(m_dagPath.node()); bool isMasterDag = false; bool transformBlur = IsMotionBlurEnabled(MTOA_MBLUR_OBJECT) && IsLocalMotionBlurEnabled(); bool deformBlur = IsMotionBlurEnabled(MTOA_MBLUR_DEFORM) && IsLocalMotionBlurEnabled(); char buffer[64]; MString command = exportCmd; command += "("; sprintf(buffer, "%f", GetExportFrame()); command += buffer; command += ", "; sprintf(buffer, "%d", step); command += buffer; command += ", "; // current sample frame sprintf(buffer, "%f", GetSampleFrame(m_session, step)); command += buffer; command += ", "; // List of arnold attributes the custom shape export command has overriden MStringArray attrs; if (!m_masterNode) { command += "(\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), None)"; isMasterDag = true; } else { command += "(\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), (\"" + GetMasterInstance().partialPathName() + "\", \""; command += AiNodeGetName(m_masterNode); command += "\"))"; } MStatus status = MGlobal::executePythonCommand(command, attrs); if (!status) { AiMsgError("[mtoa.scriptedTranslators] Failed to export node \"%s\".", node.name().asChar()); return; } // Build set of attributes already processed std::set<std::string> attrsSet; for (unsigned int i=0; i<attrs.length(); ++i) { attrsSet.insert(attrs[i].asChar()); } std::set<std::string>::iterator attrsEnd = attrsSet.end(); // Should be getting displacement shader from master instance only // as arnold do not support displacement shader overrides for ginstance MFnDependencyNode masterShadingEngine; MFnDependencyNode shadingEngine; float dispPadding = -AI_BIG; float dispHeight = 1.0f; float dispZeroValue = 0.0f; bool dispAutobump = false; bool outputDispPadding = false; bool outputDispHeight = false; bool outputDispZeroValue = false; bool outputDispAutobump = false; const AtNodeEntry *anodeEntry = AiNodeGetNodeEntry(atNode); GetShapeInstanceShader(m_dagPath, shadingEngine); if (!IsMasterInstance()) { GetShapeInstanceShader(GetMasterInstance(), masterShadingEngine); } else { masterShadingEngine.setObject(shadingEngine.object()); } AtMatrix matrix; MMatrix mmatrix = m_dagPath.inclusiveMatrix(); ConvertMatrix(matrix, mmatrix); // Set transformation matrix if (attrsSet.find("matrix") == attrsEnd) { if (HasParameter(anodeEntry, "matrix")) { if (transformBlur) { if (step == 0) { AtArray* matrices = AiArrayAllocate(1, GetNumMotionSteps(), AI_TYPE_MATRIX); AiArraySetMtx(matrices, step, matrix); AiNodeSetArray(atNode, "matrix", matrices); } else { AtArray* matrices = AiNodeGetArray(atNode, "matrix"); AiArraySetMtx(matrices, step, matrix); } } else { AiNodeSetMatrix(atNode, "matrix", matrix); } } } // Set bounding box if (attrsSet.find("min") == attrsEnd && attrsSet.find("max") == attrsEnd) { // Now check if min and max parameters are valid parameter names on arnold node if (HasParameter(anodeEntry, "min") != 0 && HasParameter(anodeEntry, "max") != 0) { if (step == 0) { MBoundingBox bbox = node.boundingBox(); MPoint bmin = bbox.min(); MPoint bmax = bbox.max(); AiNodeSetPnt(atNode, "min", static_cast<float>(bmin.x), static_cast<float>(bmin.y), static_cast<float>(bmin.z)); AiNodeSetPnt(atNode, "max", static_cast<float>(bmax.x), static_cast<float>(bmax.y), static_cast<float>(bmax.z)); } else { if (transformBlur || deformBlur) { AtPoint cmin = AiNodeGetPnt(atNode, "min"); AtPoint cmax = AiNodeGetPnt(atNode, "max"); MBoundingBox bbox = node.boundingBox(); MPoint bmin = bbox.min(); MPoint bmax = bbox.max(); if (bmin.x < cmin.x) cmin.x = static_cast<float>(bmin.x); if (bmin.y < cmin.y) cmin.y = static_cast<float>(bmin.y); if (bmin.z < cmin.z) cmin.z = static_cast<float>(bmin.z); if (bmax.x > cmax.x) cmax.x = static_cast<float>(bmax.x); if (bmax.y > cmax.y) cmax.y = static_cast<float>(bmax.y); if (bmax.z > cmax.z) cmax.z = static_cast<float>(bmax.z); AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z); AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z); } } } } if (step == 0) { // Set common attributes MPlug plug; if (AiNodeIs(atNode, "procedural")) { // Note: it is up to the procedural to properly forward (or not) those parameters to the node // it creates if (attrsSet.find("subdiv_type") == attrsEnd) { plug = FindMayaPlug("subdiv_type"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivType"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_type", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_type", plug.asInt()); } } if (attrsSet.find("subdiv_iterations") == attrsEnd) { plug = FindMayaPlug("subdiv_iterations"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivIterations"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_iterations", atNode, "constant BYTE")) { AiNodeSetByte(atNode, "subdiv_iterations", plug.asInt()); } } if (attrsSet.find("subdiv_adaptive_metric") == attrsEnd) { plug = FindMayaPlug("subdiv_adaptive_metric"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivAdaptiveMetric"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_adaptive_metric", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_adaptive_metric", plug.asInt()); } } if (attrsSet.find("subdiv_pixel_error") == attrsEnd) { plug = FindMayaPlug("subdiv_pixel_error"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivPixelError"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_pixel_error", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "subdiv_pixel_error", plug.asFloat()); } } if (attrsSet.find("subdiv_dicing_camera") == attrsEnd) { plug = FindMayaPlug("subdiv_dicing_camera"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivDicingCamera"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_dicing_camera", atNode, "constant NODE")) { AtNode *cameraNode = NULL; MPlugArray plugs; plug.connectedTo(plugs, true, false); if (plugs.length() == 1) { MFnDagNode camDag(plugs[0].node()); MDagPath camPath; if (camDag.getPath(camPath) == MS::kSuccess) { cameraNode = ExportDagPath(camPath); } } AiNodeSetPtr(atNode, "subdiv_dicing_camera", cameraNode); } } if (attrsSet.find("subdiv_uv_smoothing") == attrsEnd) { plug = FindMayaPlug("subdiv_uv_smoothing"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivUvSmoothing"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_uv_smoothing", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_uv_smoothing", plug.asInt()); } } if (attrsSet.find("subdiv_smooth_derivs") == attrsEnd) { plug = FindMayaPlug("aiSubdivSmoothDerivs"); if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_smooth_derivs", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "subdiv_smooth_derivs", plug.asBool()); } } if (attrsSet.find("smoothing") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("smoothShading"); if (!plug.isNull() && HasParameter(anodeEntry, "smoothing", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "smoothing", plug.asBool()); } } if (attrsSet.find("disp_height") == attrsEnd) { plug = FindMayaPlug("aiDispHeight"); if (!plug.isNull()) { outputDispHeight = true; dispHeight = plug.asFloat(); } } if (attrsSet.find("disp_zero_value") == attrsEnd) { plug = FindMayaPlug("aiDispZeroValue"); if (!plug.isNull()) { outputDispZeroValue = true; dispZeroValue = plug.asFloat(); } } if (attrsSet.find("disp_autobump") == attrsEnd) { plug = FindMayaPlug("aiDispAutobump"); if (!plug.isNull()) { outputDispAutobump = true; dispAutobump = plug.asBool(); } } if (attrsSet.find("disp_padding") == attrsEnd) { plug = FindMayaPlug("aiDispPadding"); if (!plug.isNull()) { outputDispPadding = true; dispPadding = MAX(dispPadding, plug.asFloat()); } } // Set diplacement shader if (attrsSet.find("disp_map") == attrsEnd) { if (masterShadingEngine.object() != MObject::kNullObj) { MPlugArray shaderConns; MPlug shaderPlug = masterShadingEngine.findPlug("displacementShader"); shaderPlug.connectedTo(shaderConns, true, false); if (shaderConns.length() > 0) { MFnDependencyNode dispNode(shaderConns[0].node()); plug = dispNode.findPlug("aiDisplacementPadding"); if (!plug.isNull()) { outputDispPadding = true; dispPadding = MAX(dispPadding, plug.asFloat()); } plug = dispNode.findPlug("aiDisplacementAutoBump"); if (!plug.isNull()) { outputDispAutobump = true; dispAutobump = dispAutobump || plug.asBool(); } if (HasParameter(anodeEntry, "disp_map", atNode, "constant ARRAY NODE")) { AtNode *dispImage = ExportNode(shaderConns[0]); AiNodeSetArray(atNode, "disp_map", AiArrayConvert(1, 1, AI_TYPE_NODE, &dispImage)); } } } } if (outputDispHeight && HasParameter(anodeEntry, "disp_height", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_height", dispHeight); } if (outputDispZeroValue && HasParameter(anodeEntry, "disp_zero_value", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_zero_value", dispZeroValue); } if (outputDispPadding && HasParameter(anodeEntry, "disp_padding", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_padding", dispPadding); } if (outputDispAutobump && HasParameter(anodeEntry, "disp_autobump", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "disp_autobump", dispAutobump); } // Old point based SSS parameter if (attrsSet.find("sss_sample_distribution") == attrsEnd) { plug = FindMayaPlug("sss_sample_distribution"); if (plug.isNull()) { plug = FindMayaPlug("aiSssSampleDistribution"); } if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_distribution", atNode, "constant INT")) { AiNodeSetInt(atNode, "sss_sample_distribution", plug.asInt()); } } // Old point based SSS parameter if (attrsSet.find("sss_sample_spacing") == attrsEnd) { plug = FindMayaPlug("sss_sample_spacing"); if (plug.isNull()) { plug = FindMayaPlug("aiSssSampleSpacing"); } if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_spacing", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "sss_sample_spacing", plug.asFloat()); } } if (attrsSet.find("min_pixel_width") == attrsEnd) { plug = FindMayaPlug("aiMinPixelWidth"); if (!plug.isNull() && HasParameter(anodeEntry, "min_pixel_width", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "min_pixel_width", plug.asFloat()); } } if (attrsSet.find("mode") == attrsEnd) { plug = FindMayaPlug("aiMode"); if (!plug.isNull() && HasParameter(anodeEntry, "mode", atNode, "constant INT")) { AiNodeSetInt(atNode, "mode", plug.asShort()); } } if (attrsSet.find("basis") == attrsEnd) { plug = FindMayaPlug("aiBasis"); if (!plug.isNull() && HasParameter(anodeEntry, "basis", atNode, "constant INT")) { AiNodeSetInt(atNode, "basis", plug.asShort()); } } } if (AiNodeIs(atNode, "ginstance")) { if (attrsSet.find("node") == attrsEnd) { AiNodeSetPtr(atNode, "node", m_masterNode); } if (attrsSet.find("inherit_xform") == attrsEnd) { AiNodeSetBool(atNode, "inherit_xform", false); } } else { // box or procedural if (attrsSet.find("step_size") == attrsEnd) { plug = FindMayaPlug("step_size"); if (plug.isNull()) { plug = FindMayaPlug("aiStepSize"); } if (!plug.isNull() && HasParameter(anodeEntry, "step_size", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "step_size", plug.asFloat()); } } } if (attrsSet.find("sidedness") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("doubleSided"); if (!plug.isNull() && HasParameter(anodeEntry, "sidedness", atNode, "constant BYTE")) { AiNodeSetByte(atNode, "sidedness", plug.asBool() ? AI_RAY_ALL : 0); // Only set invert_normals if doubleSided attribute could be found if (!plug.asBool() && attrsSet.find("invert_normals") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("opposite"); if (!plug.isNull() && HasParameter(anodeEntry, "invert_normals", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "invert_normals", plug.asBool()); } } } } if (attrsSet.find("receive_shadows") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("receiveShadows"); if (!plug.isNull() && HasParameter(anodeEntry, "receive_shadows", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "receive_shadows", plug.asBool()); } } if (attrsSet.find("self_shadows") == attrsEnd) { plug = FindMayaPlug("self_shadows"); if (plug.isNull()) { plug = FindMayaPlug("aiSelfShadows"); } if (!plug.isNull() && HasParameter(anodeEntry, "self_shadows", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "self_shadows", plug.asBool()); } } if (attrsSet.find("opaque") == attrsEnd) { plug = FindMayaPlug("opaque"); if (plug.isNull()) { plug = FindMayaPlug("aiOpaque"); } if (!plug.isNull() && HasParameter(anodeEntry, "opaque", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "opaque", plug.asBool()); } } if (attrsSet.find("visibility") == attrsEnd) { if (HasParameter(anodeEntry, "visibility", atNode, "constant BYTE")) { int visibility = AI_RAY_ALL; // Use maya shape built-in attribute plug = FindMayaPlug("castsShadows"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_SHADOW; } // Use maya shape built-in attribute plug = FindMayaPlug("primaryVisibility"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_CAMERA; } // Use maya shape built-in attribute plug = FindMayaPlug("visibleInReflections"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_REFLECTED; } // Use maya shape built-in attribute plug = FindMayaPlug("visibleInRefractions"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_REFRACTED; } plug = FindMayaPlug("diffuse_visibility"); if (plug.isNull()) { plug = FindMayaPlug("aiVisibleInDiffuse"); } if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_DIFFUSE; } plug = FindMayaPlug("glossy_visibility"); if (plug.isNull()) { plug = FindMayaPlug("aiVisibleInGlossy"); } if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_GLOSSY; } AiNodeSetByte(atNode, "visibility", visibility & 0xFF); } } if (attrsSet.find("sss_setname") == attrsEnd) { plug = FindMayaPlug("aiSssSetname"); if (!plug.isNull() && plug.asString().length() > 0) { if (HasParameter(anodeEntry, "sss_setname", atNode, "constant STRING")) { AiNodeSetStr(atNode, "sss_setname", plug.asString().asChar()); } } } // Set surface shader if (HasParameter(anodeEntry, "shader", atNode, "constant NODE")) { if (attrsSet.find("shader") == attrsEnd) { if (shadingEngine.object() != MObject::kNullObj) { AtNode *shader = ExportNode(shadingEngine.findPlug("message")); if (shader != NULL) { const AtNodeEntry *entry = AiNodeGetNodeEntry(shader); if (AiNodeEntryGetType(entry) != AI_NODE_SHADER) { MGlobal::displayWarning("[mtoaScriptedTranslators] Node generated from \"" + shadingEngine.name() + "\" of type " + shadingEngine.typeName() + " for shader is not a shader but a " + MString(AiNodeEntryGetTypeName(entry))); } else { AiNodeSetPtr(atNode, "shader", shader); if (AiNodeLookUpUserParameter(atNode, "mtoa_shading_groups") == 0) { AiNodeDeclare(atNode, "mtoa_shading_groups", "constant ARRAY NODE"); AiNodeSetArray(atNode, "mtoa_shading_groups", AiArrayConvert(1, 1, AI_TYPE_NODE, &shader)); } } } } } } } ExportLightLinking(atNode); MPlug plug = FindMayaPlug("aiTraceSets"); if (!plug.isNull()) { ExportTraceSets(atNode, plug); } // Call cleanup command on last export step if (!IsMotionBlurEnabled() || !IsLocalMotionBlurEnabled() || int(step) >= (int(GetNumMotionSteps()) - 1)) { if (HasParameter(anodeEntry, "disp_padding", atNode)) { float padding = AiNodeGetFlt(atNode, "disp_padding"); AtPoint cmin = AiNodeGetPnt(atNode, "min"); AtPoint cmax = AiNodeGetPnt(atNode, "max"); cmin.x -= padding; cmin.y -= padding; cmin.z -= padding; cmax.x += padding; cmax.y += padding; cmax.z += padding; AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z); AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z); } if (cleanupCmd != "") { command = cleanupCmd += "((\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), "; if (!m_masterNode) { command += "None)"; } else { command += "(\"" + GetMasterInstance().partialPathName() + "\", \""; command += AiNodeGetName(m_masterNode); command += "\"))"; } status = MGlobal::executePythonCommand(command); if (!status) { AiMsgError("[mtoa.scriptedTranslators] Failed to cleanup node \"%s\".", node.name().asChar()); } } } }
// This method inspects the JSON blob stored in the 'USD_UserExportedAttributesJson' // attribute on the Maya node at dagPath and exports any attributes specified // there onto usdPrim at time usdTime. The JSON should contain an object that // maps Maya attribute names to other JSON objects that contain metadata about // how to export the attribute into USD. For example: // // { // "myMayaAttributeOne": { // }, // "myMayaAttributeTwo": { // "usdAttrName": "my:namespace:attributeTwo" // } // } // // If the attribute metadata contains a value for "usdAttrName", the attribute // will be given that name in USD. Otherwise, the Maya attribute name will be // used. Maya attributes in the JSON will be processed in sorted order, and any // USD attribute name collisions will be resolved by using the first attribute // visited and warning about subsequent attribute tags. // bool PxrUsdMayaWriteUtil::WriteUserExportedAttributes( const MDagPath& dagPath, const UsdPrim& usdPrim, const UsdTimeCode& usdTime) { MStatus status; MFnDependencyNode depFn(dagPath.node()); MPlug exportedAttrsJsonPlug = depFn.findPlug( _tokens->USD_UserExportedAttributesJson.GetText(), true, &status); if (status != MS::kSuccess || exportedAttrsJsonPlug.isNull()) { // No attributes specified for export on this node. return false; } std::string exportedAttrsJsonString(exportedAttrsJsonPlug.asString().asChar()); if (exportedAttrsJsonString.empty()) { return false; } JsParseError jsError; JsValue jsValue = JsParseString(exportedAttrsJsonString, &jsError); if (not jsValue) { MString errorMsg(TfStringPrintf( "Failed to parse USD exported attributes JSON on node at dagPath '%s'" " at line %d, column %d: %s", dagPath.fullPathName().asChar(), jsError.line, jsError.column, jsError.reason.c_str()).c_str()); MGlobal::displayError(errorMsg); return false; } // Maintain a set of USD attribute names that have been processed. If an // attribute is multiply-defined, we'll use the first tag encountered and // issue warnings for the subsequent definitions. JsObject is really just a // std::map, so we'll be considering attributes in sorted order. std::set<std::string> exportedUsdAttrNames; JsObject exportedAttrs = jsValue.GetObject(); for (JsObject::const_iterator iter = exportedAttrs.begin(); iter != exportedAttrs.end(); ++iter) { const std::string mayaAttrName = iter->first; const MPlug attrPlug = depFn.findPlug(mayaAttrName.c_str(), true, &status); if (status != MS::kSuccess || attrPlug.isNull()) { MString errorMsg(TfStringPrintf( "Could not find attribute '%s' for USD export on node at dagPath '%s'", mayaAttrName.c_str(), dagPath.fullPathName().asChar()).c_str()); MGlobal::displayError(errorMsg); continue; } const JsObject attrMetadata = iter->second.GetObject(); // Check the metadata to see if the USD attribute name should be // different than the Maya attribute name. std::string usdAttrName = mayaAttrName; JsObject::const_iterator usdAttrValueIter = attrMetadata.find(_tokens->usdAttrName); if (usdAttrValueIter != attrMetadata.end()) { std::string nameValue = usdAttrValueIter->second.GetString(); if (not nameValue.empty()) { usdAttrName = nameValue; } } const auto& insertIter = exportedUsdAttrNames.insert(usdAttrName); if (not insertIter.second) { MString errorMsg(TfStringPrintf( "Ignoring duplicate USD export tag for attribute '%s' on node at dagPath '%s'", usdAttrName.c_str(), dagPath.fullPathName().asChar()).c_str()); MGlobal::displayError(errorMsg); continue; } UsdAttribute usdAttr = PxrUsdMayaWriteUtil::GetOrCreateUsdAttr( attrPlug, usdPrim, usdAttrName, true); if (usdAttr) { PxrUsdMayaWriteUtil::SetUsdAttr(attrPlug, usdAttr, usdTime); } } return true; }
virtual void ExportUserAttrs( AtNode *node ) { // Get the optional attributes and export them as user vars MPlug plug = FindMayaObjectPlug( "shaderAssignation" ); if( !plug.isNull() ) { AiNodeDeclare( node, "shaderAssignation", "constant STRING" ); AiNodeSetStr( node, "shaderAssignation", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "displacementAssignation" ); if( !plug.isNull() ) { AiNodeDeclare( node, "displacementAssignation", "constant STRING" ); AiNodeSetStr( node, "displacementAssignation", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "shaderAssignmentfile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "shaderAssignmentfile", "constant STRING" ); AiNodeSetStr( node, "shaderAssignmentfile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "overrides" ); if( !plug.isNull() ) { AiNodeDeclare( node, "overrides", "constant STRING" ); AiNodeSetStr( node, "overrides", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "overridefile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "overridefile", "constant STRING" ); AiNodeSetStr( node, "overridefile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "userAttributes" ); if( !plug.isNull() ) { AiNodeDeclare( node, "userAttributes", "constant STRING" ); AiNodeSetStr( node, "userAttributes", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "userAttributesfile" ); if( !plug.isNull() ) { AiNodeDeclare( node, "userAttributesfile", "constant STRING" ); AiNodeSetStr( node, "userAttributesfile", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "skipJson" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipJson", "constant BOOL" ); AiNodeSetBool( node, "skipJson", plug.asBool() ); } plug = FindMayaObjectPlug( "skipShaders" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipShaders", "constant BOOL" ); AiNodeSetBool( node, "skipShaders", plug.asBool() ); } plug = FindMayaObjectPlug( "skipOverrides" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipOverrides", "constant BOOL" ); AiNodeSetBool( node, "skipOverrides", plug.asBool() ); } plug = FindMayaObjectPlug( "skipUserAttributes" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipUserAttributes", "constant BOOL" ); AiNodeSetBool( node, "skipUserAttributes", plug.asBool() ); } plug = FindMayaObjectPlug( "skipDisplacements" ); if( !plug.isNull() ) { AiNodeDeclare( node, "skipDisplacements", "constant BOOL" ); AiNodeSetBool( node, "skipDisplacements", plug.asBool() ); } plug = FindMayaObjectPlug( "objectPattern" ); if( !plug.isNull() ) { AiNodeDeclare( node, "objectPattern", "constant STRING" ); AiNodeSetStr( node, "objectPattern", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "assShaders" ); if( !plug.isNull() ) { AiNodeDeclare( node, "assShaders", "constant STRING" ); AiNodeSetStr( node, "assShaders", plug.asString().asChar() ); } plug = FindMayaObjectPlug( "radiusPoint" ); if( !plug.isNull() ) { AiNodeDeclare( node, "radiusPoint", "constant FLOAT" ); AiNodeSetFlt( node, "radiusPoint", plug.asFloat() ); } plug = FindMayaObjectPlug( "radiusCurve" ); if( !plug.isNull() ) { AiNodeDeclare( node, "radiusCurve", "constant FLOAT" ); AiNodeSetFlt( node, "radiusCurve", plug.asFloat() ); } plug = FindMayaObjectPlug( "modeCurve" ); if( !plug.isNull() ) { AiNodeDeclare( node, "modeCurve", "constant STRING" ); int modeCurveInt = plug.asInt(); if (modeCurveInt == 1) AiNodeSetStr(node, "modeCurve", "thick"); else if (modeCurveInt == 2) AiNodeSetStr(node, "modeCurve", "oriented"); else AiNodeSetStr(node, "modeCurve", "ribbon"); } plug = FindMayaObjectPlug( "scaleVelocity" ); if( !plug.isNull() ) { AiNodeDeclare( node, "scaleVelocity", "constant FLOAT" ); AiNodeSetFlt( node, "scaleVelocity", plug.asFloat() ); } }
virtual void ExportProcedural( AtNode *node ) { // do basic node export ExportMatrix( node, 0 ); // AiNodeSetPtr( node, "shader", arnoldShader(node) ); AiNodeSetInt( node, "visibility", ComputeVisibility() ); MPlug plug = FindMayaObjectPlug( "receiveShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "receive_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiSelfShadows" ); if( !plug.isNull() ) { AiNodeSetBool( node, "self_shadows", plug.asBool() ); } plug = FindMayaObjectPlug( "aiOpaque" ); if( !plug.isNull() ) { AiNodeSetBool( node, "opaque", plug.asBool() ); } // now set the procedural-specific parameters AiNodeSetBool( node, "load_at_init", true ); // just for now so that it can load the shaders at the right time MFnDagNode fnDagNode( m_dagPath ); MBoundingBox bound = fnDagNode.boundingBox(); AiNodeSetPnt( node, "min", bound.min().x-m_dispPadding, bound.min().y-m_dispPadding, bound.min().z-m_dispPadding ); AiNodeSetPnt( node, "max", bound.max().x+m_dispPadding, bound.max().y, bound.max().z+m_dispPadding ); const char *dsoPath = getenv( "ALEMBIC_ARNOLD_PROCEDURAL_PATH" ); AiNodeSetStr( node, "dso", dsoPath ? dsoPath : "bb_AlembicArnoldProcedural.so" ); // Set the parameters for the procedural //abcFile path MString abcFile = fnDagNode.findPlug("cacheFileName").asString().expandEnvironmentVariablesAndTilde(); //object path MString objectPath = fnDagNode.findPlug("cacheGeomPath").asString(); //object pattern MString objectPattern = "*"; plug = FindMayaObjectPlug( "objectPattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { objectPattern = plug.asString(); } } //object pattern MString excludePattern = ""; plug = FindMayaObjectPlug( "excludePattern" ); if (!plug.isNull() ) { if (plug.asString() != "") { excludePattern = plug.asString(); } } float shutterOpen = 0.0; plug = FindMayaObjectPlug( "shutterOpen" ); if (!plug.isNull() ) { shutterOpen = plug.asFloat(); } float shutterClose = 0.0; plug = FindMayaObjectPlug( "shutterClose" ); if (!plug.isNull() ) { shutterClose = plug.asFloat(); } float timeOffset = 0.0; plug = FindMayaObjectPlug( "timeOffset" ); if (!plug.isNull() ) { timeOffset = plug.asFloat(); } int subDIterations = 0; plug = FindMayaObjectPlug( "ai_subDIterations" ); if (!plug.isNull() ) { subDIterations = plug.asInt(); } MString nameprefix = ""; plug = FindMayaObjectPlug( "namePrefix" ); if (!plug.isNull() ) { nameprefix = plug.asString(); } // bool exportFaceIds = fnDagNode.findPlug("exportFaceIds").asBool(); bool makeInstance = true; // always on for now plug = FindMayaObjectPlug( "makeInstance" ); if (!plug.isNull() ) { makeInstance = plug.asBool(); } bool flipv = false; plug = FindMayaObjectPlug( "flipv" ); if (!plug.isNull() ) { flipv = plug.asBool(); } bool invertNormals = false; plug = FindMayaObjectPlug( "invertNormals" ); if (!plug.isNull() ) { invertNormals = plug.asBool(); } short i_subDUVSmoothing = 1; plug = FindMayaObjectPlug( "ai_subDUVSmoothing" ); if (!plug.isNull() ) { i_subDUVSmoothing = plug.asShort(); } MString subDUVSmoothing; switch (i_subDUVSmoothing) { case 0: subDUVSmoothing = "pin_corners"; break; case 1: subDUVSmoothing = "pin_borders"; break; case 2: subDUVSmoothing = "linear"; break; case 3: subDUVSmoothing = "smooth"; break; default : subDUVSmoothing = "pin_corners"; break; } MTime curTime = MAnimControl::currentTime(); // fnDagNode.findPlug("time").getValue( frame ); // MTime frameOffset; // fnDagNode.findPlug("timeOffset").getValue( frameOffset ); float time = curTime.as(MTime::kFilm)+timeOffset; MString argsString; if (objectPath != "|"){ argsString += "-objectpath "; // convert "|" to "/" argsString += MString(replace_all(objectPath,"|","/").c_str()); } if (objectPattern != "*"){ argsString += "-pattern "; argsString += objectPattern; } if (excludePattern != ""){ argsString += "-excludepattern "; argsString += excludePattern; } if (shutterOpen != 0.0){ argsString += " -shutteropen "; argsString += shutterOpen; } if (shutterClose != 0.0){ argsString += " -shutterclose "; argsString += shutterClose; } if (subDIterations != 0){ argsString += " -subditerations "; argsString += subDIterations; argsString += " -subduvsmoothing "; argsString += subDUVSmoothing; } if (makeInstance){ argsString += " -makeinstance "; } if (nameprefix != ""){ argsString += " -nameprefix "; argsString += nameprefix; } if (flipv){ argsString += " -flipv "; } if (invertNormals){ argsString += " -invertNormals "; } argsString += " -filename "; argsString += abcFile; argsString += " -frame "; argsString += time; if (m_displaced){ argsString += " -disp_map "; argsString += AiNodeGetName(m_dispNode); } AiNodeSetStr(node, "data", argsString.asChar()); ExportUserAttrs(node); // Export light linking per instance ExportLightLinking(node); }
/* static */ std::vector<UsdMayaUserTaggedAttribute> UsdMayaUserTaggedAttribute::GetUserTaggedAttributesForNode( const MObject& mayaNode) { std::vector<UsdMayaUserTaggedAttribute> result; MStatus status; const MFnDependencyNode depNodeFn(mayaNode, &status); if (status != MS::kSuccess) { return result; } const MPlug exportedAttrsJsonPlug = depNodeFn.findPlug( _tokens->USD_UserExportedAttributesJson.GetText(), true, &status); if (status != MS::kSuccess || exportedAttrsJsonPlug.isNull()) { // No attributes specified for export on this node. return result; } const std::string exportedAttrsJsonString( exportedAttrsJsonPlug.asString().asChar()); if (exportedAttrsJsonString.empty()) { return result; } JsParseError jsError; const JsValue jsValue = JsParseString(exportedAttrsJsonString, &jsError); if (!jsValue) { TF_RUNTIME_ERROR( "Failed to parse USD exported attributes JSON on node '%s' " "at line %d, column %d: %s", UsdMayaUtil::GetMayaNodeName(mayaNode).c_str(), jsError.line, jsError.column, jsError.reason.c_str()); return result; } // If an attribute is multiply-defined, we'll use the first tag encountered // and issue warnings for the subsequent definitions. JsObject is really // just a std::map, so we'll be considering attributes in sorted order. std::set<std::string> processedAttributeNames; const JsObject& exportedAttrs = jsValue.GetJsObject(); for (const auto& exportedAttr : exportedAttrs) { const std::string mayaAttrName = exportedAttr.first; const MPlug attrPlug = depNodeFn.findPlug(mayaAttrName.c_str(), true, &status); if (status != MS::kSuccess || attrPlug.isNull()) { TF_RUNTIME_ERROR( "Could not find attribute '%s' for USD export on node '%s'", mayaAttrName.c_str(), UsdMayaUtil::GetMayaNodeName(mayaNode).c_str()); continue; } const JsObject& attrMetadata = exportedAttr.second.GetJsObject(); // Check if this is a particular type of attribute (e.g. primvar or // usdRi attribute). If we don't recognize the type specified, we'll // fall back to a regular USD attribute. const TfToken usdAttrType( _GetExportAttributeMetadata(attrMetadata, _tokens->usdAttrType)); // Check whether an interpolation type was specified. This is only // relevant for primvars. const TfToken interpolation( _GetExportAttributeMetadata(attrMetadata, UsdGeomTokens->interpolation)); // Check whether it was specified that the double precision Maya // attribute type should be mapped to a single precision USD type. // If it wasn't specified, use the fallback value. const bool translateMayaDoubleToUsdSinglePrecision( _GetExportAttributeMetadata( attrMetadata, _tokens->translateMayaDoubleToUsdSinglePrecision, GetFallbackTranslateMayaDoubleToUsdSinglePrecision())); // Check whether the USD attribute name should be different than the // Maya attribute name. std::string usdAttrName = _GetExportAttributeMetadata(attrMetadata, _tokens->usdAttrName); if (usdAttrName.empty()) { const auto& tokens = UsdMayaUserTaggedAttributeTokens; if (usdAttrType == tokens->USDAttrTypePrimvar || usdAttrType == tokens->USDAttrTypeUsdRi) { // Primvars and UsdRi attributes will be given a type-specific // namespace, so just use the Maya attribute name. usdAttrName = mayaAttrName; } else { // For regular USD attributes, when no name was specified we // prepend the userProperties namespace to the Maya attribute // name to get the USD attribute name. usdAttrName = _tokens->UserPropertiesNamespace.GetString() + mayaAttrName; } } const auto& insertIter = processedAttributeNames.emplace(usdAttrName); if (!insertIter.second) { TF_RUNTIME_ERROR( "Ignoring duplicate USD export tag for attribute '%s' " "on node '%s'", usdAttrName.c_str(), UsdMayaUtil::GetMayaNodeName(mayaNode).c_str()); continue; } result.emplace_back(attrPlug, usdAttrName, usdAttrType, interpolation, translateMayaDoubleToUsdSinglePrecision); } return result; }
MStatus AbcExport::doIt(const MArgList & args) { try { MStatus status; MTime oldCurTime = MAnimControl::currentTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } bool verbose = argData.isFlagSet("verbose"); // If skipFrame is true, when going through the playback range of the // scene, as much frames are skipped when possible. This could cause // a problem for, time dependent solutions like // particle system / hair simulation bool skipFrame = true; if (argData.isFlagSet("dontSkipUnwrittenFrames")) skipFrame = false; double startEvaluationTime = DBL_MAX; if (argData.isFlagSet("preRollStartFrame")) { double startAt = 0.0; argData.getFlagArgument("preRollStartFrame", 0, startAt); startEvaluationTime = startAt; } unsigned int jobSize = argData.numberOfFlagUses("jobArg"); if (jobSize == 0) return status; // the frame range we will be iterating over for all jobs, // includes frames which are not skipped and the startAt offset std::set<double> allFrameRange; // this will eventually hold only the animated jobs. // its a list because we will be removing jobs from it std::list < AbcWriteJobPtr > jobList; for (unsigned int jobIndex = 0; jobIndex < jobSize; jobIndex++) { JobArgs jobArgs; MArgList jobArgList; argData.getFlagArgumentList("jobArg", jobIndex, jobArgList); MString jobArgsStr = jobArgList.asString(0); MStringArray jobArgsArray; { // parse the job arguments // e.g. -perFrameCallbackMel "print \"something\"" will be splitted to // [0] -perFrameCallbackMel // [1] print "something" enum State { kArgument, // parsing an argument (not quoted) kDoubleQuotedString, // parsing a double quoted string kSingleQuotedString, // parsing a single quoted string }; State state = kArgument; MString stringBuffer; for (unsigned int charIdx = 0; charIdx < jobArgsStr.numChars(); charIdx++) { MString ch = jobArgsStr.substringW(charIdx, charIdx); switch (state) { case kArgument: if (ch == " ") { // space terminates the current argument if (stringBuffer.length() > 0) { jobArgsArray.append(stringBuffer); stringBuffer.clear(); } // goto another argument state = kArgument; } else if (ch == "\"") { if (stringBuffer.length() > 0) { // double quote is part of the argument stringBuffer += ch; } else { // goto double quoted string state = kDoubleQuotedString; } } else if (ch == "'") { if (stringBuffer.length() > 0) { // single quote is part of the argument stringBuffer += ch; } else { // goto single quoted string state = kSingleQuotedString; } } else { stringBuffer += ch; } break; case kDoubleQuotedString: // double quote terminates the current string if (ch == "\"") { jobArgsArray.append(stringBuffer); stringBuffer.clear(); state = kArgument; } else if (ch == "\\") { // escaped character MString nextCh = (++charIdx < jobArgsStr.numChars()) ? jobArgsStr.substringW(charIdx, charIdx) : "\\"; if (nextCh == "n") stringBuffer += "\n"; else if (nextCh == "t") stringBuffer += "\t"; else if (nextCh == "r") stringBuffer += "\r"; else if (nextCh == "\\") stringBuffer += "\\"; else if (nextCh == "'") stringBuffer += "'"; else if (nextCh == "\"") stringBuffer += "\""; else stringBuffer += nextCh; } else { stringBuffer += ch; } break; case kSingleQuotedString: // single quote terminates the current string if (ch == "'") { jobArgsArray.append(stringBuffer); stringBuffer.clear(); state = kArgument; } else if (ch == "\\") { // escaped character MString nextCh = (++charIdx < jobArgsStr.numChars()) ? jobArgsStr.substringW(charIdx, charIdx) : "\\"; if (nextCh == "n") stringBuffer += "\n"; else if (nextCh == "t") stringBuffer += "\t"; else if (nextCh == "r") stringBuffer += "\r"; else if (nextCh == "\\") stringBuffer += "\\"; else if (nextCh == "'") stringBuffer += "'"; else if (nextCh == "\"") stringBuffer += "\""; else stringBuffer += nextCh; } else { stringBuffer += ch; } break; } } // the rest of the argument if (stringBuffer.length() > 0) { jobArgsArray.append(stringBuffer); } } // the frame range within this job std::vector< FrameRangeArgs > frameRanges(1); frameRanges.back().startTime = oldCurTime.value(); frameRanges.back().endTime = oldCurTime.value(); frameRanges.back().strideTime = 1.0; bool hasRange = false; bool hasRoot = false; bool sampleGeo = true; // whether or not to subsample geometry std::string fileName; bool asOgawa = true; unsigned int numJobArgs = jobArgsArray.length(); for (unsigned int i = 0; i < numJobArgs; ++i) { MString arg = jobArgsArray[i]; arg.toLowerCase(); if (arg == "-f" || arg == "-file") { if (i+1 >= numJobArgs) { MGlobal::displayError("File incorrectly specified."); return MS::kFailure; } fileName = jobArgsArray[++i].asChar(); } else if (arg == "-fr" || arg == "-framerange") { if (i+2 >= numJobArgs || !jobArgsArray[i+1].isDouble() || !jobArgsArray[i+2].isDouble()) { MGlobal::displayError("Frame Range incorrectly specified."); return MS::kFailure; } // this is not the first -frameRange argument, we are going // to add one more frame range to the frame range array. if (hasRange) { frameRanges.push_back(FrameRangeArgs()); } hasRange = true; frameRanges.back().startTime = jobArgsArray[++i].asDouble(); frameRanges.back().endTime = jobArgsArray[++i].asDouble(); // make sure start frame is smaller or equal to endTime if (frameRanges.back().startTime > frameRanges.back().endTime) { std::swap(frameRanges.back().startTime, frameRanges.back().endTime); } } else if (arg == "-frs" || arg == "-framerelativesample") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble()) { MGlobal::displayError( "Frame Relative Sample incorrectly specified."); return MS::kFailure; } frameRanges.back().shutterSamples.insert( jobArgsArray[++i].asDouble()); } else if (arg == "-nn" || arg == "-nonormals") { jobArgs.noNormals = true; } else if (arg == "-pr" || arg == "-preroll") { frameRanges.back().preRoll = true; } else if (arg == "-ro" || arg == "-renderableonly") { jobArgs.excludeInvisible = true; } else if (arg == "-s" || arg == "-step") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble()) { MGlobal::displayError("Step incorrectly specified."); return MS::kFailure; } frameRanges.back().strideTime = jobArgsArray[++i].asDouble(); } else if (arg == "-sl" || arg == "-selection") { jobArgs.useSelectionList = true; } else if (arg == "-sn" || arg == "-stripnamespaces") { if (i+1 >= numJobArgs || !jobArgsArray[i+1].isUnsigned()) { // the strip all namespaces case // so we pick a very LARGE number jobArgs.stripNamespace = 0xffffffff; } else { jobArgs.stripNamespace = jobArgsArray[++i].asUnsigned(); } } else if (arg == "-uv" || arg == "-uvwrite") { jobArgs.writeUVs = true; } else if (arg == "-wcs" || arg == "-writecolorsets") { jobArgs.writeColorSets = true; } else if (arg == "-wfs" || arg == "-writefacesets") { jobArgs.writeFaceSets = true; } else if (arg == "-wfg" || arg == "-wholeframegeo") { sampleGeo = false; } else if (arg == "-ws" || arg == "-worldspace") { jobArgs.worldSpace = true; } else if (arg == "-wuvs" || arg == "-writeuvsets") { jobArgs.writeUVSets = true; } else if (arg == "-wv" || arg == "-writevisibility") { jobArgs.writeVisibility = true; } else if (arg == "-as" || arg == "-autosubd") { jobArgs.autoSubd = true; } else if (arg == "-mfc" || arg == "-melperframecallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "melPerFrameCallback incorrectly specified."); return MS::kFailure; } jobArgs.melPerFrameCallback = jobArgsArray[++i].asChar(); } else if (arg == "-pfc" || arg == "-pythonperframecallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "pythonPerFrameCallback incorrectly specified."); return MS::kFailure; } jobArgs.pythonPerFrameCallback = jobArgsArray[++i].asChar(); } else if (arg == "-mpc" || arg == "-melpostjobcallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "melPostJobCallback incorrectly specified."); return MS::kFailure; } jobArgs.melPostCallback = jobArgsArray[++i].asChar(); } else if (arg == "-ppc" || arg == "-pythonpostjobcallback") { if (i+1 >= numJobArgs) { MGlobal::displayError( "pythonPostJobCallback incorrectly specified."); return MS::kFailure; } jobArgs.pythonPostCallback = jobArgsArray[++i].asChar(); } // geomArbParams - attribute filtering stuff else if (arg == "-atp" || arg == "-attrprefix") { if (i+1 >= numJobArgs) { MGlobal::displayError( "attrPrefix incorrectly specified."); return MS::kFailure; } jobArgs.prefixFilters.push_back(jobArgsArray[++i].asChar()); } else if (arg == "-a" || arg == "-attr") { if (i+1 >= numJobArgs) { MGlobal::displayError( "attr incorrectly specified."); return MS::kFailure; } jobArgs.attribs.insert(jobArgsArray[++i].asChar()); } // userProperties - attribute filtering stuff else if (arg == "-uatp" || arg == "-userattrprefix") { if (i+1 >= numJobArgs) { MGlobal::displayError( "userAttrPrefix incorrectly specified."); return MS::kFailure; } jobArgs.userPrefixFilters.push_back(jobArgsArray[++i].asChar()); } else if (arg == "-u" || arg == "-userattr") { if (i+1 >= numJobArgs) { MGlobal::displayError( "userAttr incorrectly specified."); return MS::kFailure; } jobArgs.userAttribs.insert(jobArgsArray[++i].asChar()); } else if (arg == "-rt" || arg == "-root") { if (i+1 >= numJobArgs) { MGlobal::displayError( "root incorrectly specified."); return MS::kFailure; } hasRoot = true; MString root = jobArgsArray[++i]; MSelectionList sel; if (sel.add(root) != MS::kSuccess) { MString warn = root; warn += " could not be select, skipping."; MGlobal::displayWarning(warn); continue; } unsigned int numRoots = sel.length(); for (unsigned int j = 0; j < numRoots; ++j) { MDagPath path; if (sel.getDagPath(j, path) != MS::kSuccess) { MString warn = path.fullPathName(); warn += " (part of "; warn += root; warn += " ) not a DAG Node, skipping."; MGlobal::displayWarning(warn); continue; } jobArgs.dagPaths.insert(path); } } else if (arg == "-ef" || arg == "-eulerfilter") { jobArgs.filterEulerRotations = true; } else if (arg == "-df" || arg == "-dataformat") { if (i+1 >= numJobArgs) { MGlobal::displayError( "dataFormat incorrectly specified."); return MS::kFailure; } MString dataFormat = jobArgsArray[++i]; dataFormat.toLowerCase(); if (dataFormat == "hdf") { asOgawa = false; } else if (dataFormat == "ogawa") { asOgawa = true; } } else { MString warn = "Ignoring unsupported flag: "; warn += jobArgsArray[i]; MGlobal::displayWarning(warn); } } // for i if (fileName == "") { MString error = "-file not specified."; MGlobal::displayError(error); return MS::kFailure; } { MString fileRule, expandName; MString alembicFileRule = "alembicCache"; MString alembicFilePath = "cache/alembic"; MString queryFileRuleCmd; queryFileRuleCmd.format("workspace -q -fre \"^1s\"", alembicFileRule); MString queryFolderCmd; queryFolderCmd.format("workspace -en `workspace -q -fre \"^1s\"`", alembicFileRule); // query the file rule for alembic cache MGlobal::executeCommand(queryFileRuleCmd, fileRule); if (fileRule.length() > 0) { // we have alembic file rule, query the folder MGlobal::executeCommand(queryFolderCmd, expandName); } else { // alembic file rule does not exist, create it MString addFileRuleCmd; addFileRuleCmd.format("workspace -fr \"^1s\" \"^2s\"", alembicFileRule, alembicFilePath); MGlobal::executeCommand(addFileRuleCmd); // save the workspace. maya may discard file rules on exit MGlobal::executeCommand("workspace -s"); // query the folder MGlobal::executeCommand(queryFolderCmd, expandName); } // resolve the expanded file rule if (expandName.length() == 0) { expandName = alembicFilePath; } // get the path to the alembic file rule MFileObject directory; directory.setRawFullName(expandName); MString directoryName = directory.resolvedFullName(); // make sure the cache folder exists if (!directory.exists()) { // create the cache folder MString createFolderCmd; createFolderCmd.format("sysFile -md \"^1s\"", directoryName); MGlobal::executeCommand(createFolderCmd); } // resolve the relative path MFileObject absoluteFile; absoluteFile.setRawFullName(fileName.c_str()); #if MAYA_API_VERSION < 201300 if (absoluteFile.resolvedFullName() != absoluteFile.expandedFullName()) { #else if (!MFileObject::isAbsolutePath(fileName.c_str())) { #endif // this is a relative path MString absoluteFileName = directoryName + "/" + fileName.c_str(); absoluteFile.setRawFullName(absoluteFileName); fileName = absoluteFile.resolvedFullName().asChar(); } else { fileName = absoluteFile.resolvedFullName().asChar(); } // check the path must exist before writing MFileObject absoluteFilePath; absoluteFilePath.setRawFullName(absoluteFile.path()); if (!absoluteFilePath.exists()) { MString error; error.format("Path ^1s does not exist!", absoluteFilePath.resolvedFullName()); MGlobal::displayError(error); return MS::kFailure; } // check the file is used by any AlembicNode in the scene MItDependencyNodes dgIter(MFn::kPluginDependNode); for (; !dgIter.isDone(); dgIter.next()) { MFnDependencyNode alembicNode(dgIter.thisNode()); if (alembicNode.typeName() != "AlembicNode") { continue; } MPlug abcFilePlug = alembicNode.findPlug("abc_File"); if (abcFilePlug.isNull()) { continue; } MFileObject alembicFile; alembicFile.setRawFullName(abcFilePlug.asString()); if (!alembicFile.exists()) { continue; } if (alembicFile.resolvedFullName() == absoluteFile.resolvedFullName()) { MString error = "Can't export to an Alembic file which is in use."; MGlobal::displayError(error); return MS::kFailure; } } std::ofstream ofs(fileName.c_str()); if (!ofs.is_open()) { MString error = MString("Can't write to file: ") + fileName.c_str(); MGlobal::displayError(error); return MS::kFailure; } ofs.close(); } // if -frameRelativeSample argument is not specified for a frame range, // we are assuming a -frameRelativeSample 0.0 for (std::vector<FrameRangeArgs>::iterator range = frameRanges.begin(); range != frameRanges.end(); ++range) { if (range->shutterSamples.empty()) range->shutterSamples.insert(0.0); } if (jobArgs.prefixFilters.empty()) { jobArgs.prefixFilters.push_back("ABC_"); } // the list of frame ranges for sampling std::vector<FrameRangeArgs> sampleRanges; std::vector<FrameRangeArgs> preRollRanges; for (std::vector<FrameRangeArgs>::const_iterator range = frameRanges.begin(); range != frameRanges.end(); ++range) { if (range->preRoll) preRollRanges.push_back(*range); else sampleRanges.push_back(*range); } // the list of frames written into the abc file std::set<double> geoSamples; std::set<double> transSamples; for (std::vector<FrameRangeArgs>::const_iterator range = sampleRanges.begin(); range != sampleRanges.end(); ++range) { for (double frame = range->startTime; frame <= range->endTime; frame += range->strideTime) { for (std::set<double>::const_iterator shutter = range->shutterSamples.begin(); shutter != range->shutterSamples.end(); ++shutter) { double curFrame = *shutter + frame; if (!sampleGeo) { double intFrame = (double)(int)( curFrame >= 0 ? curFrame + .5 : curFrame - .5); // only insert samples that are close to being an integer if (fabs(curFrame - intFrame) < 1e-4) { geoSamples.insert(curFrame); } } else { geoSamples.insert(curFrame); } transSamples.insert(curFrame); } } if (geoSamples.empty()) { geoSamples.insert(range->startTime); } if (transSamples.empty()) { transSamples.insert(range->startTime); } } bool isAcyclic = false; if (sampleRanges.empty()) { // no frame ranges or all frame ranges are pre-roll ranges hasRange = false; geoSamples.insert(frameRanges.back().startTime); transSamples.insert(frameRanges.back().startTime); } else { // check if the time range is even (cyclic) // otherwise, we will use acyclic // sub frames pattern std::vector<double> pattern( sampleRanges.begin()->shutterSamples.begin(), sampleRanges.begin()->shutterSamples.end()); std::transform(pattern.begin(), pattern.end(), pattern.begin(), std::bind2nd(std::plus<double>(), sampleRanges.begin()->startTime)); // check the frames against the pattern std::vector<double> timeSamples( transSamples.begin(), transSamples.end()); for (size_t i = 0; i < timeSamples.size(); i++) { // next pattern if (i % pattern.size() == 0 && i / pattern.size() > 0) { std::transform(pattern.begin(), pattern.end(), pattern.begin(), std::bind2nd(std::plus<double>(), sampleRanges.begin()->strideTime)); } // pattern mismatch, we use acyclic time sampling type if (timeSamples[i] != pattern[i % pattern.size()]) { isAcyclic = true; break; } } } // the list of frames to pre-roll std::set<double> preRollSamples; for (std::vector<FrameRangeArgs>::const_iterator range = preRollRanges.begin(); range != preRollRanges.end(); ++range) { for (double frame = range->startTime; frame <= range->endTime; frame += range->strideTime) { for (std::set<double>::const_iterator shutter = range->shutterSamples.begin(); shutter != range->shutterSamples.end(); ++shutter) { double curFrame = *shutter + frame; preRollSamples.insert(curFrame); } } if (preRollSamples.empty()) { preRollSamples.insert(range->startTime); } } if (jobArgs.dagPaths.size() > 1) { // check for validity of the DagPath relationships complexity : n^2 util::ShapeSet::const_iterator m, n; util::ShapeSet::const_iterator end = jobArgs.dagPaths.end(); for (m = jobArgs.dagPaths.begin(); m != end; ) { MDagPath path1 = *m; m++; for (n = m; n != end; n++) { MDagPath path2 = *n; if (util::isAncestorDescendentRelationship(path1,path2)) { MString errorMsg = path1.fullPathName(); errorMsg += " and "; errorMsg += path2.fullPathName(); errorMsg += " have an ancestor relationship."; MGlobal::displayError(errorMsg); return MS::kFailure; } } // for n } // for m } // no root is specified, and we aren't using a selection // so we'll try to translate the whole Maya scene by using all // children of the world as roots. else if (!hasRoot && !jobArgs.useSelectionList) { MSelectionList sel; #if MAYA_API_VERSION >= 201100 sel.add("|*", true); #else // older versions of Maya will not be able to find top level nodes // within namespaces sel.add("|*"); #endif unsigned int numRoots = sel.length(); for (unsigned int i = 0; i < numRoots; ++i) { MDagPath path; sel.getDagPath(i, path); jobArgs.dagPaths.insert(path); } } else if (hasRoot && jobArgs.dagPaths.empty()) { MString errorMsg = "No valid root nodes were specified."; MGlobal::displayError(errorMsg); return MS::kFailure; } else if (jobArgs.useSelectionList) { MSelectionList activeList; MGlobal::getActiveSelectionList(activeList); if (activeList.length() == 0) { MString errorMsg = "-selection specified but nothing is actively selected."; MGlobal::displayError(errorMsg); return MS::kFailure; } } AbcA::TimeSamplingPtr transTime, geoTime; if (hasRange) { if (isAcyclic) { // acyclic, uneven time sampling // e.g. [0.8, 1, 1.2], [2.8, 3, 3.2], .. not continuous // [0.8, 1, 1.2], [1.7, 2, 2.3], .. shutter different std::vector<double> samples( transSamples.begin(), transSamples.end()); std::transform(samples.begin(), samples.end(), samples.begin(), std::bind2nd(std::multiplies<double>(), util::spf())); transTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType( AbcA::TimeSamplingType::kAcyclic), samples)); } else { // cyclic, even time sampling between time periods // e.g. [0.8, 1, 1.2], [1.8, 2, 2.2], ... std::vector<double> samples; double startTime = sampleRanges[0].startTime; double strideTime = sampleRanges[0].strideTime; for (std::set<double>::const_iterator shutter = sampleRanges[0].shutterSamples.begin(); shutter != sampleRanges[0].shutterSamples.end(); ++shutter) { samples.push_back((startTime + *shutter) * util::spf()); } if (samples.size() > 1) { Alembic::Util::uint32_t numSamples = static_cast<Alembic::Util::uint32_t>(samples.size()); transTime.reset( new AbcA::TimeSampling(AbcA::TimeSamplingType( numSamples, strideTime * util::spf()), samples)); } // uniform sampling else { transTime.reset(new AbcA::TimeSampling( strideTime * util::spf(), samples[0])); } } } else { // time ranges are not specified transTime.reset(new AbcA::TimeSampling()); } if (sampleGeo || !hasRange) { geoTime = transTime; } else { // sampling geo on whole frames if (isAcyclic) { // acyclic, uneven time sampling std::vector<double> samples( geoSamples.begin(), geoSamples.end()); // one more sample for setup() if (*transSamples.begin() != *geoSamples.begin()) samples.insert(samples.begin(), *transSamples.begin()); std::transform(samples.begin(), samples.end(), samples.begin(), std::bind2nd(std::multiplies<double>(), util::spf())); geoTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType( AbcA::TimeSamplingType::kAcyclic), samples)); } else { double geoStride = sampleRanges[0].strideTime; if (geoStride < 1.0) geoStride = 1.0; double geoStart = *geoSamples.begin() * util::spf(); geoTime.reset(new AbcA::TimeSampling( geoStride * util::spf(), geoStart)); } } AbcWriteJobPtr job(new AbcWriteJob(fileName.c_str(), asOgawa, transSamples, transTime, geoSamples, geoTime, jobArgs)); jobList.push_front(job); // make sure we add additional whole frames, if we arent skipping // the inbetween ones if (!skipFrame && !allFrameRange.empty()) { double localMin = *(transSamples.begin()); std::set<double>::iterator last = transSamples.end(); last--; double localMax = *last; double globalMin = *(allFrameRange.begin()); last = allFrameRange.end(); last--; double globalMax = *last; // if the min of our current frame range is beyond // what we know about, pad a few more frames if (localMin > globalMax) { for (double f = globalMax; f < localMin; f++) { allFrameRange.insert(f); } } // if the max of our current frame range is beyond // what we know about, pad a few more frames if (localMax < globalMin) { for (double f = localMax; f < globalMin; f++) { allFrameRange.insert(f); } } } // right now we just copy over the translation samples since // they are guaranteed to contain all the geometry samples allFrameRange.insert(transSamples.begin(), transSamples.end()); // copy over the pre-roll samples allFrameRange.insert(preRollSamples.begin(), preRollSamples.end()); } // add extra evaluation run up, if necessary if (startEvaluationTime != DBL_MAX && !allFrameRange.empty()) { double firstFrame = *allFrameRange.begin(); for (double f = startEvaluationTime; f < firstFrame; ++f) { allFrameRange.insert(f); } } std::set<double>::iterator it = allFrameRange.begin(); std::set<double>::iterator itEnd = allFrameRange.end(); MComputation computation; computation.beginComputation(); // loop through every frame in the list, if a job has that frame in it's // list of transform or shape frames, then it will write out data and // call the perFrameCallback, if that frame is also the last one it has // to work on then it will also call the postCallback. // If it doesn't have this frame, then it does nothing for (; it != itEnd; it++) { if (verbose) { double frame = *it; MString info; info = frame; MGlobal::displayInfo(info); } MGlobal::viewFrame(*it); std::list< AbcWriteJobPtr >::iterator j = jobList.begin(); std::list< AbcWriteJobPtr >::iterator jend = jobList.end(); while (j != jend) { if (computation.isInterruptRequested()) return MS::kFailure; bool lastFrame = (*j)->eval(*it); if (lastFrame) { j = jobList.erase(j); } else j++; } } computation.endComputation(); // set the time back MGlobal::viewFrame(oldCurTime); return MS::kSuccess; } catch (Alembic::Util::Exception & e) { MString theError("Alembic Exception encountered: "); theError += e.what(); MGlobal::displayError(theError); return MS::kFailure; } catch (std::exception & e) { MString theError("std::exception encountered: "); theError += e.what(); MGlobal::displayError(theError); return MS::kFailure; } }
void CoronaRenderer::defineCamera() { MPoint rot, pos, scale; for(int objId = 0; objId < this->mtco_scene->camList.size(); objId++) { mtco_MayaObject *cam = (mtco_MayaObject *)this->mtco_scene->camList[objId]; if( !this->mtco_scene->isCameraRenderable(cam->mobject) && (!(cam->dagPath == this->mtco_scene->uiCamera))) { continue; } logger.debug(MString("using camera ") + cam->shortName); MFnCamera camera(cam->mobject); MPoint pos, rot, scale; MMatrix camMatrix = cam->transformMatrices[0] * this->mtco_renderGlobals->globalConversionMatrix; getMatrixComponents(camMatrix, pos, rot, scale); Corona::Pos cpos(pos.x, pos.y, pos.z); float focusDistance = 0.0; float fStop = 0.0; float focalLength = 35.0f; bool dof; float horizontalFilmAperture, verticalFilmAperture; float coi = 100.0f; getFloat(MString("horizontalFilmAperture"), camera, horizontalFilmAperture); getFloat(MString("verticalFilmAperture"), camera, verticalFilmAperture); getFloat(MString("focalLength"), camera, focalLength); getBool(MString("depthOfField"), camera, dof); getFloat(MString("focusDistance"), camera, focusDistance); getFloat(MString("fStop"), camera, fStop); getFloat(MString("centerOfInterest"), camera, coi); focusDistance *= this->mtco_renderGlobals->scaleFactor; MPoint coiBase(0,0,-coi); MPoint coiTransform = coiBase * camMatrix; //logger.debug(MString("Center of interest: ") + coi + " transformed " + coiTransform.x + " " + coiTransform.y + " " + coiTransform.z); Corona::Pos center(coiTransform.x, coiTransform.y, coiTransform.z); float fov = 2.0 * atan((horizontalFilmAperture * 0.5f) / (focalLength * 0.03937)); float fovDeg = fov * 57.29578; Corona::AnimatedFloat fieldOfView(fov); //logger.debug(MString("fov ") + fov + " deg: " + fovDeg); //Corona::AnimatedFloat fieldOfView(Corona::DEG_TO_RAD(45.f)); Corona::CameraData cameraData; //cameraData.type cameraData.createPerspective(Corona::AnimatedPos(cpos), Corona::AnimatedPos(center), Corona::AnimatedDir(Corona::Dir::UNIT_Z), fieldOfView); Corona::AnimatedFloat focalDist(focusDistance); cameraData.perspective.focalDist = focalDist; cameraData.perspective.fStop = fStop; cameraData.perspective.filmWidth = this->mtco_renderGlobals->toMillimeters(horizontalFilmAperture * 2.54f * 10.0f); //film width in mm if( dof && this->mtco_renderGlobals->doDof) cameraData.perspective.useDof = true; if (getBoolAttr("mtco_useBokeh", camera, false)) { cameraData.perspective.bokeh.use = true; cameraData.perspective.bokeh.blades = getIntAttr("mtco_blades", camera, 6); cameraData.perspective.bokeh.bladesRotation = getIntAttr("mtco_bladeRotation", camera, 0.0); MPlug bokehBitMapPlug = camera.findPlug("mtco_bokehBitmap"); if (!bokehBitMapPlug.isNull()) { if (bokehBitMapPlug.isConnected()) { MObject bitmapNode = getConnectedInNode(bokehBitMapPlug); if (bitmapNode.hasFn(MFn::kFileTexture)) { MFnDependencyNode bitMapFn(bitmapNode); MPlug texNamePlug = bitMapFn.findPlug("fileTextureName"); if (!texNamePlug.isNull()) { MString fileName = texNamePlug.asString(); logger.debug(MString("Found bokeh bitmap file: ") + fileName); Corona::Bitmap<Corona::Rgb> bokehBitmap; Corona::loadImage(fileName.asChar(), bokehBitmap); cameraData.perspective.bokeh.customShape = bokehBitmap; } } } } } this->context.scene->getCamera() = cameraData; } }
bool PxrUsdMayaWriteUtil::SetUsdAttr( const MPlug &plg, const UsdAttribute& usdAttr, const UsdTimeCode &usdTime) { MStatus status; if (!usdAttr || plg.isNull() ) { return false; } bool isAnimated = plg.isDestination(); if (usdTime.IsDefault() == isAnimated ) { return true; } // Set UsdAttr MObject attrObj = plg.attribute(); if (attrObj.hasFn(MFn::kNumericAttribute)) { MFnNumericAttribute attrNumericFn(attrObj); switch (attrNumericFn.unitType()) { case MFnNumericData::kBoolean: usdAttr.Set(plg.asBool(), usdTime); break; case MFnNumericData::kByte: case MFnNumericData::kChar: usdAttr.Set((int)plg.asChar(), usdTime); break; case MFnNumericData::kShort: usdAttr.Set(int(plg.asShort()), usdTime); break; case MFnNumericData::kInt: usdAttr.Set(int(plg.asInt()), usdTime); break; //case MFnNumericData::kLong: //case MFnNumericData::kAddr: // usdAttr.Set(plg.asInt(), usdTime); // break; case MFnNumericData::kFloat: usdAttr.Set(plg.asFloat(), usdTime); break; case MFnNumericData::kDouble: usdAttr.Set(plg.asDouble(), usdTime); break; case MFnNumericData::k2Short: { short tmp1, tmp2; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2); usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime); break; } case MFnNumericData::k2Int: { int tmp1, tmp2; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2); usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime); break; } //case MFnNumericData::k2Long: case MFnNumericData::k3Short: { short tmp1, tmp2, tmp3; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2, tmp3); usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime); break; } case MFnNumericData::k3Int: { int tmp1, tmp2, tmp3; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2, tmp3); usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime); break; } //case MFnNumericData::k3Long: case MFnNumericData::k2Float: { float tmp1, tmp2; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2); usdAttr.Set(GfVec2f(tmp1, tmp2), usdTime); break; } case MFnNumericData::k3Float: { float tmp1, tmp2, tmp3; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2, tmp3); _SetVec(usdAttr, GfVec3f(tmp1, tmp2, tmp3), usdTime); break; } case MFnNumericData::k2Double: { double tmp1, tmp2; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2); usdAttr.Set(GfVec2d(tmp1, tmp2), usdTime); break; } case MFnNumericData::k3Double: { double tmp1, tmp2, tmp3; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2, tmp3); _SetVec(usdAttr, GfVec3d(tmp1, tmp2, tmp3), usdTime); break; } case MFnNumericData::k4Double: { double tmp1, tmp2, tmp3, tmp4; MFnNumericData attrNumericDataFn(plg.asMObject()); attrNumericDataFn.getData(tmp1, tmp2, tmp3, tmp4); _SetVec(usdAttr, GfVec4d(tmp1, tmp2, tmp3, tmp4), usdTime); break; } default: return false; } } else if (attrObj.hasFn(MFn::kTypedAttribute)) { MFnTypedAttribute attrTypedFn(attrObj); switch (attrTypedFn.attrType()) { case MFnData::kString: usdAttr.Set(std::string(plg.asString().asChar()), usdTime); break; case MFnData::kMatrix: { MFnMatrixData attrMatrixDataFn(plg.asMObject()); MMatrix mat1 = attrMatrixDataFn.matrix(); usdAttr.Set(GfMatrix4d(mat1.matrix), usdTime); break; } case MFnData::kStringArray: { MFnStringArrayData attrDataFn(plg.asMObject()); VtArray<std::string> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { usdVal[i] = std::string(attrDataFn[i].asChar()); } usdAttr.Set(usdVal, usdTime); break; } case MFnData::kIntArray: { MFnIntArrayData attrDataFn(plg.asMObject()); VtArray<int> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { usdVal[i] = attrDataFn[i]; } usdAttr.Set(usdVal, usdTime); break; } case MFnData::kFloatArray: { MFnFloatArrayData attrDataFn(plg.asMObject()); VtArray<float> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { usdVal[i] = attrDataFn[i]; } usdAttr.Set(usdVal, usdTime); break; } case MFnData::kDoubleArray: { MFnDoubleArrayData attrDataFn(plg.asMObject()); VtArray<double> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { usdVal[i] = attrDataFn[i]; } usdAttr.Set(usdVal, usdTime); break; } case MFnData::kVectorArray: { MFnVectorArrayData attrDataFn(plg.asMObject()); VtArray<GfVec3d> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { MVector tmpMayaVal = attrDataFn[i]; usdVal[i] = GfVec3d(tmpMayaVal[0], tmpMayaVal[1], tmpMayaVal[2]); } usdAttr.Set(usdVal, usdTime); break; } case MFnData::kPointArray: { MFnPointArrayData attrDataFn(plg.asMObject()); VtArray<GfVec4d> usdVal(attrDataFn.length()); for (unsigned int i=0; i < attrDataFn.length(); i++) { MPoint tmpMayaVal = attrDataFn[i]; usdVal[i] = GfVec4d(tmpMayaVal[0], tmpMayaVal[1], tmpMayaVal[2], tmpMayaVal[3]); } usdAttr.Set(usdVal, usdTime); break; } default: return false; } } else if (attrObj.hasFn(MFn::kUnitAttribute)) { //MFnUnitAttribute attrUnitFn(attrObj); return false; } else if (attrObj.hasFn(MFn::kEnumAttribute)) { MFnEnumAttribute attrEnumFn(attrObj); short enumIndex = plg.asShort(); TfToken enumToken( std::string(attrEnumFn.fieldName(enumIndex, &status).asChar()) ); usdAttr.Set(enumToken, usdTime); return false; } return true; }