| On this page |
概要 ¶
ユーザがノードのViewer Stateでインタラクティブにパラメータを編集できるようにする標準的な方法は、ノードパラメータにハンドルをバインド(紐づけ)させることです。
よりローレベルの入力イベントを解釈することも可能ですが、ハンドルは依然としてステート内でユーザ操作を可能にする主要な方法です。 ハンドルにはパラメータ設定用の強力で柔軟なインターフェースが備わっており、豊富な定義済みハンドルタイプのライブラリによって支えられています。
ビューアステートでは、ノードのパラメータをハンドルのパラメータにバインドすることで、ハンドルを活用します。 ハンドルのバインドは通常ではステートテンプレートを介してステートの登録時に実行されます。 ただし、hou.SceneViewerを使用して、ビューアハンドルを動的にバインドおよびアンバインドすることも可能です。 ビューアステートは、hou.Handleを介して、実行時にハンドルを操作することができます。
バインド ¶
ビューアステートは、hou.ViewerStateTemplate APIを使用してプログラム的に、または、Digital Asset Handle Bindingsダイアログを使用してインタラクティブに、ビューアハンドルにバインドすることができます。
hou.ViewerStateTemplateAPIについては、以下のセクションで説明します。
Digital Assetダイアログでは、ステートコンテキストに一致する利用可能なハンドルのリストからハンドルを選択することができます。 ハンドルを選択すると、そのハンドルで制御したいアセットのパラメータにハンドルのパラメータをバインドすることができます。
Note
Digital Asset Handle Bindingsダイアログを使用してPythonハンドルをバインドする場合、そのバインディングを有効にするには、デジタルアセットにビューアステートを追加する必要があります。 アセットにまだビューアステートがない場合は、Digital Asset New…ボタンから利用可能なViewer Handle Code Generatorを使用して、空っぽのデフォルトステートを生成することができます。
静的ハンドル ¶
静的ハンドルバインディングでは、ハンドルパラメータとノードパラメータとの単純な1対1のマッピングがサポートされています。 Translate、Rotate、Scale、Lengthといったハンドルパラメータは、通常ではノード上のパラメータに直接呼応しているため、たいていの場合はこれで十分です。
ステートに静的ハンドルを追加するには、ハンドルタイプ名、ハンドルの固有な内部名(ツール内のすべてのハンドル間で固有であること)、ノードパラメータをハンドルパラメータにマッピングする(“node_parm_name”, “handle_parm_name”)タプルのリストを引数としてhou.ViewerStateTemplate.bindHandleStaticをコールします。
簡単なテスト用にPython Source Editor内で以下のサンプルを実行することができます:
import hou class PythonMeasureState(): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer template = hou.ViewerStateTemplate( "pythonmeasure", "Python Measure", hou.sopNodeTypeCategory() ) template.bindFactory(PythonMeasureState) # このステートのアセットに"start"と"end"の2個の移動パラメータがあることを想定します。 template.bindHandleStatic( "xform", "start_handle", [("startx", "tx"), ("starty", "ty"), ("startz", "tz")] ) template.bindHandleStatic( "xform", "end_handle", [("endx", "tx"), ("endy", "ty"), ("endz", "tz")] ) hou.ui.registerViewerState(template)
動的ハンドル ¶
動的ハンドルバインディングは、(コールバックを使用して)ハンドルの変更がノードのパラメータにどのように影響するか、そして、ノードのパラメータの変更がハンドルにどのように影響するかを決めることができます。
ステートに動的ハンドルを追加するには、ハンドルタイプ名、ハンドルの固有な内部名(ツール内のすべてのハンドル間で固有であること)を引数としてhou.ViewerStateTemplate.bindHandleをコールします。
Note
hou.ViewerStateTemplate.bindHandleは、cache_previous_parmsブール引数を受け取ります:
-
cache_previous_parms=Trueを渡すと、Houdiniはハンドルの値を追跡して、ハンドルコールバックに 以前 の値と 新しい 値の両方を用意します。これは、例えばユーザがハンドルをどのくらいの速さで動かしているかを判断するなど、変化量を追跡するのに役立ちます。 -
False(デフォルト)にすると、Houdiniはハンドルコールバックに以前の値を含めません。
簡単なテスト用にPython Source Editor内で以下のサンプルを実行することができます:
import hou class PythonTwistState(): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer def onHandleToState(self, kwargs): # ユーザがハンドルを操作した時にコールされます。 handle_name = kwargs["handle"] parms = kwargs["parms"] prev_parms = kwargs["prev_parms"] print("User edited handle:", handle_name) for parm_name in kwargs["mod_parms"]: old_value = prev_parms[parm_name] new_value = parms[parm_name] print("%s was: %s now: %s" % (parm_name, old_value, new_value)) def onStateToHandle(self, kwargs): # 必要に応じて動的ハンドルを更新できるように、 # ユーザがパラメータ(s)を変更した時にコールされます。 parms = kwargs["parms"] print("Parameters are now:", parms) for p in parms: print(p) template = hou.ViewerStateTemplate( "pythontwist", "Python Twist", hou.sopNodeTypeCategory() ) template.bindFactory(PythonTwistState) template.bindHandle("xform", "twist_handle", cache_previous_parms=True) hou.ui.registerViewerState(template)
動的ハンドルイベントのメソッドに渡される辞書には、以下の標準アイテムが含まれています:
node
現行ステートで作用しているノードを表現したhou.OpNodeインスタンスを含んでいます。
state_parms
現行ステートにバインドされたステートパラメータを表現した名前を含んでいます。 この辞書は、パラメータステートを変更する際に使用します。 詳細は、ここを参照してください。
state_flags
ステートに関連した色々なフラグを含んだ辞書。
ステートフラグは、kwargs引数を介して、すべてのステートハンドラーで設定することができます。
フラグ |
メモ |
|---|---|
|
(
あなたのステートではマウスドラッグイベントが不要な場合は、 class MyState(object): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer def onEnter( self, kwargs): kwargs['state_flags']['mouse_drag'] = False ... |
|
このフラグは、 デフォルトでは、ビューポートは常に再描画します。大規模シーンのパフォーマンス問題を軽減したいのであれば、あなたのステートがでビューポートの再描画が不要な時には class MyState(object): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer def onMouseEvent( self, kwargs): kwargs['state_flags']['redraw'] = False if __some_redraw_test__: kwargs['state_flags']['redraw'] = True ... |
|
このフラグは、 Note 以下の条件が満たされている場合、ステートは
class MyState(object): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer def onEnter( self, kwargs): # 間接ハンドルドラッグを無効にします。 # ビューポート内でのMMBドラッグによってハンドルパラメータが修正できなくなります。 kwargs['state_flags']['indirect_handle_drag'] = False ... |
|
このフラグは、別のノードが選択された時に、ステートを抜けるのか、それともアクティブのままにするのか決めます。
True(デフォルトの挙動)に設定すると、別のノードが選択されるとステートが抜けます。
Falseに設定すると、別のノードが選択されてもステートはアクティブのままになります。
class MyState(object): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer def onGenerate( self, kwargs): # ノード選択が行なわれても、このノードなしステートがアクティブのままになるように設定します。 kwargs['state_flags']['exit_on_node_select'] = False ... |
interrupt_state
Volatileステートが有効な時または空っぽの文字列の時にPythonステートを中断するステートの名前。
onHandleToState ¶
これは、ハンドルを変更した時にノードパラメータ(またはステート/表示)を更新することができます。
このメソッドに渡される辞書には、以下の追加アイテムが含まれています:
handle
ハンドルの文字列ID。
parms
新しいハンドルパラメータ値を含んだ辞書。
mod_parms
変更されたパラメータの名前のリスト。
prev_parms
このキーは、hou.ViewerStateTemplate.bindHandleメソッドにcache_previous_parms=Trueを渡した場合に のみ存在します 。
これは、前のハンドルのパラメータ値を含んだ辞書です。 これは、差分計算に役立ちます。
ui_event
ハンドル状態にアクセスするためのhou.UIEventオブジェクト。 例えば、hou.UIEvent.reasonが返したhou.uiEventReason値を使用することで、ユーザがハンドルのドラッグを開始または終了したかどうかを調べることができます。
以下のhou.uiEventReason値は、onHandleToStateに対して色々な意味があります:
-
uiEventReason.Active: ユーザがハンドルをドラッグ中です。 -
uiEventReason.Changed: ユーザがハンドルのドラッグを終了しました。この時点で、prev_parmsには直近のハンドル値が入っているはずです。 -
uiEventReason.Start: ユーザがハンドルのドラッグを開始しました。 -
uiEventReason.Picked: ハンドルメニュー操作、ホットキー、マウスクリック。例えば、Picked値はHUDスライダをクリックした時に生成されます。
onStateToHandle ¶
このメソッドは、 ノードのパラメータを変更する度に ステートにバインドされた 動的ハンドル毎に 別々にコールされます。 これは、変更されたノードパラメータに合うようにハンドルパラメータを更新することができます。
このメソッドに渡される辞書には、以下の追加アイテムが含まれています:
handle
ハンドルの名前。
parms
ハンドルのパラメータ名と値をマッピングした辞書。 この辞書の値を変更することで、そのハンドルパラメータを編集することができます 。
このメソッドでは、ノードのパラメータからパラメータを読み込んで、kwargs["parms"]内の必要なハンドルのパラメータを動的に更新します:
def onStateToHandle(self, kwargs): node = kwargs["node"] handle_parms = kwargs["parms"] if kwargs["handle"] == "my_angle": node_tx = node.parm("tx").evalAsFloat() handle_parms["tx"] = node_tx * 2
特別な通知 ¶
Houdiniには、ユーザが動的ハンドルの制御を開始または終了した時にステートに通知するための特別なコールバックが備わっています。
onBeginHandleToStateは、onHandleToStateコールバックの直前にコールされます。
例えば、onBeginHandleToStateを使用することで、ユーザがハンドルを制御している間に
Undoブロックを開いて、Undo可能オペレーションを実行することができます。
onEndHandleToStateは、onHandleToStateコールバックの直後にコールされます。
onEndHandleToStateを使用することで、onBeginHandleToStateで開いたUndoブロックを閉じることができます。
ハンドルタイプ ¶
名前 |
説明 |
パラメータ |
|---|---|---|
|
位置と回転のハンドル |
|
|
Bounding Box Vector |
|
|
Bounding Box |
|
|
Bounding Rectangle |
|
|
Bounder Bounding Box |
|
|
Circle Transform |
|
|
Clay Translate |
|
|
Curve Point Options |
|
|
Distance |
|
|
Domain |
|
|
Edit |
|
|
Extrude |
|
|
Extrude v2 |
|
|
Vector with Fallback |
|
|
HUD Int Slider |
|
|
HUD Slider |
|
|
Isoparm Segment |
|
|
Isoparm Segment |
|
|
Mouse Wheel Bump |
|
|
Mouse Wheel Radius |
|
|
Paste Range |
|
|
Peak |
|
|
Pill |
|
|
Pivot |
|
|
Project |
|
|
Tangent Pivot |
|
|
Transform2d |
|
|
Soft Transformer |
|
|
Sphere Transformer |
|
|
Translate |
|
|
Torus Transformer |
|
|
Tube Transformer |
|
|
U Isoparm |
|
|
UV Edit Manipulator |
|
|
Texture Transformer |
|
|
UV Point |
|
|
UV Project Manipulator |
|
|
UV Range Manipulator |
|
|
UV Transform Manipulator |
|
|
UV Unwrap Manipulator |
|
|
Vector |
|
|
V Isoparm |
|
|
Transformer |
|
ハンドル設定 ¶
ハンドル設定は、ハンドルの挙動を変更するためのアトリビュートになっています。
関連項目:
HUD整数スライダの設定 ¶
hudharbourname('name') スライダをグループに割り当てます。同じグループのスライダ同士がドッキングされます。
hudharbourx(int) スライダグループのX位置。
hudharboury(int) スライダグループのY位置。
hudnameside(int) ラベル位置: 上(1), 左(2), 右(3), 下(4)
hudrangehigh(int) スライダ範囲の上限値。
hudrangelow(int) スライダ範囲の下限値。
hudlockhigh(int) 1に設定すると、スライダの上限がhudrangehighに設定され、スライダはその値より上に移動できません。
hudlocklow(int) 1に設定すると、スライダの下限がhudrangelowに設定され、スライダはその値より下に移動できません。
hudvalueside(int) 位置の値: 上(1), 左(2), 右(3), 下(4)
hudx(int) ビューアペイントのX位置。
hudy(int) ビューアペインのY位置。
hudw(int) 幅
hudh: 高さ
HUDスライダ設定 ¶
hudh: 高さ
hudharbourname('name') スライダをグループに割り当てます。同じグループのスライダ同士がドッキングされます。
hudharbourx(int) スライダグループのX位置。
hudharboury(int) スライダグループのY位置。
hudnameside(int) ラベル位置: 上(1), 左(2), 右(3), 下(4)
hudrangehigh(float) スライダ範囲の上限値。
hudrangelow(float) スライダ範囲の下限値。
hudlockhigh(int) 1に設定すると、スライダの上限がhudrangehighに設定され、スライダはその値より上に移動できません。
hudlocklow(int) 1に設定すると、スライダの下限がhudrangelowに設定され、スライダはその値より下に移動できません。
hudvalueside(int) 位置の値: 上(1), 左(2), 右(3), 下(4)
hudx(int) ビューアペイントのX位置。
hudy(int) ビューアペイントのY位置。
hudw(int) 幅
hudh(int) 高さ
sidefx_transform2d設定 ¶
sidefx_transform2dハンドルは、移動、回転、スケールのバインドパラメータを制御することができます。
このセクションでは、このハンドルで利用可能な設定を載せています。
これらの設定は、ピボット座標を含め、ハンドルの動作をカスタマイズすることができます。
ハンドルのピボット設定(handlepivotx、handlepivoty、handlepivotrz)には、ハンドルのピボットポイントの座標と回転が格納されます。
これらの設定は、ピボットの位置を追跡する(例えば、ハンドルのピボットに依存するDrawableの配置を更新する)のに役立ちます。
sidefx_transform2dはdetachable(切り離し)モードに対応しています。
このモードを有効にすると、バインドされたパラメータを更新することなく、ハンドルのピボットを独立して操作することができます。
デフォルトでは、ハンドルのdetachableモードは無効になっており、バインドされたパラメータの値に追従します。
ハンドルが切り離され、ピボットが変更されると、バインドされたパラメータの変更には反応しなくなります。
設定 |
説明 |
値 |
|---|---|---|
|
ハンドルの切り離しモード機能を有効または無効にします |
0: ハンドルは切り離せません(デフォルト)。 1: ハンドルは切り離し可能です。 |
|
ハンドルモードを設定します |
0: Rotate 1: Translate(デフォルト) 2: Scale |
|
ハンドルのピボットポイントのX座標を格納します。 |
この値は通常ではハンドルの作成時にバインドされたパラメータによって上書きされます。 |
|
ハンドルのピボットポイントのY座標を格納します。 |
この値は通常ではハンドルの作成時にバインドされたパラメータによって上書きされます。 |
|
ハンドルのピボットポイントのZ軸回転角(単位は度)を格納します。 |
この値は通常ではハンドルの作成時にバインドされたパラメータによって上書きされます。 |
|
回転リングスタイルを制御します。 |
0: 4つの円弧(デフォルト) 1: 第1象限の円弧 |
|
回転のステップ角度(単位は度)を指定します。このパラメータは、定義済みのステップサイズのリストのインデックスに呼応しています。 |
1, 2, 3, 4, 5, 5.625, 10, 11.25, 12, 15, 20, 22.5, 30, 45, 60, 90 |
|
スケールパラメータのステップサイズを指定します。 |
デフォルトは0.1です。 |
|
移動軸の表示を切り替えます。 |
0: 両方の軸を無効にします 1: 両方の軸を有効にします(デフォルト) |
|
移動ピボットのカラーを制御します。 |
0: ホワイト 1: ピボットカラー 2: ポイントカラー |
|
移動ピボットスタイルを制御します。 |
0: Cross 1: Diamond 2: Dot 4: HollowDot 5: HollowSquare 6: Square 7: SquareCross 8: XShape |
|
移動パラメータのステップサイズを指定します。 |
デフォルトは0.1です。 |
xform設定 ¶
translate(int) xform移動モードを有効(1)または無効(0)。
scale(int) xformスケールモードを有効(1)または無効(0)。
rotate(int) xform回転モードを有効(1)または無効(0)。
snap_to_selection(int) 1に設定すると、ジオメトリコンポーネントへのスナップが有効になります。詳細はここを参照してください。
境界ボックス設定 ¶
translate(int) boundingbox移動モードを有効(1)または無効(0)。
rotate(int) boundingbox回転モードを有効(1)または無効(0)。
snap_to_selection(int) 1に設定すると、選択したジオメトリコンポーネントへのスナップが有効になります。詳細はここを参照してください。
ハンドルのスナップ ¶
ほとんどのハンドル(例えば、xform, pivot, distance, boundingboxなど)では、選択したコンポーネントへのスナップを回避したいです。 これらのハンドルは選択したジオメトリを動かすことを想定しているので、そのハンドルを同じジオメトリにスナップさせると、良くないフィードバックループが起きます。 たいていの場合、ここで問題になる選択は、ノードが生成したクック選択です。
Houdiniは、選択が存在した時にジオメトリコンポーネントが選択されているのか選択されていないのかの区別しかできません。
選択が存在しなければ、Houdiniはそのハンドルにバインドされているノードが生成したジオメトリ全体が選択されていると見なし、ハンドルがそのジオメトリにスナップするのを回避します。
snap_to_selection設定を使用することで、選択されたコンポーネントにハンドルをスナップさせるかどうか制御することができ、
通常のAPIを使ってその設定をハンドルに適用することができます: