On this page

概要

このサンプルモジュールには、メソッドに基づいてコンポジットネットワークを生成するオブジェクトが含まれています。 メソッドをコールすると、コンポジット(COP)ノードを作成し、そのノード上にパラメータを設定し、ノードを一緒に接続します。

Tip

これは、icompositeユーティリティプログラムの動作に似ています。

サンプルの使い方

>>> import comp

# $HFS/houdini/pic/default.picを読み込み、jpegに変換、
# 現行ディレクトリに出力を書き込む。
>>> comp.readFile("default.pic").writeFile("default.jpg")

# ($HFS/houdini/picから)連番画像を読み込み、明るくして、
# jpegに変換。
>>> comp.readFile("butterfly$F.pic").bright(1.8).writeFile("butterfly$F.jpg")

# default.picを読み込み、明るくして、グレーの背景上に合成、
# out.picに書き込む。
>>> comp.readFile("default.pic").bright(1.2).over(
...     comp.constant(0.3, 0.3, 0.3)).writeFile("out.pic")
...

実装

import hou

"""
このモジュールを使用すると、実行する合成処理を記述するエクスプレッションを書き込むだけで、
コンポジットネットワークの作成と評価ができるようになります。
このサンプルのいくつかの簡単な拡張機能を使用することで、
Houdiniのicompositeプログラムに相当するPythonプログラムを作成することができます。

例えば、以下を書き込むことができます:

    import comp
    comp.readFile("default.pic").bright(1.2).over(comp.constant(0.3, 0.3, 0.3)
        ).writeFile("out.pic")

すると、Houdiniは、default.pic画像を読み込むコンポジットネットワークを構築し、
それを明るくし、単色に合成して、その結果をout.picへ書き出します。

尚、このモジュールは、連番画像に対する合成をサポートしています:
つまり、入出力画像の名前で($Fのような)時間依存のエクスプレッションを使用するだけです。

グラフィカルなHoudiniのセッションから、このモジュールを使用する場合、
作成されるコンポジットネットワークをチェックすることができます。
"""

def test():
    """この関数は、以下を評価する簡単なテストケースを作成します:
       comp.readFile("default.pic").bright(1.2).over(
           comp.constant(0.3, 0.3, 0.3)).writeFile("out.pic")
    """
    readFile("default.pic").bright(1.2).over(constant(0.3, 0.3, 0.3)
        ).writeFile("out.pic")

class _Image:
    """この画像クラスは、COPノードをラップし、
       単にCOPノードを作成するメソッドにより画像のオペレーションを表示させ、
       そのノードをラップする新しい画像を返します。
    """
    def __init__(self, node):
        # ノードパラメータは、COPノードです。このモジュールのユーザは、
        # readFileおよび常数法を使用して画像を作成し、直接
        # _Imageオブジェクトを構築します。
        self.node = node

    def __createNode(self, type):
        # 現行のネットワークで指定されたタイプの
        # COPノードを作成して返します。
        return self.node.parent().createNode(type)

    def bright(self, amount):
        """画像を明るくして、新しい画像を返します。"""
        n = self.__createNode("bright")
        n.setFirstInput(self.node)
        n.parm("bright").set(amount)
        return _Image(n)

    def over(self, image):
        """指定された画像上にこの画像を合成し、
           新しい画像を返します。"""
        n = self.__createNode("over")
        n.setFirstInput(self.node)
        n.setInput(1, image.node)
        return _Image(n)

    def writeFile(self, file_name):
        """この画像をファイルまたはファイルシーケンスへ書き込みます。"""
        n = self.__createNode("rop_comp")
        n.setFirstInput(self.node)
        n.parm("copoutput").set(file_name)
        self.node.parent().layoutChildren()

        # 標準のPythonシェルやhythonからコールした場合、
        # 実際にファイルを書き出します。
        if hou.applicationName() == 'hbatch':
            n.render()

def __network():
    # この内部関数は、COPネットワークを返すだけです。このサンプルでは、
    # 特定のネットワークをハードコード化するだけです。
    return hou.node("/img/comp1") or hou.node("/img").createNode("img", "comp1")

def __nodeResolution(node):
    """hscript res()エクスプレッションを使用して、コンポジットノードの
       画像解像度を返します。"""
    return (hou.hscriptExpression('res("%s", D_XRES)' % node.path()),
        hou.hscriptExpression('res("%s", D_YRES)' % node.path()))

_lastResolution = None

def readFile(file_name):
    """ファイルまたはファイルシーケンスに対応する画像オブジェクトを返します。"""
    n = __network().createNode("file")
    n.parm("filename1").set(file_name)

    # 画像解像度を忘れないようにしてください。後で単色を作成する場合、
    # この解像度を使用します。
    global _lastResolution
    _lastResolution = __nodeResolution(n)

    return _Image(n)

def constant(r, g, b, a=1.0):
    """単色である画像を返します。画像サイズは、
       最後に読み込んだファイルのサイズと同じになります。"""
    n = __network().createNode("color")
    n.parmTuple("color").set((r, g, b, a))

    if _lastResolution is not None:
        n.parm("overridesize").set(True)
        n.parmTuple("size").set(_lastResolution)
    return _Image(n)

HOMクックブック