次のサンプルは、ファイル トランスレータの使用法を示します。
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() メソッドを実装する必要があります。
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() メソッドを実装する必要があります。
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() メソッドがコールされ、適切にマッチするトランスレータが見つかるまで各トランスレータが照会されます。このメソッドは、チェック中のファイルを示す 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);
}