API ガイド > ファイル トランスレータを作成する >

# ファイル トランスレータのサンプル

次のサンプルは、ファイル トランスレータの使用法を示します。

プロキシ ポリゴン エクスポータの実装

polyExporter クラスは MPxFileTranslator から派生し、writer() などいくつかの仮想メソッドを定義します。

    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;
    };

プラグインの初期化

プラグインを初期化する場合、MFnPlugin を使用して新しいファイル トランスレータを登録する必要があります。registerFileTranslator メソッドには 6 個の引数が関連付けられています。後半 3 つの引数はオプションです。

このサンプルでは、引数 Rawtext がファイル トランスレータ名です。option1=1 引数には、トランスレータのオプション ボックスに使用するオプション文字列の既定値が含まれます。最後の引数はブーリアン型で、トランスレータ内部で MEL スクリプトを実行可能かどうかを定義します。この引数を true 値にすると、MGlobal::executeCommand メソッドを使用して MEL コマンドを実行できます。

    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;
    }

トランスレータの除去は、MFnPlugin の deregisterFileTranslator() メソッドをコールして uninitializePlugin() で実行されます。

    MStatus uninitializePlugin(MObject obj)
    {
        MStatus status;
        MFnPlugin plugin( obj );
        status = plugin.deregisterFileTranslator("RawText");
        if (!status) {
            status.perror("deregisterFileTranslator");
            return status;
        }
        return status;
    }

reader メソッド

ファイル トランスレータによってサポートされているファイル タイプをロードする場合は、reader() メソッドを実装する必要があります。

haveReadMethod() メソッドは、トランスレータが read メソッドを提供しているかどうかチェックします。LepTranslator クラス内では、reader() メソッドが存在するためこのメソッドは true を返します。

    bool LepTranslator::haveReadMethod () const
    {
        return true;
    }

reader() メソッドはファイルの各ラインを読み取り、トランスレータが開けない場合 MS::kFailure を返します。トランスレータがファイル タイプを認識できない場合、このメソッドはそのファイルのデータをサポートするための新しいオブジェクトを MEL 経由で作成します。

    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;
    }

モデルに新しいオブジェクトを追加するため、ファイルの各ラインが処理されます。

writer メソッド

ファイル トランスレータによってサポートされているファイル タイプを保存する場合は、writer() メソッドを実装する必要があります。

haveWriteMethod() メソッドは、トランスレータに write() メソッドが存在するかどうかチェックします。polyExporter クラス内では、writer() メソッドが実装されているためこのメソッドは true を返します。

    bool polyExporter::haveWriteMethod() const
    {
        return true;
    }

writer() メソッドはスクリプト エディタを介してメッセージを提供し、ステータスを返して結果を示します。

このサンプルでは、データの保存時に許可されているのは、すべて書き出し(Export All)オプションと選択項目の書き出し(Export Selection)のみです。その他のオプションでは、スクリプト エディタに失敗メッセージが表示され、トランスレータが該当するファイル タイプを解釈できないことを示す MS:kFailure が返されます。お使いのプラグインで、独自の識別文字列を設定する必要があります。メソッドが成功した場合、トランスレータがサポートしているファイル タイプの新しいファイルとしてデータが保存されます。

    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 メソッド

このメソッドは通常、対象のファイルの拡張子がトランスレータにとって正しいものかどうかをチェックするのに使用します。

ファイルが検出されると identifyFile() メソッドがコールされ、適切に一致するトランスレータが見つかるまで各トランスレータが照会されます。このメソッドは、チェック中のファイルを示す MFileObject とファイルの内容の初期値を指すポインタ name を備えています。次の例では、このメソッドに渡された .anim 以外のすべてのファイル タイプに対して MS::kNotMyFileType が返されます。これは、このファイル タイプをトランスレータが解釈できないことを示します。それ以外の場合、ファイルはトランスレータによって解釈され、トランスレータ プラグインを経由して Maya で操作することができます。

    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);
    }

ファイル拡張子

defaultExtension() メソッドは、トランスレータの既定のファイル拡張子を定義し、文字列を返します。

    MString polyRawExporter::defaultExtension () const
    {
        return MString("raw");
    }

この例では、このメソッドがコールされて拡張子 .raw でファイルが保存されます。拡張子の名前にはピリオドを含めないでください。

ファイル アクセス モード

fileAccessMode() は、Maya が現在動作中のファイル アクセス モードのタイプを返す enum メソッドです。Maya には 6 タイプのファイル アクセス モードが存在します。

この例では、モードは kImportAccessMode です。これは Maya がデータをシーンに読み込むときのモードです。

    if (mode == kImportAccessMode) {
        status = importAnim(animFile, pasteFlags);
    }