2014-10-22

matrix


matrixに値を入れたいとき、
node['matrix'].setValueAt(value, frame, index) 
matrixの値を取得したいとき、
node['matrix'].getValueAt(frame)[index]



When you want to set the value into matrix,
node['matrix'].setValueAt(value, frame, index) 
When you want to get the value of matrix,
node['matrix'].getValueAt(frame)[index]


2014-10-15

ノードグラフ上でノードを移動するツール

あれ?これって標準であったりする?
ノードグラフ上でグリッドの値だけノードをオフセットするツール。

NodeShift.py
import nuke def shiftHP():     shiftH = nuke.toNode('preferences')['GridWidth'].value()     sn = nuke.selectedNodes()     for n in sn:         posX = n['xpos'].value()         newPosX = posX + shiftH         n['xpos'].setValue(newPosX) def shiftHN():     shiftH = nuke.toNode('preferences')['GridWidth'].value()     sn = nuke.selectedNodes()     for n in sn:         posX = n['xpos'].value()         newPosX = posX - shiftH         n['xpos'].setValue(newPosX) def shiftVP():     shiftV = nuke.toNode('preferences')['GridHeight'].value()     sn = nuke.selectedNodes()     for n in sn:         posY = n['ypos'].value()         newPosY = posY - shiftV         n['ypos'].setValue(newPosY) def shiftVN():     shiftV = nuke.toNode('preferences')['GridHeight'].value()     sn = nuke.selectedNodes()     for n in sn:         posY = n['ypos'].value()         newPosY = posY + shiftV         n['ypos'].setValue(newPosY)


でmenu.pyに

menu.py
import NodeShift m.addCommand("shiftHP", "NodeShift.shiftHP()", "ctrl+shift+Right") m.addCommand("shiftHN", "NodeShift.shiftHN()", "ctrl+shift+Left") m.addCommand("shiftVP", "NodeShift.shiftVP()", "ctrl+shift+Up") m.addCommand("shiftVN", "NodeShift.shiftVN()", "ctrl+shift+Down")

の記述を加えれば。ctrl + shift + カーソルキー(矢印キー)で選んだノードを矢印方向に1グリッドだけ動かせる。複数選択でもOK。

2014-10-09

キーフレームにアクセスする

今回も、果たして誰かの役にたっているのだろうか・・・ というかなり備忘録的なpythonに関してです。

あるattributeにアニメーションがついているとして、そのキーフレームにアクセスして値を取得したり、シフトしたりしたいとします。
たとえばその場合、Transform1ノードのtranslateにx,yについている2個目のキーフレームの値を取得したい場合。



nuke.toNode('Transform1')['translate'].animation(0).keys()[1].y
となり、これが、xのアニメーション( animation(0) )の2個目のキーフレーム( keys()[1] )の値( y ) となります。
また、その2番目のキーフレームが何フレーム目に存在しているかってのは、

nuke.toNode('Transform1')['translate'].animation(0).keys()[1].x

となります。実行すると、そのフレームナンバーが返ってきます。
Graph Editor上でのxとy、つまり時間軸とその値です。

また、そのキーフレームの値を変更する場合は・・・

nuke.animation("Transform1.translate.x" , "x", ("2", "10"))

これで、Transform1 ってノードのattribute "translate.x" ( 位置のx座標 ) をフレームナンバー的( x ) に3個目のキーフレーム ( "2" ) を10フレーム目 ( "10" ) に移動させるといったことになります。

nuke.animation("Transform1.translate.x" , "y", ("2", "-30"))

これで、Transform1 の translate.x の3個目のキーフレームの値を( GraphEditor的にy値を )、-30 にするってことになります。

値を取得する場合は、

animation(i).keys() 

で、値を変更したい場合は、

nuke.animation("ノード名.アトリビュート名" , "コマンド名", (コマンドの種類に応じた引数))

となります。
後者はココが参考になるかと。
http://www.nukepedia.com/python/using-nukeanimation-without-tearing-your-hair-out


2014-10-03

ディレクトリをOSのファイルブラウザから開く

nukeは、ファイルブラウズにOSのファインダーやエクスプロラーなどといったものを使わずにnuke独自のものを使ってファイルを読み込んだりする。
が、時にこれが不便だったりする。特にReadノードのファイルパスの階層を開きたいとか、同じくWriteノードで指定しているファイルパスの階層にいきたいとか・・・

