On this page |
概要 ¶
-
Pythonを使って新しい、または再利用可能なジオメトリノードを定義したいのであれば、以下の“新しいノードタイプの作成”を参照してください。
-
一回限りの変更をスクリプト化したいのであれば、Python SOPを使うことで、新しいノードタイプを作成することなく、ジオメトリ上のPython snippetを実行することができます。
Note
Python SOP内にノードパラメータを設定しないでください。 これによって、壊れた依存関係が生成されてしまい、たくさんの問題を引き起こしてしまいます。
新しいノードタイプの作成 ¶
-
File ▸ New Asset を選択します。
-
Operator Definition を
python
に、 Network Type を Geometry に設定します。 -
Save To Library に、新しいノードタイプを保存するOTLライブラリファイルを設定します。
-
Accept をクリックします。
-
Edit Operator Type Propertiesウィンドウのオプションを使って新しいノードタイプのインターフェースを定義します。
-
Code タブをクリックして、Pythonスクリプトを編集することでSOPの動作を定義します。
Tip
Type Propertiesウィンドウを閉じた後にスクリプトを編集したい場合、ノードのインスタンスをクリックして、 Type Properties を選択します。
コードの記述 ¶
ノードの入力のジオメトリを取得するには、以下のコードを記述します。
geo = hou.pwd().geometry()
hou.pwd()
関数は、現在処理されているNodeを返し、geometry()
はhou.Geometryオブジェクトを返します。Python SOPの1番目の入力にSOPが接続されていれば、Houdiniは、Pythonコードを実行する前にその入力のSOPのジオメトリをPython SOPのジオメトリにコピーします。
Tip
1番目以外の入力からジオメトリを取得するには、Nodeのinputs()
メソッドを使用して、入力ノードを取得し、そのノードのgeometry()
メソッドを使用することでジオメトリを取得することができます。
this_node = hou.pwd() inputs = this_node.inputs() # 2番目の入力からジオメトリを取得します # (first input=0, second input=1, third=2など) second_input_geo = inputs[1].geometry()
ジオメトリオブジェクト(この例ではgeo
)に対してメソッドをコールすれば、出力するジオメトリを修正することができます。ジオメトリを制御する方法は、hou.Geometryオブジェクトのドキュメントを参照してください。
例えば、ポリゴンをジオメトリに追加するには、以下のコードを記述します:
poly = geo.createPolygon() for position in (0,0,0), (1,0,0), (0,1,0): point = geo.createPoint() point.setPosition(position) poly.addVertex(point)
“filter”ノードよりも“source”ノードを作成したい場合は、単にType PropertiesでMaximum Inputsを0に設定すればいいだけです。hou.pwd().geometry()
をコールすると追加可能な空っぽのジオメトリが返されます。
SOPを中断可能にする ¶
指定した入力ジオメトリが膨大なために、ノードの処理に時間がかかる場合、 ⎋ Escを押してその処理を中断したい場合があります。SOPを中断可能にするには、定期的にhou.updateProgressAndCheckForInterrupt()をコールする必要があります。例えば、 ⎋ Escを押すと、このSOPの処理が停止します:
geo = hou.pwd().geometry() # 各ポイントの移動量を調べるために、"t"パラメータを評価します。 translation = hou.Vector3(hou.parmTuple("t").eval()) for point in geo.points(): # ポイント毎に新しい位置を設定します。 point.setPosition(point.position() + translation) # ユーザがEscapeを押したかどうかを確認します。 if hou.updateProgressAndCheckForInterrupt(): break
SOPのエラーと警告 ¶
Python SOPに例外が発生すれば、ノードがエラーとして赤く表示されます。ノードをクリックすることで、そのエラーのスタックトレースを見ることができます。
ユーザ側にPythonスタックトレースを表示させないようにエラーメッセージを生成するには、hou.NodeErrorの例外を発生させてください。例えば、
raise hou.NodeError("Invalid parameter settings")
を実行すると、"Invalid parameter settings"
のエラーメッセージでノードが赤く表示されます。同様に、ノードの警告を追加するには、hou.NodeWarningのインスタンスを発生させます。
新しいアトリビュート用ローカル変数の作成 ¶
hou.Geometry.addAttribには、Houdiniが、新しく追加したアトリビュート用のローカル変数を作成するかどうか設定するパラメータがあります。直接varmapアトリビュートを修正する必要はありません。
SOPコードのプロファイリング ¶
PythonのcProfile
モジュールによってPython SOPをプロファイリングすることができます。
Tip
UbuntuをOSに使用している場合、Ubuntuでは標準ライブラリがpstatsを持っていないので、aptitude
を使ってpython-profiler
をインストールします。
トップレベルでたくさんのステートメントを記述するのではなく、関数内で作業が完結するように、あなたが作成したSOPにスクリプトを記述します。例:
def cook(): poly = geo.createPolygon() for position in (0,0,0), (1,0,0), (0,1,0): point = geo.createPoint() point.setPosition(position) poly.addVertex(point) cook()
cProfile
をインポートし、あなたが作成した関数を直接コールせずにcProfile.runctx
を使ってコールします:
def cook(): poly = geo.createPolygon() for position in (0,0,0), (1,0,0), (0,1,0): point = geo.createPoint() point.setPosition(position) poly.addVertex(point) cProfile.runctx('cook()', globals(), locals())
これにより、ノードが処理される時に、スクリプトのランタイムの要約がPythonシェルに表示されます。
SOPの一部をC++で記述する ¶
SOPの一部をC++で記述する簡単な方法は、C++を使ったhouモジュールの拡張を参照してください。
デジタルアセット外でコードを保存する ¶
バージョン管理システムでソースコードを管理するために、デジタルアセット外にソースコードを保存したい場合があります。Type Propertiesダイアログを使って、アセットのパラメータをセットアップし、Pythonソースコードをotl
ファイルに挿入することができます。
以下の関数を使えば、外部ファイルからPythonソースコードを読み取り、それをデジタルアセットに反映することができます:
def loadPythonSourceIntoAsset(otl_file_path, node_type_name, source_file_path): # Pythonソースコードを読み込みます。 source_file = open(source_file_path, "rb") source = source_file.read() source_file.close() # OTLファイルからアセット定義を探します。 definitions = [definition for definition in hou.hda.definitionsInFile(otl_file_path) if definition.nodeTypeName() == node_type_name] assert(len(definitions) == 1) definition = definitions[0] # アセットのPythonCookセクションにソースコードを保存します。 definition.addSection("PythonCook", source)