Houdini 19.0 Pythonスクリプト

HOMバイナリデータ

Python3でHOM APIからバイナリデータを取得する方法。

On this page

概要

  • HOM APIは元々はPython2用に設計されたので、hou.AgentClip.data, hou.Parm.clipData, hou.ChopNode.clipDataなどのバイナリデータを返す関数は、Python2ではstrオブジェクトを返していました。

  • 同様に、hou.CopNode.setPixelsOfCookingPlaneFromStringhou.Parm.setClipDataなどのバイナリデータを受け取る関数は、Python2ではstrオブジェクトが必要でした。

  • Python3では、これらの関数は、バイナリデータを表現したbytesオブジェクトを使用します。

  • Python2からPython3に移行する際、HOM関数の間でバイナリデータを受け渡す時にはコードを変更する必要はありません。例えば、以下のコードはPython2とPython3のどちらのHoudiniビルドでも動作します:

    #
    # Python2でも3でも動作します。
    #
    
    parm = hou.parm("/obj/geo1/tx")
    binary_clip_data = parm.clipData(1, 100)
    
    parm2 = hou.parm("/obj/geo1/ty")
    parm2.setClipData(binary_clip_data)
    
  • Python3では、bytesオブジェクトではなくstrオブジェクトを必要とするPython関数に対してバイナリデータを渡す時に気をつけなければなりません。

    例:

    parm = hou.parm("/obj/geo1/tx")
    binary_clip_data = parm.clipData(1, 100)
    
    # 以下のコードは、Python2では動作しますが、Python3では失敗します。
    # ファイルはテキストモードで開かれているので、書き出しには`str`オブジェクトが必要です。
    str_file = open("anim.bclip", "w")
    str_file.write(binary_clip_data)
    
    # 以下のコードは、Python2でもPython3でも動作します。
    # ファイルはバイナリモードで開かれているので、書き出しにはPython3では`bytes`オブジェクトが必要であるのに対して、Python2では`str`オブジェクトが必要です。
    str_file = open("anim.bclip", "wb")
    str_file.write(binary_clip_data)
    
  • 以下で説明しているメソッドを使用すれば、Python文字列関数にバイナリデータを渡せるようにするためにbytesオブジェクトをstrオブジェクトに変換することができます。同様に、HOMバイナリデータ関数に渡せるようにするためにバイナリデータを含んだstrオブジェクトをbytesオブジェクトに変換することができます。

Python3でBytesオブジェクトと文字列バイナリデータオブジェクトを双方向に変換する方法

To...Do this

HOMが返したbytesstrに変換する

bytes.decode(errors="surrogateescape")を使用します。例:

# AgentClipメソッドからバイナリデータを取得します。
binary_data = agent_clip.data(True)

# `str`オブジェクトに変換します。
str_binary_data = binary_data.decode(errors="surrogateescape")

# テキストモードで開かれたファイルに`str`オブジェクトを書き出します。
open("agent.bclip", "w").write(str_binary_data)

strbytesに変換してHOMに渡す

str.encode(errors="surrogateescape")を使用します。例:

# `str`バイナリデータを`bytes`に変換します。
binary_pixel_data = str_binary_pixel_data.encode(errors="surrogateescape")

# バイナリデータをHOM CopNodeメソッドに渡します。
cop_node.setPixelsOfCookingPlaneFromString(binary_pixel_data)

bytesオブジェクトから数値配列を取得します

Raw Bytesの代わりに、そのBytesで表現された数列が必要になることが多いです。 Pythonのarrayオブジェクトでは、パック化されたバイナリを通常のPythonのint(s)またはfloat(s)として解釈することができます。

import array

data_bytes = cop_node.pixelsOfCookingPlaneAsString()

# intには"i"、floatには"f"、64ビットintには"q"、倍精度のfloatには"d"を指定します。
# arrayモジュールに関してはPythonのドキュメントを参照してください。
arry = array("i")
arry.frombytes(data_bytes)

for x in arry:
    print(x)

Tipsとメモ

  • 上記の文字列への変換は、Raw Bytesと比べて非常に長いユニコード文字列が生成されます(たいていの場合、1バイトのデータは5文字分のエクケープ文字に展開されます)。

  • hou.convertClipData関数は、“バイナリClipデータとASCII Clipデータを変換する”ためのものです。この関数ではstrbytesかどうかは関係ないことに注意してください。代わりに、この関数はASCII(“人が解読可能な”.clip)バージョンのHoudiniアニメーションクリップフォーマットとバイナリ(.bclip)バージョンを参照します。

See also

Pythonスクリプト

はじめよう

次のステップ

リファレンス

導師レベル

Python Viewerステート

Pythonビューアハンドル

プラグインタイプ