Houdini

Houdini の Python 環境構築 ① メニューからスクリプトを実行する

サイト移転しています。

下記へ移転しました。

Houdini にのメニューバーにメニューを自作し、
そこから Python スクリプトを実行します。

環境は Windows でやってます。

追加したメニューをクリックすると選択中のノードが持っている
パラメータとその値をコンソールに出力します。

最終的なデータをアップしておいたので、必要な方はダウンロードしてみてください。

下記のような構成でパスを通していきます。

ここでは bat ファイルからメニューと Python ディレクトリにパスを通した上で Houdini を起動していきます。
全体像としては下記のような感じ。

環境変数って何?って方は あんどうめぐみ さんの記事を参考にされるとよいかと思います。

bat ファイルから Houdini を起動

まずは bat ファイルから Houdini を起動するまで。

空の bat ファイルを作って下記のコードを作って叩けば Houdini が起動します。

@echo off

set VERSION=19.0.657
set EXE="C:\Program Files\Side Effects Software\Houdini %VERSION%\bin\houdini.exe"

start "" %EXE%

バージョンやパスは適宜変更してください。

上記のコードは Houdini を起動するだけで、メニューや Python のパスはまだ通していません。

上記のコードでやってるのはこれだけです。

$HIP と $JOB にパスが通る

bat ファイルで Houdini を起動した場合、環境変数「HIP」に
起動したbat ファイルがあるディレクトリのパスが自動で通ります。

$HIP は起動直後にファイルを開く際に参照するパスです。
bat ファイルから Houdini を起動すると同じ場所にあるファイルを開きやすくなります。

環境変数の確認

環境変数を確認するにはいくつか方法があります。
ここでは 2種類紹介しておきます。

Variables ウィンドウ

Edit > Aliases and Variables... から環境変数を確認できます。

$HIPFILE にも通ってます。

Python Source Editor

下記のコードで Python エディタからも確認できます。

import os
print(os.environ['HIP'])

Variables ウィンドウは全ての環境変数を確認できるわけではありません。
確認できない環境変数は Python エディタから確認できます。

メニューのパスを通す

メニューの作成方法は公式に詳しく書いてあるので割愛します。

要約すると、

  • MainMenuCommon.xml の名前でメニューを作る
  • $HOUDINI_MENU_PATH にパスを通す
  • C:\Program Files\Side Effects Software\Houdini<バージョン>\houdini の中の MainMenuCommon.xml を参考にするといい

みたいなことが書いてあります。

まずは Houdini にメニューを追加するところまで進めます。

MainMenuCommon.xml の作成

D > launch-test > menu-test の中につくっていきます。
場所はどこでもいいんですが、その際は今後のパスを適宜変更していってください。

xml ファイルの中身は下記のようにします。

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
  <menuBar>
    <subMenu id="test-menu">
      <label>Test-Menu</label>
      <scriptItem>
        <label>Parameter Check</label>
        <scriptPath></scriptPath>
      </scriptItem>
    </subMenu>
  </menuBar>
</mainMenu>

とりあえずメニューを追加するだけなのでまだ scriptPath は記載していません。

$HOUDINI_MENU_PATH にパスを通す

bat ファイルで HOUDINI_MENU_PATH を通していきます。

パスの通し方は

set HOUDINI_MENU_PATH=<メニューのパス>;@

です。「;@」が必須です。
下記のように Houdini を実行する前に書きます。

@echo off

set VERSION=19.0.657
set EXE="C:\Program Files\Side Effects Software\Houdini %VERSION%\bin\houdini.exe"

set HOUDINI_MENU_PATH=D:/launch-test/menu-test;@

start "" %EXE%

パスが通ることでメニューが追加された状態で Houdini が起動します。

確認するまでもないんですが、一応 Python エディタから下記のコードで確認できます。

import os
print(os.environ['HOUDINI_MENU_PATH'])

$HOUDINI_MENU_PATH は Variables エディタでは確認できません。

Python スクリプトのパスを通す

