Houdini 19.5 ジオメトリ

プログラム的にVerb(動詞)を使ったジオメトリ

ほとんどのジオメトリ(SOP)ノードをPythonスクリプトから使用することで、プログラム的にジオメトリを生成することができます。

On this page

概要

SOPノードをコンパイル可能にする一環として、ノードを基本オペレーションコード(このノードがジオメトリに対して 行なう コード)とノードの取り回しをするコード(キャッシュ化、入力の読み込み、パラメータの評価など)に分けました。 これらの関数を Verbs と呼んでいます。Pythonスクリプトでそれらの関数を使用することで、hou.Geometryオブジェクトに保持されているジオメトリを修正することができます。 これは、ジオメトリをプログラム的に変更する必要があり、そのためにわざわざジオメトリネットワークを構築したくない時に役立ちます。

Verbの取得

  • hou.NodeTypeCategory.nodeVerbは、指定した名前のノードタイプのVerbを返します。:

    box_verb = hou.sopNodeTypeCategory().nodeVerb("box")
    
  • 既に特定のSOPノードを参照していれば、hou.SopNode.verbを使用することで、それに該当するVerbを取得することができます:

    node = hou.node("/obj/geo1/box")
    box_verb = node.verb()
    
  • hou.NodeTypeCategory.nodeVerbsは、ノードタイプ名とVerbをマップした辞書を返します:

    verbs = hou.sopNodeTypeCategory().nodeVerbs()
    box_verb = verbs["box"]
    sphere_verb = verbs["sphere"]
    

    Pythonシェルで利用可能な“Verbs”をリストすることができます:

    sorted(hou.sopNodeTypeCategory().nodeVerbs().keys())
    

Verbの使い方

Verbは、2つの手順を踏んで使用します:まずVerbにパラメータを設定します。次に、そのVerbをhou.Geometryオブジェクトに適用します。

  1. Verbにパラメータを設定します。

    パラメータの内部名がキーの辞書をhou.SopVerb.setParmsに渡します。パラメータエディタ内のパラメータ名の上にマウスカーソルを置くと、そのパラメータの内部名を確認することができます。

    box_verb.setParms({
        "t": hou.Vector3(0.5, -0.5, 2.0),
        "scale": 0.5,
    })
    

    Multiparmは、そのMultiparmパラメータ名の辞書のリスト/タプルを渡すことで設定されます。 それらの辞書のトークン名は、数字の代わりに#を含めてください。 以下の例では、タプルとして扱われるようにするために、そのタプルの末尾にカンマが必要であることに注意してください。単一辞書だと機能しません。

    add_verb.setParms({
        'points':
        [
            {
                'usept#': True,
                'pt#': (1, 2, 3),
            }
        ]
    })
    
  2. そのノードをジオメトリオブジェクトに適用します。

    これを行なう前に、ジオメトリオブジェクトがなければなりません。以下のコードで空っぽのジオメトリオブジェクトを作成することができます:

    geo = hou.Geometry()
    

    次に、そのVerbを実行すると、その出力をジオメトリオブジェクトに書き出すことができます:

    box_verb.execute(geo, [])
    

    Verbが入力を持っている場合(例えば、/nodes/sop/copy.htmlのVerbは、コピーするジオメトリと、そのコピー先のポイントを受け取ります)、その2番目の引数に、それらの入力を表現したhou.Geometryオブジェクトを指定することができます。 hou.SopNode.geometryを使用すれば、ノードから、そのジオメトリの現在の参照を 読み込み専用 で取得することができます。

    c2p_verb = hou.sopNodeTypeCategory.nodeVerb("copytopoints")
    instance = hou.node("/obj/geo1/sphere1").geometry()
    points = hou.node("/obj/geo1/pointcloud").geometry()
    c2p_verb.execute(geo, [instance, points])
    

Note

Verbをexecute()すると、その引数に渡したジオメトリが 上書き されます。 複数のジェネレータ(または複数のジェネレータ/フィルタのチェーン)を組み合わせたい場合、“バッファ”であるGeometryオブジェクト内に各ピースを生成し、hou.Geometry.mergeを使って、それらのピースを“メイン”であるGeometryオブジェクトにマージしなければなりません。

sops = hou.sopNodeTypeCategory()
box = sops.nodeVerb("box")
box.setParms({"scale": 0.25})

geo = hou.Geometry()
temp = hou.Geometry()

for x in (-0.5, 0.5):
    for y in (-0.5, 0.5):
        for z in (-0.5, 0.5):
            box.setParms({
                "t": hou.Vector3(x, y, z)
            })
            box.execute(temp, [])
            geo.merge(temp)

メモとTips

  • Python SOPを使用すれば、ジオメトリ生成スクリプトのプレビュー、テスト、デバッグをすることができます。このSOPは、 Python Code パラメータ内で構築したhou.Geometryオブジェクトを出力します。

  • hou.SopVerb.executeは、指定したジオメトリオブジェクトを常に上書きします。既存のジオメトリオブジェクトに 追加 したいのであれば、空っぽのジオメトリに対して実行してから、hou.Geometry.mergeを使って、それを他のジオメトリオブジェクトとマージします。

    # 追加先の既存コンテンツ。
    existing_geometry = hou.node("/obj/geo1/phone").geometry()
    # 新しいコンテンツを格納するための空っぽのジオメトリ。
    new_geometry = hou.Geometry()
    # 新しいジオメトリに書き込みます。
    box_verb.execute(new_geometry, [])
    # その新しいジオメトリを既存ジオメトリに追加します。
    existing_geometry.merge(new_geometry)
    
  • Python SOP内でVerbsを使ってジオメトリを修正する場合、そのスクリプトの最後でそのノードのジオメトリを上書きする必要があります:

    # このノードの参照を取得します。
    node = hou.pwd()
    geo = node.geometry()
    
    # ... ジオメトリを操作します ...
    
    # Verbsをhou.Geometryに対して実行すると、Verbsはその大元のジオメトリを直接編集するのではなくて置換します。
    # そのため、それをそのノードのジオメトリに明示的に書き戻す必要があります。
    node.geometry().clear()
    node.geometry().merge(resultgeo)
    

サンプル

以下のサンプルでは、ノードからジオメトリを取得して、そのジオメトリにSubdivideIsoOffsetのVerbsを適用しています。

node = hou.node("/obj/geo1/testgeometry_pighead1")
geo = node.geometry()
resultgeo = hou.Geometry()

# サブディビジョン化の方法を知っているhou.SopVerbを取得します。
sops = hou.sopNodeTypeCategory()
subverb = sops.nodeVerb('subdivide')

# パラメータ名と値をマッピングした辞書を渡します。
# ノードのデフォルトが既に設定されているので、後はデフォルト以外の内容を設定するだけです。
subverb.setParms({'iterations': 3})

# SopVerb.execute()は、その結果の書き出し先となるターゲットのhou.Geometryと
# そのVerbの入力であるhou.Geometryのリストを受け取ります(未接続の入力を表現するには、リストにNoneを使用します)。
subverb.execute(resultgeo, [geo])

# ここでIsooffsetを実行します。
isoverb = sops.nodeVerb('isooffset')
isoverb.setParms({'samplediv':100, 'output':0})
isoverb.execute(resultgeo, [resultgeo])

ジオメトリ

学ぼう

モデリング

地形

粉砕

破壊を参照してください。

次のステップ

導師レベル