Skip to main 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 側のレイヤーがどうなってるかというと

#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 ファイルの構造を コントロールすると良さそうかなと思います。