Skip to content

Flattenでレイヤーをコントロールしよう

前回 のConfigureノードを利用することで、自分の意図したところで
usdaファイルをコントールできることがわかりました。
ですが、それだけだとUSDファイルに名前をつけて保存はできますが
レイヤーの数だけUSDファイルが作成されてしまい、コントロールができなくなってしまいます。

また、場合によっては結果が意図しない形になったりすることもあるので
前回の補足としてFlattenについてまとめてみます。

Flattenとは、複数別れているレイヤーを1つのレイヤーに統合することです。
Flatttnをすると、コンポジションアークで別のレイヤーを読み込んでいたりする場所も
1つのレイヤーにまとめることができます。

このFlattenがSOLARIS上でどう扱われているかというと、

たとえばマージノードには Merge Styleという項目があり

このように、2つのレイヤーをマージした場合、
デフォルトの Separate Layers であれば、マージ結果は 2Layersになります。
つまり、2つのレイヤーが合成されている状態(レイヤーの状態は保持されたまま)
というわけです。

これを Flatten Layers にすると、 2 Layers という表示がなくなりました。
どうなったかというと、
今までは 2つのレイヤーがそれぞれ保持されていて、それをコンポジションしていたのが
それぞれのレイヤーにあった情報が1つのレイヤーに統合されたという状態になっています。

つまり、Flattenしていない場合は、 USD ROPなどでExportするときに
SavePathをしていない場合は、1つの USDファイルではなく
複数の USDに分かれて出力されることになります。
一方でFlattenしている場合は、出力されるUSDは1つだけになります。

なので、USDの出力する単位をどうするかをコントロールしたい場合は
このFlattenの設定(色んな所にある)をコントロールしていけばいいことになります。

トラップ その1 - Pruneしたら...

出力する単位を管理する以外に、これを正しく指定しないと
結果が意図しないことになる場合があります。
それがPruneノードを使用して1つのUSDを複数に切り分けるような処理をした場合です。

実際にやってみます。

こういうサンプルを用意します。

Pruneで切り出す前のシーングラフはこんな感じ。
CubeとSphereがそれぞれあるような状態。
これを、 Cubeだけ Sphere だけで切り出してそれぞれ別レイヤーとして
出力する。
そして最後に1つにコンポジションをしたいとします。
なので、最終的にはCubeとSphereは両方見えていてほしいです。

が、この結果がどうなるかというと

こうなります。
両方消えてしまいました。

これは、USDのレイヤーそれぞれは非破壊でオーサリングした情報を持っています。
で、この Prune3 側のレイヤーがどうなってるかというと

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#sdf 1.4.32
(
    framesPerSecond = 24
    metersPerUnit = 1
    timeCodesPerSecond = 24
)

def HoudiniLayerInfo "HoudiniLayerInfo" (
    customData = {
        string HoudiniCreatorNode = "/stage/prune3"
        string[] HoudiniEditorNodes = ["/stage/prune3"]
    }
)
{
}

over "sphere1"
{
    token visibility = "invisible"
}

Pruneで消したPrimには「visibility」が invisible (非表示)が指定されています。
で、この invisible したものがつぎのマージノードで
サブレイヤーされてしまうので
結果両方のノードがきえてしまうというわけです。

じゃあこれはどうすりゃいいんだ?っていうときに使用するのが
前回も使用したConfigureLayerノードです。

まず、Pruneノードの Methodを Deactive にします。

Pruneノードの次にConfigureLayerを追加します。

そして Configure Layer の Flatten Input を Flatten Input Stage します。

結果のシーングラフを見ると

先ほどとは違い、PrimがHideではなく削除されて
切り出されたモデルのみになっています。

何が起きたかというと、 Pruneノードで切り出されてモデル以外は
Activeが False 状態になります。
これだけだとあくまでも「無効化」された状態なだけで、
レイヤーには情報が存在します。
いわゆる、PhotoShopのレイヤーの表示をOFFにしたのと同じ状態です。

これを、Flatten Input Stageすると、Photoshopのレイヤー統合を実行したのと
同じ状態になり、いままで非表示にしていただけのPrimは
なくなってしまいます。

結果。
それぞれ切り出されてFlattenした状態のレイヤーを合成したら
そもそも visibility や active の情報はすでになく
単純に切り出されたモデル同士を合成したことになるので
両方消える...みたいなことにはなりません。

SOLARIS上の合成処理はコンポジションアークのルールで行われているので
このあたりの構造を理解していないと、意図しない結果になるので
注意が必要です。

トラップ2 消えるバリアント

というわけで、場合によってはFlattenしてレイヤーをまとめたりする必要が
あることはわかりましたが
このFlattenを入れたせいで意図しないことが起きる場合があります。

例として、こういうシンプルなバリアントセットを用意します。
これで複数のモデルをきりかえできるようになります。

これに、ConfigureLayerを追加して

Flatten Input Stage してみます。

結果、追加したはずのバリアントセットが消滅しました。

なぜかというと、Flatten(Flatten Input Stage) は
USDのコンポジションなどを1つのレイヤーにまとめる処理だからです。
なので、バリアントセットもなくなって
現在選択されているバリアントセットのみが残る...ということになります。

こういうシンプルな場合は問題なのですが、
ノードが複雑になって、複数のレイヤーを合成するようなことをすると
Flatten Input Stage してコンポジション(とくにバリアントが)がきえて
混乱する...ということにもなりかねないので
注意が必要です。(やらかした)

なお、 Configure Layerの Flatten Input にはもう1つ
Flatten Input Layers というのがありますが
こちらは複数に分かれたレイヤーを1つにまとめるもので
MergeノードのFlatten Layersと同じ挙動になります。

この場合は、「2 Layers」という表記がなくなり、1つのレイヤーに統合されただけで
コンポジションの合成などの情報は非破壊で保持されます。

まとめ

というわけで、ConfigureLayerとFlattenを利用することで
どこまでをどのレイヤーに入れるかをコントロールできることがわかりました。

これがどういうときに役立つかと言うと
例えばSOP内で作ったモデルをUSDアセットとして出力する場合に
どのようにモデルを分割して、どのように出力するかをコントロールしないと
すべてのレイヤーに重複したデータが保存されるので
ファイルサイズが増えたり、いらないPrimが含まれたUSDファイルが出来上がります。

ので、SOLARIS上で色々加工してアセットを作りたい場合などは
FlattenとConfigureLayerのExportPath指定などを活用して
最終的にUSD ROPなどで出力される USD ファイルの構造を
コントロールすると良さそうかなと思います。