Python は $PYTHONPATH で通します。
ここもまずはパスを通すことを目指します。

スクリプトの作成

D > launch-test > python-test の中に作っていきます。

スクリプトの中身はこちら。
選択中のノードのパラメータとその値を出力します。

import hou

select_node = hou.selectedNodes()

if len(select_node) > 0:

    param_list = select_node[0].parms()

    for param in param_list:
        print(' name : {}'.format(param.name()))
        print('value : {}'.format(param.eval()))
        print()

面倒なら print('hello') とかでいいと思います。

$PYTHONPATH にパスを通す

@echo off

set VERSION=19.0.657
set EXE="C:\Program Files\Side Effects Software\Houdini %VERSION%\bin\houdini.exe"

set HOUDINI_MENU_PATH=D:/launch-test/menu-test;@
set PYTHONPATH=D:/launch-test/python-test

start "" %EXE%

$PYTHONPATH も Variables ウィンドウで確認できないので、Python エディタから確認します。

import os
print(os.environ['PYTHONPATH'])

Python エディタからスクリプトの実行

そういえばスクリプトを関数化していませんでした。
関数化してないやつどう読むんだろうなーと思ってたんですが、どうやらリロードすれば読み込めるようです。

import check_param
import importlib
importlib.reload(check_param)

上記でスクリプトが走りました。
なんか不格好なんで、もっとちゃんとした方法がありそうな気はします。

メニューからスクリプトを接続する

では最後にメニューからスクリプトを実行できるようにします。

ここまで来るとあとは MainMenuCommon.xml に1行記載するだけです。

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
  <menuBar>
    <subMenu id="test-menu">
      <label>Test-Menu</label>
      <scriptItem>
        <label>Parameter Check</label>
        <scriptPath>$PYTHONPATH/check_param.py</scriptPath>
      </scriptItem>
    </subMenu>
  </menuBar>
</mainMenu>

8行目に

$PYTHONPATH/check_param.py

と追記しました。

MainMenuCommon.xml は内部で環境変数を指定できます。

check_param.py が入っている python-test ディレクトリは既に
$PYTHONPATH でパスが通っています。

そのため、$PYTHONPATH/check_param.py でスクリプトを実行できます。

Maya だとメニューに Python コードが書けるんですが、Houdini は Python ファイルの実行しかできません。
少し面倒になりなりますが、実行文はファイルで用意することになります。

なぜメニュー内で環境変数が利用できるのか

※ 追記しました。

bat ファイルのコード順をみると、

  1. メニューのパスを通す($HOUDINI_MENU_PATH)
  2. Python のパスを通す($PYTHONPATH)
  3. houdini.exe の実行

の順で書いています。

それなのにメニューで $PYTHONPATH が利用できるのは、メニューの内部を見るのが Houdini が立ち上がった後だからです。

メニュー起動までの順番をちゃんと書くと、

  1. メニューのパスを通す($HOUDINI_MENU_PATH)
  2. Python のパスを通す($PYTHONPATH)
  3. houdini.exe の実行
  4. Houdini の起動
  5. MainMenuCommon.xml 内部を見る
  6. メニューに追加

という流れになっています。
1 の時点で $PYTHONPATH が通っている必要はなく、5 の時点で $PYTHONPATH が通っていれば問題ありません。

もう少し詳しく書いておくと、bat ファイルで $PYTHONPATH を通さず、メニュー実行前に通しても問題ないです。

  1. メニューのパスを通す($HOUDINI_MENU_PATH)
  2. houdini.exe の実行
  3. Houdini の起動
  4. MainMenuCommon.xml 内部を見る
  5. メニューに追加
  6. Python のパスを通す($PYTHONPATH)
  7. メニュー押下

$PYTHONPATH を 6 の段階で行っていますが、これでもスクリプトが走ります。

Python エディタから下記のコードを実行することで、Houdini 起動後でも $PYTHONPATH を通せます。

import os
os.environ["PYTHONPATH"] = "D:\\launch-test\\python-test"

要はメニュー押す前に $PYTHONPATH 通しておけば繋がるってことです。

