| On this page |
概要
Layout LOPノードには、ポイントインスタンスモデル(例えば、木、茂み、岩、建物)をシーン内にインタラクティブに配置可能なブラシモードがあります。
このノードがマウスイベントからどのようにインスタンスを生成するべきなのかは、 ブラシアセット 側で制御します。
SOPネットワークで独自の挙動が定義された独自のブラシアセットを作成することができます。
このブラシの挙動はコンパイルSOPブロックで定義されているので、カーブやポリゴンの操作ノード、ばら撒きノード、WrangleによるVEXコードを含む(コンパイル可能な)SOPのフルパワーを活かすことができます。
ブラシアセットにパラメータインターフェスを加えることができます。 このインターフェースは、ブラシがアクティブな時にLayout UI内に表示されます。 これによって、あなたの使い勝手に合わせてブラシの挙動をカスタマイズすることができます。
ブラシを実装する前に、おそらく以下のテーマを理解している必要があります:
-
コンパイルブロック。ブラシの実装は、(親のLayoutノードから高パフォーマンスでその実装を呼び出せるように)コンパイルブロックの中で行ないます。コンパイルブロック内で使用可能なSOPノードには制限事項があり、SOPノードがクックするエクスプレッションにも制限事項があります。
-
WrangleノードとVEXスニペット。たいていの場合、何かしらの挙動を実装する最も簡単な方法は、
Attribute Wrangleを使用してアトリビュートを読み込んで、値を計算し、新しいアトリビュートを書き出すことです。とはいえ、これにはVEXスニペットとビルトインのVEX関数に関してある程度の知識が必要になります。
用語
Stroke(ストローク)
ユーザがマウスボタンを押したままマウスを動かしてマウスボタンを離すことです。
Invocation(呼び出し)
ブラシSOPネットワーク内のコンパイルブロックを1回実行することです。 そのコンパイルブロックは、 ストローク 中に何回も呼び出されます。
Tracking Points(トラッキングポイント)
ストローク 中にマウスカーソルからステージ平面/サーフェス上に投影して生成されたポイントのことです。
Model(モデル)
このドキュメントでは、ポイント上にインスタンス化できるUSDモデルのことを Model(モデル) と呼んでいます。 これは、通常ではブラシデジタルアセットノードを指した アセット という単語と混乱を避けるためにそう呼ぶようにしています。
Working Set(ワーキングセット)
ブラシは実質的にLayoutノード用プラグインであり、Layoutステートでマウスクリックやマウスドラッグなどの解釈のされ方をカスタマイズすることができます。 そのLayoutインターフェースの一部として、ユーザは、インスタンス化したいUSDモデルの“Working Set(ワーキングセット)”を構築します。
ブラッシネットワーク内では、このワーキングセットは6番目の入力( **Working Set )のポイント一式で表現されます。
各ポイントのポイント番号(とidPointアトリビュート)は、ポイント上にインスタンス化されるモデルの番号に呼応し、他のPointアトリビュートには境界ボックスなどのモデルに関する基本情報を格納します。
ワーキングセット内の様々なモデルをインスタンス化する方法/インスタンス化するかどうかは、ブラシ側で決めます(以下のワーキングセットの使い方を参照)。
新しいカスタムブラシの作り方
| To... | Do this |
|---|---|
新しくブラシアセットを作成する |
LayoutノードUI内の Brushes セクションにある これは、新しくデジタルアセットを作成するためのダイアログが開きます。 アセットのネームスペース、名前、保存場所を指定することができます。 詳細は、新しくデジタルアセットを作成する方法を参照してください。 このボタンを使って新しくブラシアセットを作成すると、ブラシの実装が簡単にできるように定型ノード、ステッキーノート、定型Pythonコードがそのアセットに取り込まれます。 さらに、その新しいアセットは、Layoutノードで新規ブラシとして自動的に発見されるようにセットアップされます。 |
ブラシアセットを編集する |
|
Tip
Layoutノードは、layout_brushというセクション名を含んだアセットを検索して、利用可能なブラシのリストを構築します。
何かしらの理由で、テンプレートのコピーからではなくゼロからブラシアセットを作成したいのであれば、アセットの Extra Files タブにこの名前のセクションを追加することを忘れないでください。
SOPネットワークの中
-
ブラシは、6本の入力と2本の出力を持ったSOPアセットです。
-
ブラシの中のネットワークには、ユーザがマウスを動かす度に何回も呼び出されるコンパイルブロックが存在します。
-
このコンパイルブロックは、親のLayoutノードからの現行ステートに関する情報とユーザが実行した内容を含んだたくさんの入力を持っています。このコンパイルブロック内のネットワークは、それらの入力からのジオメトリとアトリビュートを使用して、インスタンス先となる新しいポイントを出力したり、既存のポイントを修正または削除します。
-
このコンパイルブロックは、ユーザがストロークを開始する前にマウスを動かしただけでも呼び出されます。これによって、ユーザがシーン上でマウスを動かした時にガイドを表示したり、場合によっては既存のモデルをハイライトさせることができます。
ユーザがストロークをしている時(つまり、マウスをドラッグしている時)にのみポイントを編集したいのであれば、
Switch Ifノードを使用してください。
-
1番目の入力には、現在のストロークで作成した新しいポイントが格納されます。2番目の入力には、親のLayoutノードで既に作成済みの“既存の”ポイントが格納されます。5番目の入力には、(最後のポイントが現在のマウスの位置になっている)現在のストロークを表現したポリラインが格納されます。1番目の出力は、“NEW_POINTS”の新しいリストにしたいポイントが出力されます。
ブラシがその“New Points”をどのように処理するかによって、そのインタラクションスタイルが制御されます。例:
-
コンパイルブロックネットワーク内で、マウス位置における新しいポイント(“Stroke”入力からの最後のポイント)を追加しつつ、1番目の入力(“New Points”)を出力に送り続けると、ストロークがポイントの軌跡を残すようになります。
-
“New Points”入力を破棄して、マウス位置におけるポイント(“Stroke”入力からの最後のポイント)のみを作成して、そのポイントのみを出力に送ると、ブラシはマウスで1個のポイントをドラッグしているように見えます。
詳細は、以下の入力を参照してください。
-
-
新しくポイントを作成するには、
Add SOPを追加し、次に
Attribute Wrangleを追加して、そのポイント上に必要なアトリビュートをコピー/計算します。
最初の2つの入力(“New Points”と“Existing Points”)以外の入力は、他の入力から再利用ポイントを直接使用することはないです(例えば、ストロークの最後のポイント以外のすべてのポイントを削除してから、その最後のポイントを1番目の出力に送ります)。 これらのポイントには、たくさんのアトリビュートが追加されています。
未使用のPointアトリビュートを残しておくと、パフォーマンスに悪影響が出ます。
Tip
Layoutノードは、出力に送信するポイントのPointアトリビュートを自動的に 除去しません 。 ブラシネットワーク外で意味のないアトリビュートがポイントに残っている場合、それらのポイントを出力する前に
Attribute Deleteを使ってそれらのアトリビュートを除去してください。
-
ワーキングセットのモデルをポイント上にインスタンス化するために、以下の事を行ないます:
-
ポイントの
asset_idアトリビュートに、インスタンス化したいモデルに呼応した6番目の入力( Working Set )のポイントのポイント番号を設定します。
-
-
(“New Points”入力または“Existing Points”入力のどれかからの)ポイントを修正するには、以下の事を行ないます:
-
ポイントの位置を設定するには、
vector3タイプのPPointアトリビュートを設定します。 -
ポイント上にインスタンス化されるモデルの向きとスケールを設定するには、その回転とスケールを
matrix3タイプのtransformPointアトリビュートにエンコードする必要があります。Transform SOPを使用すれば、簡単に
transformアトリビュートを設定/編集することができます。 Transofrm SOPをネットワークに追加し、そのノードの Rotate パラメータと Scale パラメータに必要な値を設定し、 Attributes パラメータをtransformに設定してトランスフォームをそのアトリビュートに書き出します。 -
修正したポイントを1番目の出力に送ります。
既存のポイントを修正した場合、そのポイントは削除され、それと同じ新しいポイントが次の呼び出し時に1番目の入力( New Points )に追加されます。 そのため、ストロークで編集した既存のポイントは、そのストロークの“New Points”の一部になります。
Note
インスタンスをスケール/回転させるには、そのスケール/回転を
matrix3タイプのtransformアトリビュートに エンコードしなければなりません 。pscaleやorientなどの他の従来のインスタンス系アトリビュートを使用しないでください。 -
-
既存のポイントを修正しなかった場合、それらのポイントを出力に送らないでください(出力は常に現在のストロークで作成された新しい一連の“New Points”を表現します)。ブラシが既存のポイントに影響を与えなかった場合、その2番目の入力をどこかにまったく接続する必要はありません。
-
既存のポイントを削除するには、そのポイント上に整数
deletePointアトリビュートを作成し、その値を1に設定します。次に、そのポイントを1番目の出力にマージします。現在のストローク(1番目の入力( New Points ))からポイントを削除するには、単にそのポイントを出力に送らなければよいだけです。
入力
ラベル |
説明 |
|---|---|
1. New Points |
現在のストローク 中に前回の呼び出しで追加されたすべてのポイント。 これらのポイントを残したいのであれば(つまり、これらのポイント上にモデルをインスタンス化したいのであれば)、これらのポイントを1番目の出力に接続してください。出力に送られなかった1番目の入力のポイントは破棄されます。 |
2. Existing Points |
ブラシで前回のオペレーションで作成されたすべてのポイント。 これらのポイントは、現在確定されているポイントインスタンスです。 SOPネットワークでは、Pointアトリビュートを変更することで、これらのポイントを修正することができます。 SOPネットワークで2番目の入力( Existing Points )のポイントのアトリビュートを修正すると、親のLayoutノードは、実際に“既存のポイント”のリストのポイントを削除して、(その修正さえた)ポイントを1番目の入力( New Points )に追加します。 既存のポイントを 削除 するには、削除したいポイント上に整数 |
3. Static Geometry |
これは、ユーザがLayoutノードに接続した“コリジョン”ジオメトリです。たいていの場合、アセットの配置先にしたい“地面”ジオメトリを指定します。 追加でポイントを作成する時にこれを使用すると良いでしょう。
例えば、これを |
4. Asset Geometry |
このノードで作成されたすべてのインスタンスのジオメトリ(つまり、既存のポイント上にインスタンス化されたモデルの出力)。 追加でポイントを作成する際にこれを使用すると良いでしょう。
例えば、これを |
5. Stroke |
ポリラインプリミティブが格納されます。このポイントは、現在のストロークに沿って投影された交点を表現しています。 この入力には、現在の瞬間に関する情報(例えば、ユーザが⇧ Shiftキーを押しているかどうか)をエンコードしたグローバル(Detail)アトリビュートも含まれています。 それらのアトリビュートを使用することで、ユーザは修飾キーを使ってブラシの挙動を可変させたりカスタマイズすることができます。
ストロークで利用可能なアトリビュートのリストは、以下のストロークのアトリビュートを参照してください。 |
6. Working Set |
Layoutノードのワーキングセット内の各アイテム(インスタンス化されるモデル)を独立ポイントとしてエンコードします。 モデルをインスタンス化するには、新しいポイントの これらのポイントで利用可能な他のアトリビュートのリストは、以下のワーキングセットのアトリビュートを参照してください。 |
出力
ラベル |
説明 |
|---|---|
1. Output Points |
Invocation(呼び出し)の度に、ここには、インスタンス先となる一連のポイントが格納されます。 ここで出力されたポイントは、次の呼び出し時の1番目の入力( New Points )に追加されます。 |
2. Guides |
インスタンス出力に対して描画されるガイドジオメトリ。 これによって、ユーザは視覚的なフィードバックが得られます。 例えば、ブラシがマウスポインタから特定の半径内にモデルをばら撒くと、そのばら撒き領域の限界を示したリングのガイドを描画することができます。 ブラシアセットのPythonモジュール内に、 アセットのPythonモジュール内に |
ストローク入力のアトリビュート
グローバル(Detail)アトリビュート
名前 |
タイプ |
説明 |
|---|---|---|
|
|
マウスボタンが押されたままかどうか(Trueなら |
|
|
これがドラッグの開始かどうか(Trueなら |
|
|
ユーザがドラッグせずにマウスを動かしているかどうか(Trueなら |
|
|
ユーザがクックしたかどうか(Trueなら |
|
|
これがドラッグの終了かどうか(Trueなら |
|
|
|
|
|
|
|
|
|
|
|
Caps Lockキーが押されているかどうか(Trueなら |
|
|
⌃ Ctrlキー(Macの場合はcommandキー)が押されているかどうか(Trueなら |
|
|
⇧ Shiftキーが押されているかどうか(Trueなら |
|
|
Altキー(Macの場合はoptionキー)が押されているかどうか(Trueなら |
|
|
クリック/ストロークの度に変わる番号が格納されますが、ストローク中は同じ値のままです。 これは、ストローク中は値が変わらないランダム値のシードとして使用するのに役立ちます。 |
|
|
スクリーン空間からワールド空間にマップする変換マトリックス。 これは、スクリーン空間で動作するブラシを実装する時に役立ちます。 |
ストロークポリライン上のPointアトリビュート
5番目の入力のポリラインは、ユーザによるインタラクティブなストロークを表現しています。 このポリライン上の各ポイントは、ストロークに沿って取得されたサンプルを意味しています。 各ポイントには、サンプリングされた交差に関するデータが格納されたアトリビュートがいくつかあります。
ユーザがビューポート内でストロークを“描画”すると、Layoutノードは光線をスクリーン“に”送信して、ポインタが3D空間内の何に当たっているのか調べます。
デフォルトでは、Layoutノードは、既存のインスタンス、静的ジオメトリ(たいていの場合は“地面”)、XZグランド平面に最も近い交点を調べます。 (Layoutノードを使用する際にユーザ側で静的ジオメトリまたは既存インスタンスとの交点を調べないようにするオプションを設定することができます。)
光線がどこにも交差しなかった場合、それでもネットワークは呼び出されますが、Stroke入力の新しいポイントは単に前の有効なポイントのコピーになるだけです。
名前 |
タイプ |
説明 |
|---|---|---|
|
|
3D空間の(交差した)位置。 |
|
|
交差したポイントでの法線。 |
|
|
(マウスポインタのスクリーン座標から算出された)3D空間の交差光線の原点。 これは、スクリーン空間で動作するブラシを作成するのに役立ちます。 |
|
|
3D空間の交差光線の方向(カメラ投影に準拠してマウスポインタがスクリーンに“向かった”方向)。 |
|
|
マウスポインタの水平位置(スクリーンピクセル)。 |
|
|
マウスポインタの垂直位置(スクリーンピクセル)。 |
|
|
マウスポインタがインスタンスモデル上にあった場合、この値には、2番目の入力( Existing Points )のインスタンスのポイント番号が入ります。 例えば、このアトリビュートの値をチェックして、そのポイントを出力しないようにすることで、ドラッグしたインスタンスを削除するブラシを作成することができます。 または、既存のインスタンスを押したり寄せたりするブラシを作成することもできます。 ストロークをインスタンス上で開始すると、そのストロークの開始ポイントに続くポイントを使用して、そのインスタンスのポイントを移動させることができます。 |
|
|
ストロークをタブレットまたは同様のデバイスを使用して作成した場合のそのタブレットペンの角度。 |
|
|
ストロークをタブレットまたは同様のデバイスを使用して作成した場合のタブレットペンの筆圧。 |
ワーキングセットの入力Pointアトリビュート
6番目の入力( Working Set )の各ポイントは、Layoutノードのワーキングセット内の現在のアイテムに呼応しています。
|
|
ポイント番号と同じ。これは、1番目の出力のポイント上に呼応したモデルをインスタンス化するために、そのポイントの |
|
|
このポイントに呼応したモデルの境界ボックスのサイズ。 |
|
|
境界ボックスの中心。 |
この境界ボックス系アトリビュートは、インスタンスを配置する時に交差しないようにインスタンスの間隔を空けたり、占有領域や境界ボックスガイドを表示するのに役立ちます。
詳細は、ワーキングセットの使い方を参照してください。
マルチストロークなブラシ
-
通常では、1回のストロークが終了した時のマウスのUpイベントでそのブラシのコンパイルブロックのポイント出力が“確定”されて、Layoutノードのポイントインスタンスデータに統合されます。
-
必要に応じて、ユーザが複数のストロークを1オペレーションとして作成できるようにブラシを実装することができます。
例えば、クリック/ドラッグの度にユーザが開始点と繋げてフェンスを閉じない限り(または、ユーザがEnterを押してフェンスを開いたままで抜けない限り)フェンス内に新しいコーナーが作成されるフェンス描画ブラシを実装することができます。
マルチストローク操作を使用することで、ユーザは矩形を描画することもできます。その場合、1回のストロークで矩形の一辺の長さを定義し、次のドラッグでその一辺に隣接する辺を引っ張り出してその長さを定義します。
-
現在のオペレーションを現在のストロークの後に続けたいことを親のLayoutノードに伝えるために、1番目の出力に
end_strokeDetailアトリビュートを追加して値を0に設定します。Layoutノードは、そのアトリビュートが存在することを確認したら、現在のオペレーションをアクティブなままにします。 すると、以降のストロークは、“Existing Points”と同じリストにポイントの追加を継続するようになります。
-
次に、現在のオペレーションを終了することを親のLayoutノードに伝えるために、1番目の出力yのその
end_strokeDetailアトリビュートの値を1に設定します。フェンスの作成を例にすると、
Attribute Createノードを作成して
end_stroke整数Detailアトリビュートを作成し、そのノードを1番目の出力に接続することになります。 そしてエクスプレッションやAttribute Wrangleノードを使用して、もし現在のストロークが開始点または1回目のストロークの近くにあればそのアトリビュート値を1に、そうでないなら0に設定します。Layoutノードは、
end_strokeが存在することを確認し、その値が1に設定されていれば、出力を確定します。 -
ユーザはEnter`を押すことでいつでもストロークを終了して現在のオペレーションを確定することができます。
-
マルチストロークなブラシを実装するのは非常に複雑ですが、いくつか役に立つテクニックがあります。
-
一連の
Switch Ifノードを使用して個々のブランチを切り替えることで、異なるイベントタイプを制御することができます。
-
Invocation(呼び出し)とストロークの間で情報を渡す必要がある場合は、1番目の出力に独自のDetailアトリビュートを設定すると良いでしょう。オペレーションが確定しない限り、その1番目の出力からそのDetailアトリビュートが1番目の入力( New Points )にコピーされるようになります。
矩形の描画の例では、Detailアトリビュートを使用することで、現在のストロークがオペレーションの 1回目 それとも 2回目 のどちらのストロークなのか追跡することができます。
-
オペレーションの確定
ユーザがオペレーションを終了した時:
-
Layoutノードは、出力ジオメトリに追加されたすべてのDetaiアトリビュートをクリアします。
出力ジオメトリ上に作成したDetailアトリビュートは、次の反復の1番目の入力( New Points )のDetailアトリビュートとして利用可能です。 これらのDetailアトリビュートを使用して反復(または、マルチストロークなブラシのストローク)間で情報を渡しても、その情報はオペレーション間では渡りません。
パラメータインターフェース
ブラシ用にパラメータインターフェスをデザインすることができます。 そして、そのブラシのコンパイルブロック内でchエクスプレッションを使用してパラメータの値を読み込んで、その値を使ってそのブラシの挙動を変更することができます。
例えば、ユーザがドラッグした時にブラシがばら撒くポイント数を制御することができるDensityパラメータ(内部名がdensity)をブラシアセット上に追加したとします。
そのブラシのコンパイルブロック内で、例えば、Scatter SOPの Force Total Count パラメータに
ch("../density")のエクスプレッションを使用することで、そのDensityパラメータの値をコピーすることができます。
ブラシがLayoutノード内でアクティブになっている時、そのLayoutノードのインターフェースは、パラメータエディタで表示されるものと同じブラシパラメータを表示します。
スクロールホイール
ユーザがスクロールホイールを使ってブラシの挙動を変更できる方法が2つあります。
-
ブラシのパラメータインターフェースに内部名が
scrollで始まるパラメータがあれば、ユーザがマウスホイールをスクロールするとそのパラメータ値が増減します(2個以上のパラメータがscrollで始まっている場合、Layoutノードはそれらすべてのパラメータを変更します)。 -
アセットのPythonモジュール内に
onMouseWheelEvent(kwargs)関数を実装すれば、ユーザがマウスホイールをスクロールすると、Layoutノードステートがその関数をコールします。
ワーキングセットの使い方
ブラシ作成者のあなたは、ユーザが選んだモデルのワーキングセットの使い方を決めることができます。 ワーキングセット内のアイテムの順番に意味を持たせるのかどうか選択することができます。
-
ワーキングセットのよくある使われる方は、(例えば、シーン内にアイテムをばら撒く時に)ワーキングセットからランダムにアイテムを選択することです。
-
ブラシは、ワーキングセットの順番を利用することができます。例えば、ワーキングセット内の1番目のアイテムをシーンに投入し、そのアイテムを中心に2番目のアイテムのインスタンスをおおまかに円状にばら撒いて、さらにそのインスタンスを中心に3番目のアイテムを円状にばら撒くといったブラシを作成することができます(これは、周辺に岩、枯れ枝などの小さな生態系をもった木々を散乱させるのに役立ちます)。
アイテムをランダムに配置するブラシの他の例を挙げると、アイテムの順番を利用して、ワーキングセット内の順番が先のアイテムほど確率が高くなるように、各アイテムが選択される確率に影響を与えることができます。
-
現在のところ、ブラシがワーキングセットの順番に意味をもたせているかどうかをブラシ利用者に自動的に伝える方法がありません。そのため、ブラシのドキュメントにそのことを記載するか、または、ブラシのパラメータインターフェースで制御できるようにする必要があります。
Pythonコールバック
デジタルアセットには、Pythonソースコードを格納するために使用できるセクションが用意されています。 これは、アセットの様々なコールバックで利用できるように共有された便利関数を格納するのに役立つことが多いです。 さらには、もしあればアセットのインタラクティブステートの実装の格納先としても役立ちます。
ブラシアセットに対して、親のLayoutノードはそのアセット内のいくつかの関数をチェックします。
| To... | Do this |
|---|---|
アセットのPythonモジュールを編集する |
|
現在のところ、Layoutノードステートは、ブラシアセットのPythonモジュール内に以下の関数が存在すれば、その関数を使用します。
registerGadgets()
Layoutノードステートからコールされて、ガイドに必須のhou.GeometryDrawableオブジェクトを生成します。
名前とhou.drawableGeometryTypeを含んだタプルのリストを返してください。
def registerGadgets(): return [("line_gadget", hou.drawableGeometryType.Line), ("face_gadget", hou.drawableGeometryType.Face)]
onDrawGuides(kwargs)
Layoutノードステートが再描画を要求された時にこれがコールされます。いくつか重要なkwargsを以下に載せます:
gadgets
文字列とregisterGadgetsで登録されたhou.GeometryDrawableガジェットとのマップ。
draw_handle
ビューハンドル。gadgets引数内のhou.GeometryDrawableガジェットのdraw()メソッドにこれを渡します。
guide_geo
ブラシSOPネットワークのGUIDE_OUT出力に送信されるジオメトリを含んだhou.Geometryオブジェクト。
Note
この引数にNoneを指定することができます。そのため、あなたの関数側で、このNoneをチェックして適切に処理してください。
このオブジェクトを使用することで、ブラシからガイドに情報を渡すことができます。 例えば、テキストDrawableを使用すれば、あなたのブラシが追加したDetailアトリビュートを表示することができます。
def onDrawGuides(kwargs): draw_handle = kwargs['draw_handle'] guide_geo = kwargs['guide_geo'] line_gadget = kwargs['gadgets']['line_gadget'] face_gadget = kwargs['gadgets']['face_gadget'] line_gadget.setGeometry(guide_geo) line_gadget.show(True) line_gadget.draw(draw_handle) face_gadget.setGeometry(guide_geo) face_gadget.show(True) face_gadget.draw(draw_handle)
onMouseWheelEvent(kwargs)
ユーザがマウスホイールをスクロールした時にコールされます。
def onMouseWheelEvent(self, kwargs): # Get the UI device object device = kwargs["ui_event"].device() scroll_amount = device.mouseWheel()
現在のところ、このAPIは垂直以外の軸のスクロールに対応していません。
返される数値に関する情報は、hou.UIEventDevice.mouseWheel()のヘルプを参照してください。
hudTemplate()
これは、このブラシ固有のHUD Infoテンプレート行を指定することができます。 Layoutノードは、これらの行をHUD Infoパネルに挿入します。
この関数は、(トップレベルのテンプレート辞書 ではなくて ) テンプレート行オブジェクトのリスト を返します。 テンプレートフォーマットに関する情報は、HUD Infoパネルを参照してください。
def hudTemplate(): return [ {"key": "G", "label": "Change brush shape"}, {"key": "mousewheel", "label": "Change brush radius"}, {"key": "LMB", "label": "Scatter instances"}, {"key": "Shift + LMB", "label": "Smooth instance orientations"}, ]
hudUpdate()
この関数は、ブラシの変更、または、layout.utils.requestHUDUpdate関数を介して更新が発動された事が発端で、LayoutノードステートがHUDを更新する必要になった時にコールされます。
これは、モデルなどの何かが変更された時にHUD内の値を更新するのに役立ちます。 Fillブラシは、この関数を使用して、アクティブになっているFillモードに応じて異なる情報を表示しています。
def hudTemplate(): return [{ 'id': 'info', 'label': '' }] def hudUpdate(): # パラメータコールバックスクリプトでlayout.utils.requestHUDUpdate()をコールすることで、 # この関数を発動させることができます。 # 何のモードがアクティブになっているのか評価して、そのモードに応じて'info'ラベルを更新します。 import layout.utils node = layout.utils.currentBrushNode() mode = node.evalParm("mode") if mode == 0: label = 'Define grid' elif mode == 1: label = 'Define disk radius' elif mode == 2: label = 'Draw scatter region' else: raise ValueError("Invalid brush mode.") return {'info': {'label': label, 'key': 'LMB'}}
スクリーン空間で動作するブラシの作り方
スクリーン空間で動作するブラシの作成を簡単にするために、5番目の入力( Stroke )にscreen_to_world_xform Detailアトリビュートが用意されます。
このトランスフォーム行列は次の計算結果に相当します:
viewport.windowToViewportTransform() * viewport.viewportToNDCTransform() * viewport.ndcToCameraTransform() * viewport.cameraToModelTransform() * viewport.modelToGeometryTransform()
これが意味していること言葉で説明すると、ワールド空間のポイントをスクリーン空間にマッピングしています。 しかし、適切なスクリーン空間の位置を取得するには、その結果のベクトルを'w'コンポーネントで除算して非同次化する必要があります。 非同次化すると、xとyのコンポーネントは、スクリーン座標を示し、zコンポーネントは-1から1までのNDC座標の深度(-1がニアクリップ、1がファークリップに相当)を示します。
Tipsとメモ
-
2個以上のアイテムを持つワーキングセットからアセットの割り当てを制御するには、そのワーキングセットを
Connectivity SOPに接続して、Pieceアトリビュート名を
asset_indexに設定してから、そのConnectivity SOPをAttrib From Pieces SOPの2番目の入力に接続します(インスタンス先のポイントを1番目の入力に接続します)。
-
Wrangleの入力内のポイントの数を取得するには、VEXスニペット内で
npoints(input_num)を使用します。これはWrangleで動作するものの、すべての入力をクックするので、コンパイルSOPsでは通常Spare入力を使用して、そのSpare入力に対してnpointsをコールする必要があります。例えば、npoints(-1)です。コンパイルSOPsを参照してください。 -
コンパイルブロックの外側で、“セットアップ”を実施するノードを作成してから、もう1つCompile Block Startノードをそのコンパイルブロックに“追加引数”として追加して、その“外側”のノードをそのCompile Block Startノードに接続することができます。これらのノードは 1回だけ クックされ、その静的な結果をそのブロック入力からブロック内で利用可能になります。
例えば、何か複雑なガイドジオメトリをセットアップしたい時に、Invocation中はトランスフォームのみが変わり、ジオメトリ自体が変わらないのであれば、コンパイルブロックの外側でそのジオメトリを作成して、それをコンパイルブロックに接続すれば、Invocationの度にジオメトリが再生成されなく済みます。