🐐

Houdini PythonでSubnetの出力コネクタ数を増やす(備忘録4)

2025/03/02に公開

Subnetに出力コネクタを追加したい

今回のスクリプトは、Subnetを利用してノードを整理する際に、繰り返し使うノードの組み合わせを自動的にSubnet内に作成することを目的としています。ここではOutputノード追加して、Subnetの出力コネクタを増やしたいと思います。


出力コネクタを増やしたい

Subnetを作成すると、デフォルトではOutputノードが1つですが、私の作業ではOutputを3つにする必要がありました。RBDの仕込みにおいて、パーツによってVDB to Spheresを使用したり、軸を拘束したり、元の形状をコリジョンで使用したりと、異なる仕込みが必要になるため、Output先を複数用意することにしました。ここでは、"Geo"、"Spheres"、"Constraint"という3つのOutputを作成します。Subnet内でOutputノードを増やすと、subnetの出力コネクタも増えます。

既存のsubnet内でOutputノードを追加して、Output Indexを切り替える作業は手間がかかるため、ワンボタンで自動化したいと考えました。

そこで、以下の機能を持つスクリプトを作成しました。

  • Subnet内にOutputノードを追加(出力コネクタを増やす)

この機能を実装するにあたり、事前に以下のスクリプトを作成し、上記スクリプトに組み込みました。

  • 選択されたノードがSubnetであるかどうか確認する
  • Subnet内の既存のOutputノードを削除する

環境

Windows10 Pro
Houdini Indie 20.5.332 py3.11

選択したノードがSubnetであるかどうか確認

import hou

def is_subnet(node):
    return node.type().name() == "subnet"


selected_nodes = hou.selectedNodes()

if selected_nodes:
    for node in selected_nodes:
        if is_subnet(node):
            print ("Selected node is a subnet.")
        else:
            print ("Selected node is not a subnet.")        
else:
    print ("Please select a subnetwork!")

選択したノードが"subnet"かどうかを確認するスクリプトです。流用しやすいようにチェックする部分を関数にしました。


スクリプトを実行するとメッセージが表示されます

上記4行目は、次のように書き換えることもできます。

return node.isSubNetwork():

他の種類のノードでも流用することを考慮すると、type().name()で確認する方が使いやすいかもしれません。

選択したSubnet内で、既存のOutputノードを削除

import hou

def delete_child_nodes_by_type(node, type_name = "output"):
    for child in node.children():
        if child.type().name() == type_name:
            child_name = child.name()
            child.destroy()
            print (f"Successfully deleted output node: {child_name}")

            
selected_nodes = hou.selectedNodes()

if selected_nodes:
    node = selected_nodes[0]    
    delete_child_nodes_by_type(node)

    pane = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)
    pane.setPwd(node.parent())
else:
    print ("Please select a subnetwork!")

このスクリプトは、選択したSubnetノード内のOutputノードを削除します。


既存のOutputノード


スクリプトを実行するとOutputノードが削除されます

または、関数を呼び出す際に、

delete_child_nodes_by_type(node, "merge")

上記のようにノードに続いて削除したいノードのタイプ名を指定することで、Outputノード以外のノードも削除できます。

選択したSubnet内にOutputノードを追加(出力コネクタを増やす)

import hou

def is_subnet(node):
    return node.type().name() == "subnet"

def add_output_in_subnet(node, list):
    count = len(list)
    for i in range(count):
        new_name = "OUT_" + list[i]
        output = node.createNode("output", new_name)
        output.parm("outputidx").set(i)
        output.moveToGoodPosition()
    return print(f"Successfully added output nodes: {', '.join(['OUT_' + name for name in list])}")

def delete_child_nodes_by_type(node, type_name = "output"):
    for child in node.children():
        if child.type().name() == type_name:
            child_name = child.name()
            child.destroy()
            print (f"Successfully deleted output node: {child_name}")

def show_selection_error():
    print ("Please select a subnetwork!")

    
selected_nodes = hou.selectedNodes()
name_list = ["geo", "spheres", "cons"]

if selected_nodes:
    for node in selected_nodes:
    
        if is_subnet(node):
            delete_child_nodes_by_type(node)
            add_output_in_subnet(node, name_list)
    
        else:
            show_selection_error()
else:
    show_selection_error()

このスクリプトは、選択したSubnetノードから既存のOutputを削除し、指定された名前のOutputノードを追加します。記事上段で作成したis_subnet()とdelete_child_nodes_by_type()を流用しています。


出力コネクタが増えました

name_list = ["geo", "spheres", "cons"]

name_listで追加する名前のリストを指定しています。ここではgeo、 spheres、consの3つ記載していて、その数だけノードが追加されます。9行目でPrefixとして ”OUT_” を名前に加えています。


Subnet内でOutputノードが追加された

まとめ

お読みいただきありがとうございました。今回は関数にまとめるのを意識してスクリプトを作成しました。シンプルなスクリプトでも関数の形にしておくと、コードを流用しやすいというのを実感できました。また、「フォーマット済み文字列リテラル」というものも少し理解ができました。コードが読みやすくなって良いですね。

この記事が少しでもお役に立てれば幸いです。

参考

http://nomoreretake.net/2018/09/14/houdinipython-memo-part04/
https://qiita.com/Tadataka_Takahashi/items/1f667e11f80423e2dda1

Discussion