2011-11-27

ToolSets と python の組み合わせ その1

ver6.3 よりToolSetsという便利なものが搭載された。
要するに、ノードの組み合わせ、もしくは単体でもいいのであるが、パラメーター等をあらかじめ組んでおいたものを呼び出せるというツールだ。スタジオやもしくは各アーティストごとのカスタムツールが容易に組めるというモノである。


ツール化したいノード(群)を選択して、ToolSets → Create ってやると名前をつけるように求められるので、適当に名前をつけるとその後からはこの ToolSets にその名前で、その選択したノード(群)をワンアクションで呼び出せるようになります。Photoshopの アクション に近い感覚です。

実は、選んだノードだけが、「.nuke」ディレクトリにある「ToolSets」フォルダに.nk形式保存されているだけだ。


なので、後からでも、修正したり、ノードを追加したりも割りと簡単に出来る。

コレを用いてたとえば、Writeノードを作るツールを作ってみる。
Writeノードをつくるなんて簡単じゃないか! って思われるだろうけど、Writeノードは割りとメンドイ。フォルダ切って、名前付けて、フレーム数指定して・・・ など。
そのあたりを勝手に都合よくやってくれればトライアンドエラーを億劫にならずに出来るかもしれない。それがコンプのクオリティーアップにつながる可能性もある。なによりも、「どこにレンダーしたっけ?」みたいなケアレスミスも防げる。
といっても、それをやるためには各個人なのか各スタジオでなのか、ともかく法則性が、つまりは明確なルール付けが必要である、とくにディレクトリー構造においては。決まってさえいればそれに則ってやるだけなので、スクリプト等でツール化が可能だ。

nukeではノードのプロパティー上で右クリックをすると、ユーザー定義の変数を設けることが出来る。



その中に「python scripts button」というのがあり、ボタンを押すと指定したpythonスクリプトを実行するというなんとも便利なモノがある。


とりあえず適当なノード(ココではBackdropノード)にこの「python scripts button」を設けて、そのボタンを押すとWriteノードが出来るというものを作る。

単純にWriteノードを作るpythonスクリプトは・・・

nuke.createNode('Write')

である。なので、 「python scripts button」を選んで、出てくるエディットウィンドウのScript欄に上記のスクリプトを入力して

 
として、OKでボタンを作成する。


するとこんな感じでボタンができて、押すとWriteノードができる。
と、これでは出来るだけなので、このWriteノードにある各種の値を変えたいのだけど、できるWriteノードの名前は任意(というか同一スクリプト(シーン)内のWriteノードの数に応じて番号が付く)なので、名前を指定して値を設定するってことが出来ない。
こういうときは下記のようにできる

cw = nuke.createNode('Write')
cw.knob('file').setValue('hogehoge')

コレを同じく、「python scripts button」の設定ウィンドウのScript欄に入れて、


ボタンを実行すると・・・


となり、「hogehoge」がファイルパスに入っている。

ボクの場合、.nk を 各プロジェクトディレクトリにある「nukeScripts」というディレクトリに保存して、nukeのレンダー結果は「nukeRender」というディレクトリに保存している。
なので、たとえば、.nkの保存場所から判断して、Writeノードからのレンダー先をある程度決め込むことが出来る。とりあえず、「nukeRender」ディレクトリンに.nkと同じ名前のフォルダを切ってその中に連番をレンダリングするとする。
.nk の保存先は「Project Settings」の「name」というknobから取得できる。


(ちなみに、「Project Settings」はノードグラフ上で[s]キーを押すと呼び出せる)
これをpythonで取得するには

nuke.root().knob('name').value()

である。この.nkのファイルパス

C:/Users/Jean/Documents/test/nukeScripts/cut01_v001.nk

であるが、この文字列の

1.nukeScripts を nukeRender に変える。
2.「.nk」 を削除する。
3.最後尾に 「/(.nk名)_%04d.tif を足す。

とすると、4桁のtiff連番でレンダ先を指定できる。


1を行うにはpythonの機能 replace を用いる。
.nkのファイルパスが nuke.root().knob('name').value() なので、これを一旦 nkPath とかにして、

nkPath = nuke.root().knob('name').value()
nkPath.replace('nukeScripts', 'nukeRender')

