Houdini x Pythonのイベント関連備忘録(例:ライトの色を変えたらノードの色も同じ色に変わる)


はじめに

今回は例とをしてライトの色を変更すると、ライトのノードの色も設定したライトと同じ色に自動で変更され、一目でライトの色がわかるようにしたいと思います。

この実装には2種類のイベントコールバックの設定が必要となりますのでそれぞれ解説していきたいと思います。

1. ライトの色が変更されたイベントによりノードの色を変更するコールバックを設定する。

Nodeのコールバック設定はaddEventCallback(event_types, callback)addParmCallback(callback, parm_names)があります。
この2つのメソッドの使い分けですが、ヘルプによると

1.いくつかのパラメータのみを考慮する。
2.ノードにパラメータがたくさんある。
上記に該当する場合は、addEventCallback(event_types, callback)を使ってパラメータをフィルタリングするよりもaddParmCallback(callback, parm_names)の方が処理が高速。

とありますので、今回はカラーパラメータ変更によるコールバックなのでaddParmCallback(callback, parm_names)を使います。
ここで一つ注意なのですが、param_namesはパラメータが単数であってもListやTupleでなければエラーが出ます。
引数はcallbackがコールバック関数オブジェクト(この例ではchange_color)、parm_names('light_color',)となります。

parm_change_addCallback.py
node.addParmCallback(change_color, ('light_color',))

一方のコールバック関数側ですが、引数にevent_typeshou.nodeEventType), **kawrgsを取ります。
kwargsの内容はコールしたNodeへの参照とイベントタイプに応じた参照へのキーワードが含まれます。
各タイプの追加キーワードはこのリンクのヘルプを参照してください。
今回の例ではparm_tupleキーワードでパラメータの参照(今回の例では'light_color'パラメータ)を得ることが出来ます。
関数内ではノードの色をパラメータの色に変更しているだけです。

parm_change_callback.py
def change_color(event_type, **kwargs):
    kwargs['node'].setColor(hou.Color(kwargs['parm_tuple'].eval()))

2. Lightノードがネットワークビューに追加されるたびにそのノードに1の設定を追加する。

1の設定では単一のLightノードにしか適用されないので、Lightノードがビューに追加される毎に1で設定したコールバックが追加されるようにします。
そのためにノードのイベントハンドラーファイル(Node event handler files)を作成して配置します。
具体的には1で作ったPythonコードのファイルと規則に則ったファイル名に変更し、配置します。

ヘルプによると、

イベントを指定し全てのノードに適用される。
HOUDINIPATH/scripts/event.py
ノードとイベントの組み合わせに適用される。
HOUDINIPATH/scripts/category/nodename_event.py

今回はLightノードの生成イベントにコールバックを設定したいので、
categoryobj
nodenamehlight-2.0
eventOnCreated
となり最終的なファイル名とパスは以下のようになります。
ファイル名:hlight-2.0_OnCreated.py
パス:HOUDINIPATH/scripts/obj/hlight-2.0_OnCreated.py

HOUDINIPATHは環境によりますのでご自身のHOUDINIPATHをお調べください。
Windows環境ですと例えば、C:\Users\HoudiniUser\Documents\houdini18.5\scripts\obj\hlight-2.0_OnCreated.pyのようになります。

また、コールバック時には**kwargsで引数を受けます。今回の例ではnode,typeのキーワードでノードとそのタイプを得ることが出来ます。

コード全体

hlight-2.0_OnCreated.py
# 色を変更するコールバック関数
def change_color(event_type, **kwargs):
    kwargs['node'].setColor(hou.Color(kwargs['parm_tuple'].eval()))

node = kwargs['node']   # OnCreated(ノード作成のイベント)コールバックの引数からノードを取得
node.parmTuple('light_color').set(node.color().rgb())   # 最初の色合わせ(オプション)
node.addParmCallback(change_color, ['light_color']) #ライトの色が変更された時のコールバックの設定

最後に

理解してみればコードもシンプルで大したものでもないのですが、情報が少なく方法を理解するのに多少苦労しました。
環境(Houdini Indie 18.5.563 Python3 Windows)