Nuke Python 立体

在nuke中如何处理立体

多视图knob 的数值

给立体项目的每个view中添数值,就跟向translate的x,y knob添加一样。代码添加Transform节点,并将右view分离出来:

n = nuke.createNode('Transform')
k = n['translate']
k.splitView('right')

当分离出一个view时,所有的un-split view像一个main view一样在一起控制,因此,如果没有指定view,所有的un-split knob都会改变。
下面将main view的knob的值设置为1,但分离view除外:

k.setValue(1)
image
image

将右侧view的值设置为2:

k.setValue(2, view='right')
image
image

将main view的translate设置为 x=1, y=2

k.setValue(1,0)
k.setValue(2,1)
image
image

right view的translate设置成 x=3, y=4

k.setValue(3, 0, view='right')
k.setValue(4, 1, view='right')
image
image

在不同view里面可以用同样的方式创建动画,将main view设置为可动画:

k.setanimated()

右侧视图可动画:

k.setAnimated( view='right')

main和right view的1-100帧设置关键帧:

k.setValueAt( 50, 1)
k.setValueAt(70, 100)
k.setValueAt(80, 1, view='right')
k.setValueAt(110, 100, view='right')

为两个view渲染动画值:

mainX = k.valueAt(50, 0)
mainY = k.valueAt(50, 1)
rightX = k.valueAt(50, 0, view='right')
rightY = k.valueAt(50, 1, view='right')

print 'left (main) view values at frame 50 are X=%s, Y=%s' %(mainX, mainY)
print 'right view values at frame 50 are X=%s, Y=%s' % (rightX, rightY)

Result:
left (main) view values at frame 50 are X=59.898989898, Y=59.898989898
right view values at frame 50 are X=94.8484848507, Y=94.8484848507
例子
创建、转换立体camera

下面有一个例子,用常用的函数,两个参数,一个定义camera节点,一个定义视距。node默认值为none(这种情况创建新camera)视距只
要能工作就行:

def serreoCam( node=None, interoc=.6 ):
    try:
        node = node or nuke.selectedNode()
    except ValueError:
        node = nuke.createNode( 'Camera2' )

接下来我们获取当前脚本的视图。假设列表中的第一个视图是左眼,第二个是右眼:

views = nuke.views() leftView = views[0] right = views[1]

根据给定的视距值计算摄像机的左右偏移:

rightOffset = float( interoc)/2
leftOffset = -rightOffset

可以用matrix或者transform knob来驱动camera。来开始第一个例子,抓取matrix knob并拷贝当前矩阵,就可以创建第二只眼睛。

if node['useMatrix'].value():
    knob = node['matrix']
    leftEyeMatrix = node['transform'].value()
    rightEyeMatrix = nuke.math.Matrix4( leftEyeMatrix )

基于上面计算的左眼值,将原始矩阵移动到左边,右眼照做:

leftEyeMatrix.translate( leftOffset, 0, 0)
rightEyeMatrix.translate( rightOffset, 0, 0)

因为node['transform'].value() 返回的矩阵是逆序的,使用前需要反转回来。

leftEyeMatrix.transpose()
rightEyeMatrix.transpose()

如果脚本中只有两个view,就使用左眼作为主view,仅分离出右view,如果多于两个view,就都分离出来:

if len(views) >2:
    knob.splitView( leftView)
knob.splitView( rightView)

现在将4x4的矩阵循环赋值给其他了:

for i in range(16):
    knob.setValue( leftEyeMatrix[i], nuke.frame(), i, leftView)
    knob.setValue( rightEyeMatrix[i], nuke.frame(), i, rightView)

这会关心摄像机被matrix knob的哪个部分驱动,其他例子中,事情简单点但是我们做的事情一样。抓取transform knob的x值和并
按照从视距计算出来的值来offset:

else:
    knob = node['translate']
    leftEye = knob.value(0) + leftOffset
    rightEye = knob.value(0) +rightOffset

按要求分割knob:

if len( views) >2:
        knob.splitView( leftView )
knob.splitView( rightView )

将新值赋给新view

knob.setValue( leftEye, 0, view=leftView )
knob.setValue( rightEye, 0, view = rightView )

最终代码:

import nuke
def stereoCam( node=None, interoc=.6 ):
    '''
    Create a simple stereo camera or convert an existing one.
    args:
       node - camera node to convert to stereo. if None a camera will be created
       interoc  -  distance between right and left view
    '''
    try:
        node = node or nuke.selectedNode()
    except ValueError:
        # IF NO NODE IS GIVEN AND NOTHING IS SELECTED, CREATE A NEW NODE
        node = nuke.createNode( 'Camera2' )

    # GET SCRIPT SETTIONGS' VIEWS
    views = nuke.views()
    leftView = views[0]
    rightView = views[1]

    # THE OFFSET AS REQUESTED
    rightOffset = float(interoc)/2
    leftOffset = -rightOffset

    # THE KNOB TO SPLIT
    if node['useMatrix'].value():
        knob = node['matrix']
        leftEyeMatrix = node['transform'].value() # GETS MATRIX BUT IN REVERSE ORDER
        rightEyeMatrix = nuke.math.Matrix4( leftEyeMatrix ) # COPY MATRIX

        # GET THE NEW VALUES FOR LEFT AND RIGHT EYE
        leftEyeMatrix.translate( leftOffset, 0, 0 )
        rightEyeMatrix.translate( rightOffset, 0, 0 )

        # REVERSE FOR ASSIGNMENT
        leftEyeMatrix.transpose()
        rightEyeMatrix.transpose()

        # IF THERE ARE MORE THAN 2 VIEWS MAKE SURE TO SPLIT OFF LEFT VIEW AS WELL
        if len( views ) > 2:
            knob.splitView( leftView )
        knob.splitView( rightView )

        # ASSIGN VALUES
        for i in range(16):
            knob.setValueAt( leftEyeMatrix[i], nuke.frame(), i, leftView )
            knob.setValueAt( rightEyeMatrix[i], nuke.frame(), i, rightView )
    else:
        knob = node['translate']
        # GET THE NEW VALUES FOR LEFT AND RIGHT EYE
        leftEye = knob.value(0) + leftOffset
        rightEye = knob.value(0) + rightOffset

        # IF THERE ARE MORE THAN 2 VIEWS MAKE SURE TO SPLIT OFF LEFT VIEW AS WELL
        if len( views ) > 2:
            knob.splitView( leftView )
        knob.splitView( rightView )

        # ASSIGN NEW VALUE
        knob.setValue( leftEye, 0, view=leftView )
        knob.setValue( rightEye, 0, view=rightView )


