環境:Houdini 20.5.584
ViewerStateを使ってプリミティブを範囲選択する手法について。

テンプレートにジオメトリセレクタをバインドして、onSelection()メソッドで取得したプリミティブをリストに変換します。
#
# 範囲選択
#
# onSelectionメソッド
# https://www.sidefx.com/ja/docs/houdini/hom/python_states.html
#
# selection = kwargs["selection"] # hou.GeometrySelectionクラス
# https://www.sidefx.com/ja/docs/houdini/hom/hou/GeometrySelection.html
#
import hou
import viewerstate.utils as su
class State(object):
def __init__(self, state_name, scene_viewer):
self.state_name = state_name
self.scene_viewer = scene_viewer
def onSelection(self, kwargs):
self.node = kwargs["node"]
# セレクション情報を取得
selection = kwargs["selection"]
# セレクションの詳細取得(プリミティブ選択)
sel_strings = selection.selectionStrings()
print("sel_strings: " + str(sel_strings))
# インデックスリストを取得・作成する
# 例: ['0', '2-4'] → [0, 2, 3, 4]
# ('',)(空文字列)を返すケースは、「すべてが選択された状態」を示している
primitive_indices = []
if not sel_strings or (len(sel_strings) == 1 and sel_strings[0].strip() == ""):
# 空選択と解釈 → すべてのプリミティブを対象とする
if self.node:
geo = self.node.geometry()
primitive_indices = [prim.number() for prim in geo.prims()]
else:
for sel_str in sel_strings:
parts = sel_str.replace(',', ' ').split()
for part in parts:
if '-' in part:
start, end = map(int, part.split('-'))
primitive_indices.extend(range(start, end + 1))
else:
primitive_indices.append(int(part))
print("選択されたPrimitiveのインデックス:", primitive_indices)
def createViewerStateTemplate():
""" Mandatory entry point to create and return the viewer state
template to register. """
state_typename = kwargs["type"].definition().sections()["DefaultState"].contents()
state_label = "SampleSelectGeometry::1.0"
state_cat = hou.sopNodeTypeCategory()
template = hou.ViewerStateTemplate(state_typename, state_label, state_cat)
template.bindFactory(State)
template.bindIcon(kwargs["type"].icon())
# ジオメトリセレクタをバインドする
template.bindGeometrySelector(
name = "custom_geometry_selector",
prompt = "ジオメトリを選択するサンプルです。",
geometry_types=(hou.geometryType.Primitives,),
quick_select = True,
use_existing_selection = False
)
return template