Playing with Houdini + Python

by syoyo

htol_small.jpeg

Houdini で fur などのプロシージャルデータを生成してそのジオメトリデータを RIB で吐いて lucille でレンダリングすべく、
Houdini(Apprentice) の Python スクリプトをいじって RIB エクスポータを書いています.
とりえあずポリゴン + カメラをエクスポートできるくらいができました.

http://github.com/syoyo/lucille/tree/master/exporters/houdini

Houdini 製品版なら RIB のエクスポータが付いているらしいのだけれど、
自分でジオメトリ情報とか自由にいじりたいことも今後あるだろうから、やっぱり Python スクリプトを自分で書きます.
それにそれができれば、無償で Houdini(apprentice) + lucille でレンダリングというパイプラインが出来ることになりますし.

Python エクスポータが発展すれば、
houdini + GI 付き RenderMan(疑似) をフリーで、と、
数年前では個人ユースでは到底考えられなかったことが出来る、かもしれません.

# ただ、今後、Apprentice 版廃止や、
# Apprentice が Python 経由でのファイル書き込みを禁止されると命を断たれることになります.
# 結局は Blender ベースでやっていくほうが、長期的にはいいのかなぁ.

Writing your Python script for Houdini

houdini での Python スクリプトですが、なぜかは知りませんがファイルマネージャ(スクリプトマネージャ?)みたいなのが無いのです(Apprentice 版だけなのかもしれません).
chop とかのネットワークビューとかで Python スクリプトとか管理できると便利なのにね.

なので外部スクリプトファイルを読んだり、スクリプトを複数モジュールから構成させてとか、
みたいなことはどうすればいいのかなと思っていたのですが、Houdini の python 環境では自動で

$HOME/houdini9.5/scripts/python

あたりがスクリプト検索パスに登録されているのでそれでなんとかしろ、という方針らしい.

たとえば


def muda():
    print "muda muda muda!"

こんなファイルを muda,py として $HOME/houdini/scripts/python/muda.py に置くと、
houdini の python shell にて import で読み込むことができます.

>>> import muda
>>> print muda.muda()
muda muda muda!

モジュールとしての読み込みが嫌なら

execfile(hou.findFile(“yourfile.py”))

で実行させろ、と. execfile の方法はなんとも Python の動的言語の特質を使いこなしていますね 🙂
(ただ、Mac Apprentice 版では findFile は fail します…)

ジオメトリデータを出してみるためには

とりあえずはシーンのジオメトリだけを出すことを目的とします.

参考にしたのはここらへん

Particle Cache Example: Writing Particle Data to a Custom Format
http://www.sidefx.com/docs/houdini9.5/hom/cookbook/particle_cache/

VRay 向け Python エクスポータ(taikomatsu さんから教えてもらいました)
http://www.xn--d1abb4ane.com/blog/archives/99

VRay のエクスポータでは soho と呼ばれるシーンデータのレンダラへの出力を簡単にするらしいモジュールを使っていますが、
Apprentice 版では使えないようです(import soho が出来なかった).
なので hou だけ使って頑張ります. もしかしたら soho は古いやり方で、今は hou に変わったのかも.

ジオメトリのノードは /obj にあって、ノードオブジェクトの displayNode().geometry() を取れば
ジオメトリオブジェクトを取得できるようです.
(ほかにも node の children の SopNode を取ってやる方法もあるみたいです)

たとえば /obj/muda1 というジオメトリノードがあったら、


geo = hou.node("/obj/muda1").displayNode().geometry()

で muda1 オブジェクトノードのジオメトリが取得できます.
ただ、displayNode() が None を返す場合は、子のノードをさらに辿って displayNode() が None でない
ノードを探しだす必要があるようです.

以降はポリゴンジオメトリを仮定して話を進めます.

ジオメトリはそれぞれ points() と pointAttribs() というメソッドで点データと、点データに関するアトリビュート情報が得られます.

ポリゴンジオメトリを構成する点データからは、アトリビュート “P” で点情報が、 アトリビュート “N” で法線情報が得られます(法線があれば).


for p in geo.points():
  print p.position()  # p.attribValue("P")
  print p.attribValue("N")

ただ、点の位置はローカル座標での値なので、
グローバル座標にするには親になっているジオメトリノードの変換行列も必要になります.
これは node.paramTransform() で得ることができます.

以上の前提知識があれば、あとはスクリプトを見てもらったほうが早いでしょう.

パフォーマンスがやはり気になる

houdini で python スクリプトは強力な機能拡張手段なのですが、
やはりこれから使っていくにはスクリプト処理のパフォーマンスに懸念がありますね.
たとえば巨大なパーティクルデータをエクスポートするとなると、とてつもなく時間がかかりそう.
(もちろん、パフォーマンスがネックならネイティブのプラグインを書いたりしてもいいのだけれど、
それはそれでプログラム作業や保守が大変になるし、ネイティブは Apprentice 版では書けない)

なのでやっぱり、開発フェーズはいつもどおりコンパイルなしで素早く実行.まあこれは遅くてもいい.
しかしいったんコードがフリーズしたら静的にコンパイルさせてネイティブと同じ速度で実行できる.
そんな特徴をもった、主に映像制作向けのスクリプト言語があるといいのかなと再度考えています.

参考: http://lucille.atso-net.jp/blog/?p=628

ちょっと前に py2llvm というのを作ったりして、まあ動的言語な機能を使わなければ結構いけることは確かめてあります.
http://code.google.com/p/py2llvm/

でも houdini の python インターフェイスは動的言語的な機能バリバリ使っているのよね.
(x.param(“tx”) とか x.evalParam(“tx”) みたいなやつ)

なのでそういう部分がパフォーマンスネックであるなら、なにかしら程度どうにかする方法を見つけないといけないけど、
そこはやってみないと分からない.

いずれにせよ、CG 向けの高速に動くスクリプト言語って結構需要あると思うんですよね. houdini 用とかに限らず.
どうですか? そんな開発案件に投資してみませんか?(業界関係の方)

おまけ

あとは、Haskell ベースの、houdini のようなノードベースツールってのも作ってみたいなぁ.
ノードネットワークは Haskell のコードを Visualize している、というような感じ.
関数型とノードネットワークの考えって結構関連が大きいし、自然だと思うんですよね.
小さいブロックを作ってそれを組み合わせて機能を作ったり、lazy に評価したり、ノード階層間で計算をスキップしたり(これは Haskell では Arrow で表現できそう)とか.

Advertisements