NEXTSCAPE blog

株式会社ネクストスケープの社員による会社公式ブログです。ネスケラボでは、社員が日頃どのようなことに興味をもっているのか、仕事を通してどのような面白いことに取り組んでいるのかなど、会社や技術に関する情報をマイペースに紹介しています。

MENU

Mayaで出力したFBXファイルを検査する

こんばんは @hiroakitです。 この記事はNEXTSCAPE Advent Calendar 2021 10日目の記事です。

qiita.com

我が子に「パパってパソコンがないとホント何もできないのね。」と言われ「ああ、そうだ。だから、俺のようにはなるな。」と伝えました。

さて、表題の件にまいりましょう。

Mayaで作成した3DモデルをFBXファイルに出力したら
そのファイルを次の工程に回す前にはどのように検査しましょうか。
(Mayaに限らず、Blenderや3dsMaxなどでも)

例題としてテクスチャのファイルリンク切れをあげましょう。
これは完全なケアレスミスですから避けたい事象です。

例えば、Maya上にお店の看板の3Dモデルがあったとして、その看板にはロゴがあり、ロゴが描かれていたテクスチャ(画像ファイル)をリンク参照で割り当てたとします。その後にFBXファイルで出力して、それを制作環境、開発環境以外の端末で開いたときに (Windowsだと3Dビューア) 看板の3Dモデルにはロゴがテクスチャファイルのリンク切れを起こさずに表示できることをどのように保証しますか。FBXファイルを1つずつ開いて肉眼でチェックしますか?

そこで便利なのがAutodeskが提供するFBX SDKです。
そのSDKを使うことでFBXファイルの中身を知ることができます。

雑ですがFBXファイルからテクスチャのファイルパスを取得する例です。

#include <iostream>
#include <string>
#include <fbxsdk.h>

int main(int argc, char* argv[])
{
    // 実行時引数として先頭にFBXファイルのパスを指定する
    std::string fbx_filename = argv[1];
    std::cout << "FBX: " << fbx_filename << std::endl;

    // FBXのシーン読み込み
    fbxsdk::FbxManager* fbx_man = FbxManager::Create();
    fbxsdk::FbxIOSettings* fbx_io_settings = FbxIOSettings::Create(fbx_man, IOSROOT);
    fbx_man->SetIOSettings(fbx_io_settings);
    fbxsdk::FbxScene* fbx_scene = FbxScene::Create(fbx_man, "");
    fbxsdk::FbxImporter* importer = FbxImporter::Create(fbx_man, "");
    importer->Initialize(fbx_filename.c_str(), -1, fbx_man->GetIOSettings());
    importer->Import(fbx_scene);
    importer->Destroy();

    // マテリアルのテクスチャのファイルパス出力
    int mat_count = fbx_scene->GetMaterialCount();
    for (int i = 0; mat_count > i; i++) {
        FbxSurfaceMaterial* mat = fbx_scene->GetMaterial(i);
        FbxProperty prop = mat->FindProperty(fbxsdk::FbxSurfaceMaterial::sDiffuse);

        // FbxLayeredTextureは割愛
        int fileTexCnt = prop.GetSrcObjectCount<FbxFileTexture>();
        if (fileTexCnt > 0)
        {
            for (int j = 0; fileTexCnt > j; j++)
            {
                FbxFileTexture* tex = prop.GetSrcObject<FbxFileTexture>(j);
                printf("Texture: %s.\n", tex->GetFileName());
            }
        }
    }

    fbx_man->Destroy();
    return 0;
}

上のようなプログラムを組めば、FBXファイルが必要とするテクスチャのファイルパスがわかります。ですので、それを基に関係のあるファイルをまとめて転送するようなコードを追加すればリンク切れは防げそうです。また、FBXファイルを受け取る側も検査の自動化できそうですね。

ということでFBX SDKの紹介でした。