Houdiniにグラデーションピッカーを実装する方法


はじめに

先日、PySide勉強会であんどうさんが発表したSubstance DesignerのようなグラデーションピッカーをHoudiniに実装する方法を紹介します。
あんどうさんのグラデーションピッカーの紹介、解説記事

実際に使うと下図のようにランプパラメータにピッカーで拾ったグラデーションが適用されます。
下図はネットワークエディタに画像を読み込んでますが、画面内であればどこでも色を取得出来ます。

実装方法

  1. 下記URLからコードをダウンロードします。
    https://snippets.cacher.io/snippet/2c7496d1dbbdc093033c
  2. ダウンロードしたgradationPicker.pyをHoudiniがPythonを読み込めるフォルダに移します。
    分からない場合は%HOMEDRIVE%%HOMEPATH%\Documents\houdiniバージョン\scripts\pythonにコピーすると自動で認識されます(フォルダが無い場合は作成します)。
  3. ここからHDAに実装する場合とすでに存在してるノードのパラメータに実装する場合で少し異なります。
  • HDAに実装する場合
    HDAのType Properties > Scriptsタブにアクセスし、Event HandlerPython Moduleに変更します。
    そうすると右側のPythonコード欄がアクティブになるので、そこに下記のランプパラメータにグラデーションを適用するコードを入力します。

  • 存在してるノードのパラメータに実装する場合
    HoudiniメニューのWindows > Python Source Editorをクリックし、Python Source Editorを起動し、コード入力欄に下記のランプパラメータにグラデーションを適用するコードを入力します。

ランプパラメータにグラデーションを適用するコード

# -*- coding: utf-8 -*-

import hou
from PySide2.QtCore import Qt

from gradationPicker import ColorPick

class _GCProtector(object):
    widgets = []

def rampColorPicker(parm, threshold=0.05):
    def setRampColor(colors):
        # 引数のcolorsは[グラデーションの位置, 色]が入ったリスト
        curveKeys = []
        curveValues = []
        # 二次元のリストをcurveKeys、curveValuesの二つに分ける
        for pos, color in colors:
            curveKeys.append(pos)
            # PySideの色空間がsRGBで、Houdiniはリニアなので、2.2乗して変換
            curveValues.append([(ch / 255.0) ** 2.2 for ch in color])
        linears = [hou.rampBasis.Linear] * len(colors)
        ramp = hou.Ramp(linears, curveKeys, curveValues)
        parm.set(ramp)

    picker = ColorPick()
    # フォーカスが移らないように最前面に表示
    picker.setWindowFlags(Qt.WindowStaysOnTopHint)
    # どれぐらい色の差を識別するかのしきい値を設定
    picker.threshold = threshold
    # ピッカーのメインウィンドウをスクリーン全体に表示する
    picker.showFullScreen()
    # マウスを離した時に関数を実行する
    picker.getGradation.connect(setRampColor)
    # 普通に表示するとメモリを開放してすぐに消えてしまうのを回避する処理
    _GCProtector.widgets.append(picker)

4. 最後にこのコードを実行する用のボタンを作成します。
5. 作成したボタンのCallback Script欄に下記コードを入力します。

  • HDAの場合
    hou.phm().rampColorPicker(kwargs['node'].parm('ramp'), threshold=0.05)

  • すでに存在するノードの場合
    hou.session.rampColorPicker(kwargs['node'].parm('ramp'), threshold=0.05)

    parm('ramp')の箇所は対象とするランプパラメータの名前に変更して下さい。
    thresholdの値は数値が低いほど、精度が上がりますが、その分キーが増えます。

ボタンにアイコンを設定したい場合はButton Icon欄にBUTTONS_secondary_colorsと入力するとそれっぽいアイコンが付きます。

これでボタンを押すとグラデーションピッカーモードになるので、ドラッグして色をピックしてみて下さい。

最後に

以上グラデーションピッカーをHoudiniに実装する方法でした。
PySideは色んな事が出来て、楽しいですね。
ちなみにグラデーションピッカーを改変する事で下記のようなランプパラメータのカーブを手書きで書く機能を作ることも出来ます。