![]()
File Translator Examples
The following examples demonstrate the usage of file translators.
Implementing the Proxy Polygon Exporter
The
polyExporterclass inherits fromMPxFileTranslatorand defines a number of virtual methods such aswriter().class polyExporter:public MPxFileTranslator { public: polyExporter(); virtual ~polyExporter(); virtual MStatus writer (const MFileObject& file, const MString& optionsString, MPxFileTranslator::FileAccessMode mode); virtual bool haveWriteMethod () const; virtual bool haveReadMethod () const; virtual bool canBeOpened () const; virtual MString defaultExtension () const = 0; protected: virtual bool isVisible(MFnDagNode& fnDag, MStatus& status); virtual MStatus exportAll(ostream& os); virtual MStatus exportSelection(ostream& os); virtual void writeHeader(ostream& os); virtual void writeFooter(ostream& os); virtual MStatus processPolyMesh(const MDagPath dagPath, ostream& os); virtual polyWriter* createPolyWriter(const MDagPath dagPath, MStatus& status) = 0; };Initializing the Plug-in
You need to register the new File Translator with
MFnPluginwhen initializing the plug-in. There are six arguments associated with theregisterFileTranslatormethod. The latter three arguments are optional.In this example, the argument
Rawtextis the file translator name. Theoption1=1argument contains the default value of the options strings for the option box for the translator. The last argument is of boolean type that determines the ability for a translator to execute MEL scripts within the translator. Atruevalue of this argument allows the MEL commands be executed through theMGlobal::executeCommandmethod.MStatus initializePlugin(MObject obj) { MStatus status; MFnPlugin plugin(obj, "Autodesk", "4.5", "Any"); status = plugin.registerFileTranslator("RawText", "", polyRawExporter::creator, "", "option1=1", true); if (!status) { status.perror("registerFileTranslator"); return status; } return status; }Removing the translator is done in the
uninitializePlugin()through a call to thederegisterFileTranslator()method ofMFnPlugin.MStatus uninitializePlugin(MObject obj) { MStatus status; MFnPlugin plugin( obj ); status = plugin.deregisterFileTranslator("RawText"); if (!status) { status.perror("deregisterFileTranslator"); return status; } return status; }Reader Method
You need to implement a
reader()method if you wish to load a file type that is supported by your file translator.The
haveReadMethod()method checks if the translator provides a read method. In theLepTranslatorclass, the method returns true because thereader()method exists.The
reader()method reads each line of the file and returns aMS::kFailureif it cannot be opened by the translator. If a file type cannot be recognized by the translator, the method creates a new object via MEL to support the data in that file.MStatus LepTranslator::reader ( const MFileObject& file, const MString& options, MPxFileTranslator::FileAccessMode mode) { #if defined (OSMac_) char nameBuffer[MAXPATHLEN]; strcpy (nameBuffer, file.fullName().asChar()); const MString fname(nameBuffer); #else const MString fname = file.fullName(); #endif MStatus rval(MS::kSuccess); const int maxLineSize = 1024; char buf[maxLineSize]; ifstream inputfile(fname.asChar(), ios::in); if (!inputfile) { // open failed cerr << fname << ": could not be opened for reading\n"; return MS::kFailure; } if (!inputfile.getline (buf, maxLineSize)) { cerr << "file " << fname << " contained no lines ... aborting\n"; return MS::kFailure; } if (0 != strncmp(buf, magic.asChar(), magic.length())) { cerr << "first line of file " << fname; cerr << " did not contain " << magic.asChar() << " ... aborting\n"; return MS::kFailure; } while (inputfile.getline (buf, maxLineSize)) { //processing each line of the file MString cmdString; cmdString.set(buf); if (!MGlobal::executeCommand(cmdString)) rval = MS::kFailure; } inputfile.close(); return rval; }Lines of files are processed in order to add new objects to the model.
Writer Method
You need to include a
writer()method if you want to save a file type that is supported by your translator.The
haveWriteMethod()method checks if the translator has a write method. In thepolyExporterclass, the method returns true because thewriter()method is implemented.The
writer()method provides a message through the script editor and returns a status to indicate the results.In this example, only ‘export all’ and ‘export selection’ options are allowed when trying to save data. Other options will result in the display of a failure message through the script editor and returns a
MS:kFailure, which indicates that the file type cannot be understood by the translator. For your plug-in, you will have to set your own identifier string. If the method is successful, the data will be saved as a new file in a file type that is supported by the translator.MStatus polyExporter::writer(const MFileObject& file, const MString& /*options*/, MPxFileTranslator::FileAccessMode mode) { #if defined (OSMac_) char nameBuffer[MAXPATHLEN]; strcpy (nameBuffer, file.fullName().asChar()); const MString fileName(nameBuffer); #else const MString fileName = file.fullName(); #endif ofstream newFile(fileName.asChar(), ios::out); if (!newFile) { MGlobal::displayError(fileName + ": could not be opened for reading"); return MS::kFailure; } newFile.setf(ios::unitbuf); writeHeader(newFile); if (MPxFileTranslator::kExportAccessMode == mode) { if (MStatus::kFailure == exportAll(newFile)) { return MStatus::kFailure; } } else if (MPxFileTranslator::kExportActiveAccessMode == mode) { if (MStatus::kFailure == exportSelection(newFile)) { return MStatus::kFailure; } } else { return MStatus::kFailure; } writeFooter(newFile); newFile.flush(); newFile.close(); MGlobal::displayInfo("Export to " + fileName + " successful!"); return MS::kSuccess; }IdentifyFile Method
This method is typically used to check if the file extension of the file in question is the correct file type for the translator.
When a file is encountered, Maya calls the
identifyFile()method and queries each translator until it finds an appropriate match. The method is given anMFileObjectindicating the file being checked and a pointernameto the initial file contents. In this example below, any file types being passed to this method other than.animwill result inMS::kNotMyFileTypebeing returned, which indicates that the translator cannot understand the file type. Otherwise, the file is understood by the translator and is able to operate in Maya through the translator plug-in.MPxFileTranslator::MFileKind animExportUtil::identifyFile ( const MFileObject &file, const char * /*buffer*/, short /*size*/ ) const { const char *name = file.name().asChar(); int nameLength = (int)strlen(name); if ((nameLength > 5) && !strcasecmp(name+nameLength-5, ".anim")) { return (kIsMyFileType); } return (kNotMyFileType); }File Extensions
The
defaultExtension()method defines the default file extension of a translator and returns a string.In this example, Maya calls the method and saves the file with a
.rawfile extension. Note that the period should not be included in the extension name.FileAccess Mode
The
fileAccessMode()is an enum method that returns the type of file access mode that Maya is currently in. There are six types of file access modes in Maya.In this example, the mode is
kImportAccessMode, which is when Maya imports data into the scene.