Houdini 19.5 Pythonスクリプト

PythonステートInfoパネル

Pythonステートは、現行設定だけでなくホットキーとマウスの使い方のヒントを表示した“Infoパネル”を表示することができます。

On this page

Note

現在のところ、この機能は実験段階であり、機能とプログラミングインターフェースは変更される可能性があります。

How to

ステートを初期化する時、hou.SceneViewer.hudInfoをコールして、そこにテンプレート辞書を指定することで、Infoディスプレイをセットアップすることができます。

HUD_TEMPLATE = {
    "title": "Vellum Brush", "desc": "tool", "icon": "SOP_vellumbrush",
    "rows": [
        {"id": "shape", "label": "Brush Shape", "key": "B / Shift B"},
        {"id": "shape_g", "type": "choicegraph", "count": len(SHAPES)},
        {"id": "mode", "label": "Mode", "key": "1-6"},
        {"id": "mode_g", "type": "choicegraph", "count": len(MODES)},
        {"id": "radius", "label": "Radius", "key": "mousewheel"},
        {"id": "radius_g", "type": "bargraph"},
        {"id": "frozen", "label": "Frozen", "key": "F"},
        {"id": "setrest", "label": "Set rest state", "key": "H"},

        {"id": "modedev", "type": "divider", "label": "Brush"},
        {"id": "brush_act", "label": "Brush", "key": "LMB"},
        {"id": "sim_act", "label": "Simulate", "key": "Shift LMB"},
        {"id": "drag_act", "label": "Drag pins", "key": "MMB"},
        {"id": "add_act", "label": "Add pin", "key": "Shift MMB"},
        {"id": "del_act", "label": "Remove pin", "key": "Ctrl MMB"},
        {"id": "rot_act", "label": "Rotate pins", "key": "Ctrl Shift MMB"},
    ]
}


class State(object):
    def __init__(self, state_name, scene_viewer):
        self.state_name = state_name
        self.scene_viewer = scene_viewer        

        self.scene_viewer.hudInfo(template=HUD_TEMPLATE)

ステートの操作中に、行/グループの値と可視性を更新することができます:

def onEnter(self, kwargs):
    updates = {
        "shape": self.current_spape_name,
        "shape_g": self.all_shape_names.index(self.current_shape_name)
        "mode": self.current_mode_name,
        "mode_g": self.all_mode_names.index(self.current_mode_name),
        "radius": "{:0.3f}".format(self.radius),
        "radius_g": self.radius / self.max_radius,
        "frozen": "true" if self.is_frozen else "false",
    }
    self.scene_viewer.hudInfo(values=updates)

テンプレート辞書

最初にhudInfo()をコールする時、そのhud_template引数には以下のトップレベルのキーを含んだJSON風の辞書を指定してください:

トップレベル

"title"

任意, 文字列

パネルの上部に大きなテキストで表示されます。通常では、これはノード/ステートの名前です。

"icon"

任意, 文字列

Houdiniアイコン名またはファイルパス。タイトルの隣に表示されます。

"desc"

任意, 文字列

タイトルの後に解説形式で表示されます。

"rows"

任意, リスト

行辞書(以下参照)のリスト。

行オブジェクト

rowsリスト内の各辞書には、以下の共通キーを含めることができます:

"id"

任意, 文字列

これを使用することで、更新用の辞書でこの行を参照することができます。 この行に値がない、または、決して値を変更することがない場合、これはなくても構いません。

"type"

任意, 文字列

行が情報をどのように表示するか。以下の行タイプを参照してください。これがない場合、その行は"plain"になります。

"visible"

任意, ブール

この行をInfoパネルで表示するかどうか。

  • 行のタイプによっては、"label""value"などのキーを追加することができます。

  • 特別なタイプの行がグループです。グループには、サブ行のリストを格納します。これによって、一度にグループの可視性を制御することができます。詳細は、行グループを参照してください。

plain

これがメイン/通常の行タイプです。このタイプの行を使用すると、ユーザにホットキーまたは値または両方を表示することができます。

"label"

任意, 文字列

キー/値の隣に表示するテキスト。

