コンテンツにスキップ

FileFormatPluginについて

Universal Scene Description AdventCalendar2021 24日目は、FileFormatPlugin についてです。

File Format Plugin とは

https://graphics.pixar.com/usd/release/glossary.html#crate-file-format

FileFormatPluginとは、USDの特徴的な機能の1つで
usd以外のファイルフォーマット(FBX,OBJ,Alembic等)をUSDとしてロードできるようにする機能です。

USDは、繰り返しになりますが 複数のUSDファイル(レイヤー)をコンポジションアークによって合成し
1つのStageになります。
このときのLayerは、 usdc (バイナリ) であったり usda(アスキー) 形式のファイルですが
FileFormatPluginを使用することで、別のファイルフォーマットであっても
あたかもUSDのレイヤーを読んだかのように、別のフォーマットをロードできるようにできます。

Alembic FileFormat Pluginを使う

USDのリポジトリには、デフォルトでAlembicのFileFormatPluginが含まれています。
https://graphics.pixar.com/usd/release/api/usdabc_page_front.html

1
python build_scripts\build_usd.py --alembic C:\USD

USDをビルドするときに、 --alembic オプションを追加すると、AlembicFileFormatを使用できるようになります。

試しに、Blenderからこんな感じのSuzanneを

Alembicで出力します。

そして、このようにabcファイルをリファレンスするレイヤーを用意します。

AlembicPluginを使用した結果、

Alembicをリファレンスでロードすることができました。
アニメーションも持ち込みできているのがわかります。

このように、USD以外のファイルフォーマットを 「さもUSDかのように」 リファレンスにロードすることができました。

ロードしたAlembicファイルは、USDとして扱うことができるので、
このようにMaterialをAssignすることができます。

Alembic を Reference したあとに、MaterialAssignができました。

図に表すとこのようになります。
Alembic であっても、ファイルはLayerとして扱われ、コンポジションされ、Stageになります。

このように FileFormatPlugin をしようすることで、異なるファイルフォーマットを
事前にコンバートすることなく、USDファイルと同様にできるようになります。

デフォルトで使用できるのは、AlembicPluginですが
たとえばFbxFileFormat等を作れば、すでにあるFbxアセットをUSDとして配置できるようになります。
もちろん、AlembicとFbx、その他対応するプラグインがあれば
様々なファイルをUSDに取り込みシーンを構築することが可能になります。

FileFormatPluginを拡張すれば、USDへの導入がやりやすくなるのではないかと思います。

FileFormatPlugin と DynamicFileFormat

FileFormatPlugin は、上のAlembicFileFormatPluginのように「ある別のフォーマットをUSDとしてロードする」FileFormatPluginと
もう1つ 「ある指定の拡張子にすることでプロシージャルにシーングラフを構築する」 DynamicFileFormat が存在しています。

extras/usd/examples/usdDancingCubesExample

それが、この DancingCubesExample です。
このプラグインを使用して、 DynamicFileFormatがどんなものかを見ていきます。

DancingCubeExample を試してみる

まずは、こちらの方法でUSDをビルドしておきます。

そして、 USD/share/usd/examples/plugin 以下の usdDancingCubesExample と usdDancingCubesExample.dll を plugin/usd フォルダにコピーします。
コピーしたら準備完了です。

<InstallDir>/plugin/usd/usdDancingCubesExample/resources/usdDancingCubesExample/dancingCubes.usda

このDancingCubeExampleプラグインを使用したサンプルは、上記のフォルダにあるので、
ンプルの usda ファイルがあるので、usdviewでロードしてみます。

実行するとこのようになります。
DancingしているCubeのStageを開くことができました。
dancingCubes.usda を開いて中を確認すると、

1
2
3
4
5
6
7
8
9
    Usd_DCE_Params = {
        int perSide = 15
        int framesPerCycle = 36
        int numFrames = 200
        double distance = 6.0
        double moveScale = 1.5
        token geomType = "Cube"
    }
    payload = @anon:dummy:cubes.usddancingcubesexample@

Payloadでロードされているのは anon: つまりは 自動生成された無名レイヤの識別子で(参考)
usddancingcubesexample という拡張子のファイルは存在していませんし、 Root 以下の prim_0~を含むような
USDのレイヤーは存在していません。
しかし、実際にはCubeが動くStageが生成されています。

