バイナリではなくASCII形式でFBXを出力したい
Python版FBX SDKでFBXファイルを出力する際に、デフォルトだとバイナリ形式になりますが、ASCII形式で出力したかったので、その方法を調査しました。
サンプルプロジェクトはこちらに置きました。
https://github.com/segurvita/fbx_sdk_python_sample
C++版の公式サンプルコードを参考にした
C++版の公式ドキュメントのこちらのページに、ASCII形式でシーンを保存するサンプルコードを見つけました。
Autodesk FBX 2017 HELP / C++ API Reference / Examples / Common/Common.cxx
該当箇所のC++コードを抜粋します。
int lFormatIndex, lFormatCount = pManager->GetIOPluginRegistry()->GetWriterFormatCount();
for (lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
{
if (pManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
{
FbxString lDesc =pManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
const char *lASCII = "ascii";
if (lDesc.Find(lASCII)>=0)
{
pFileFormat = lFormatIndex;
break;
}
}
}
こちらのコードを読む限り、ASCII形式を表すフォーマットIDというものを、ファイルを出力する際に指定すればよさそうなのですが、そのフォーマットIDはどうやら定数として定義されておらず、動的に検索する必要があるみたいです。(もっと効率よい方法があればどなたか教えてください)
フォーマットIDを検索する処理
公式のC++コードを参考にしてPythonのコードを書きます。
ASCII形式のフォーマットIDを検索する処理は以下のような関数にしました。
def get_ascii_format_id(manager):
# 書き出し可能なフォーマットの数だけループ
for formatId in range(manager.GetIOPluginRegistry().GetWriterFormatCount()):
# FBX形式かどうか
if manager.GetIOPluginRegistry().WriterIsFBX(formatId):
# ASCII形式かどうか
if "ascii" in manager.GetIOPluginRegistry().GetWriterFormatDescription(formatId):
# フォーマットIDを返却
return formatId
# ASCII形式が見つからない場合はautoを返却
return -1
引数の manager
には FbxManager.Create()
で生成したインスタンスを入力してください。
戻り値はASCII形式のフォーマットIDです。
ファイルを出力する処理
以下のように exporter.Initialize()
の第二引数に、先ほどの関数を指定します。
exporter = FbxExporter.Create(manager, "")
exporter.Initialize("./test.fbx", get_ascii_format_id(manager))
exporter.Export(scene)
これで無事にASCII形式のFBXを出力することができました。
さいごに
for文とか、C++とPythonで文法が全然違うので、書いてて面白いです。
サンプルプロジェクトはこちらに設置しました。
https://github.com/segurvita/fbx_sdk_python_sample
また、本記事作成にあたり、以下のサイトを参考にさせていただきました。ありがとうございました。