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 )のポイント一式と各ポイントにマッチした境界ボックスパックプリミティブで表現されます。 各ポイントのポイント番号は、ポイント上にインスタンス化されるモデルの番号に呼応し、他のPointアトリビュートには境界ボックスなどのモデルに関する基本情報を格納します。
ワーキングセット内の様々なモデルをインスタンス化する方法/インスタンス化するかどうかは、ブラシ側で決めます(以下のワーキングセットの使い方を参照)。
新しいカスタムブラシの作り方 ¶
To... | Do this |
---|---|
新しくブラシアセットを作成する |
LayoutノードUI内の Brushes セクションのギアメニューにある New Brush オプションをクリックします。 これは、新しくデジタルアセットを作成するためのダイアログが開きます。 アセットのネームスペース、名前、保存場所を指定することができます。 詳細は、新しくデジタルアセットを作成する方法を参照してください。 このボタンを使って新しくブラシアセットを作成すると、ブラシの実装が簡単にできるように定型ノード、ステッキーノート、定型Pythonコードがそのアセットに取り込まれます。 さらに、その新しいアセットは、Layoutノードで新規ブラシとして自動的に発見されるようにセットアップされます。 |
ブラシアセットを編集する |
ブラシアセットの内部ネットワーク、パラメータインターフェース、ブラシアセットのPythonスクリプトを編集するには、Layout LOPステートのオペレーションツールバーにある“Debug Brush”ボタンを押して、ビューポート内でサンプルストロークを描画することを強く推奨します。 これは、Layout LOPステートに最も似せようとしたSOPネットワークを作成します。 そうすることで、反復処理が大幅に高速化されデバッグが容易になります。 Layout LOP内部のブラシを編集したいのであれば、そのブラシアイコンを右クリックして Edit Network を選択します。 |
Tip
Layoutノードは、layout_brush
というセクション名を含んだアセットを検索して、利用可能なブラシのリストを構築します。
何かしらの理由で、テンプレートのコピーからではなくゼロからブラシアセットを作成したいのであれば、アセットの Extra Files タブにこの名前のセクションを追加することを忘れないでください。
SOPネットワークの中 ¶
-
ブラシは、6本の入力と2本の出力を持ったSOPアセットです。ブラシは、新規ポイントを作成したり、既存ポイントを修正/削除することができます。
-
ブラシの中のネットワークには、ユーザがマウスを動かす度に何回も呼び出されるコンパイルブロックが存在します。
-
このコンパイルブロックの入力には、親のLayout LOPからの現行ステートとユーザが実行した内容に関する情報が格納されます。
-
このコンパイルブロックは、ユーザがストロークを開始する前にマウスを動かしただけでも呼び出されます。これによって、ガイドとプレビューを表示させることができます。
Switch Ifノードは、特定のマウス操作固有の挙動(例えば、ユーザがマウスをドラッグしている時にポイントのみを出力)を制御するのに役立ちます。
-
トランスフォームを表現するレイアウトブラシの規則は、Scatter and Align SOPなどの多くの一般的なSOPから出力されるのと同じで
pscale
とorient
のアトリビュートで表現されています。Note
他のインスタンス系アトリビュートを追加すると、 現在とこれまでの編集されたすべてのポイント の
pscale
とorient
のすべてのアトリビュートが上書きされておかしな挙動を招く可能性があります。 -
独自のPointアトリビュートを出力すると、その編集されたすべてのポイントの結果のインスタンス上にPrimitiveアトリビュートが作成されます。アトリビュートが増えるとパフォーマンスが悪くなってしまうので、あまり大量のアトリビュートを取り込まないように注意してください。
-
ワーキングセットのモデルをポイント上にインスタンス化するために、以下の事を行ないます:
-
ポイントの
asset_index
アトリビュートに、インスタンス化したいモデルに呼応した6番目の入力( Working Set )のポイントのポイント番号を設定します。
-
-
(“New Points”入力または“Existing Points”入力のどれかからの)ポイントを修正するには、以下の事を行ないます:
-
ポイントの位置を設定するには、
vector3
タイプのP
Pointアトリビュートを設定します。 -
ポイント上にインスタンス化されるモデルの向きとスケールを設定するには、その回転とスケールを
matrix3
タイプのtransform
Pointアトリビュートにエンコードする必要があります。Transform SOPを使用すれば、簡単に
transform
アトリビュートを設定/編集することができます。 Transofrm SOPをネットワークに追加し、そのノードの Rotate パラメータと Scale パラメータに必要な値を設定し、 Attributes パラメータをtransform
に設定してトランスフォームをそのアトリビュートに書き出します。 -
修正したポイントを1番目の出力に送ります。
既存のポイントを修正した場合、そのポイントは削除され、それと同じ新しいポイントが次の呼び出し時に1番目の入力( New Points )に追加されます。 そのため、ストロークで編集した既存のポイントは、そのストロークの“New Points”の一部になります。
Note
インスタンスをスケール/回転させるには、標準の
orient
vector4アトリビュートとpscale
floatアトリビュートで エンコードしなければなりません 。 他のインスタンス系アトリビュートを使用すると、スケール/回転が上書きされて不当な効果を招く可能性があります。 -
-
既存のポイントを修正しなかった場合、それらのポイントを出力に送らないでください(出力は常に現在のストロークで作成された新しい一連の“New Points”を表現します)。ブラシが既存のポイントに影響を与えなかった場合、その2番目の入力をどこかにまったく接続する必要はありません。
-
既存のポイントを削除するには、そのポイント上に整数
delete
Pointアトリビュートを作成し、その値を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ノードに接続した“コリジョン”ジオメトリです。たいていの場合、アセットの配置先にしたい“地面”ジオメトリを指定します。 追加でポイントを作成する時にこれを使用すると良いでしょう。 例えば、これをScatterの入力として使用することで、地面ジオメトリ上に新しくポイントをばら撒くことができます。 これを次の入力にマージすることで、静的ジオメトリと既存アセットの両方に新しくポイントをばら撒くことができます。 |
4. Asset Geometry |
このノードで作成されたすべてのインスタンスのジオメトリ(つまり、既存のポイント上にインスタンス化されたモデルの出力)。 追加でポイントを作成する際にこれを使用すると良いでしょう。 例えば、これをScatterの入力として使用することで、既存のアセット上に新しくポイントをばら撒くことができます。 これを前の入力にマージすることで、静的ジオメトリと既存アセットの両方に新しくポイントをばら撒くことができます。 |
5. Stroke |
ポリラインプリミティブが格納されます。このポイントは、マウス光線と現行シーンの交点を表現しています。 この入力には、現在の状態に関する情報(例えば、ユーザが⇧ Shiftキーを押しているかどうか)をエンコードしたグローバル(Detail)アトリビュートも含まれています。 それらのアトリビュートを使用することで、ユーザは修飾キーを使ってブラシの挙動を可変させたりカスタマイズすることができます。
ストロークで利用可能なアトリビュートのリストは、以下のストロークのアトリビュートを参照してください。 |
6. Working Set |
Layoutノードのワーキングセット内の各アイテム(インスタンス化されるモデル)を独立ポイントとそのポイントに関連付けられた境界ボックスパックプリミティブとしてエンコードします。 モデルをインスタンス化するには、新しいポイントの これらのポイントで利用可能な他のアトリビュートのリストは、以下のワーキングセットのアトリビュートを参照してください。 |
出力 ¶
ラベル |
説明 |
---|---|
1. Output Points |
Invocation(呼び出し)の度に、ここには、インスタンス先となる一連のポイントが格納されます。
ここで出力されたポイントは、次の呼び出し時の1番目の入力( New Points )として渡されます。
これは、SOPでの |
2. Guides |
インスタンス出力に対して描画されるガイドジオメトリ。 これによって、ユーザは視覚的なフィードバックが得られます。 例えば、ブラシがマウスポインタから特定の半径内にモデルをばら撒くと、そのばら撒き領域の限界を示したリングのガイドを描画することができます。 ブラシアセットのPythonモジュール内に、 アセットのPythonモジュール内に |
ストローク入力のアトリビュート ¶
グローバル(Detail)アトリビュート ¶
名前 |
タイプ |
説明 |
---|---|---|
|
|
マウスボタンが押されたままかどうか(Trueなら |
|
|
これがドラッグの開始かどうか(Trueなら |
|
|
ユーザがドラッグせずにマウスを動かしているかどうか(Trueなら |
|
|
ユーザがクックしたかどうか(Trueなら |
|
|
これがドラッグの終了かどうか(Trueなら |
|
|
が押されているかどうか(Trueなら |
|
|
が押されているかどうか(Trueなら |
|
|
が押されているかどうか(Trueなら |
|
|
Caps Lockキーが押されているかどうか(Trueなら |
|
|
⌃ Ctrlキー(Macの場合はcommandキー)が押されているかどうか(Trueなら |
|
|
⇧ Shiftキーが押されているかどうか(Trueなら |
|
|
Altキー(Macの場合はoptionキー)が押されているかどうか(Trueなら |
|
|
クリック/ストロークの度に変わる番号が格納されますが、ストローク中は同じ値のままです。 これは、ストローク中は値が変わらないランダム値のシードとして使用するのに役立ちます。 |
|
|
スクリーン空間からワールド空間にマップする変換マトリックス。 これは、スクリーン空間で動作するブラシを実装する時に役立ちます。 |
|
|
Layout LOPのステージ入力上の |
ストロークポリライン上のPointアトリビュート ¶
5番目の入力のポリラインは、ユーザによるインタラクティブなストロークを表現しています。 このポリライン上の各ポイントは、ストロークに沿って取得されたサンプルを意味しています。 各ポイントには、サンプリングされた交差に関するデータが格納されたアトリビュートがいくつかあります。
ユーザがビューポート内でストロークを“描画”すると、Layoutノードは光線をスクリーン“に”送信して、ポインタが3D空間内の何に当たっているのか調べます。
デフォルトでは、Layoutノードは、既存のインスタンス、静的ジオメトリ(たいていの場合は“地面”)、XZグランド平面に最も近い交点を調べます。 (Layoutノードを使用する際にユーザ側で静的ジオメトリまたは既存インスタンスとの交点を調べないようにするオプションを設定することができます。)
光線がどこにも交差しなかった場合、それでもネットワークは呼び出されますが、Stroke入力の新しいポイントは単に前の有効なポイントのコピーになるだけです。
名前 |
タイプ |
説明 |
---|---|---|
|
|
3D空間の(交差した)位置。 |
|
|
交差したポイントでの法線。 |
|
|
(マウスポインタのスクリーン座標から算出された)3D空間の交差光線の原点。 これは、スクリーン空間で動作するブラシを作成するのに役立ちます。 |
|
|
3D空間の交差光線の方向(カメラ投影に準拠してマウスポインタがスクリーンに“向かった”方向)。 |
|
|
マウスポインタの水平位置(スクリーンピクセル)。 |
|
|
マウスポインタの垂直位置(スクリーンピクセル)。 |
|
|
マウスポインタがインスタンスモデル上にあった場合、この値には、2番目の入力( Existing Points )のインスタンスのポイント番号が入ります。 例えば、このアトリビュートの値をチェックして、そのポイントを出力しないようにすることで、ドラッグしたインスタンスを削除するブラシを作成することができます。 または、既存のインスタンスを押したり寄せたりするブラシを作成することもできます。 ストロークをインスタンス上で開始すると、そのストロークの開始ポイントに続くポイントを使用して、そのインスタンスのポイントを移動させることができます。 |
|
|
ストロークをタブレットまたは同様のデバイスを使用して作成した場合のそのタブレットペンの角度。 |
|
|
ストロークをタブレットまたは同様のデバイスを使用して作成した場合のタブレットペンの筆圧。 |
ワーキングセットの入力Pointアトリビュート ¶
6番目の入力( Working Set )の各ポイントは、Layoutノードのワーキングセット内の現在のアイテムに呼応しています。
|
|
ポイント番号と同じ。これは、1番目の出力のポイント上に呼応したモデルをインスタンス化するために、そのポイントの |
|
|
このポイントに呼応したモデルの境界ボックスのサイズ。 |
|
|
境界ボックスの中心。 |
この境界ボックス系アトリビュートは、インスタンスを配置する時に交差しないようにインスタンスの間隔を空けたり、占有領域や境界ボックスガイドを表示するのに役立ちます。
Note
各ポイントは、同じインデックスのアセット境界ボックスをパックプリミティブとして持っています。
詳細は、ワーキングセットの使い方を参照してください。
マルチストロークなブラシ ¶
-
通常では、1回のストロークが終了した時のマウスのUpイベントでそのブラシのコンパイルブロックのポイント出力が“確定”されて、Layoutノードのポイントインスタンスデータに統合されます。
-
必要に応じて、ユーザが複数のストロークを1オペレーションとして作成できるようにブラシを実装することができます。
例えば、クリック/ドラッグの度にユーザが開始点と繋げてフェンスを閉じない限り(または、ユーザがEnterを押してフェンスを開いたままで抜けない限り)フェンス内に新しいコーナーが作成されるフェンス描画ブラシを実装することができます。
マルチストローク操作を使用することで、ユーザは矩形を描画することもできます。その場合、1回のストロークで矩形の一辺の長さを定義し、次のドラッグでその一辺に隣接する辺を引っ張り出してその長さを定義します。
-
現在のオペレーションを現在のストロークの後に続けたいことを親のLayoutノードに伝えるために、1番目の出力に
end_stroke
Detailアトリビュートを追加して値を0
に設定します。Layoutノードは、そのアトリビュートが存在することを確認したら、現在のオペレーションをアクティブなままにします。 すると、以降のストロークは、“Existing Points”と同じリストにポイントの追加を継続するようになります。
-
次に、現在のオペレーションを終了することを親のLayoutノードに伝えるために、1番目の出力yのその
end_stroke
Detailアトリビュートの値を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アトリビュートを使用して反復(または、マルチストロークなブラシのストローク)間で情報を渡しても、その情報はオペレーション間では渡りません。
-
Layoutノードは、ブラシから生成されたすべてのプリミティブも念のためにクリアします。
ポイントクラウドのマージが頻繁に行われるので、プリミティブが呼び出されると、そのプリミティブのマージによってすぐに指数関数的に重くなりHoudiniがロックアップしてしまいます。
パラメータインターフェース ¶
ブラシ用にパラメータインターフェスをデザインすることができます。 そして、そのブラシのコンパイルブロック内でchエクスプレッションを使用してパラメータの値を読み込んで、その値を使ってそのブラシの挙動を変更することができます。
例えば、ユーザがドラッグした時にブラシがばら撒くポイント数を制御することができるDensityパラメータ(内部名がdensity
)をブラシアセット上に追加したとします。
そのブラシのコンパイルブロック内で、例えば、Scatter SOPの Force Total Count パラメータにch("../density")
のエクスプレッションを使用することで、そのDensityパラメータの値をコピーすることができます。
ブラシがLayoutノード内でアクティブになっている時、そのLayoutノードのインターフェースは、パラメータエディタで表示されるものと同じブラシパラメータを表示します。
スクロールホイール ¶
ユーザがスクロールホイールを使ってブラシの挙動を変更できる方法が2つあります。
-
ブラシのパラメータインターフェースに内部名が
scroll
で始まるパラメータがあれば、ユーザがマウスホイールをスクロールするとそのパラメータ値が増減します(2個以上のパラメータがscroll
で始まっている場合、Layoutノードはそれらすべてのパラメータを変更します)。 -
アセットのPythonモジュール内に
onMouseWheelEvent(kwargs)
関数を実装すれば、ユーザがマウスホイールをスクロールすると、Layoutノードステートがその関数をコールします。
ブラシのサイズを変更する方法 ¶
ブラシの半径(または同等のアトリビュート)のサイズ変更の規則は、Attribute Paint SOPやVellumブラシと同様で⌃ Ctrl + ⇧ Shift + です。
ブラシでこれを有効にするには、影響を与えたいパラメータ(s)に対してdrag_resize
タグを追加します。
Edit Last Strokeを無視する方法 ¶
デフォルトでは、パラメータを変更すると、ブラシの最後の呼び出しが再適用されます。 これは、たいていのパラメータでは望ましいですが、場合によっては、フォルダなどの整理整頓系パラメータがあったり、ブラシモードを制御するメニューパラメータであっても最後のストロークに変更を加えたくないものもあります。
特定のパラメータ変更によるブラシの呼び出しを無効にするには、そうしたいパラメータに対してlayout_ignore
タグを追加します。
ワーキングセットの使い方 ¶
ブラシ作成者のあなたは、ユーザが選んだモデルのワーキングセットの使い方を決めることができます。 ワーキングセット内のアイテムの順番に意味を持たせるのかどうか選択することができます。
-
ワーキングセットのよくある使われる方は、(例えば、シーン内にアイテムをばら撒く時に)ワーキングセットからランダムにアイテムを選択することです。
-
ブラシは、ワーキングセットの順番を利用することができます。例えば、ワーキングセット内の1番目のアイテムをシーンに投入し、そのアイテムを中心に2番目のアイテムのインスタンスをおおまかに円状にばら撒いて、さらにそのインスタンスを中心に3番目のアイテムを円状にばら撒くといったブラシを作成することができます(これは、周辺に岩、枯れ枝などの小さな生態系をもった木々を散乱させるのに役立ちます)。
アイテムをランダムに配置するブラシの他の例を挙げると、アイテムの順番を利用して、ワーキングセット内の順番が先のアイテムほど確率が高くなるように、各アイテムが選択される確率に影響を与えることができます。
-
現在のところ、ブラシがワーキングセットの順番に意味をもたせているかどうかをブラシ利用者に自動的に伝える方法がありません。そのため、ブラシのドキュメントにそのことを記載するか、または、ブラシのパラメータインターフェースで制御できるようにする必要があります。
-
生成されたポイント上に上手くランダムにワーキングセットを配置する方法は、ワーキングセット入力にConnectivity SOPを接続し、ピースアトリビュート名を
asset_index
に設定してから、Attrib From Pieces SOPを使用してポイントにピースを割り当てます。
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がファークリップに相当)を示します。
DeleteブラシやNudgeブラシなどの既存のスクリーン空間ブラシは単にコピーしてから必要に応じて変更することを強く推奨します。
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の度にジオメトリが再生成されなく済みます。