このDancingCubeExampleは、PrimやSchema、AttributeがすでにUSDファイルに保存されているのではなく、
pluginfo.json で追加した Metadata (PluginでCustomMetaDataを追加する方法についてはこちら)の情報を介して、USDのシーングラフを動的に、プロシージャルに生成しています。

動的に生成しているので、
例えば、 dancingCubes.usda の Usd_DCE_Params の perSide を 5 にしてみます。

結果、Cubeの数が 5 個に変化しました。
このように、シーングラフをPlugin内で動的に構築できるのがFileFormatPluginです。
これを利用すれば、わざわざファイルを用意しなくても
なにかしらの情報をもとにしてUSDのシーングラフを生成することができます。
そしてそれをコンポジションで合成することができますので、
例えばレイアウトした各Shotのデータを動的に生成させたりといったことも可能になります。

SdfFileFormat

最後に軽く実装について触れておきます。
FileFormatPlugin も DynamicFileFormatPlugin も、 SdfFileFormatクラスを継承することで実装します。

Info

USD/extras/usd/examples/usdObj/fileFormat.cpp

の、_ReadFromStreamを参考。
UsdObjTranslateObjToUsd クラスで obj ファイル→USDのシーングラフに変換していて、
その結果を layer->TransforContenxt(objAsUsd); で渡しています。

DynamicFileFormatも、SdfFileFormatクラスを継承して実装するのは共通ですが、

DynamicFileFormatは、ReadでStageを作りLayerを返すようにするか、あるいは
完全プロシージャルに生成するのであれば(DancingCubeExampleのように)
SdfAbstractDataクラスを使用することでプロシージャルに生成することが可能です。

SdfAbstractDataは、シーンディスクリプションを格納するためのインターフェースで
あるSdfPath,Field をキーにしてある値のペアを持ちます。

たとえば、上記のようなシーングラフの場合(DancingCubeExampleの生成例)

SdfPath /Root/prim_0/prim_0/prim_0 の Field が TypeName なら Cubeを返すし
SdfPath /Root の PrimChildren なら Rootの子Primを返すし、
SdfPath / (RootPath) で、 Field が DefaultPrim なら DefaultPrim を返します。

このように、SdfAbstractDataは ある問い合わせ(key)に対しての結果を 返すことで
動的にシーングラフを構築しています。

Info

DancingCubeExampleの場合は、

USD/extras/usd/examples/usdDancingCubesExample/data.cpp

にて、SdfAbstractData クラスが実装されています。

PcpDynamicFileFormatInterface

また、DynamicFileFormatPluginの場合
MetaDataから動的精製用のパラメータ(Usd_DCE_Params)を受け取るために
SdfFileFormat とともに、 PcpDynamicFileFormatInterface を実装します。
PcpDynamicFileFormatInterface を実装すると、アセットへのPayloadがある場合
ComposeFieldsForFileFormatArguments を呼び出して、
FileFormatPluginへの引数を生成します。

Info

DancingCubeExample の場合、

USD/extras/usd/examples/usdDancingCubesExample/fileFormat.cpp

上記ファイルで ComposeFieldsForFileFormatArguments が実装されています。
この中で、MetaDataの辞書型から FileFormatArguments を生成して、 FileFormatPlugin の引数にしています。

このあたりの実装は、私自身もまだ勉強中ではあるので
別途カスタムなFormatPlugin実装の記事を書こうと思います。

まとめ

以上がFileFormatPluginでした。
実装についてはかなり端折りましたが、FileFormatPluginがどんなものかわかったでしょうか。

FileFormatPluginを使用すれば、USD以外のファイルもUSDとして扱うことができるようになるので
わざわざUSDにコンバートしなくても、今までのアセットを有効活用したり、異なるFileFormatをUSDで合成したり
できるようになるとわかりました。

また DynamicFileFormat Pluginを使用すれば、USDのPlugin内で動的にシーングラフを構築できるので
ファイルをわざわざ作らなくても、決められた処理をプロシージャルに構築が可能になります。

この機能は、CompositionArc・Schema・AssetResolutionといったこれまで解説してきた機能と同じく
USDのパイプラインを構築する上で強力な武器になりますので
パイプライン構築の際にはぜひとも取り入れてほしい機能です。


最終更新日: 2021-12-23 15:03:55
Back to top