某部门领导需要一个nuke中批量渲染的工具,而nuke中的render in background功能恰恰可以多个渲染任务同时执行,于是我考虑使用这个方法来实现。
调 试过程中发现renderinbackground对内存的管理是堪忧的,所以我添加了控制多任务渲染时内存消耗的参数。这个功能写起来很快,写完之后还 得考虑artist的使用习惯,把这个功能做成一个单独的节点放在工具栏里实在不是一个明智之举,artist会嫌麻烦,所以我决定把这个功能集成到 write节点上。
这是最终执行结果:
write节点里多了一个分页,artist用起来很顺手,但是这个功能受限于计算机计算及内存能力,毕竟是单机执行多任务,资源是吃紧的,工程简单,这个功能才有优势,工程复杂,内存吃紧,这个功能就鸡肋了。
Talk is cheap,show you the code:
#####################################################################
def RenderInBackground():
node = nuke.thisNode()
if node.knob(‘User‘):
print ‘exist‘
else:
knob_tk = nuke.Tab_Knob(‘User‘,‘RenderInBackground‘)
node.addKnob(knob_tk)
if node.knob(‘information‘):
print ‘exist‘
else:
knob_tk2 = nuke.Text_Knob(‘information‘,‘Info:‘)
knob_tk2.setValue("Please make sure your setting didn‘t overflow available memory,so enough memory is necessary.")
node.addKnob(knob_tk2)
if node.knob(‘firstframe_1‘):
print ‘exist‘
else:
knob_ff = nuke.Int_Knob(‘firstframe_1‘,‘FirstFrame‘)
knob_ff.setValue(1001)
node.addKnob(knob_ff)
knob_ff.setTooltip(‘entry first frame of render range‘)
if node.knob(‘lastframe_1‘):
print ‘exist‘
else:
knob_lf = nuke.Int_Knob(‘lastframe_1‘,‘LastFrame‘)
knob_lf.setValue(1100)
node.addKnob(knob_lf)
knob_lf.setTooltip(‘entry last frame of render range‘)
if node.knob(‘splitNum‘):
print ‘exist‘
else:
knob_sn = nuke.Int_Knob(‘splitNum‘,‘splitNum‘)
knob_sn.setValue(2)
node.addKnob(knob_sn)
knob_sn.setTooltip(‘entry number of splited framerange‘)
if node.knob(‘maxThreads‘):
print ‘exist‘
else:
knob_mt = nuke.Int_Knob(‘maxThreads‘,‘maxThreads‘)
knob_mt.setValue(4)
node.addKnob(knob_mt)
if node.knob(‘maxCache‘):
print ‘exist‘
else:
knob_mc = nuke.Int_Knob(‘maxCache‘,‘maxCache‘)
knob_mc.setValue(2000)
node.addKnob(knob_mc)
if node.knob(‘unnamed‘):
print ‘exist‘
else:
knob_tt = nuke.Text_Knob(‘unnamed‘,‘‘)
node.addKnob(knob_tt)
if node.knob(‘renderinbackground‘):
print ‘exist‘
else:
knob_py = nuke.PyScript_Knob(‘renderinbackground‘,‘RenderInBackground‘)
node.addKnob(knob_py)
knob_py.setCommand(‘‘‘import time
if nuke.thisNode().knob(‘file‘).value().find(‘:/‘) == -1:
nuke.message(‘file is empty‘)
else:
if os.path.exists(os.path.dirname(nuke.thisNode().knob(‘file‘).value()))==True:
print nuke.thisNode().knob(‘file‘).value()
else:
os.makedirs(os.path.dirname(nuke.thisNode().knob(‘file‘).value()))
firstframe_2 = int(nuke.thisNode().knob(‘firstframe_1‘).value())
lastframe_2 = int(nuke.thisNode().knob(‘lastframe_1‘).value())
splitnum_2 = int(nuke.thisNode().knob(‘splitNum‘).value())
subrange = int((lastframe_2 + 1 - firstframe_2)/splitnum_2)
maxthreads = nuke.thisNode().knob(‘maxThreads‘).value()
maxcache = nuke.thisNode().knob(‘maxCache‘).value()
view = nuke.views()
limits = {‘maxThreads‘:maxthreads,‘maxCache‘:‘%dM‘%maxcache}
for i in range(splitnum_2+1):
framerange = nuke.FrameRange()
frameranges = nuke.FrameRanges()
if firstframe_2 - 1 + subrange * (i+1) >= lastframe_2:
framerange.setLast(lastframe_2)
else:
framerange.setLast(firstframe_2 - 1 + subrange * (i+1))
if lastframe_2 >= firstframe_2 + subrange * i:
framerange.setFirst(firstframe_2 + subrange * i)
framerange.setIncrement(1)
frameranges.add(framerange)
time.sleep(0.1)
print frameranges
nuke.executeBackgroundNuke(nuke.EXE_PATH,[nuke.thisNode()],frameranges,view,limits)
else:
pass
inputx = nuke.thisNode()[‘xpos‘].value()
inputy = nuke.thisNode()[‘ypos‘].value()
newnode = nuke.nodes.Read(file=nuke.thisNode().knob(‘file‘).value(),first=firstframe_2,last=lastframe_2,)
newnode.setXYpos(int(inputx),int(inputy)+50)‘‘‘
)
nuke.addOnCreate(RenderInBackground,nodeClass = ‘Write‘)