とすると nkPath として C:/Users/Jean/Documents/test/nukeRender/cut01_v001.nk
を得ることが出来る。

(表記するためにprintしてます)

さらに、.nkを削除(空の文字列と入れ替える)して

nkPath = nuke.root().knob('name').value()
nkPath = nkPath.replace('nukeScripts', 'nukeRender')
nkPath = nkPath.replace('.nk', '')



となります。ここで.nkのファイル名は /(スラッシュ) 区切りで文字列を小分けにした一番最後の文字列なので、split を用います。ここで

nkPath.split('/')

とすると


['C:', 'Users', 'Jean', 'Documents', 'test', 'nukeRender', 'cut01_v001']

となり、/(スラッシュ)区切りで小分けにされたタプル型のリストを得ることが出来ます。
リストの最後は

(リスト名)[-1]



で表せるので、



この場合結果として.nk名である「cut01_v001」を得ることが出来ました。
なので、このファイル名を使ってレンダー先をファイルパス(renderPathとしました)を作成します。

nkPath = nuke.root().knob('name').value()
nkPath = nkPath.replace('nukeScripts', 'nukeRender')
nkPath = nkPath.replace('.nk', '')
list = nkPath.split('/')
renderPath = nkPath + '/' + list[-1] + '_%04d.tif'



C:/Users/Jean/Documents/test/nukeRender/cut01_v001/cut01_v001_%04d.tif
を取得できました。

でこれを、さっきのWriteノードに代入して(hogehogeの変わりにコレを入れる)

nkPath = nuke.root().knob('name').value()
nkPath = nkPath.replace('nukeScripts', 'nukeRender')
nkPath = nkPath.replace('.nk', '')
list = nkPath.split('/')
renderPath = nkPath + '/' + list[-1] + '_%04d.tif'
cw = nuke.createNode('Write')
cw.knob('file').setValue(renderPath)


で、ボタンを実行すると


ファイルパスに狙い通りのモノが入ったWriteノードが出来上がる。
ただ、 このレンダ先である、

C:/Users/Jean/Documents/test/nukeRender/cut01_v001

というディレクトリがない場合もあるので、それがない場合はそのディレクトリ(フォルダ)を作るという処理を加えたいと思う。

C:/Users/Jean/Documents/test/nukeRender/cut01_v001

はさっきのスクリプトの途中の結果

nkPath = nuke.root().knob('name').value()
nkPath = nkPath.replace('nukeScripts', 'nukeRender')
nkPath = nkPath.replace('.nk', '')

とまでやったところの、nkPath である。
なので、上記3行のあとに、

if not os.path.isdir(nkPath):
    os.mkdir(nkPath)

を加える。


この

os.path.isdir(hoge)

ってのいうのは、hoge というディレクトリがあれば True を返す。

if not os.path.isdir(hoge)

なので、このディレクトリが無ければ

os.mkdir(hoge)

で hoge というディレクトリを作成しなさい ということである。pythonではこのように、

条件文:
 実行文

とし、条件文の最後に「:(コロン)」加え、改行してインデント(tabもしくはいくつかのスペース)の後に実行文をおく。

これで、ボタンを押せば.nkの保存先から nukeRender/hoge/hoge_%04d.tif と自動的に出力先をファイルパス、及びそのディレクトリが無ければ作成するというボタンが出来た。


で、このボタンをもっている、Backdropノードを選択して、ToolSets に登録すれば次回からはコレを簡単に呼び出せる。また「python scripts button」はこのBackdropノードに複数設定できるので、ある程度のツール群を入れておくとかなり便利だ。

ウチでは


こんな感じで、ディスパッチャーである「deadline」に投げるために、ファイルパスをローカル⇔ファイルサーバーと入れ替えれたりなど色々な組み合わせで使っている。

次回はレンダ後プレビューファイルを作るまでを自動化させたり、そのプレビューファイルを外部から見れるように別のディレクトリにコピーしたり、それをメールで送ったりって言うことをやってみたいと思います。

2 comments:

  1. いいチュートリアル。感謝しました!

    ReplyDelete
  2. ありがとうございます!
    Thank you! What you said is a great encouragement to me!!

    ReplyDelete