ここでは、実際に Python を Houdini で使う場合の初歩的な事柄について説明。
- なぜ Python を使うのか? いつ使うのか?
- Houdini の Python
- Python Shell
- オブジェクト名・パスの取得
- 子ノード情報の取得
- パラメータの取得・値の設定
- ヘルプ
- 関数の定義
1. なぜ Python を使うのか? いつ使うのか?
- 機能補完
Houdini の機能が Python で書かれている。バージョンが上がるたびに増える傾向にある。- シェルフツール
- HQueue
- それ以外にも、モーションエフェクト, Houdini Help Server, Amazon クラウドレンダリング, カラーピッカ, Orbolt からのダウンロード機能など多数
- 機能を置き換えるためではない
- VEX/VOP などでできることはそちらを使う(その方が速い)
- 機能拡張
- Python ライブラリで提供される機能を使うため
- 新しい SOP/COP/DOP/Object を C++ なしで (テスト) 実装するとき
- 自動化
- アセットやシェルフにボタンを配置し、クリックしたときの自動化
- 画像やジオメトリをスタンドアロンスクリプトから生成するとき
2. Houdini の Python
- Python 2.7 (と 2.6) が含まれている
- インストール時に $HFS (Houdini インストール先) にインストールされる
- Houdini 14.0.249/python27 (および python26)
- 別途インストールは不要
- インストール時に $HFS (Houdini インストール先) にインストールされる
- Python が使えるところ
- Python Shell
- Python Source Editor
- Python Panel Editor
- シェルフツール
- パラメータフィールド
- デジタルアセット
- Hython
3. Python Shell
Python コマンドを Houdini内でインタラクティブに実行するには、まず Python Shellを使う。このシェルは、次のいずれかの方法で起動可能。
- Desktop を Build (デフォルト)から Technical へ。メイン UI 下部に表示される。
- menu から実行 (Windows -> Python Shell またはAlt+Shift+P) 別ウィンドウで起動する。
- パネルの一つとして、パネル脇の "+" ボタンをクリック、New Pane Type->Python Shell とする。
4. オブジェクト名・パスの取得
以下 Build デスクトップを使用していると仮定。
- 例えば Node Editor で、Geometry ノードを作成 (TABキーを押して、'g', 'e', 'o' と入力 + Enter)。
- 出来たノード(geo1)を選択し、Python シェルにドラッグ&ドロップ。
すると、>>> hou.node('/obj/box_object1')
と、このノードの定義同等のPython コマンドとして入力される。 - Enterを押して実行すれば、
<hou.ObjNode of type geo at /obj/box_object1>
と表示される。 - こうして出来るコマンドを変数に格納することも可能。
>>> n = hou.node('/obj/box_object1')
とすると、変数 n に Python オブジェクトとして格納される。そうした上で、>>> n.name()
とすると、'geo1'
とノード名を取得することが可能。コマンドを記述する際には、自動補間を使ってコマンドを入力可能。 - ノードまでのパスを取得するには、
>>> n.path()
とすれば、'/obj/geo1'
とノードまでの絶対パスが返る。
5. 子ノード情報の取得
- geo1 の中に入り、
- file1 ノードを削除
- Box, Sphere, Merge を作成
- box と sphere1 を merge1 に接続
変数 n は先ほどのままの hou.node('/obj/box_object1') 。 - 子ノード情報を取得するには、
n.children()
とすると(<hou.SopNode of type sphere at /obj/geo1/sphere1>, <hou.SopNode of type box at /obj/geo1/box1>, <hou.SopNode of type merge at /obj/geo1/merge1>)
と3つの名前が tuple (タプル)として返り値になる。 - 上記の返り値を変数で受けることも可能。例えば変数 t で受けるには、
>>> t = n.children()
このあと、配列として処理することが可能。>>> t[0] <hou.SopNode of type box at /obj/geo1/box1> >>> t[1] <hou.SopNode of type sphere at /obj/geo1/sphere1> >>> t[2] <hou.SopNode of type merge at /obj/geo1/merge1>
- ループに通すことも可能
>>> for c in n.children(): ... print c.name() ... box1 sphere1 merge1
6. パラメータの取得・値の設定
ジオメトリレベルからオブジェクトレベルに上がる。
- geo1のtxの値を取得する場合、
>>> n.parm("tx") <hou.Parm tx in /obj/geo1>
で、パラメータの存在を確認可能。>>> n.parm("tx").eval()
とすれば、
0.0
と返ってくる。 - 先ほど同様、変数に取ることも可能。
>>> p = n.parm("tx")
としたあと、>>> p.eval()
とすれば、同じように
0.0
となる。 - 値を設定するには、
>>> n.parm("tx").set(1.0)
とすれば、tx の値は 1.0 となる。また、>>> p.set(0.0)
とすれば原点に戻る。
7. ヘルプ
dir
-
dir(引数) とすれば対応するメソッドが表示される。例えば、
>>> dir(hou.Geometry)
>>> dir(hou.node('/obj/geo1'))
>>> dir(n)
>>> dir(p)
など。
- また、
>>> dir(hou.Geometry)
>>> help(n.parm)
とすれば、下記の様にヘルプが表示される。
Help on method parm in module hou: parm(*args) method of hou.ObjNode instance parm(self, parm_path) -> hou.Parm or None Return the parameter at the given path, or None if the parameterドキュメント
doesn't exist. REPLACES chexist function
-
Help->Houdini Helpからヘルプを参照することも可能。"Python Scripting with the Houdini Object Model"に行き、Reference 以下のhouに行くと、ノードのメソッドを知ることが可能。
8. 関数の定義
>>> def childrenOfNode(node): ... result = [] ... for c in node.children(): ... result.append(c) ... result += childrenOfNode(c) ... return result ...これを実行すれば以下のようになる。
>>> childrenOfNode(n) [<hou.SopNode of type box at /obj/geo1/box1>, <hou.SopNode of type sphere at /obj/geo1/sphere1>, <hou.SopNode of type merge at /obj/geo1/merge1>]
8.1 関数の格納場所
- Python Source Editor
Windows->Python Source Editor で起動。ここにdef childrenOfNode(node): result = [] for c in node.children(): result.append(c) result += childrenOfNode(c) return result
と記述し、Accept を押せば、この関数はシーンファイル (.hip) に保存される。
この関数を呼ぶには以下のように行う。>>> hou.session.childrenOfNode(n) [<hou.SopNode of type box at /obj/geo1/box1>, <hou.SopNode of type sphere at /obj/geo1/sphere1>, <hou.SopNode of type merge at /obj/geo1/merge1>]
- シェルフへの登録
- シェルフの空いたスペースで、RMB(右マウスボタン)->New Tool...を実行。
- 名前とラベルを変更。例えばhello, Helloなど。
- Scriptタブに行き、フィールドにスクリプトを入力。
print "hello"
など。Accept としたあと、シェルフに出来た Hello ボタンを押せば、Python Shellに hello が表示される。
- .py ファイル
- 詳しくはこちら。
8.2 Python によるエクスプレッション
-
例えば、Translate Xに $F/10 (フレーム番号/10)というエクスプレッションをPythonで定義する場合、
hou.frame()/10とし、RMB->Expression->Change to Python Expressionとする。 もしくは、Parameterウィンドウの"H" (HScript)というアイコンをPythonに変更する。 "hou."は無くとも良い。
同様にRotate Xに
frame()*5とすることも可能。
HとPythonアイコンの部分が、ノードのデフォルトエクスプレッション言語を決定している。 デフォルト言語でエクスプレッションを書いた場合には、緑で表示され、デフォルトで無い言語で書いた場合には赤く表示される。
その他、$PTなど、ローカル変数を使う場合には、
lvar("PT")や
lvar("TX")などと定義可能。
lvar("TX")は、
pwd().curPoint().positionと定義可能。
複数行のExpressionを書く場合は、Alt+Eでエディタを表示可能。
この場合、次のようなエクスプレッションを複数行で書くことも可能。
point = pwd().curPoint() if point.number() == 0: return 2.0 return point.position()
各パラメータのエクスプレッション全部選択し、をPython Shellにドラッグ&ドロップすれば、そのパラメータまでのPythonによるパスが表示される。同様にパラメータのラベルをドラッグ&ドロップすることも可能。 前者の場合、
>>> hou.parm('/obj/geo1/point1/tx') <hou.Parm tx in /obj/geo1/point1>となり、後者の場合、
>>> hou.parmTuple('/obj/geo1/point1/t') <hou.ParmTuple t in /obj/geo1/point1> となる。今までのノードを削除し、Fontノードを作成。Text Fieldに一度キーフレームを設定(ラベルをAlt+LMBクリック)してから、Expression TypeをPythonにして、
"Frame: %s" % int(frame())と入力。
0 件のコメント:
コメントを投稿