はじめに
HoudiniでHDAを作っていると、
・ノードにたくさんパラメータを追加したり
・学習中のViewer Stateでもパラメータを読んだり書き換えたり
といったことがよくあります。
こういうときに Python の Enum(列挙型) を使ってパラメータを管理しておくと、
- パラメータ名のタイプミスを防げる
- Viewer State 側と Python Module 側で、同じ名前を安全に共有できる
- パラメータを自動生成したり、まとめて扱ったりしやすくなる
といったメリットがあります。
この記事では、次の流れで説明します。
- Python Enum の基本的な使い方
- Enum を使って HDA のパラメータを自動生成する方法
- Enum を Viewer State から参照して、SimpleDrawable の見た目を制御する方法
1. Enumの基本
Python には Enum(列挙型) という仕組みがあります。
「決まった選択肢に名前をつけて管理するためのクラス」と考えるれば分かりやすいです。
この Enum は、Houdini の HDA でもそのまま使えます。
from enum import Enum
class DisplayMode(Enum):
CURRENT = ('current_viewport', 'Current Viewport Mode')
WIREFRAME = ('wireframe', 'Wireframe Mode')
# 値の取り出し
print(DisplayMode.CURRENT.name) # → 'CURRENT'
print(DisplayMode.CURRENT.value) # → ('current_viewport', 'Current Viewport Mode')
このように定義しておくと、
-
DisplayMode.CURRENT.value[0]→ Houdini の「パラメータ名(token)」として使える文字列
-
DisplayMode.CURRENT.value[1]→ UI に表示する「ラベル文字列」として使える
という形で、1つの Enum から「内部用の名前」と「表示用の名前」をまとめて取り出すことができます。
Python Source Editor でこのコードを貼って試すと、動作を確認しやすいです。
2. Enumを使ってHDAのパラメータを自動生成する
まず、インプットが 2 つある簡単な HDA を Null から作ったとします
この HDA の Python Module に Enum を定義し、
create_parameters() という関数でパラメータを自動的に追加してみます。
(最後にget_enum_info(enum_class)としてVeiwer Stateへパラメータ名を渡す関数を追加しています。クラス名を取得する必要はなかったですがマジックメソッドにも慣れるために書いています。)
import hou
from enum import Enum
# ============================================================
# Enum定義
# ============================================================
class ToggleParms(Enum):
"""トグルパラメータの定義"""
ENABLE_MATERIALS = ('enable_materials', 'Enable Materials')
OUTLINE = ('outline', 'Outline')
OUTLINE_ONLY = ('outline_only', 'Outline Only')
class Color(Enum):
"""カラー関連のパラメータ定義"""
OUTLINE = ('outline_color', 'Outline Color')
# ============================================================
# パラメータ作成関数
# ============================================================
def create_parameters(node: hou.SopNode):
"""Enum定義に基づき、HDAノードにパラメータを自動生成"""
ptg = hou.ParmTemplateGroup()
# --- トグルパラメータ作成 ---
for enum in ToggleParms:
name, label = enum.value
parm = hou.ToggleParmTemplate(name, label)
ptg.addParmTemplate(parm)
# --- カラーパラメータ作成 ---
for enum in Color:
name, label = enum.value
color = hou.FloatParmTemplate(name, label, 3)
color.setLook(hou.parmLook.ColorSquare)
color.setNamingScheme(hou.parmNamingScheme.RGBA)
color.setDefaultValue((0.5, 0.25, 0.25))
ptg.addParmTemplate(color)
# --- ノードに反映 ---
node.setParmTemplateGroup(ptg)
# ============================================================
# Enum情報取得関数(ViewerStateで使用)
# ============================================================
def get_enum_info(enum_class):
"""Enumクラスからクラス名と値リストを辞書形式で返す"""
return {
"name": enum_class.__name__,
"values": [v[0] for v in [member.value for member in enum_class]]
}
これをHDAのPythonModuleに記述して、OnCreated に
kwargs['node'].hdaModule().create_parameters(kwargs['node'])
と書いておくと、HDA ノードを作成したタイミングで、自動的にパラメータが生成されます。
ポイントは、
- どのパラメータを作るかは Enum 側に集約されている
- 実際にパラメータを作る処理は for 文で Enum をループするだけ
という形になっていて、後からパラメータを追加するときも Enum に 1 行足すだけで済む点です。
3. EnumをViewerStateで活用する
次に、Viewer State 側から Enum を使う例です。
このViewer Stateの処理は、Houdiniに内蔵されているDemo Stateの Simple drawable を
ベースに、学習のためにHDA moduleのEnumから値を取得する形に改変したものです。
Viewer Stateに興味を持つ方がいれば比較してみてください。