"value"

任意, 文字列

行に表示する値。値が数値の場合でも、それを文字列として書式化してください。

"key"

任意, 文字列

行の隣に表示するキー仕様。以下のキー指定を参照してください。

"wide"

任意, ブール

これがTrueの場合、ラベルはパネルの全幅を使用し、従来キーと値で確保されている余分なスペースを占有します。 これは、ワードラップ(単語区切りで改行)も有効にします。

Note

これはテンプレート内でのみ設定することができ、更新用の辞書を使ってこの値を変更することはできません。

例えば、ユーザがマウスホイールを使って“density”値を制御できるようにPythonステートを組んだとします。 これをユーザにヒントとして表示したいのであれば、Infoテンプレート内に以下の行を使用します:

{ "id": "density", "label": "Density", "key": "mousewheel", "value": "0.0" }

divider

これは、パネルの“セクション”間の分割線です。

"label"

任意, 文字列

分割線のパーツとして表示するテキスト。これは、“タイトル”セクションを付けるのに便利です。

例:

{ "type": "divider", "label": "Brushes" }

bargraph

これは、ラベル列に“進捗バー”タイプのグラフを表示します。 これを使用することで、(“半径”や“アルファ”などの)数値情報を表示することができます。

現在のところ、この値の範囲は必ず0.0から1.0でなければなりません。 表示したい“本当の”値がどのようなスケール/単位であっても、必ずその値を正規化した後にbargraph行にその値を設定する必要があります。

ほとんどの場合、このグラフは、同じ情報をテキストで表示する“plain”行の後に表示します。以下のスタイルガイドを参照してください。

"value"

任意, 浮動小数点

進捗バーの割合(0.0から1.0)。

例:

{ "type": "bargraph", "id": "alpha_g", "value": 0.25 }

choicegraph

この行は、数個の候補値のみで設定(例えば、現行モードとか現行ジオメトリタイプなど)する現行値をグラフィカルに表示します。 これは、その値をラベル列内にバーセグメントで表示します。 選択候補の数は、テンプレート内にcountキーを使用して指定します。 現行値(0からcount - 1)は、そのグラフ内の“アクティブ”なセグメントを制御します。

ほとんどの場合、このグラフは、同じ情報をテキストで表示する“plain”行の後に表示します。以下のスタイルガイドを参照してください。

"count"

必須, 整数

グラフ内のセグメント数。

"value"

任意, 整数

“アクティブ”にするセグメントのインデックス(0からcount - 1)。

例:

{ "type": "choicegraph", "id": "mode_g", "value": 0 }

group

これは、特別なタイプの“行”で、まとめて表示/非表示ができるように0個以上の“サブ行”をグループ化します。

更新用の辞書"current"によって、相互に排他的な子セットを切り替えることができます。 別の方法だと、"visible"を更新することでグループ内の行の可視性を直接制御することができます、

以下の行グループを参照してください。

"rows"

リスト

このグループのサブ行の辞書のリスト。

"current"

任意, 整数または文字列またはNone

サブ行のインデックス、rows内のアイテムのどれかのIDを受け取ります。 指定された項目が表示され、それ以外の項目が非表示になります。

"visible"

任意, ブール

このグループ内の項目を可視にするかどうか。

例:

{
    "type": "group", "id": "mode_pages",
    "rows": [
        ...
    ]
}

キーの指定

行のkeyフィールドは文字列です。これは以下のパーツで構成することができます。

  • 単一キー(またはマウスボタン)。例えば、A, 5, LMB

  • 以下の文字列がユニコードシンボルまたはグラフィックに置換されます: backspace, del, esc, left, right, up, down, LMB, MMB, RMB, mousewheel

  • キーコンボ: 2個以上の単一キーを+で結合した文字列。例えば、Ctrl + LMB, Ctrl + Shift + A

  • キー範囲: “開始”キーと“終了”キーを-で結合した文字列。例えば、1-3, 5-8

  • 代替キー: 別々のキー/コンボ/範囲を/で区切った文字列。例えば、E / Shift + E / MMB

値辞書の更新

