On this page |
概要
ユーザーがノードのViewer Stateで作業する時にインタラクティブにパラメータを編集できるようにする標準的な方法は、ノードパラメータに ハンドル をバインド(紐づけ)させることです。
ローレベルの入力デバイスイベントを解釈できたとしても、ハンドルの方が今でもステートでユーザーがインタラクティブに操作できるようにセットアップするためのメインの方法です。 ハンドル自体が非常に強力で、幅広く色々とパラメータをセットアップできるように既製ユーザーインターフェースを指定することができます。 色々なハンドルの多くのライブラリからそれを選択することができます。
ステートテンプレートを作成する時は、ステートにハンドルを バインド させます。 現在のところ、動的にハンドルを作成したり破棄することができません。つまり、ステートで必要となるハンドルすべてを事前に指定しておく必要があります。 しかし、hou.Handleを使えば動的にハンドルを制御することは可能です。
静的ハンドル
静的 ハンドルのバインドは、ハンドルパラメータとノードパラメータの単純な1:1のマッピングに対応しています。 移動、回転、スケール、長さなどのハンドルパラメータは、ノードのそれに該当するパラメータと合わせることがほとんどなので、このマッピングを使用することがほとんどです。
ステートに追加したい静的ハンドル毎に、そのハンドルタイプの名前、そのハンドルの内部名(各ハンドルの名前はツール内の他のハンドルと被ってはいけません)、
ノードパラメータとハンドルパラメータをマッピングさせた("node_parm_name", "handle_parm_name")
タプルのリストでhou.ViewerStateTemplate.bindHandleStatic()をコールします。
class PythonMeasureState(): def __init__(self, state_name, scene_viewer): self.state_name = state_name self.scene_viewer = scene_viewer template = hou.ViewerStateTemplate( "pythonmeasure.pystate", "Python Measure", hou.sopNodeTypeCategory() ) template.bindFactory(PythonMeasure) # このステートのアセットに"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.ViewerStateTemplate.bindHandle()をコールします。
Note
hou.ViewerStateTemplate.bindHandle()は、cache_previous_parms
ブール引数を受け取ります。
cache_previous_parms=True
を渡すと、Houdiniは、そのハンドル値を追跡して、ハンドルコールバックに 以前 のハンドルと 新しい ハンドルの値の両方を渡します。
これは、ユーザーがハンドルを動かした速さを調べたい時にその差分を追跡できるので便利です。
False
(デフォルト)を渡すと、Houdiniは、ハンドルコールバックに以前の値を渡しません。
from __future__ import print_function 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.pystate", "Python Twist", hou.sopNodeTypeCategory() ) template.bindFactory(PythonTwistState) template.bindHandle("xform", "twist_handle", cache_previous_parms=True)
動的ハンドルイベントのメソッドに渡される辞書には、以下の標準アイテムが含まれています:
node
現行ステートで作用しているノードを表現したhou.Nodeインスタンスを含んでいます。
Menu items
メニューアイテム名をキーとして使用したメニューアイテム関連の現行値を含んでいます。
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
ハンドルタイプ
名前 |
説明 |
パラメータ |
---|---|---|
|
位置と回転のハンドル |
|
|
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 |
|
|
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整数スライダの設定
hudh
: 高さ
hudharbourname('name')
スライダをグループに割り当てます。同じグループのスライダ同士がドッキングされます。
hudharbourx(int)
スライダグループのX位置。
hudharboury(int)
スライダグループのY位置。
hudnameside(int)
ラベル位置: 上(1), 左(2), 右(3), 下(4)
hudrangehigh(int)
スライダ範囲の上限値。
hudrangelow(int)
スライダ範囲の下限値。
hudlockhigh(int)
最大制限値。
hudlocklow(int)
最小制限値。
hudvalueside(int)
位置の値: 上(1), 左(2), 右(3), 下(4)
hudx(int)
ビューアペイントのX位置。
hudw(int)
ビューアペインのY位置。
hudw(int)
幅
HUDスライダ設定
hudh
: 高さ
hudharbourname('name')
スライダをグループに割り当てます。同じグループのスライダ同士がドッキングされます。
hudharbourx(int)
スライダグループのX位置。
hudharboury(int)
スライダグループのY位置。
hudnameside(int)
ラベル位置: 上(1), 左(2), 右(3), 下(4)
hudrangehigh(float)
スライダ範囲の上限値。
hudrangelow(float)
スライダ範囲の下限値。
hudlockhigh(float)
最大制限値。
hudlocklow(float)
最小制限値。
hudvalueside(int)
位置の値: 上(1), 左(2), 右(3), 下(4)
hudx(int)
ビューアペイントのX位置。
hudw(int)
ビューアペイントのY位置。
hudw(int)
幅