Houdini – Python(HOM)によるパラメータ操作

 前回は、HOMによりノードを選択する操作に関する記事を書きました。
 ノードを探して選択するだけではあまりにも寂しいので、今回はそれに引き続き、ノードのパラメータを操作する部分に関するメモを書き残したいと思います。
 Houdiniでは、ノードパラメータへの操作パスが幾通りも存在しており、とても柔軟な作りになっていますが、今回は、自分がよくやる方法を取り上げます。
「もっと便利な方法があるよー」などの情報があればぜひ教えてください。
 ここで紹介する各種メソッドはあくまでも一例で、実際には更に多くのメソッドが用意されているので、ぜひマニュアルも参照してください。
http://www.sidefx.com/docs/houdini/hom/hou/Node.html
http://www.sidefx.com/docs/houdini/hom/hou/Parm.html
http://www.sidefx.com/docs/houdini/hom/hou/ParmTuple.html


パラメータ名の確認

 まず最初に、パラメータへアクセスする際はパラメータ名が重要になるので、名前の確認方法から。

Parameter Spread Sheetで確認

 Parameter Spread Sheetで、ノードとパラメータをツリー表示で確認できる。
 各項目名の右端にある、カッコで囲まれた名前が実際にアクセスする際に使用するパラメータ名。パラメータにはUniform Scaleのような単一の値を持つパラメータと、位置や回転など、複数の値をひとまとめにして持つ配列パラメータがある。
 下図を例にすると、Axis Divisionsという「ラベル」が付けられたパラメータは、実際の名前が「divrate」であり、3つの子要素(divratex/y/z)を持っている配列パラメータである事がわかる。

ドラッグ&ドロップで確認


 Python Source Editorに、パラメータラベルをドラッグ&ドロップすることで正しい配列パラメータのパスと名前が確認できる。

ポップアップウインドウで確認

 Parametersパネルなどでパラメータ名ラベルの上にマウスカーソルを置き、少し待つと、パラメータ情報がポップアップで表示される。この中の、Parametersの部分にある文字列が、このノードにおけるパラメータの正式な名前になる。

↑↑↑
 この場合、tx ty tz がパラメータ名であると確認できるが、あくまでも配列要素の単一パラメータ名のみがわかる。
 正確な親の配列パラメータ名が知りたければ、Parameter Spread Sheetを確認するなど一手間必要。(大体の場合、配列要素パラメータ名の末尾を削ったものが配列パラメータ名になっているっぽい)


おおまかなパラメータアクセスの方法

パラメータへのアクセス方法

  1. パスを指定して直接パラメータオブジェクト(hou.Parm)へアクセス
  2. 任意のノードのパラメータオブジェクト(hou.Parm)へ、名前を指定してアクセス

パラメータの操作方法

  1. ノードオブジェクト(hou.Node)を直接操作
  2. パラメータオブジェクト(hou.Parm)を通して操作

単一パラメータオブジェクトの取得

import hou

# パラメータオブジェクトを直接取得
parm_direct = hou.parm('parm_path')

# ノードオブジェクトからパラメータ名を使用してパラメータオブジェクトを取得 
node = hou.node("node_path")
parm_from_node = node.parm('parm_name')

配列パラメータオブジェクトの取得

 translateやrotateのような複数要素で構成されるパラメータは、配列パラメータとしてまとめて各要素へアクセスすることができる。
 基本的に、これは単一のパラメータへのアクセスと同じように行うが、その際は、parmTupleやevalParmTupleといった配列パラメータを扱う専用のメソッドを使う。

import hou

# 配列パラメータオブジェクトの子要素配列を取得
tupleParm_direct = hou.parmTuple('tupleParm_path')

# 配列パラメータの値を取得
# ノードオブジェクトをつかまえておく
node = hou.node("node_path")
tupleParm_from_node = node.parmTuple('tupleParm_name')

# 子要素へは、tupleParmの配列要素へアクセスして行う
tupleParm_x = tupleParm_from_node[0]
tupleParm_y = tupleParm_from_node[1]
tupleParm_z = tupleParm_from_node[2]

単一パラメータの値を取得する

 eval~と名づけられたメソッドを使う。
 型を指定して型変換しながら値を取得するメソッドや、時間指定で値を取得するメソッド、それらを組み合わせて取得するメソッドなどもある。

import hou

# 単一パラメータオブジェクトから現在の値を取得
parm = hou.parm("parm_path")
parmValue = parm.eval()

# 型を指定ながら現在の値を取得
parmIntValue = parm.evalAsInt()
parmFloatValue = parm.evalAsFloat()
parmNodeValue = parm.evalAsNode()

# 指定時間での値を取得
parmAtFrameValue = parm.evalAtFrame( FRAME_NUMBER )

# 型指定と時間指定の組み合わせ
parmIntAtFrameValue = parm.evalAsIntAtFrame( FRAME_NUMBER )
parmFloatAtFrameValue = parm.evalAsFloatAtFrame( FRAME_NUMBER )

配列パラメータの値を取得する

 配列パラメータの値取得も、単一パラメータとほぼ同様。

import hou

# 配列パラメータオブジェクトから現在の値を取得
tupleParm = hou.parmTuple("parm_path")
tupleParmValue = tupleParm.eval()

# 型を指定ながら現在の値を取得
parmIntValues = tupleParm.evalAsInts()
parmFloatValues = tupleParm.evalAsFloats()
parmNodeValues = tupleParm.evalAsNodes()

# 指定時間での値を取得
parmAtTimeValue = parm.evalAtTime( TIME )
parmAtFrameValue = parm.evalAtFrame( FRAME_NUMBER )

# 型指定と時間指定の組み合わせ
parmIntAtFrameValues = parm.evalAsIntsAtFrame( FRAME_NUMBER )
parmFloatAtFrameValues = parm.evalAsFloatsAtFrame( FRAME_NUMBER )

パラメータをセットする

 値のセットは、set系メソッドを使う。
 事前に組み立てたパラメータ辞書をsetParmsメソッドに与え、一括で値をセットするのがとても楽なのでおすすめ。
 その際、setParmsメソッドでは配列パラメータ名は認識できないので、各要素を個別の単一パラメータとして辞書に値を用意します。

import hou

# 単一パラメータに値をセットする
parm = hou.parm('parm_path')
parm.set( value )

# 配列パラメータにシンプルな値の配列をセットする
tupleParm = hou.parmTuple('parm_path')
tupleParm.set( (value1, value2, value3, ...) )

# ノードオブジェクトを使い、複数のパラメータをまとめてセットする
# セットしたいパラメータを辞書に溜め込み、setParms()に与える
parmDict = { 'parm_name1':value1, 'parm_name2':value2, ... }
node = hou.node('node_path')
node.setParms(parmDict)

 以上、何か不明点などあれば気軽にご質問ください。
 間違いがあればツッコミも大歓迎です。