複数の Python パッケージを通す

複数の Python パッケージを通します。

こっちはそこまで需要なさそうなんで別のデータにしました。

ディレクトリ名を変更したのと、python-test-B を追加しています。

python-test-B の print_hello.py は「Hello」の文字列を出すだけにしています。

print('Hello')

目指すのは下記の構成です。

複数の PYTHONPATH の通し方

複数通すには「;」で繋げます。

set PYTHONPATH=D:/launch-test-2/python-test-A;D:/launch-test-2/python-test-B
@echo off

set VERSION=19.0.657
set EXE="C:\Program Files\Side Effects Software\Houdini %VERSION%\bin\houdini.exe"

set HOUDINI_MENU_PATH=D:/launch-test-2/menu-test;@
set PYTHONPATH=D:/launch-test-2/python-test-A;D:/launch-test-2/python-test-B

start "" %EXE%

メニューの $PYTHONPATH は効かない

複数通した場合、メニューの scriptPath に $PYTHONPATH を使っているとエラーがでるようになります。

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
  <menuBar>
    <subMenu id="test-menu">

      <label>Test-Menu</label>
      <scriptItem>
        <label>Parameter Check</label>
        <scriptPath>$PYTHONPATH/check_param.py</scriptPath>
      </scriptItem>

      <scriptItem>
        <label>Print Hello</label>
        <scriptPath>$PYTHONPATH/print_hello.py</scriptPath>
      </scriptItem>

    </subMenu>
  </menuBar>
</mainMenu>

メニューを上記のように書いた場合です。

Python エディタで通したパスを見てみます。

import os
print(os.environ['PYTHONPATH'])
D:/launch-test-2/python-test-A;D:/launch-test-2/python-test-B

bat ファイルで「 ; 」で繋げて通したパスがそのまま入っています。

$PYTHONPATH にはこの「 ; 」 で繋げたパスが入ってるため、
メニューから実行しようとすると
D:/launch-test-2/python-test-A;D:/launch-test-2/python-test-B/check.param.py
のファイルを実行しようとします。
しかしそんなファイルは存在しないため上記のエラーがでています。

パスは通ってる

パスの通し方が悪かったのかというと、そんなことはなく ちゃんと通っています。
下記のコードで問題なくスクリプトが走ります。

import check_param
import importlib
importlib.reload(check_param)
import print_hello
import importlib
importlib.reload(print_hello)

絶対パスでメニューから実行

エラーが起こるのはメニューで $PYTHONPATH を使用しているためなので、ここを絶対パスにすることでスクリプトを実行できるようになります。

<?xml version="1.0" encoding="UTF-8"?>
<mainMenu>
  <menuBar>
    <subMenu id="test-menu">

      <label>Test-Menu</label>
      <scriptItem>
        <label>Parameter Check</label>
        <scriptPath>D:/launch-test-2/python-test-A/check_param.py</scriptPath>
      </scriptItem>

      <scriptItem>
        <label>Print Hello</label>
        <scriptPath>D:/launch-test-2/python-test-B/print_hello.py</scriptPath>
      </scriptItem>

    </subMenu>
  </menuBar>
</mainMenu>

まとめ

bat ファイルで環境変数を通してメニューからスクリプトを実行する流れを見てきました。

個人で利用する分にはこれでよいと思います。
特に bat ファイルから開くだけで $HIP にパスが通るので、ファイルを開くまでが非常に楽になります。
Python も問題なく扱えます。

ただ、私はこのやり方でやってるかっていうと一切やっていません。
一番シンプルで説明しやすいのがこれなんですが、チームとして Houdini を使っていくには少々問題のあるやり方です。

この辺はまた次回。

また、今回扱ったのは $HOUDINI_MENU_PATH と $PYTHONPATH だけですが他にも様々な環境変数が用意されています。
詳しくは参考サイトをご紹介しておきます。

それと、環境変数をマイドキュメントで設定する方法もありますが、下記で詳しく書かれているためここでは解説していません。

-Houdini