Infoパネル内の値/可視性を更新するには、更新用の辞書を構築し、hou.SceneViewer.hudInfoメソッドのhud_valuesキーワード引数にその辞書を渡してください。

  • その辞書のキーでは、テンプレート内のアイテムのid文字列を参照します。

  • その辞書の値がスカラー(整数、浮動小数点、文字列)の場合、その行のvalueの設定を省略することができます。

  • その値に、複数のキーと値で構成された辞書を指定すると、指定した行/グループの特定のオプション(例えば、"visible"オプション)を更新することができます。

Tip

Infoパネルで(ホットキーのヒントだけでなく)値も表示する場合、必ずそれらの値を最新に維持してください。 通常では、入力時、再開時、 そして 値に影響するパラメータの変更がある度(通常では、hou.Node.addParmCallbackを使用してノードのパラメータ変更を定期的にチェックできるようにする必要があります)に更新をする必要があります。

例:

updates = {
    # 値を直接設定する省略形:
    "shape": self.current_spape_name,
    # 上記の省略形は以下の設定と等価です:
    "mode": {"value": self.curent_mode_name},
    # 値は必ず文字列であることを忘れないでください。
    "radius": "{:0.3f}".format(self.radius),
    "frozen": "true" if self.is_frozen else "false",
    # 行または行グループの可視性を設定します。
    "tangents": {"visible": self.curve_type == "bezier"},
}
self.scene_viewer.hudInfo(hud_values=updates)

行グループ

グループは、一度に行ブロックを表示/非表示にするのに役立ちます。

  • 行またはグループの“visible”キーを設定することで、それを表示/非表示することができます。

  • グループでは、"current"キーにそのグループ内の項目のIDを設定することができます。その行/グループのみが表示され、それ以外のすべてが非表示になります。これは、行の“ページ”間を切り替えるのに役立ちます。

HUD_TEMPLATE = {
    "title": "Curve", "desc": "tool",
    "icon": "SOP_curve",
    "rows": [
        {
            "id": "mode", "label": "Mode",
            "key": "{}/{}/{}".format(ENTER_EDITMODE_KEY,
                                     ENTER_DRAWMODE_KEY,
                                     ENTER_AUTODRAWMODE_KEY)
         },
        {"id": "mode_g", "type": "choicegraph", "count": 3},
        {"id": "primtype", "label": "Curve Type"},
        {
            # このグループは、モード別に異なるヒントの"ページ"を切り替えることができます。
            "type": "group", "id": "mode_page",
            "rows": [
                {
                    "type": "group", "id": "edit",
                    "rows": [
                        {"label": "Drag entire curve",
                         "key": "Shift + LMB"},
                        {"label": "Insert a point", "key": "Ctrl + LMB"},
                    ]
                },
                {
                    "type": "group", "id": "draw",
                    "rows": [
                        {"label": "Insert a point (on curve)", "key": "Ctrl + LMB"},
                        {"label": "Finish curve", "key": '{}/{}'.format(FINISH_KEY, "MMB")},
                        {"label" : "Drag point (With no curve active)", "key" : "MMB"},
                        {"label": "Align point with previous point (hold)",
                         "key": "Shift"},
                        { "type" : "group", "id": "bezierdraw", 
                          "rows" : [
                            {"label": "Draw arc segment (hold)",
                             "key": CIRCLE_SEGMENT_KEY},
                            {"label": "Draw straight line segment (hold)",
                             "key": "Shift + Ctrl"}
                        ]}
                    ]
                },
                {
                    "type": "group", "id": "auto",
                    "rows": [
                        {"label": "Insert a point (on curve)", "key": "Ctrl + LMB"},
                        {"label": "Finish curve", "key": '{}/{}'.format(FINISH_KEY,"MMB")},
                        {"label" : "Drag point (With no curve active)", "key" : "MMB"},
                        {"label": "Click where curve should go"},
                        {"label": "Use more points in curvy areas"},
                        {"label": "Finish curve", "key": FINISH_KEY},
                    ]
                },
            ]
        },
        {
            # このグループは、接線を持たないジオメトリタイプに対してこのセクションを非表示にすることができます。
            "type": "group", "id": "tangents",
            "rows": [
                {"type": "divider", "label": "Tangents"},
                {"label": "Set selected point type", "key": "1-3"},
                {"label": "Re-pull tangents (on point)",
                 "key": "Ctrl + LMB"},
                {"label": "Break tangent handle while dragging",
                 "key": "Ctrl"},
                {"label": "Lock tangent direction while dragging",
                 "key": "Shift + Ctrl"},
                {"label": "Snap tangents to 45 degree angles (hold)",
                 "key": "Shift"},
            ]
        },
        {"type": "divider", "label": "Common"},
        {"label": "Show Radial Menu", "key": RADIAL_MENU_KEY},
        {"label": "Toggle Transform Handle", "key": TRANSFORM_TOGGLE_KEY}
    ]
}


