あるシーンを開いた時、膨大なオブジェクト数とグループ数により階層が深く、なおかつすべてのノードに命名規則が全く見当たらないという、ツール作成者視点でシーンを眺めた時、ついつい汚い床の上をのたうち回りたくなるような状況は往々にしてあることなのですが、そのような状況下でのHoudiniの選択操作は、他のDCCツールよりも遅れを取っている気がします。
例えば、ビューポートで選択しているすべてのノードの親を簡単にまとめて再選択したかったり、同様に、選択アイテムのすべての下流ノードをまとめて選択したかったりと言った状況です。
ノードを右クリックして表示されるポップアップメニューから、Inputs/Outputsサブメニューを駆使してみるも、単一の選択アイテムのみがノード検索の起点になるので、複数のノードツリーをまとめて選択できなかったりします。
このように、意外とHoudiniデフォルトの選択機能に痒いところが多かったので、選択補助スクリプトを書いてみました。
ついでと言ってしまうと何だか申し訳なく感じてしまうのですが、簡単なメモを書き残したいと思います。
基本的なノード検索
import hou
nodeObject = hou.node("node_path")
import hou selectedItems = hou.selectedItems()
ノードの親子関係
import hou
node = hou.node('node_path')
# parent()は自身を含む外側のノードの取得
outerNode = node.parent()
print( outerNode )
# children()は自身が含む内側のノードリストを取得
innerNodes = node.children()
print( innerNodes )
import hou
node = hou.node('node_path')
# inputs()は自身へ入力している直接の上流ノードリストの取得
inputNodes = node.inputs()
print( inputNodes )
# outputs()は自身が直接出力しているノードリストを取得
outputNodes = node.outputs()
print( outputNodes )
# inputAncestors()は直系の祖先をまとめて取得
ansectorNodes = node.inputAncestors()
print( ansectorNodes )
かなり基本的なところではこんな感じ。
他にもたくさんあるので、その他のメソッドは要マニュアル参照。
出力の全子孫を取得するメソッドがパット見見つからない感じだったので、再帰的に子孫をたどる関数を作ってみる。
import hou
def getDescendents(node, *args, **kwargs):
"""
DESCRIPTION : 引数で与えたノードから再帰的に子孫を辿って返す
ARGUMENTS : node : 探索を開始するノード
RETURN : descendents : 見つかった子孫ノードリスト
"""
descendents = []
direct_outputs = node.outputs()
if direct_outputs:
for direct_output in direct_outputs:
descendents += [direct_output]
descendents += getDescendents(direct_output)
return descendents
node = hou.node('node_path')
descendents = getDescendents(node)
for descendent in descendents:
print( descendent )
選択操作
import hou
node = hou.node("node_path")
# 選択 setSelectedメソッドにブール値をセット 1で選択0で非選択
node.setSelected(1)
# 選択解除
node.setSelected(0)
上記を組み合わせて、現在のノードから1つ上流のノードを探し、再度全下流ノードを探して全選択を行うなどの便利なコマンドを作成できます。