设置立体

有一种方法自动将新的nuke projects设置为立体(或者通常的多视图)。第一,写一个函数将nuke的project转变成多视图,然后将其
挂接到回调函数上,确保新的root节点创建时运行。

创建新view时需要修改的knob是 nuke.root().knob('views'), 此knob木有其他方法来设置view,因此检查其脚本语法:

viewKnob = nuke.root().knob('views')
print viewKnob.toScript()

#result:
left #ff0000
right #00ff00

toScript方法将knob转换成脚本语法,就像.nk文件中那样,并是分析复杂knob的好方法。这个例子中,会查出root view的名字,相关的
颜色代码 16进制形式。view通过线来分割。有了这个信息,我们可以重建自己的名字和颜色列表。然后使用fromScript方法来初始化我们的值:

先检测:

veiwKnob = nuke.root().knob('views')
viewKnob.fromScript( 'testView #ff000')

root的view knob有叫做testView的单一视图,并将最初的红色付给他。实际上,想赋值红色要比使用16进制码简单的多。因此,写一个
小工具来转换这个过程,使用python的字符格式化工程,小case。

下面将一个int转换成hex值:

intValue = 255
hexValue = '%x' % intValue
print hexValue

用这个来操作r,g,b

rgb= (255, 0, 0)
hexCol = '#%02x%02x%02x' % rgb
print hexCol

既然nuke大部分都工作在浮点数据模式下,稍微修改下,就能输入0-1而不是八位int 0-255:

col = ( .5, .3, .2)
rgb = tuple( [int(v*255) for v in col ] )
hexCol = '#02x%02x%02x' % rgb
print hexCol

# Result:
#7f4c33

上面的代码会将每个正规化的浮点值col 变换成 8位整形。 输出是一个列表,其在存储到rgb前被转换成tuple。
将所有的东西放在一起来构建testView的view,并赋给黑红色。

name = 'testView'
col = (.5, 0, 0)
rgb = tuple( [int(v*255) for v in col ])
hexCol = '#%02x%02x%02x' % rgb
view = '%s %s ' %(name, hexCol)
nuke.root().knob('views'), fromScript( view)

如果想要不止一个view,会在多个view间有一条线:

newViews = []
name = 'testView'
col = (.5, 0, 0)
rgb = tuple([ int(v*255) for v in col ])
hexCol = '#%02x%02x%02x' % rgb
view = '%s %s' % (name, hexCol)
newViews.append(view)

name2 = 'testView2'
col2 = (0, .5, 0)
rgb2 = tuple([ int(v*255) for v in col2 ])
hexCol2 = '#%02x%02x%02x' % rgb2
view2 = '%s %s' % (name2, hexCol2)
newViews.append(view2)

nuke.root().knob('views').fromScript('\n'.join(newViews))

现在将其整理下,添加nuke的import,创建一个函数,参数为元组,view的名字,以及颜色:


import nuke

def setUpMultiView( views=[ ('left',(0,1,0)), ('right',(1,0,0) ) ] ):
    '''
    set up the nuke project with an arbitrary amount of colour coded views
    args:
       views  -  nested list with view names and rgb tuples for each view. rgb values are assumed to be normalise, eg red = (1,0,0)
    '''
    newViews = []
    for v in views:   # CYCLE THROUGH EACH REQUESTED VIEW
        name = v[0]   # GRAB THE CURRENT VIEWS NAME
        col = v[1]    # GRAB THE CURRENT VIEWS COLOUR
        rgb = tuple( [ int(v*255) for v in col ] ) #CONVERT FLOAT TO 8BIT INT AND RETURN A TUPLE
        hexCol = '#%02x%02x%02x' % rgb             #CONVERT INTEGER NUMBERS TO HEX CODE
        curView = '%s %s' % ( name, hexCol )       #COMBINE NAME AND HEX COLOUR TO SCRIPT SYNTAX
        newViews.append( curView )      # COLLECT ALL REQUESTED VIEWS

    # COMBINE ALL VIEWS WITH LINE BREAK AND INITIALISE THE VIEWS KNOB WITH THE RESULTING SCRIPT SYNTAX
    nuke.root().knob('views').fromScript( '\n'.join( newViews ) )

运行来测试下,注意上面的函数定义了左右视图,红蓝色。因为没有任何参数也可以运行此函数:

    setUpMultiView()

如果想要左边view为红色,右边为绿色,用不同的值来调用:

    setUpMultiView( [('left', (1,0,0)), ('right', (0,1,0)])

创建了left和right的两个view,分别为红色和绿色:


setUpMultiView_01.png
setUpMultiView_01.png

如果想要nuke在启动的时候运行次脚本,在立体模式下会自动创建新session,将函数挂载在onUserCreate上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容