Houdini 20.0 Pythonスクリプト

ノード毎のユーザ定義データ

HOMを使って個々のノードに任意のデータを保存、取得することができます。

On this page

概要

場合よっては、各ノードに追加情報を格納する必要があります。例えば、以下の場合です。

  • シーンレベルのノードをプロダクションのデータベースエントリーやアセットタグと関連付けしたい場合。

  • Houdiniで既に格納されているものに加えてバージョン情報を追加したい場合。

  • 余計な作業をしないように、いくつかのツールを使って処理できるようにノードにタグを付けたい場合。

hou.OpNodeオブジェクトのメソッドは、ユーザデータの辞書の値を取得/設定/削除することができます。 Houdiniは、ノードに2つの異なるタイプのユーザデータを持ちます。それらのユーザデータの違いは、シーンファイルに保存されるかどうか、そして許可されている値のタイプが違います。

持続性

メソッド

シーンファイルに保存されます

文字列のみ

シーンファイルに保存されません

任意のオブジェクト

“キャッシュ化された”ユーザデータ辞書は、Pythonで実装されたノードが、再計算しないで済むようにクック間で計算された値を保存するのに役立ちます。

ユーザデータのサンプル

>>> import time
>>> # ノードインスタンスを取得します。
>>> n = hou.node("/obj/sphere1")
>>> # ノードに名前/値を格納します。
>>> n.setUserData("last_indexed", str(time.time()))
>>> # ノードからその名前の付いた値を取得します。
>>> n.userData("last_indexed")
1260572254.21
>>> # ノード上のすべての名前/値のペアの辞書を取得します。
>>> n.userDataDict()
{'last_indexed': '1260572254.21'}
>>> # 存在しない名前にアクセスすると、Noneを返します。
>>> print n.userData("foo")
None
>>> # ノードから値を削除します。
>>> n.destroyUserData("last_indexed")

文字列の内容は、XML、JSONのような構造化されたデータ、圧縮したバイナリデータ、Pickle化したPythonオブジェクトにすることができます。しかし、構造化されたデータを単純な文字列に変換またはその逆をすることは、あなたの判断に委ねられています。

例えば、以下のサンプルでは、Pythonの値を圧縮したJSON表現で保存するために2つの関数を使用しています:

import zlib
import hutil.json

def setCompressedJSON(node, data):
    node.setUserData(
        "acme_studio", zlib.compress(hutil.json.utf8Dumps(data)))

def compressedJSON(node):
    str_data = node.userData("acme_studio")
    if str_data is None:
        return None
    return hutil.json.utf8Loads(zlib.decompress(str_data))
>>> n = hou.node("/obj/geo1")
>>> setNodeData(n, {"version": 1, "database_id": 1723})
>>> print nodeData(n)["database_id"]
1723

ノード情報ウィンドウにカスタムフィールドを表示させる

  • ユーザデータキーにnodeinfo_の接頭辞を付けると、(その接頭辞を取った)キーと値がnode info popupウィンドウにカスタムフィールドとして表示されます。

  • nodeinfo_キーの最後に_nodeを付けると、その値がノードパスとして扱われ、クリック可能なリンクになり、そのノードに移動することができます。

  • nodeinfo_キーの最後に_urlを付けると、その値がURLとして扱われ、クリック可能なリンクになり、そのURLをブラウザタブで開くことができます。

ユーザデータのキャッシュ化のサンプル

以下のサンプルコードは、Pythonで実装したノードタイプ(例:SOP)の Cook タブに記述します。このサンプルでは、無駄に計算が終了したクック間で設定ファイルを再度読まれないようにしています。

def cook(node):
    config_file_name = node.evalParm("configfile")
    if node.cachedUserData("config_file_name") != config_file_name:
        config = ConfigParser.RawConfigParser()
        config.read(config_file_name)
        node.setCachedUserData("config", config)
        node.setCachedUserData("config_file_name", config_file_name)
    else:
        config = node.cachedUserData("config")

    # コンフィグ値を使用して、クックを実行します。
    #value = config.getfloat("foo")
    # ...

cook(hou.pwd())

役立つ情報

  • 存在しない値を取得しようとすると、KeyErrorが発生せずに、Noneが返されます。キャッシュ化された辞書は、Noneを値として保存することができるので、key in node.cachedUserDataDict()を使用してキーの有無をチェックして、その違いを知ることができます。

  • ノードから値を削除するには、hou.OpNode.destroyUserDataまたはhou.OpNode.destroyCachedUserDataを使用します。del node.userDataDict()["foo"]を実行しても、ノードの値は 変わりません

  • ユーザデータ値に構造化されたデータを保存(例えば、JSON文字列)する時に、“version”キーをデータに追加すれば、あなたが動作させているデータ構造のバージョンを知ることができます。経験上、保存されたフォーマットを変更したり拡張する必要がある時に役立ちます。

See also

Pythonスクリプト

はじめよう

次のステップ

リファレンス

  • hou

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

導師レベル

Python Viewerステート

Pythonビューアハンドル

プラグインタイプ