ここでは、SimpleDrawable を使って、ノードのパラメータ状態をビューポートに反映します。
ViewerStateModule 側で Enum を使う
import hou
import logging
# ------------------------------------------------------------
# ロガー設定
# ------------------------------------------------------------
logger = logging.getLogger("CurrentViewportState")
logger.setLevel(logging.INFO)
class State(object):
def __init__(self, state_name, scene_viewer):
"""ViewerState初期化"""
self.state_name = state_name
self.scene_viewer = scene_viewer
self.drawable = None
def onEnter(self, kwargs):
"""ViewerState起動時:Drawable初期化とパラメータ反映"""
self.node = kwargs["node"]
# 入力ジオメトリ (input[1]) を取得
geo = self.node.inputGeometry(1)
if geo is None:
logger.warning("Input[1] にジオメトリが接続されていません。")
return
# SimpleDrawable を作成
self.drawable = hou.SimpleDrawable(self.scene_viewer, geo, "simple_drawable")
self.updateDrawableFromParms()
def updateDrawableFromParms(self):
"""ノードパラメータ値を読み取り、Drawableへ反映"""
if self.drawable is None:
return
mod = self.node.hdaModule()
# --- Toggle設定を反映 ---
for token in mod.get_enum_info(mod.ToggleParms)["values"]:
val = self.node.evalParm(token)
if token == "enable_materials":
self.drawable.setShowMaterials(val)
elif token == "outline":
self.drawable.setDrawOutline(val)
elif token == "outline_only":
self.drawable.setOutlineOnly(val)
# --- Outline Color設定を反映 ---
for token in mod.get_enum_info(mod.Color)["values"]:
rgb = self.node.parmTuple(token).evalAsFloats()
color = hou.Color(rgb)
if token == "outline_color":
self.drawable.setOutlineColor(color)
# --- 表示モード ---
# 今回は「Current Viewport Mode」をベースとして表示
self.drawable.setDisplayMode(hou.drawableDisplayMode.CurrentViewportMode)
self.drawable.enable(True)
self.drawable.show(True)
def onNodeChangeEvent(self, kwargs):
"""ノードのパラメータ変更時に再描画"""
if kwargs["parm_tuple"] is None:
return
self.updateDrawableFromParms()
def createViewerStateTemplate():
"""
ViewerState登録関数。
Houdiniがこの関数を呼び出してViewerStateを登録する。
"""
state_typename = kwargs["type"].definition().sections()["DefaultState"].contents()
state_label = "Current Viewport State"
state_cat = hou.sopNodeTypeCategory()
template = hou.ViewerStateTemplate(state_typename, state_label, state_cat)
template.bindFactory(State)
template.bindIcon(kwargs["type"].icon())
# ノードのパラメータ変更イベントを監視
template.bindNodeChangeEvent([hou.nodeEventType.ParmTupleChanged])
return template
ここでのポイントは、
-
mod = self.node.hdaModule()で Python Module にアクセス -
mod.get_enum_info(mod.ToggleParms)["values"]で
Enum に定義した パラメータ名(token)のリストを取得 - Viewer State 側では、生の文字列を書くのではなく Enum 情報を読むだけ
という形になっている点です。
これにより、
- HDA の Python Module 側でパラメータ名を定義
- Viewer State 側は「Enum 情報を読むだけ」で常に最新の状態に追従
という構造になります。
パラメータ名を文字列でコピペする必要がないので、名前ズレによるバグを減らせます。
3つのトグルパラメータにチェックを入れ、input[1] にジオメトリをつなぐと、
SimpleDrawable がアウトライン付きで表示されるはずです。
4. まとめ
| 項目 | 従来 | Enum利用後 |
|---|---|---|
| パラメータ名の管理 | 文字列ハードコード | Enum定義に集約 |
| パラメータ生成 | 手動追加 | Enumループで自動生成 |
| ViewerStateとの整合性 | 名前ズレでバグが出やすい | Enumで常に同期可能 |
| 拡張性 | 新規追加時に複数修正が必要 | Enumに1行追加するだけ |
この方法を使うと、HDA・ViewerState・PythonModuleの管理が一貫します。
開発チームでも安全かつ再利用性の高いHDA構築が可能になります。





