//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ //////////////////////////////////////////////////////////////////////// // // filteredAsciiFile.cpp // // This plug-in is an example of a user-defined MPxMayaAsciiFilter. It // allows users to segment scenes into files containing various types // of nodes. Users can specify which node types are exported by // using the "includeType" and "excludeType" options in the file command. // For example, the following would save only renderLayer nodes: // // mel: file -rename "myLayerData"; // mel: file -type "filteredAsciiFile"; // mel: file -save -options ";includeType kRenderLayer;"; // // In addition, the type of connectAttrs written in the ASCII file are // determined by the nodes types which are exported. If the source node // in the connectAttr is to be output, then the connectAttr is written. // // In addition to allowing scenes to be segmented, this plugin also // allows ASCII files to write a line which will source other ASCII // files. This can be used to allow a single master file source in // all of the different files containing scene segments. Again, this is // controlled via the file command's options. The following illustrates // how to source in the render layer segment saved in the above example: // // mel: file -rename "myMasterFile"; // mel: file -save -options ";excludeType kRenderLayer; sourceFile myLayerData.faf" // // Here, the excludeType argument is used to ensure no render layer // information is output in myMasterFile. The sourceFile option outputs // the following line in myMasterFile.faf: // // customSourceFile -fileName "myLayerData.faf"; // // When this line is parsed as myMasterFile.faf is loaded, the // customSourceFile command, also contained in this plugin, is executed. // It simply sources myLayerData.faf, first prepending the // myMasterFile.faf's path. // //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #define kFileNameFlag "-fn" #define kFileNameFlagLong "-fileName" #define commandName "customSourceFile" class filteredAsciiFile : public MPxMayaAsciiFilter { public: static void* creator(); static void setPluginName(const MString& name); static MString translatorName(); MString defaultExtension() const; filteredAsciiFile(); static MString fExtension; static MString fPluginName; static MString fTranslatorName; protected: MStatus processReadOptions(const MString& optionsString); MStatus processWriteOptions(const MString& optionsString); bool writesRequirements() const; bool writesCreateNode( const MObject& node ) const; bool writesSelectNode( const MObject& node ) const; bool writesFileReference( const MFileObject& referenceFile ) const; bool writesConnectAttr( const MPlug& srcPlug, const MPlug& destPlug ) const; bool writesSetAttr( const MPlug& srcPlug ) const; MStatus writePostRequires( MPxMayaAsciiFilterOutput& fileIO ); MStatus writePostCreateNodesBlock( MPxMayaAsciiFilterOutput& fileIO ); private: bool isNodeTypeIncluded(const MString& type) const; bool isNodeNameExcluded(const MObject& node) const; MStringArray includedNodeTypesArray; MStringArray excludedNodeTypesArray; MStringArray sourcedFilesArray; MStringArray excludedNamesArray; bool outputRequirements; bool outputReferences; }; MString filteredAsciiFile::fExtension = "faf"; MString filteredAsciiFile::fPluginName = ""; MString filteredAsciiFile::fTranslatorName = "filteredAsciiFile"; inline void filteredAsciiFile::setPluginName(const MString& name) { fPluginName = name; } inline MString filteredAsciiFile::translatorName() { return fTranslatorName; } inline MString filteredAsciiFile::defaultExtension() const { return fExtension; } filteredAsciiFile::filteredAsciiFile() : includedNodeTypesArray() , outputRequirements(false) , outputReferences(true) { } MStatus filteredAsciiFile::processReadOptions(const MString& optionsString) { return MStatus::kSuccess; } MStatus filteredAsciiFile::processWriteOptions(const MString& optionsString) { MStringArray optionsArray; includedNodeTypesArray.clear(); excludedNodeTypesArray.clear(); sourcedFilesArray.clear(); excludedNamesArray.clear(); outputRequirements = true; outputReferences = true; optionsString.split(';', optionsArray); for (unsigned i = 0; i < optionsArray.length(); i++) { const MString& option = optionsArray[i]; MStringArray optionArray; option.split(' ', optionArray); if (optionArray[0] == "includeNodeType" && optionArray.length() > 1) { includedNodeTypesArray.append(optionArray[1]); } else if (optionArray[0] == "excludeNodeType" && optionArray.length() > 1) { excludedNodeTypesArray.append(optionArray[1]); } else if (optionArray[0] == "sourceFile" && optionArray.length() > 1) { sourcedFilesArray.append(optionArray[1]); } } return MStatus::kSuccess; } void* filteredAsciiFile::creator() { return new filteredAsciiFile(); } bool filteredAsciiFile::writesRequirements() const { return outputRequirements; } bool filteredAsciiFile::writesCreateNode( const MObject& node ) const { bool result = false; MFnDependencyNode depNode(node); if (depNode.isFromReferencedFile() && !outputReferences) { return false; } if (isNodeNameExcluded(node)) { return false; } if (!result) { result = isNodeTypeIncluded(node.apiTypeStr()); } return result; } bool filteredAsciiFile::writesConnectAttr( const MPlug& srcPlug, const MPlug& destPlug ) const { return (writesCreateNode(srcPlug.node()) && !isNodeNameExcluded(destPlug.node())); } bool filteredAsciiFile::writesSelectNode( const MObject& node ) const { return writesCreateNode(node); } bool filteredAsciiFile::writesFileReference( const MFileObject& referenceFile ) const { return outputReferences; } bool filteredAsciiFile::writesSetAttr( const MPlug& srcPlug ) const { return writesCreateNode(srcPlug.node()); } MStatus filteredAsciiFile::writePostRequires( MPxMayaAsciiFilterOutput& fileIO ) { fileIO << "requires " << fPluginName.asChar() << " \"1.0\";\n"; return MS::kSuccess; } MStatus filteredAsciiFile::writePostCreateNodesBlock( MPxMayaAsciiFilterOutput& fileIO ) { for (unsigned int i = 0; i < sourcedFilesArray.length(); i++) { fileIO << "eval (\"customSourceFile -fileName \\\""; fileIO << sourcedFilesArray[i].asChar(); fileIO << "\\\";\");\n"; } return MS::kSuccess; } bool filteredAsciiFile::isNodeTypeIncluded(const MString& nodeType) const { if ( (excludedNodeTypesArray.length() == 0 ) && (includedNodeTypesArray.length() == 0 ) ) { // there are no types specifically included or excluded, // so we assume everything is included. return true; } // if we aren't excluding any nodes at this point, then we're // only interested in nodes which are explicitly included. bool result = (excludedNodeTypesArray.length() > 0); for (unsigned int i = 0; i < includedNodeTypesArray.length(); i++) { if (nodeType == includedNodeTypesArray[i]) { result = true; break; } } for (unsigned int j = 0; j < excludedNodeTypesArray.length(); j++) { if (nodeType == excludedNodeTypesArray[j]) { result = false; break; } } return result; } bool filteredAsciiFile::isNodeNameExcluded(const MObject& node) const { for (unsigned int i = 0; i < excludedNamesArray.length(); i++) { MFnDependencyNode depNode(node); if (excludedNamesArray[i] == depNode.name()) { return true; } } return false; } // **************************************** class sourceFileCmd : public MPxCommand { public: sourceFileCmd(); virtual ~sourceFileCmd(); MStatus doIt( const MArgList& args ); static MSyntax newSyntax(); static void* creator(); private: }; sourceFileCmd::sourceFileCmd() { } sourceFileCmd::~sourceFileCmd() { } MStatus sourceFileCmd::doIt (const MArgList& args ) { MString fileName; MStatus status = MS::kSuccess; MArgDatabase argData(syntax(), args); if (argData.isFlagSet(kFileNameFlag)) { status = argData.getFlagArgument(kFileNameFlag, 0, fileName); if (status == MS::kSuccess) { MString currFile = MFileIO::fileCurrentlyLoading(); MStringArray pathDirectories; currFile.split ('/', pathDirectories); if (pathDirectories.length() > 0) { MString expandedFileName; for (unsigned int i = 0; i < pathDirectories.length()-1; i++) { expandedFileName += pathDirectories[i]; expandedFileName += "/"; } expandedFileName += fileName; MGlobal::sourceFile(expandedFileName); } } } return status; } void* sourceFileCmd::creator() { return (void*) new sourceFileCmd(); } MSyntax sourceFileCmd::newSyntax() { MSyntax syntax; syntax.addFlag(kFileNameFlag, kFileNameFlagLong, MSyntax::kString); return syntax; } // **************************************** MStatus initializePlugin(MObject obj) { MFnPlugin plugin(obj, PLUGIN_COMPANY, "1.0", "Any"); filteredAsciiFile::setPluginName(plugin.name()); plugin.registerFileTranslator( filteredAsciiFile::translatorName(), NULL, filteredAsciiFile::creator, NULL, NULL, false ); MStatus status = plugin.registerCommand( commandName, sourceFileCmd::creator, sourceFileCmd::newSyntax); return MS::kSuccess; } MStatus uninitializePlugin(MObject obj) { MFnPlugin plugin( obj ); plugin.deregisterFileTranslator(filteredAsciiFile::translatorName()); return MS::kSuccess; }