std::auto_ptr< Accessor > AdskSceneMetadataCmd::getAccessorForScene( MString scenePath ) { // This string gets populated with errors by the Metadata library when they occur std::string errors; std::string stdScenePath( scenePath.asChar() ); std::auto_ptr< Accessor > accessor( Accessor::accessorByExtension( stdScenePath ) ); if ( NULL == accessor.get() ) { MStatus resStatus; MString errorString = MStringResource::getString( rAccessorNotFoundError, resStatus ); errorString.format( errorString, scenePath ); displayError( errorString ); return std::auto_ptr< Accessor >(); } // Optimization: only read the scene associations. std::set< std::string > wantedAssociations; wantedAssociations.insert( AccessorMaya::getSceneAssociationsName() ); if ( !accessor->read( stdScenePath, NULL, // read all the structures &wantedAssociations, errors ) ) { MStatus resStatus; MString errorString = MStringResource::getString( rCannotReadFileError, resStatus ); errorString.format( errorString, scenePath, errors.c_str() ); displayError( errorString ); return std::auto_ptr< Accessor >(); } return accessor; }
//====================================================================== // // Do the command in query mode. It only does one thing, print the Stream, // Channel, Associations, and Structure formats available. // MStatus exportMetadataCmd::doQuery() { assert( fSerializer ); MStatus status = MS::kSuccess; std::set<const adsk::Data::StreamSerializer*>::iterator sFmtIt; for( sFmtIt = adsk::Data::StreamSerializer::allFormats().begin(); sFmtIt != adsk::Data::StreamSerializer::allFormats().end(); sFmtIt++ ) { const adsk::Data::StreamSerializer* fmt = *sFmtIt; MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) ); MString fmtType( "Stream" ); MString fmtName( fmt->formatType() ); MString msg; msg.format( fmtMsg, fmtType, fmtName ); appendToResult( msg ); } std::set<const adsk::Data::ChannelSerializer*>::iterator cFmtIt; for( cFmtIt = adsk::Data::ChannelSerializer::allFormats().begin(); cFmtIt != adsk::Data::ChannelSerializer::allFormats().end(); cFmtIt++ ) { const adsk::Data::ChannelSerializer* fmt = *cFmtIt; MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) ); MString fmtType( "Channel" ); MString fmtName( fmt->formatType() ); MString msg; msg.format( fmtMsg, fmtType, fmtName ); appendToResult( msg ); } std::set<const adsk::Data::AssociationsSerializer*>::iterator aFmtIt; for( aFmtIt = adsk::Data::AssociationsSerializer::allFormats().begin(); aFmtIt != adsk::Data::AssociationsSerializer::allFormats().end(); aFmtIt++ ) { const adsk::Data::AssociationsSerializer* fmt = *aFmtIt; MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) ); MString fmtType( "Associations" ); MString fmtName( fmt->formatType() ); MString msg; msg.format( fmtMsg, fmtType, fmtName ); appendToResult( msg ); } std::set<const adsk::Data::StructureSerializer*>::iterator fmtIt; for( fmtIt = adsk::Data::StructureSerializer::allFormats().begin(); fmtIt != adsk::Data::StructureSerializer::allFormats().end(); fmtIt++ ) { const adsk::Data::StructureSerializer* fmt = *fmtIt; MString fmtMsg( MStringResource::getString(kExportMetadataFormatType, status) ); MString fmtType( "Structure" ); MString fmtName( fmt->formatType() ); MString msg; msg.format( fmtMsg, fmtType, fmtName ); appendToResult( msg ); } return status; }
//====================================================================== // // Check the parsed arguments and do/undo/redo the command as appropriate // MStatus importMetadataCmd::checkArgs(MArgDatabase& argsDb) { MStatus status = metadataBase::checkArgs( argsDb ); if( status != MS::kSuccess ) return status; //---------------------------------------- // -string flag // // If specified then the -file flag is not allowed. // fStringFlag.parse(argsDb, flagString); if( fStringFlag.isSet() ) { if( fFile ) { MString fmt = MStringResource::getString(kFileIgnored, status); MString msg; msg.format( fmt, flagString ); displayWarning( msg ); } if( !fStringFlag.isModeValid(fMode) ) { MString fmt = MStringResource::getString(kOnlyCreateModeMsg, status); MString msg; msg.format( fmt, flagString ); displayError(msg); return MS::kFailure; } if( ! fStringFlag.isArgValid() ) { MString errMsg( MStringResource::getString(kInvalidString, status) ); displayError( errMsg ); return MS::kFailure; } fString = fStringFlag.arg(); } else if( ! fFile ) { MString fmt = MStringResource::getString(kFileOrStringNeeded, status); MString msg; msg.format( fmt, flagString ); displayError( msg ); return MS::kFailure; } else if( ! fFile->exists() ) { MString fmt = MStringResource::getString(kFileNotFound, status); MString msg; msg.format( fmt, fFileFlag.arg().asChar() ); displayError(msg); status = MS::kNotFound; } return status; }
MString hwApiTextureTestStrings::getString(const MStringResourceId &stringId, float arg1, float arg2, float arg3, float arg4) { MString string; MString arg1String; arg1String += arg1; MString arg2String; arg2String += arg2; MString arg3String; arg3String += arg3; MString arg4String; arg4String += arg4; string.format( hwApiTextureTestStrings::getString( stringId ), arg1String, arg2String, arg3String, arg4String ); return string; }
void MVGMesh::setIsActive(const bool isActive) const { MStatus status; // Check is flag exists MFnMesh fn(_dagpath); MPlug mvgPlug = fn.findPlug(_MVG, false, &status); if(!status && !isActive) return; if(!status && isActive) { // Create MayaMVG attribute MDagModifier dagModifier; MFnNumericAttribute nAttr; MObject mvgAttr = nAttr.create(_MVG, "mvg", MFnNumericData::kBoolean); status = dagModifier.addAttribute(_object, mvgAttr); CHECK(status) dagModifier.doIt(); mvgPlug = fn.findPlug(_MVG, false, &status); } status = mvgPlug.setValue(isActive); CHECK(status) if(isActive) { status = MGlobal::executePythonCommand("from mayaMVG import scale"); CHECK(status) MString cmd; // Retrieve transform node cmd.format("scale.getParent(\"^1s\")", _dagpath.fullPathName()); MString transform; status = MGlobal::executePythonCommand(cmd, transform); // Freeze transform mesh cmd.format("makeIdentity -apply true \"^1s\"", transform); status = MGlobal::executeCommand(cmd); CHECK(status) // Lock node cmd.format("scale.lockNode(\"^1s\", True)", transform); status = MGlobal::executePythonCommand(cmd); CHECK(status) } else {
MStatus AbcImport::doIt(const MArgList & args) { MStatus status; MArgParser argData(syntax(), args, &status); MString filename(""); MString connectRootNodes(""); MString filterString(""); MString excludeFilterString(""); MObject reparentObj = MObject::kNullObj; bool swap = false; bool createIfNotFound = false; bool removeIfNoUpdate = false; bool debugOn = false; if (argData.isFlagSet("help")) { MGlobal::displayInfo(usage); return status; } if (argData.isFlagSet("debug")) debugOn = true; if (argData.isFlagSet("reparent")) { MString parent(""); MDagPath reparentDagPath; status = argData.getFlagArgument("reparent", 0, parent); if (status == MS::kSuccess && getDagPathByName(parent, reparentDagPath) == MS::kSuccess) { reparentObj = reparentDagPath.node(); } else { MString theWarning = parent; theWarning += MString(" is not a valid DagPath"); printWarning(theWarning); } } if (!argData.isFlagSet("connect") && argData.isFlagSet("mode")) { MString modeStr; argData.getFlagArgument("mode", 0, modeStr); if (modeStr == "replace") deleteCurrentSelection(); else if (modeStr == "open") { MFileIO fileIo; fileIo.newFile(true); } } else if (argData.isFlagSet("connect")) { swap = true; argData.getFlagArgument("connect", 0, connectRootNodes); if (argData.isFlagSet("createIfNotFound")) { createIfNotFound = true; } if (argData.isFlagSet("removeIfNoUpdate")) removeIfNoUpdate = true; } if (argData.isFlagSet("filterObjects")) { argData.getFlagArgument("filterObjects", 0, filterString); } if (argData.isFlagSet("excludeFilterObjects")) { argData.getFlagArgument("excludeFilterObjects", 0, excludeFilterString); } // if the flag isn't specified we'll only do stuff marked with the Maya // meta data bool recreateColorSets = false; if (argData.isFlagSet("recreateAllColorSets")) { recreateColorSets = true; } status = argData.getCommandArgument(0, filename); MString abcNodeName; if (status == MS::kSuccess) { { 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); } // 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(); // resolve the relative path MFileObject absoluteFile; absoluteFile.setRawFullName(filename); absoluteFile.setResolveMethod(MFileObject::kInputFile); #if MAYA_API_VERSION < 201300 if (absoluteFile.resolvedFullName() != absoluteFile.expandedFullName()) { #else if (!MFileObject::isAbsolutePath(filename)) { #endif // this is a relative path MString absoluteFileName = directoryName + "/" + filename; absoluteFile.setRawFullName(absoluteFileName); filename = absoluteFile.resolvedFullName(); } else { filename = absoluteFile.resolvedFullName(); } } MFileObject fileObj; status = fileObj.setRawFullName(filename); if (status == MS::kSuccess && fileObj.exists()) { ArgData inputData(filename, debugOn, reparentObj, swap, connectRootNodes, createIfNotFound, removeIfNoUpdate, recreateColorSets, filterString, excludeFilterString); abcNodeName = createScene(inputData); if (inputData.mSequenceStartTime != inputData.mSequenceEndTime && inputData.mSequenceStartTime != -DBL_MAX && inputData.mSequenceEndTime != DBL_MAX) { if (argData.isFlagSet("fitTimeRange")) { MTime sec(1.0, MTime::kSeconds); setPlayback( inputData.mSequenceStartTime * sec.as(MTime::uiUnit()), inputData.mSequenceEndTime * sec.as(MTime::uiUnit()) ); } if (argData.isFlagSet("setToStartFrame")) { MTime sec(1.0, MTime::kSeconds); MGlobal::viewFrame( inputData.mSequenceStartTime * sec.as(MTime::uiUnit()) ); } } } else { MString theError("In AbcImport::doIt(), "); theError += filename; theError += MString(" doesn't exist"); printError(theError); } } MPxCommand::setResult(abcNodeName); return status; }
depthShaderOverride::depthShaderOverride(const MObject& obj) : MPxSurfaceShadingNodeOverride(obj) , fFragmentName("") { // Define fragments needed for VP2 version of shader, this could also be // defined in a separate XML file // // Define the input and output parameter names to match the input and // output attribute names so that the values are automatically populated // on the shader. // // Define a separate fragment for computing the camera space position so // that the operation can be done in the vertex shader rather than the // pixel shader. Then connect the two fragments together in a graph. static const MString sFragmentName("depthShaderPluginFragment"); static const char* sFragmentBody = "<fragment uiName=\"depthShaderPluginFragment\" name=\"depthShaderPluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">" " <description><![CDATA[Depth shader fragment]]></description>" " <properties>" " <float name=\"depthValue\" />" " <float3 name=\"color\" />" " <float3 name=\"colorFar\" />" " <float name=\"near\" />" " <float name=\"far\" />" " </properties>" " <values>" " <float name=\"depthValue\" value=\"0.0\" />" " <float3 name=\"color\" value=\"0.0,1.0,0.0\" />" " <float3 name=\"colorFar\" value=\"0.0,0.0,1.0\" />" " <float name=\"near\" value=\"0.0\" />" " <float name=\"far\" value=\"2.0\" />" " </values>" " <outputs>" " <float3 name=\"outColor\" />" " </outputs>" " <implementation>" " <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">" " <function_name val=\"depthShaderPluginFragment\" />" " <source><![CDATA[" "float3 depthShaderPluginFragment(float depthValue, float3 cNear, float3 cFar, float nearClip, float farClip) \n" "{ \n" " float ratio = (farClip + depthValue)/(farClip - nearClip); \n" " return cNear*ratio + cFar*(1.0f - ratio); \n" "} \n]]>" " </source>" " </implementation>" " <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">" " <function_name val=\"depthShaderPluginFragment\" />" " <source><![CDATA[" "float3 depthShaderPluginFragment(float depthValue, float3 cNear, float3 cFar, float nearClip, float farClip) \n" "{ \n" " float ratio = (farClip + depthValue)/(farClip - nearClip); \n" " return cNear*ratio + cFar*(1.0f - ratio); \n" "} \n]]>" " </source>" " </implementation>" " <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">" " <function_name val=\"depthShaderPluginFragment\" />" " <source><![CDATA[" "vec3 depthShaderPluginFragment(float depthValue, vec3 cNear, vec3 cFar, float nearClip, float farClip) \n" "{ \n" " float ratio = (farClip + depthValue)/(farClip - nearClip); \n" " return cNear*ratio + cFar*(1.0f - ratio); \n" "} \n]]>" " </source>" " </implementation>" " </implementation>" "</fragment>"; static const MString sVertexFragmentName("depthShaderPluginInterpolantFragment"); static const char* sVertexFragmentBody = "<fragment uiName=\"depthShaderPluginInterpolantFragment\" name=\"depthShaderPluginInterpolantFragment\" type=\"interpolant\" class=\"ShadeFragment\" version=\"1.0\">" " <description><![CDATA[Depth shader vertex fragment]]></description>" " <properties>" " <float3 name=\"Pm\" semantic=\"Pm\" flags=\"varyingInputParam\" />" " <float4x4 name=\"worldViewProj\" semantic=\"worldviewprojection\" />" " </properties>" " <values>" " </values>" " <outputs>" " <float name=\"outDepthValue\" ^1s/>" " </outputs>" " <implementation>" " <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">" " <function_name val=\"depthShaderPluginInterpolantFragment\" />" " <source><![CDATA[" "float depthShaderPluginInterpolantFragment(float depthValue) \n" "{ \n" " return depthValue; \n" "} \n]]>" " </source>" " <vertex_source><![CDATA[" "float idepthShaderPluginInterpolantFragment(float3 Pm, float4x4 worldViewProj) \n" "{ \n" " float4 pCamera = mul(worldViewProj, float4(Pm, 1.0f)); \n" " return (pCamera.z - pCamera.w*2.0f); \n" "} \n]]>" " </vertex_source>" " </implementation>" " <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">" " <function_name val=\"depthShaderPluginInterpolantFragment\" />" " <source><![CDATA[" "float depthShaderPluginInterpolantFragment(float depthValue) \n" "{ \n" " return depthValue; \n" "} \n]]>" " </source>" " <vertex_source><![CDATA[" "float idepthShaderPluginInterpolantFragment(float3 Pm, float4x4 worldViewProj) \n" "{ \n" " float4 pCamera = mul(float4(Pm, 1.0f), worldViewProj); \n" " return (pCamera.z - pCamera.w*2.0f); \n" "} \n]]>" " </vertex_source>" " </implementation>" " <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">" " <function_name val=\"depthShaderPluginInterpolantFragment\" />" " <source><![CDATA[" "float depthShaderPluginInterpolantFragment(float depthValue) \n" "{ \n" " return depthValue; \n" "} \n]]>" " </source>" " <vertex_source><![CDATA[" "float idepthShaderPluginInterpolantFragment(vec3 Pm, mat4 worldViewProj) \n" "{ \n" " vec4 pCamera = worldViewProj * vec4(Pm, 1.0f); \n" " return (pCamera.z - pCamera.w*2.0f); \n" "} \n]]>" " </vertex_source>" " </implementation>" " </implementation>" "</fragment>"; static const MString sFragmentGraphName("depthShaderPluginGraph"); static const char* sFragmentGraphBody = "<fragment_graph name=\"depthShaderPluginGraph\" ref=\"depthShaderPluginGraph\" class=\"FragmentGraph\" version=\"1.0\">" " <fragments>" " <fragment_ref name=\"depthShaderPluginFragment\" ref=\"depthShaderPluginFragment\" />" " <fragment_ref name=\"depthShaderPluginInterpolantFragment\" ref=\"depthShaderPluginInterpolantFragment\" />" " </fragments>" " <connections>" " <connect from=\"depthShaderPluginInterpolantFragment.outDepthValue\" to=\"depthShaderPluginFragment.depthValue\" />" " </connections>" " <properties>" " <float3 name=\"Pm\" ref=\"depthShaderPluginInterpolantFragment.Pm\" semantic=\"Pm\" flags=\"varyingInputParam\" />" " <float4x4 name=\"worldViewProj\" ref=\"depthShaderPluginInterpolantFragment.worldViewProj\" semantic=\"worldviewprojection\" />" " <float3 name=\"color\" ref=\"depthShaderPluginFragment.color\" />" " <float3 name=\"colorFar\" ref=\"depthShaderPluginFragment.colorFar\" />" " <float name=\"near\" ref=\"depthShaderPluginFragment.near\" />" " <float name=\"far\" ref=\"depthShaderPluginFragment.far\" />" " </properties>" " <values>" " <float3 name=\"color\" value=\"0.0,1.0,0.0\" />" " <float3 name=\"colorFar\" value=\"0.0,0.0,1.0\" />" " <float name=\"near\" value=\"0.0\" />" " <float name=\"far\" value=\"2.0\" />" " </values>" " <outputs>" " <float3 name=\"outColor\" ref=\"depthShaderPluginFragment.outColor\" />" " </outputs>" "</fragment_graph>"; // Register fragments with the manager if needed MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if (theRenderer) { MHWRender::MFragmentManager* fragmentMgr = theRenderer->getFragmentManager(); if (fragmentMgr) { // Add fragments if needed bool fragAdded = fragmentMgr->hasFragment(sFragmentName); bool vertFragAdded = fragmentMgr->hasFragment(sVertexFragmentName); bool graphAdded = fragmentMgr->hasFragment(sFragmentGraphName); if (!fragAdded) { fragAdded = (sFragmentName == fragmentMgr->addShadeFragmentFromBuffer(sFragmentBody, false)); } if (!vertFragAdded) { // In DirectX, need to specify a semantic for the output of the vertex shader MString vertBody; if (theRenderer->drawAPI() == MHWRender::kDirectX11) { vertBody.format(MString(sVertexFragmentBody), MString("semantic=\"extraDepth\" ")); } else { vertBody.format(MString(sVertexFragmentBody), MString(" ")); } vertFragAdded = (sVertexFragmentName == fragmentMgr->addShadeFragmentFromBuffer(vertBody.asChar(), false)); } if (!graphAdded) { graphAdded = (sFragmentGraphName == fragmentMgr->addFragmentGraphFromBuffer(sFragmentGraphBody)); } // If we have them all, use the final graph for the override if (fragAdded && vertFragAdded && graphAdded) { fFragmentName = sFragmentGraphName; } } } }
MString hwApiTextureTestStrings::getString(const MStringResourceId &stringId, const MString& arg1, const MString& arg2) { MString string; string.format( hwApiTextureTestStrings::getString( stringId ), arg1, arg2 ); return string; }
//====================================================================== // // Do the import in create mode. The metadata will be retrieved from the // file or string and imported onto the selected object(s) presuming the // specified format. Successful execution will see the imported metadata on // the object(s), returning the names of the newly created or modified streams // in the format OBJECT/CHANNEL_TYPE/STREAM // // The previously existing metadata is preserved for later undo. // MStatus importMetadataCmd::doCreate() { assert( fSerializer ); std::string errors; Associations* associationsRead = (Associations*)0; MStatus status; if( fString.length() > 0 ) { std::stringstream inStream( fString.asChar() ); associationsRead = fSerializer->read( inStream, errors ); if( ! associationsRead ) { MString fmt = MStringResource::getString(kImportMetadataStringReadFailed, status); MString msg; MString err( errors.c_str() ); msg.format( fmt, err ); displayError(msg); return MS::kFailure; } } else if( fFile ) { std::ifstream inStream( fFile->resolvedFullName().asChar() ); associationsRead = fSerializer->read( inStream, errors ); inStream.close(); if( ! associationsRead ) { MString fmt = MStringResource::getString(kImportMetadataFileReadFailed, status); MString msg; MString err( errors.c_str() ); msg.format( fmt, fFile->resolvedFullName(), err ); displayError(msg); return MS::kFailure; } } else { // This isn't a recoverable error since this situation should have // been reported in the arg checking. Just assert and fail // immediately. assert( fFile ); return MS::kFailure; } // Should have already handled this assert( associationsRead ); MString resultFmt = MStringResource::getString(kImportMetadataResult, status); for( unsigned int i=0; i<fObjects.length(); ++i ) { MFnDependencyNode node( fObjects[i], &status ); // Should have filtered out non-objects already but check anyway if( MS::kSuccess != status ) continue; displayInfo( node.name(&status) ); fDGModifier.setMetadata( fObjects[i], *associationsRead ); if( MS::kSuccess == fDGModifier.doIt() ) { for( unsigned int c=0; c<associationsRead->channelCount(); ++c ) { adsk::Data::Channel channel = associationsRead->channelAt(c); MString cName( channel.name().c_str() ); for( unsigned int s=0; s<channel.dataStreamCount(); ++s ) { adsk::Data::Stream* cStream = channel.dataStream(s); if( cStream ) { MString sName( cStream->name().c_str() ); MString msg; msg.format( resultFmt, node.name(), cName, sName ); appendToResult( msg ); } } } } else { MString fmt = MStringResource::getString(kImportMetadataSetMetadataFailed, status); MString msg; msg.format( fmt, node.name() ); displayError( msg ); status = MS::kFailure; } } return status; }
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; } }
MStatus initializePlugin( MObject obj) { MStatus status; MFnPlugin plugin(obj, "Pixar", "1.0", "Any"); // we use lambdas to pass in MCreatorFunctions into the various Maya registration // functions so that we can specify the static data that the registered // shape/data/node should be using. status = plugin.registerData( _data.stageData.typeName, _data.stageData.typeId, []() { return UsdMayaStageData::creator(_data.stageData); }); CHECK_MSTATUS(status); status = plugin.registerShape( _data.proxyShape.typeName, _data.proxyShape.typeId, []() { return UsdMayaProxyShape::creator(_data.proxyShape); }, []() { return UsdMayaProxyShape::initialize( &(_data.proxyShape)); }, UsdMayaProxyShapeUI::creator, &UsdMayaProxyDrawOverride::sm_drawDbClassification); CHECK_MSTATUS(status); status = plugin.registerNode( _data.referenceAssembly.typeName, _data.referenceAssembly.typeId, []() { return UsdMayaReferenceAssembly::creator( _data.referenceAssembly); }, []() { return UsdMayaReferenceAssembly::initialize( &(_data.referenceAssembly)); }, MPxNode::kAssembly, &UsdMayaReferenceAssembly::_classification); CHECK_MSTATUS(status); status = MHWRender::MDrawRegistry::registerDrawOverrideCreator( UsdMayaProxyDrawOverride::sm_drawDbClassification, UsdMayaProxyDrawOverride::sm_drawRegistrantId, UsdMayaProxyDrawOverride::Creator); CHECK_MSTATUS(status); status = MGlobal::sourceFile("usdMaya.mel"); CHECK_MSTATUS(status); // Set the label for the assembly node type so that it appears correctly // in the 'Create -> Scene Assembly' menu. const MString assemblyTypeLabel("UsdReferenceAssembly"); MString setLabelCmd; status = setLabelCmd.format("assembly -e -type ^1s -label ^2s", _data.referenceAssembly.typeName, assemblyTypeLabel); CHECK_MSTATUS(status); status = MGlobal::executeCommand(setLabelCmd); CHECK_MSTATUS(status); // Procs stored in usdMaya.mel // Add assembly callbacks for accessing data without creating an MPxAssembly instance status = MGlobal::executeCommand("assembly -e -repTypeLabelProc usdMaya_UsdMayaReferenceAssembly_repTypeLabel -type " + _data.referenceAssembly.typeName); CHECK_MSTATUS(status); status = MGlobal::executeCommand("assembly -e -listRepTypesProc usdMaya_UsdMayaReferenceAssembly_listRepTypes -type " + _data.referenceAssembly.typeName); CHECK_MSTATUS(status); // Attribute Editor Templates // XXX: The try/except here is temporary until we change the Pixar-internal // package name to match the external package name. MString attribEditorCmd( "try:\n" " from pxr.UsdMaya import AEpxrUsdReferenceAssemblyTemplate\n" "except ImportError:\n" " from pixar.UsdMaya import AEpxrUsdReferenceAssemblyTemplate\n" "AEpxrUsdReferenceAssemblyTemplate.addMelFunctionStubs()"); status = MGlobal::executePythonCommand(attribEditorCmd); CHECK_MSTATUS(status); status = plugin.registerCommand("usdExport", usdExport::creator, usdExport::createSyntax ); if (!status) { status.perror("registerCommand usdExport"); } status = plugin.registerCommand("usdImport", []() { return usdImport::creator(_data.referenceAssembly.typeName.asChar(), _data.proxyShape.typeName.asChar()); }, usdImport::createSyntax ); if (!status) { status.perror("registerCommand usdImport"); } status = plugin.registerCommand("usdListShadingModes", usdListShadingModes::creator, usdListShadingModes::createSyntax); if (!status) { status.perror("registerCommand usdListShadingModes"); } status = plugin.registerFileTranslator("pxrUsdImport", "", []() { return usdTranslatorImport::creator( _data.referenceAssembly.typeName.asChar(), _data.proxyShape.typeName.asChar()); }, "usdTranslatorImport", // options script name const_cast<char*>(usdTranslatorImportDefaults), false); if (!status) { status.perror("pxrUsd: unable to register USD Import translator."); } status = plugin.registerFileTranslator("pxrUsdExport", "", usdTranslatorExport::creator, "usdTranslatorExport", // options script name const_cast<char*>(usdTranslatorExportDefaults), true); if (!status) { status.perror("pxrUsd: unable to register USD Export translator."); } return status; }
void MayaTransformWriter::write() { size_t numSamples = mAnimChanList.size(); if (numSamples > 0) { std::vector < AnimChan >::iterator it, itEnd; for (it = mAnimChanList.begin(), itEnd = mAnimChanList.end(); it != itEnd; ++it) { double val = it->asDouble(); if (it->scale == -std::numeric_limits<double>::infinity()) val = util::inverseScale(val); else if (it->scale != 1.0) val *= it->scale; mSample[it->opNum].setChannelValue(it->channelNum, val); } if (!mInheritsPlug.isNull()) { mSample.setInheritsXforms(mInheritsPlug.asBool()); } if (mFilterEulerRotations) { double xx(0), yy(0), zz(0); if (getSampledRotation(mSample, mJointOrientOpIndex, xx, yy, zz)) { MEulerRotation filteredEuler(xx, yy, zz, mPrevJointOrientSolution.order); filteredEuler.setToClosestSolution(mPrevJointOrientSolution); // update sample with new solution setSampledRotation(mSample, mJointOrientOpIndex, filteredEuler.x, filteredEuler.y, filteredEuler.z); mPrevJointOrientSolution = filteredEuler; } if (getSampledRotation(mSample, mRotateOpIndex, xx, yy, zz)) { MEulerRotation filteredEuler(xx, yy, zz, mPrevRotateSolution.order); filteredEuler.setToClosestSolution(mPrevRotateSolution); #ifdef _DEBUG if (mVerbose) { MString str; MStringArray args(7,""); unsigned int i = 0; i=0; args[i++] = mName; args[i++].set(mPrevRotateSolution[0]); args[i++].set(mPrevRotateSolution[1]); args[i++].set(mPrevRotateSolution[2]); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(mPrevRotateSolution[0])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(mPrevRotateSolution[1])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(mPrevRotateSolution[2])); str.format("^1s: previous rotation radians(^2s, ^3s, ^4s) degrees(^5s, ^6s, ^7s)",args); MGlobal::displayInfo( str ); MEulerRotation currentEuler(xx, yy, zz, mPrevRotateSolution.order); i=0; args[i++] = mName; args[i++].set(currentEuler[0]); args[i++].set(currentEuler[1]); args[i++].set(currentEuler[2]); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(currentEuler[0])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(currentEuler[1])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(currentEuler[2])); str.format("^1s: current rotation radians(^2s, ^3s, ^4s) degrees(^5s, ^6s, ^7s)",args); MGlobal::displayInfo( str ); i=0; args[i++] = mName; args[i++].set(filteredEuler[0]); args[i++].set(filteredEuler[1]); args[i++].set(filteredEuler[2]); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(filteredEuler[0])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(filteredEuler[1])); args[i++].set(Alembic::AbcGeom::RadiansToDegrees(filteredEuler[2])); str.format("^1s: filtered rotation radians(^2s, ^3s, ^4s) degrees(^5s, ^6s, ^7s)",args); MGlobal::displayInfo( str ); } #endif // update sample with new solution setSampledRotation(mSample, mRotateOpIndex, filteredEuler.x, filteredEuler.y, filteredEuler.z); mPrevRotateSolution = filteredEuler; } if (getSampledRotation(mSample, mRotateAxisOpIndex, xx, yy, zz)) { MEulerRotation filteredEuler(xx, yy, zz, mPrevRotateAxisSolution.order); filteredEuler.setToClosestSolution(mPrevRotateAxisSolution); // update sample with new solution setSampledRotation(mSample, mRotateAxisOpIndex, filteredEuler.x, filteredEuler.y, filteredEuler.z); mPrevRotateAxisSolution = filteredEuler; } } mSchema.set(mSample); } }
MStatus AdskSceneMetadataCmd::setMetadata( MString scenePath ) { // This string gets populated with errors by the Metadata library when they occur std::string errors; // Retrieve the accessor std::auto_ptr< Accessor > accessor( getAccessorForScene( scenePath ) ); if ( NULL == accessor.get() ) { setResult( false ); return MS::kFailure; } // Retrieve the accessor Associations associations; if ( MS::kSuccess != getSceneAssociations(*(accessor.get()), associations) ) { setResult( false ); return MS::kFailure; } // Is our structure registered yet? Structure *structure = NULL; for ( Structure::ListIterator itrStructList = Structure::allStructures().begin(); itrStructList != Structure::allStructures().end(); ++itrStructList ) { if ( std::string((*itrStructList)->name()) == std::string(gStructureName) ) { structure = *itrStructList; break; } } if ( NULL == structure ) { // Register our structure since it is not registered yet. structure = Structure::create(); structure->setName( gStructureName ); structure->addMember( Member::kString, 1, gMemberName ); Structure::registerStructure( *structure ); } // Make sure our structure is known by the accessor const Accessor::StructureSet &accessorStructures = accessor->structures(); if ( accessorStructures.find( structure ) == accessorStructures.end() ) { // Build a new structure set from the existing one Accessor::StructureSet updatedStructures = accessorStructures; // Add our structure to it updatedStructures.insert( structure ); // Assign the new structure set accessor->setStructures( updatedStructures ); } // Retrieve or create the specified channel std::string channelName( fChannelName.arg().asChar() ); Channel channel = associations.channel( channelName ); // Create the stream Stream stream( *structure, std::string( gStreamName ) ); // Set the stream in the channel channel.setDataStream( stream ); // Create an handle to the data itself Handle handle( *structure ); // Set our string std::string dataString( fData.arg().asChar() ); if ( 0 != handle.fromStr( dataString, 0, errors ) ) { MStatus resStatus; MString errorString = MStringResource::getString( rSetDataOnChannelError, resStatus ); errorString.format( errorString, fChannelName.arg(), errors.c_str() ); displayError( errorString ); setResult( false ); return MS::kFailure; } // Set the handle in the stream stream.setElement( 0, handle ); // Write the new scene file metadata if ( !accessor->write( errors ) ) { MStatus resStatus; MString errorString = MStringResource::getString( rWriteMetadataError, resStatus ); displayError( errorString ); setResult( false ); return MS::kFailure; } // true is success; setResult( true ); return MS::kSuccess; }
MStatus AdskSceneMetadataCmd::getMetadata( MString scenePath ) { // This string gets populated with errors by the Metadata library when they occur std::string errors; // Retrieve the accessor std::auto_ptr< Accessor > accessor( getAccessorForScene( scenePath ) ); if ( NULL == accessor.get() ) { return MS::kFailure; } // Retrieve the scene associations Associations associations; if ( MS::kSuccess != getSceneAssociations(*(accessor.get()), associations) ) { return MS::kFailure; } // Look for the specified channel std::string channelName( fChannelName.arg().asChar() ); Channel *channel = associations.findChannel( channelName ); if ( NULL == channel ) { // The specified channel was not found in the metadata. // There is simply no metadata of interest in that scene file setResult( "" ); return MS::kSuccess; } // There should only be one stream in our metadata. Make sure there is at least one if ( 0 == channel->dataStreamCount() ) { MStatus resStatus; MString errorString = MStringResource::getString( rMissingStreamInChannelError, resStatus ); errorString.format( errorString, fChannelName.arg() ); displayError( errorString ); return MS::kFailure; } Stream *stream = channel->dataStream( 0 ); // There should only be one element in the stream. Make sure there is at least one if ( 0 == stream->elementCount() ) { MStatus resStatus; MString errorString = MStringResource::getString( rMissingElementInStreamError, resStatus ); errorString.format( errorString, fChannelName.arg() ); displayError( errorString ); return MS::kFailure; } Handle handle = stream->element( 0 ); // Position the handle on our data of interest if ( false == handle.setPositionByMemberName( gMemberName ) ) { MStatus resStatus; MString errorString = MStringResource::getString( rMissingMemberInElementError, resStatus ); errorString.format( errorString, gMemberName, fChannelName.arg() ); displayError( errorString ); return MS::kFailure; } if ( Member::kString != handle.dataType() ) { MStatus resStatus; MString errorString = MStringResource::getString( rInvalidMemberDataTypeError, resStatus ); errorString.format( errorString, fChannelName.arg() ); displayError( errorString ); return MS::kFailure; } char **strings = handle.asString(); setResult( strings[0] ); return MS::kSuccess; }
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag, Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex, const JobArgs & iArgs, GetMembersMap& gmMap, util::InstanceRecorder& instanceRecorder) : mNoNormals(iArgs.noNormals), mWriteUVs(iArgs.writeUVs), mWriteColorSets(iArgs.writeColorSets), 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; std::vector<float> uvs; std::vector<Alembic::Util::uint32_t> indices; 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); instanceRecorder.recordMaster(iDag,obj); mSubDSchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if ( mWriteUVs ) { getUVs(uvs, indices); if (!uvs.empty()) { 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); instanceRecorder.recordMaster(iDag,obj); mPolySchema = obj.getSchema(); Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp; if ( mWriteUVs ) { getUVs(uvs, indices); if (!uvs.empty()) { 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) { 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(); } } // 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) { MFnDependencyNode fnDepNode(connSGObj); MString message; message.format("Could not retrive face indices from set ^1s.", connSgObjName); MGlobal::displayError(message); 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()); if (mPolySchema) { 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 closestPointOnCurveCommand::redoIt() { // DOUBLE-CHECK TO MAKE SURE THERE'S A SPECIFIED OBJECT TO EVALUATE ON: if (sList.length() == 0) { MStatus stat; MString msg = MStringResource::getString(kNoValidObject, stat); displayError(msg); return MStatus::kFailure; } // RETRIEVE THE SPECIFIED OBJECT AS A DAGPATH: MDagPath curveDagPath; sList.getDagPath(0, curveDagPath); // CHECK FOR INVALID NODE-TYPE INPUT WHEN SPECIFIED/SELECTED NODE IS *NOT* A "CURVE" NOR "CURVE TRANSFORM": if (!curveDagPath.node().hasFn(MFn::kNurbsCurve) && !(curveDagPath.node().hasFn(MFn::kTransform) && curveDagPath.hasFn(MFn::kNurbsCurve))) { MStatus stat; MString msg; // Use format to place variable string into message MString msgFmt = MStringResource::getString(kInvalidType, stat); MStringArray selectionStrings; sList.getSelectionStrings(0, selectionStrings); msg.format(msgFmt, selectionStrings[0]); displayError(msg); return MStatus::kFailure; } // WHEN COMMAND *NOT* IN "QUERY MODE" (I.E. "CREATION MODE"), CREATE AND CONNECT A "closestPointOnCurve" NODE AND RETURN ITS NODE NAME: if (!queryFlagSet) { // CREATE THE NODE: MFnDependencyNode depNodeFn; if (closestPointOnCurveNodeName == "") depNodeFn.create("closestPointOnCurve"); else depNodeFn.create("closestPointOnCurve", closestPointOnCurveNodeName); closestPointOnCurveNodeName = depNodeFn.name(); // SET THE ".inPosition" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (inPositionFlagSet) { MPlug inPositionXPlug = depNodeFn.findPlug("inPositionX"); inPositionXPlug.setValue(inPosition.x); MPlug inPositionYPlug = depNodeFn.findPlug("inPositionY"); inPositionYPlug.setValue(inPosition.y); MPlug inPositionZPlug = depNodeFn.findPlug("inPositionZ"); inPositionZPlug.setValue(inPosition.z); } // MAKE SOME ADJUSTMENTS WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A CURVE SHAPE: unsigned instanceNumber=0; if (curveDagPath.node().hasFn(MFn::kTransform)) { // EXTEND THE DAGPATH TO ITS CURVE "SHAPE" NODE: curveDagPath.extendToShape(); // TRANSFORMS ARE *NOT* NECESSARILY THE "FIRST" INSTANCE TRANSFORM OF A CURVE SHAPE: instanceNumber = curveDagPath.instanceNumber(); } // CONNECT THE NODES: MPlug worldCurvePlug, inCurvePlug; inCurvePlug = depNodeFn.findPlug("inCurve"); depNodeFn.setObject(curveDagPath.node()); worldCurvePlug = depNodeFn.findPlug("worldSpace"); worldCurvePlug = worldCurvePlug.elementByLogicalIndex(instanceNumber); MDGModifier dgModifier; dgModifier.connect(worldCurvePlug, inCurvePlug); dgModifier.doIt(); // SET COMMAND RESULT TO BE NEW NODE'S NAME, AND RETURN: setResult(closestPointOnCurveNodeName); return MStatus::kSuccess; } // OTHERWISE, WE'RE IN THE COMMAND'S "QUERY MODE": else { // COMPUTE THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE, USING THE *FIRST* INSTANCE TRANSFORM WHEN CURVE IS SPECIFIED AS A "SHAPE": MPoint position; MVector normal, tangent; double paramU, distance; closestTangentUAndDistance(curveDagPath, inPosition, position, normal, tangent, paramU, distance); // WHEN NO QUERYABLE FLAG IS SPECIFIED, INDICATE AN ERROR: if (!positionFlagSet && !normalFlagSet && !tangentFlagSet && !paramUFlagSet && !distanceFlagSet) { MStatus stat; MString msg = MStringResource::getString(kNoQueryFlag, stat); displayError(msg); return MStatus::kFailure; } // WHEN JUST THE "DISTANCE" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (distanceFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || paramUFlagSet)) setResult(distance); // WHEN JUST THE "PARAMETER-U" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (paramUFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || distanceFlagSet)) setResult(paramU); // OTHERWISE, SET THE RETURN VALUE OF THE COMMAND'S RESULT TO A "COMPOSITE ARRAY OF FLOATS": else { // HOLDS FLOAT ARRAY RESULT: MDoubleArray floatArrayResult; // APPEND THE RESULTS OF THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE VALUES TO THE FLOAT ARRAY RESULT: if (positionFlagSet) { floatArrayResult.append(position.x); floatArrayResult.append(position.y); floatArrayResult.append(position.z); } if (normalFlagSet) { floatArrayResult.append(normal.x); floatArrayResult.append(normal.y); floatArrayResult.append(normal.z); } if (tangentFlagSet) { floatArrayResult.append(tangent.x); floatArrayResult.append(tangent.y); floatArrayResult.append(tangent.z); } if (paramUFlagSet) floatArrayResult.append(paramU); if (distanceFlagSet) floatArrayResult.append(distance); // FINALLY, SET THE COMMAND'S RESULT: setResult(floatArrayResult); } return MStatus::kSuccess; } }