# 値/可視性を更新するサンプル:
# "mode"変数に現行モードの文字列(例えば、"draw")が含まれているとします。
# "mode_num"変数は、その現行モードを数字(例えば、0,1,2)で表現します。
# curve_typeが"bezier"の場合にのみ接線ヒントのブロックを表示します。
updates = {
    "mode": mode,
    "mode_g": mode_num,
    "mode_page": {"current": mode},
    "tangents": {"visible": curve_type == "bezier"},
}
scene_viewer.hudInfo(hud_values=updates)

スタイルガイド

  • Infoパネルに“プロンプト”(例えば、“ポイントをクリックしてポイントを繋げてください”とか“削除したいオブジェクトを選択してください”など)を表示しないでください。このような類のメッセージは、ビューア内の下部のプロンプト領域でもプリントすることができるからです。Infoパネルは、“隠し”機能を表に出して役立つヒント/値を表示するように意図されています。

  • ステートでできる事をすべて完全にInfoパネルに載せる必要はありません。使用頻度の高い役立つデータ/ヒントのみを表示してください。

  • Infoパネルは、マウスポインタ下のものに応じてその内容を更新するように意図されていません。これは、Tips/ヒント/ホットキーを“常に知らせるのに役立つ”ように意図されています。Infoパネルが比較的大きい領域を占有するので、マウスの動きに基づいて“アニメーション”させると、非常に鬱陶しくて/うんざりしてしまいます。

  • 現行“モード”のインジケータは、スタックの上に置いてください。例えば、ブラシツールに現行“モード”(Brush、Smooth、Erase)と“空間”(World, Local, Screen)があるならば、それらを上部に表示すべきです。

  • 値が数値の場合、または、値が少ない選択候補(10個未満)の選択番号の場合、“plain”行の下に“graph”行を追加してその情報をグラフィックでも表示されるようにすると良いです。値が変更される度に“plain”行と“graph”行の両方を更新する必要があることを忘れないでください。

  • モード間を循環するキーを用意する場合、現行モードを表示する行に対してそのキーをホットキー(例えば、"B")として設定してください。モード間を前方に循環するキーと後方に循環するキーを用意する場合、それらのキーを代替キー(例えば、"B / Shift + B")として設定してください。各モードに別々のキーを用意する場合、それらのキーが代替キー(例えば、"Q / R / T")として合うかどうか確認してください。どのキーにも合わない場合、各モードのキーを表示しない、または、各モードに別々のキー/ヒントの行を表示することを検討してください。

  • ホットキーなしのヒントの前にホットキーありのヒントが来るように行を並べてみてください。ホットキーのある行とない行を混在させると見た目が乱雑になりがちです。

  • “ranges”キーは、キー列を狭く維持するのに適しています。通常では、“ranges”キーは"1-9""F5 - F8"などのように明白な連番を持つキーに使用します。

  • すべてのツールで共通なアクション(例えば、選択の追加/削除/切り替えをする修飾キー、または、すべてを選択する⌃ Ctrl + A)にはヒントを入れないでください。

Pythonスクリプト

はじめよう

次のステップ

リファレンス

  • hou

    Houdiniにアクセスできるサブモジュール、クラス、ファンクションを含んだモジュール。

導師レベル

Python Viewerステート

Pythonビューアハンドル

プラグインタイプ