On this page |
MayaとHoudiniでは、ジオメトリの表現や構成に多くの違いがあります。 その結果、プラグインのアーキテクチャには、分かりにくい特異な挙動がいくつかあります。 問題の背景が分かりやすいよう、DGでプラグインノードがどのように表示されるか、いくつかの例を以下に示します:
DAGとDGの制限事項、および同期 ¶
Mayaジオメトリは、DAG内に存在するシェイプノードで構成されています。 各シェイプが1種類のジオメトリで、各シェイプノードに親トランスフォームが必要です。 Maya DAGとディペンデンシーグラフは、計算/再生中に変更されるようにはできていません(DGモードなら注意すれば上手くいくかもしれませんが、評価マネージャのほうはもっと厳しいです)。
これが、同期する理由です。 HDAがどのようなジオメトリを出力するのか事前には分からないこともあり、アセットノードの計算中に出力ノードを作成(または削除)することはできません。 一方で、(表示可能な)出力がない場合、アセットノード自身は計算しません。 そのため、同期コマンドがアセットノードの計算を開始し(つまりHDAのクック)、出力アトリビュートを反復させて、出力ジオメトリの作成と接続を行ないます。
以下の例は、単純な出力メッシュがどのように接続されるのかを示しています。 OutputObject系アトリビュートは、対応している出力ジオメトリタイプすべてを網羅しているため、カーブ、パーティクル、さらには流体までも出力できたりするので、それに呼応するジオメトリ形状はMayaで作成する必要があります。
例えば、アセットが最初にインスタンス化されたり、接続された入力が変更されたときなど、同期すべきことが明らかな場合があります。 出力が変更されたかどうかが明らかでない場合は、自動同期オプションが、クックによって出力が追加されたり削除されたかどうかの判断を試みて、該当する場合は同期をトリガーします。 現在出力がなくても、入力やパラメータが変更されていればautoSyncも呼び出されます。
autoSyncはアイドル時に起こるため、再生中でもまだ呼び出されません。 再生の開始時に出力が存在しない場合には、再生を開始する前、出力が存在する後のフレームで、同期する必要があります。 例えば、タイムスライダの開始より後にパーティクルHDAの開始フレームがある場合などです。 フレーム毎に出力されるオブジェクトの数が変化するの場合でも、新しいオブジェクトは追加されません。 例えば、HDAがアニメーション入力でブーリアン演算を実行する場合、個々のピースが最大数になるフレームで同期する必要があります。 これにより、どのフレームでもパーツすべてをキャプチャするのに十分な数の出力メッシュの接続が存在するようになります。
autoSyncが既にリクエストされている場合には、別のautoSyncをキューしないよう注意しますが、マウス移動イベント間のautoSyncでは、インタラクティブ性を十分に確保するのは困難です。 またautoSyncは、再生キャッシュなど、アイドル時に起こる別のアクションと一緒では上手く機能しないため、必ずしも最善の選択肢とは言えません。 変更によってDG接続あるいは出力ノードの変更が必要だと検出できないケースもある点に留意してください。
パラメータ vs アトリビュート ¶
Houdiniパラメータは、無効または非表示にすることができます。 Mayaアトリビュートには、様々なタイプのプロパティがあります。 Mayaアトリビュートはロックすることができます(つまり、一時的に編集や接続を行なえなくなります)。 また、Mayaアトリビュートはチャンネルボックスに表示することができます(接続可能な場合は、チャンネルボックスにも表示されます)。
アトリビュートエディタに関しては、ウィジェットを可視またはグレーアウトするかどうかは、そのウィジェットに関連付けられたコールバックスクリプトによって決まるのであって、アトリビュートのプロパティの性質によるものではありません。 そのため、アトリビュートエディタの表示をHoudiniパラメータUIと同じようにするには、すべてのパラメータアトリビュートにコールバックを追加して、パラメータの非表示/無効を決定するコマンドを用意する必要があります。 それも一案ですが、そのようにすると、パフォーマンスに悲惨な影響が出る恐れがあります。
そこで、パラメータが非表示の場合はアトリビュートを追加せず、パラメータが無効の場合にはアトリビュートをロックすることにしました。
こうするとユーザには、Houdiniで表示されるのと同じようにアトリビュートやパラメータが表示されます。
しかし、挙動は同じではありません。
パラメータの可視性が変更された場合はSyncAttributes
が必要であり、無効なアトリビュートのロックは、ユーザ独自のロックワークフローと干渉する可能性があることに留意してください。
メッシュジオメトリ ¶
Houdiniでは、プリミティブ内で同じエッジを両方向に使用することができますが、Mayaではできません。 例えば、この穴にブリッジがあるジオメトリは、Houdiniでは有効ですが、Mayaでは有効ではありません。
これを修復するいくつかのバージョンのクリーンアップHDAがmaya_unsupported_prims.hda
やそれに類似した名前でフォーラムなどから入手することができます。
これらは、問題のプリミティブを三角形化して、ポイント/エッジを再利用している残りの縮退三角形を削除します。
ジオメトリがクリーンアップされていない場合でも、出力メッシュは作成されますが、Mayaはインデックスし直された情報がない状態で出力メッシュを作成するときは問題のコンポーネントを省略します。
その結果、UVやカラーの適用先は分からなくなるため、出力のUVやカラーが失なわれます。
カーブ ¶
Mayaにはカーブがありますが、カーブネットワークはなく、それぞれのカーブにシェイプノードがあります。 そのため、例えばHoudiniのヘアーは、何千もの個別のカーブになります。 大量のヘアーでなくても、使い物になるほどのインタラクティブなパフォーマンスを得ることはできません。 レンダリング時のみカーブを取り込むのは部分的な解決にすぎないでしょうが、大量のカーブをインタラクティブに視覚化するのは不可能です。
実装でもちょっとした違いが多くあるようです。 MayaとHoudiniでは閉じたカーブの解釈が異なるため、双方に転送し合うと思いがけない結果になることがあります。 MayaのカーブではKnot Multiplicity(ノットの多重性)をOrder(階数)より大きくすることができますが、Houdiniではできません。 また、Bezierカーブも完全には一致しません。表現の一致を向上させる必要がありますが、現時点ではまだ不一致が残っています。
単位 ¶
Mayaの内部単位はセンチメートルで、Houdiniの単位はメートルですが、私どもは変換なしにデータを送ることにしました。
しかし…Mayaの旧式のダイナミクスでは、センチメートルをメートルとして扱います(同じ理由でnucleusのデフォルトも古い設定になっています)。
そのため、Mayaのシミュレーションで使用するようにモデリングされたジオメトリをHoudiniに送ってシミュレーションに使用した場合、スケールされなくてもMayaで期待通りの結果となります。
アセットオプションにpreserveScale
オプションを追加するようにとRFE(機能拡張要求)があります。
インスタンス化 ¶
MayaにはDAGインスタンスとパーティクルインスタンスがあります。 アセットオプションに応じて、パックプリミティブをそのいずれかに変換することができます。 しかし、パーティクルインスタンスが真に役立つのは、パックプリミティブに同じジオメトリの複数のインスタンスが含まれていて、異なるジオメトリが多く含まれていない場合のみです。 インスタンサーは、固有のジオメトリ毎に固有のMayaシェイプ入力があると想定します。 最悪の場合、各ジオメトリをシェイプとして出力し、それらをインスタンサーに接続して非表示にしてから、Mayaでインスタンサーの出力を表示します。
Mayaインスタンサーやパーティクルインスタンサーからのパックプリミティブの作成は対応していません。
Mayaのパーティクルインスタンサーには出力ジオメトリがなく、描画およびレンダリングができるだけです。
インスタンスジオメトリをHoudiniに取り込むためには、入力とアトリビュートに基づいてパーティクルインスタンサーの機能を再現する必要があります。
MayaのDAGインスタンスの取り込みはむしろUIの問題であり、(いつかは、理論上は)houdiniInputGeometry
ノードにわずかな変更を加えるだけで実装することが可能です。
ダイナミクス ¶
Mayaの流体およびパーティクルには実際にコンストラクションヒストリーがないので、流体およびパーティクル出力用にMaya nCache入力を乗っ取ることにしました。
そのため、流体/パーティクルのMayaキャッシュの作成が問題になります。
CreateCache
はキャッシュファイルを書き出しますが、Houdiniアセット接続が既に存在しているため、そのキャッシュの接続は失敗します。
キャッシュは作成済みのため、流体またはパーティクルノードを複製し、作成されたキャッシュを新しいノードに割り当てるという回避策が考えられますが、UI、あるいは少なくともそのサンプルスクリプトを用意できるのが理想的です。
Houdiniではage(秒数)が明示的に示されますが、MayaではbirthTimeおよび現在のフレームから計算されます。
アセットがbirthTime
アトリビュートを明示的に定義している場合、それが出力に使用され、そうでない場合はageからbirthTimeを計算します。
コンストラクションヒストリー ¶
アセットを接続するオプションを、既存のシェイプのコンストラクションヒストリーとして追加すると、Mayaの Delete->History がプラグインノードで停止し、ヒストリーチェーン全体が削除されないことが分かりました。 また、ヒストリーチェーンからアセットノードを削除した時には、ネイティブのMayaメッシュのヒストリーとは異なり、ヒストリーでギャップが再接続されません。 こうした問題に対処するため、HoudiniEngineメニューには独自バージョンのDeleteHistoryやRemoveAssetFromHistoryが追加されています。
ライブラリの干渉 ¶
Engineがプロセス内で実行中、多くの干渉が発生しました(多くはQTの干渉で、UI依存関係のあるHoudiniモジュールをロードすることが原因でした)。
モジュールファイルは、すべての問題のあるDSOのリストに、HOUDINI
、_DSO_EXCLUDE_PATTERN
を設定します。Engineをプロセス外のみで実行できるようになるため、クライアント側の干渉はかなり少なくなります。
リストから一部のライブラリを削除しましたが、ROP_OpenGL
やOBJ_ReLight
などのライブラリが見つからないことが原因で、HDAがEngineをクラッシュさせていたものだけです。
そのリストの他の多くのdsoのライブラリも安全に削除することは可能でしたが、残りのものには固有のバグがありませんでした。
他のプラグインと干渉する可能性も残っています。Windowsでは、PATHがモジュールの仕様から変更されると、他のプラグインに同じ名前を持つライブラリがある場合に(例えばHoudiniのライブラリとmental rayのライブラリなど)、干渉が起こります。
大多数のユーザにとって、mental rayは問題にならないでしょうが、他のブラグインで同様の問題が起こる可能性もあります。
LinuxでもLD_LIBRARY_PATH
の干渉が起こり得ますが、HoudiniのプラグインはLD_LIBRARY_PATH
での設定に依存していないため、プラグインを自動起動する前にLD_LIBRARY_PATH
の設定を解除するオプションを用意しています。
同様に、PYTHONPATH
が設定されていると、干渉が起こる可能性があることも分かりました。
プラグインのプリファレンスで Unset PYTHONPATH を有効にすると、Houdini Engineサーバーを起動する前や、Houdiniで View Assets in Houdini メニューアイテムを介してアセットを表示する際に、PYTHONPATH
変数がクリアされます。