On this page |
概要 ¶
USDの背景情報、LOPノードがUSDレイヤーを生成する方法については、USDの基本とLOPノードについてを参照してください。
LOPネットワークは、USDステージをゼロから、または、トップレベルのUSDファイルから生成し、場合によってはファイルからUSDレイヤーを追加します。 ネットワークの最後では、完了したUSDを書き出すことができます。これには、トップレベルのファイルとレイヤー毎のファイルといった複数ファイルの書き出しを伴うことが多いです。
ディスクから読み込まれたレイヤーは、保存工程では常に変更なしのままになります。とはいっても、LOPノードで生成された匿名レイヤーは、既存のディスク上のレイヤーファイルを上書きすることができます。
How to ¶
-
USDを書き出すメインノードは、USDノードです。このノードは、LOP(LOPネットワークの最後に配置することができます)またはROP(レンダーネットワーク内に配置して、出力したいLOPネットワークを指すことができます)として利用可能です。
(特別なオプションの詳細は、以下のUSDを書き出す別の方法を参照してください。)
-
USDZファイルを作成したいのであれば、既存のUSDファイル一式から単一の自己完結型のUSDZファイルを作成するUSD Zipノードを使用すると良いでしょう。このファイルは、すべてのレイヤーファイルとそれらのレイヤーファイルで使用されているすべてのテクスチャを含んだアーカイブです。これは、インターネット上で最終USD作品を公開するのに非常に役に立ちますが、このファイルフォーマットには制限があるため、パイプラインでのほとんどの用途には適しません。これは修正するのが面倒で(個々のファイルに展開してから、それぞれ修正してから、再びパッケージ化しなければなりません)、USDZアーカイブ内にボリュームファイルを入れることはできません。
ファイルの出力先 ¶
-
USDノードでは、ルートレイヤーのデータを含んだ“トップレベル”のUSDファイルのファイルパス( Output File パラメータ)を指定します。
このファイルの他にも、このノードは、保存パスメタデータでUSDファイルの出力先が設定されたレイヤーを書き出します。
-
Configure Layer LOPを使用することで、ネットワーク内のレイヤーの保存パスを割り当て/変更することができます。USDを出力する時、そのレイヤーがディスクに書き出されるようになります。
-
SOP Import LOPとSOP Create LOPでも、USDを書き出す時に書き出されるジオメトリの保存パスを指定することができます。
-
保存パスは、HIP(
$HIP/props/lamp.usd
)などのグローバル変数を使用することが多く、絶対パスで指定してください。保存処理時に、デフォルトではUSDノードは、絶対パスをレイヤーファイル間での相対パスに変換する出力プロセッサを使用します。これによって、すべてのレイヤーファイルをある場所から別の場所に移しやすくなります。 -
USDノードの Flush Data After Each Frame パラメータは、各フレームを計算した後にデータをディスクに書き出すかどうかを制御します。 このオプションを使用することで、出力ファイル名または保存パスに時間変化のコンポーネント(例えば、
$F
)が含まれているかどうに応じて、それぞれ単一タイムサンプルを含んだUSDファイルのシーケンス(例えば、lamp_0001.usd
、lamp_0002.usd
など)または全フレームのタイムサンプルデータを含んだ単一ファイルを生成することができます。
出力プロセッサ ¶
出力プロセッサは、参照している外部ファイルで使用されているファイルの場所とファイルパス文字列を変更することができるPythonプラグインです。 さらに、出力プロセッサは、保存される直前に各レイヤーファイルに好きなように編集を加えることも可能です。
USDノードは、レイヤーファイル内のファイルパス参照を相対パスに変換するデフォルトの出力プロセッサを使って開始します。
独自の出力プロセッサを記述する方法 ¶
-
$HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors
という新しいディレクトリを作成します。(この例では、私どもはユーザープリファレンスディレクトリ内にこのプラグインを作成していきます。もちろん、Houdiniパス上の任意のディレクトリ下に
husdplugins/outputprocessors
ディレクトリを配置しても構いません。) -
$HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors
内に、出力プロセッサプラグイン用のPythonファイルを作成します。例:$HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors/outputreview.py
-
Pythonプラグインファイル内で、
husd.outputprocessor.OutputProcessor
クラスをサブクラスにします。このサブクラス内で、固有名を返す
name()
静的メソッド、出力プロセッサの処理内容(例えば、出力パスを基準にパスを保存
)を記述した文字列を返すdisplayName()
静的メソッドを実装します。import hou from husd.outputprocessor import OutputProcessor class ReviewOutputProcessor(OutputProcessor): @staticmethod def name(): return "review" @staticmethod def displayName(): return "Manually Review Every Output Path"
-
このファイルの最後に、引数なしで受け取り、コールされる度にクラスを返す
usdOutputProcessor()
という名前の関数を定義します。この関数は、このモジュールを出力プロセッサの実装としてマークし(Houdiniは、この関数を含んだモジュールを検索します)、Houdiniに出力プロセッサオブジェクトのインスタンスの作成方法を示すためにあります。 USD保存処理が開始される度に、出力プロセッサの新しいインスタンスが生成されます。 このインスタンスは、その保存処理の間で使用されます。
import hou from husd.outputprocessor import OutputProcessor class ReviewOutputProcessor(OutputProcessor): @staticmethod def name(): return __class__.__name__ @staticmethod def displayName(): return "Display the list of output files" # 以下の記述が必須です: プロセッサインスタンスを返すモジュールレベルの関数 outputprocessor = ReviewOutputProcessor() def usdOutputProcessor(): return outputprocessor
-
あなたの出力プロセッサを実装できるようにAPIメソッドをオーバーライドします。以下の出力プロセッサAPIを参照してください。
import hou from husd.outputprocessor import OutputProcessor class ReviewOutputProcessor(OutputProcessor): @staticmethod def name(): return "displayoutputfiles" @staticmethod def displayName(): return "Display the list of output files" def processSavePath(self, asset_path, referencing_layer_path, asset_is_layer): # アセットパスを絶対パスにします。 asset_path = hou.text.abspath(asset_path) # このプロセッサは、ユーザーに手動ですべてのファイルパスを書き換えるように促します。 # これは単なるサンプルなので、実行しないでください! 面倒くさいことになります! return hou.ui.readInput( message="Rewrite this output file path if you want", initial_contents=asset_path, buttons=("OK",), ) def processReferencePath(self, asset_path, referencing_layer_path, asset_is_layer): # ファイルパスがソースファイルの位置を基準に指すようにします。 return hou.text.relpath(asset_path, referencing_layer_path) # 以下の記述が必須です: プロセッサクラスを返すモジュールレベルの関数 outputprocessor = ReviewOutputProcessor() def usdOutputProcessor(): return ReviewOutputProcessor
出力プロセッサメソッドAPI ¶
@staticmethod name()
→ str
(必須)
プロセッサの固有名を返します。
Note
必ずサブクラス内でこのメソッドをオーバーライドしてください。
そうしないと、Houdiniがあなたのクラスをインスタンス化しようとした時にNotImplementedError
例外が発生します。
@staticmethod displayName()
→ str
(必須)
ユーザーに表示される出力プロセッサのリスト内でそのプロセッサについて記述したラベルを返します。
このラベルには、プロセッサの機能について記述してください。例えば、Save Paths Relative to Output Path
です。
Note
必ずサブクラス内でこのメソッドをオーバーライドしてください。
そうしないと、Houdiniがあなたのクラスをインスタンス化しようとした時にNotImplementedError
例外が発生します。
@staticmethod parameters()
→ str
このプロセッサがユーザー側で設定できるように表示するパラメータを記述したHoudini“ダイアログスクリプト”を含んだ文字列を返します。
デフォルトの実装は、空っぽのパラメータグループのスクリプトを返すので、 あなたのプロセッサが何もパラメータを必要としないなら、このメソッドをオーバーライドする必要はありません 。
hou.ParmTemplateオブジェクトを中で使ってhou.ParmTemplateGroupを構築して、hou.ParmTemplateGroup.asDialogScriptから値を返すことで、ダイアログスクリプトを生成することができます。
group = hou.ParmTemplateGroup() group.append(hou.StringParmTemplate( "texturedir", "Texture Directory", string_type=hou.stringParmType.FileReference )) return group.asDialogScript()
ここで作成するパラメータの内部名は、必ずレンダーノード上の他のすべてのパラメータ間で固有でなければならないので、
modulename_parmname
のような命名規則を使用するのが良いでしょう(modulenameはhusdplugins/outputprocessors
下のPythonモジュールの名前です)。
beginSave(self, config_node, config_overrides, lop_node, t)
このプロセッサを使ったレンダーノードがファイルの書き出しを始めた時にコールされます。
この時にパラメータ値(必要な情報に基づいてparameters()で追加されたコンフィグパラメータまたはレンダーノード自体のパラメータのどれか)を読み込む機会が得られます。
このメソッドの基底クラス実装を常にコールしてください。
これによって、処理系メソッドで使用できるように、config_node
、lop_node
、t
のパラメータがそれぞれself.config_node
、self.lop_node
、self.t
に格納されます。
config_node
レンダーノードを表現したhou.Nodeオブジェクト。
config_overrides
このノード上に設定可能な値を上書きする際に使用する値のdict
。
OutputProcessor.evalConfig
メソッドを使用することで、config_node
上のマッチしたパラメータを評価して設定値を照会し、
利用可能であればこの辞書からオーバーライド値を受け入れ、利用不可であれば代替値を使用します。
lop_node
保存されるステージを生成したLOPノードを表現したhou.LopNodeオブジェクト。
t
このノードがレンダリングするタイムラインに沿った時間(秒)を表現した浮動小数点値。
このノードからパラメータ値を読み込む時、そのパラメータがアニメーションしている場合はParm.evalAtTime(t)
を使用してください。
processSavePath(self, asset_path, referencing_layer_path, asset_is_layer)
→ str
レンダーノードがアセットを保存するディスク上の場所を決定する必要がある時にコールされます。
asset_path
は、Houdiniが(例えば、USDメタデータまたはHoudiniパラメータから)理解できるファイルパスです。
これは、アセットの保存先となる絶対パスを返してください。
(このメソッドで相対パスを返した場合、そのパスは現行ディレクトリ(os.getcwd()
)を基準にしたパスになります。おそらくそれはあなたが求めているものではないでしょう)
asset_path
Houdiniで指定されたとおりのアセットのパス。
この文字列は、エクスプレッションと環境変数(例えば$HIP
)が既に展開された状態になるので、
他のパスと比較したい場合は、(例えば、os.path.expandvars()
やhou.text.expandString()
を使って)そのパスも展開してください。
referencing_layer_path
このアセットを参照しているレイヤーファイルの処理される保存パス。 このパラメータによって、アセットをシーン内に取り込むレイヤーを基準にそれらのアセットを特定の場所に保存することができます。 これは、ボリュームファイルなどの保存処理中に書き出される非レイヤーファイルで特に役立ちます。
asset_is_layer
このアセットがUSDレイヤーファイルかどうかを示したブール値。
これがFalse
の場合、そのアセットは他の何かです(例えば、テクスチャやボリュームのファイル)。
Note
行内の最初のプロセッサのみが、元々Houdiniに存在したかのようにasset_path
を見ます。
行内のそれ以外のすべてのプロセッサに関しては、最初のコールが返した絶対パスを受け取ります。
processReferencePath(self, asset_path, referencing_layer_path, asset_is_layer)
→ str
レンダーノードがアセット(ファイル内のサブレイヤーまたは参照)を指したファイルパスを書き出す必要がある時にコールされます。
asset_path
アセットのパス。 アセットがUSD保存処理の一部として作成されている場合、これは、すべての出力プロセッサを実行した後のアセットの最終保存パスになります。 この値は常にフルパスになります。
referencing_layer_path
アセットの参照を含んだレイヤーファイルの処理された絶対保存場所。
このパスを使用して、パスポインタを相対パスにすることができます(例えば、hou.text.relpath(asset_saved_path, referencing_layer_path)
)。
asset_is_layer
このアセットがUSDレイヤーファイルかどうかを示したブール値。
これがFalse
の場合、そのアセットは他の何かです(例えば、テクスチャやボリュームのファイル)。
processLayer(self, layer)
レイヤーファイルをディスクに書き出す直前にコールされます。
layer
パラメータには、編集可能なpxr.Sdf.Layer
オブジェクトを渡し、どの方法でも変更することができます。
デフォルトの実装では、レイヤーは変更されません。
このメソッドがレイヤーを変更すればTrue
、変更しないならFalse
を返します。
スクリプトで出力プロセッサを追加する方法 ¶
-
Houdiniは、USDノードインスタンスの
enableoutputprocessor_modulename
(modulenameはhusdplugins/outputprocessors
下のPythonモジュールの名前)という名前のSpareチェックボックスパラメータが有効になっていれば、そのノード上の出力プロセッサを使用します。例えば、
$HOUDINI_USER_PREFS_DIR/husdplugins/outputprocessors/myprocessor.py
で独自のクラスを実装した場合、ノード上にプロセッサをアクティブ化するためのenableoutputprocessor_myprocessor
という名前のSpareチェックボックスパラメータを用意する必要があります。 -
これは、ユーザーインターフェース内のプロセッサリストでプロセッサが非表示(上記の
hidden()
メソッドを参照)になっていたとしても、スクリプトなどで正しいパラメータを作成してそれを有効にすることで、そのプロセッサを有効にすることができることを意味します。Spareチェックボックスを無効またはSpareパラメータを削除することで、プロセッサを無効にすることができます。
-
出力プロセッサが設定用の追加パラメータ(上記の
parameters()
メソッドを参照)を持っている場合でも、スクリプトでそれらのパラメータを作成して値を設定することができます。
アニメーションを保存する方法 ¶
USDレンダーノードの Flush Data After Each Frame パラメータは、各フレームのデータを生成した後にデータを書き出すのかどうかを制御します。 この機能を使用することで、各フレームのデータを含んだファイルを個々に作成したり、制限なくすべてのフレームのタイムサンプルデータを含んだ大きなファイルを作成することができます。
USDレンダーノードの Flush Data After Each Frame を無効にしてフレーム範囲を書き出す時:
-
このROPは、フレーム毎に、ディスクへの保存の準備をした一連のレイヤーを生成しますが、まだIn-Memoryレイヤーのままです。
-
USD Stitchを使って、前フレームでクックされたIn-Memoryレイヤーと現在クックされたIn-Memoryレイヤーを結合します。
LOPネットワークが膨大なデータを生成する場合、(USD Stichはフレーム間で同じデータを複製しませんが)これだと即座に大量のメモリを消費してしまいます。
アニメーションUSDを書き出す際にHoudiniでメモリが足りないようであれば、このオプションを有効にすることで、Houdiniが常に単一フレーム分のデータのみをメモリに格納するように制限することができます。 その結果として、ディスクへの書き込み時間が長くなり、最終ファイルサイズはこのオプションを無効にした場合よりも大きくなってしまいます。 しかし、書き出し可能なデータ量は、コンピュータが利用可能なメモリ量に制限されません。
他にも、それぞれ単一タイムサンプルデータを含んだUSDファイルのシーケンスを書き出してから、USD Stitch Clips ROPを使用してUSD Value Clipを生成する方法があります。 この方法は、その巨大なデータセットが存在するシーングラフツリー内に独立したブランチが存在する場合にのみ機能し、このブランチのデータを別のUSDファイルに書き出すことができます。
USDを書き出す他の方法 ¶
-
Python(Pythonシェルでインタラクティブに、または、Python Script LOPでプロシージャルに)を使って、個々のファイルに書き出すことができます。
-
ノード上で右クリックして、 LOP Actions サブメニューを開いて、 Inspect flattened stage または Inspect active layer を選択することができます。これらのメニュー項目は、ステージ/レイヤーを
usda
コードとして表示するビューアウィンドウを開きます。 このウィンドウからusda
コードをファイルに保存することができます。