そんなときに長方するスクリプトです。

dirOpen.py
import nuke
import os
def main():
    sn = nuke.selectedNode()
    fP = sn['file'].value()
    dirP = os.path.dirname(fP)
    dirP = dirP.replace("/", "\\")
    dirP = dirP + "\\"
    
    #print dirP
    os.popen("explorer.exe" + " " + os.path.dirname(dirP))

dirOpen,pyとか適当に名前をつけて保存して、nukeのpluginPathに保存します。
ちなみにmacの場合は・・・

import nuke
import os
def main():
    sn = nuke.selectedNode()
    fP = sn['file'].value()
    dirP = os.path.dirname(fP)
    os.popen("open" + " " + os.path.dirname(dirP))

あとは、menu.pyに登録します。

menu.py
import dirOpen
m = nuke.menu("Nodes")
m.addCommand("dirOpen", "dirOpen.main()", "ctrl+shift+o") 

この場合、ctrl + shift + o ってショートカットを当ててます。
ReadノードやWriteノードを選んで、そのショートカットを実行するとOSのファイルブラウザでその階層が開けます。

2014-10-01

ノードにあるpythonタブの活用 とか諸々

ノードによってはPropertyにPythonタブがあるものがある。
たとえば、Writeノードとか。


ここにpythonを読み込むと、たとえば、Writeノードのファイルパス(指定のファイルパスのフォルダディレクトリ/フォルダ)がなければ、レンダー時にそのディレクトリを作成するといったことも可能だ。
具体的には、まずこのWriteノード( nuke.thisNode() )のファイルパス( ['file'].value() )が、存在しなければ( if not os.path.exists() )そのディレクトリを作成する( os.makedirs() )、って言う具合なpythonを書く。


import os
sn = nuke.thisNode()
fp = sn['file'].value()
dirP = os.path.dirname(fp)

if not os.path.exists(dirP):
    os.makedirs(dirP)

こんな感じ。
これをファンクションとして定義して、.pyで保存する。

makeDir.py
import os
import nuke
def main():
    sn = nuke.thisNode()
    fp = sn['file'].value()
    dirP = os.path.dirname(fp)

    if not os.path.exists(dirP):
        os.makedirs(dirP)


これを、プラグインパスとして読み込むことのできる場所においてやる。
ちなみに、プラグインパス の調べ方は、スクリプトエディタで nuke.pluginPath() とやればOKです。


こんな感じででます。もし、この際あたらしいパスを追加したいって場合は、こちらを参照してください。

ともあれ、その場所に上記 makeDir.py をおいたらWriteノードのPythonタブのbefore renderのところに、



import makeDir;makeDir.main()



という具合に書けば、あとは、Writeノードのファイルパスがなければ、自動的にそのフォルダ構造をつくってくれます。
その一行の中にある ; (セミコロン)は改行をしめしている。
つまり、本当は、



import makeDir
makeDir.main()

って二行を表現している。 プラグインパス内にあるmakeDir.pyを読んできて、そのmakeDir.pyのmain()って関数を実行する makeDir.main() という意味だ。

もどって、Writeノードのファイルパスに適当なパスを入れてみて、


これで、このパスは実際には(このA/B/Cって3つのフォルダが)存在しないのだけど・・・


レンダリングすると、


バージョンアップ(v001→v002)とかだと結構便利に使えます。ファイルパスのバージョンアップには最適です。
ちなみに、/test.v001/test.v001.%04d.exr だとか、/test_v001/test_v001_%04d.exr ってなファイルパスを含むReadノードやWriteノードを選択した状態で、alt+キーボードの矢印の上下(↑↓)で、バージョンを上げ下げできます。

また、こういうのはWriteノード作るたびにPythonタブのところに、上記の一行をいれるのは非常に面倒なので、menu.pyに

nuke.knobDefault("Write.beforeRender", "import makeDir;makeDir.main()")

の一行を書き加えておく。そうすると起動時にWriteノードにデフォルトでクダンの一行が書き加わり、今後新しく作るWriteノードにはその処理がなされる。

ちなみに、WriteノードのPythonタブに書き加えた

import makeDir;makeDir.main()

は二行であらわさないといけないから ; (セミコロン)が入っているが、menu.pyに

import makeDir

の一行がはいっていれば、

makeDir.main()

だけでよい。