If anyone has some cool snippets to share please feel free to leave them in a comment below.
*last updated: 23 December 2016
user knob value in an expression / particle expression
random particle colour with particle expression node
*** a blendMat node must be applied before the emitter:
operation: plus
surface blend: modulate |
operation: plus
surface blend: modulate
the “color” parameter of a particleExpression node can be set using a 3dVector:
v( r, g, b )
and each channel can be referenced like this:
the red value for example :
x(color)
give the colour parameter a random value – (needs to be a 3dVector)
v(random*2, random, random/1.4 )
iterate over the animation curve of a Transform node copying the value of the Y position to a parameter of another Transform node.
dest = nuke.nodes.Transform()
destTransform = dest["translate"]
destTransform.setAnimated()
destAnim = dest["translate"].animation(1)
a = nuke.selectedNode()["translate"]
ypos = a.animation(1)
keys = ypos.keys()
for a in range(0,42):
dest["translate"].animation(1).setKey(a, ypos.evaluate(a)) |
dest = nuke.nodes.Transform()
destTransform = dest["translate"]
destTransform.setAnimated()
destAnim = dest["translate"].animation(1)
a = nuke.selectedNode()["translate"]
ypos = a.animation(1)
keys = ypos.keys()
for a in range(0,42):
dest["translate"].animation(1).setKey(a, ypos.evaluate(a))
display the current duration since the first frame (useful when sequence doesn’t start at zero/one)
put this in a text node or in a node’s “label” tab
[python {int( nuke.frame() - nuke.root()['first_frame'].value() ) }] |
[python {int( nuke.frame() - nuke.root()['first_frame'].value() ) }]
take a RotoPaint and change each layer’s RGBA to a grey level based on it’s “depth” – useful for prep’ing for a stereo conversion i’d imagine
import random
a = nuke.selectedNode()
if a.Class() == "RotoPaint":
knob = a['curves']
i = 0.0
for c in knob.rootLayer:
pos = float ((len(knob.rootLayer) - i) / len(knob.rootLayer))
i = i+1
attrs = c.getAttributes()
attrs.set(1, attrs.kRedOverlayAttribute, pos)
attrs.set(1, attrs.kRedAttribute, pos)
attrs.set(1, attrs.kGreenOverlayAttribute, pos)
attrs.set(1, attrs.kGreenAttribute, pos)
attrs.set(1, attrs.kBlueOverlayAttribute, pos)
attrs.set(1, attrs.kBlueAttribute, pos)
attrs.set(1, attrs.kAlphaOverlayAttribute, pos)
attrs.set(1, attrs.kAlphaAttribute, pos) |
import random
a = nuke.selectedNode()
if a.Class() == "RotoPaint":
knob = a['curves']
i = 0.0
for c in knob.rootLayer:
pos = float ((len(knob.rootLayer) - i) / len(knob.rootLayer))
i = i+1
attrs = c.getAttributes()
attrs.set(1, attrs.kRedOverlayAttribute, pos)
attrs.set(1, attrs.kRedAttribute, pos)
attrs.set(1, attrs.kGreenOverlayAttribute, pos)
attrs.set(1, attrs.kGreenAttribute, pos)
attrs.set(1, attrs.kBlueOverlayAttribute, pos)
attrs.set(1, attrs.kBlueAttribute, pos)
attrs.set(1, attrs.kAlphaOverlayAttribute, pos)
attrs.set(1, attrs.kAlphaAttribute, pos)
for all selected Tracker nodes multiply their track values by a factor of 4
for a in nuke.selectedNodes():
if a.Class()=="Tracker3":
def scaleMe(track):
if track.isAnimated():
for j in range (0,2):
anim = track.animation(j)
keys = anim.keys()
scaleFactor = 4
while keys:
keys.pop().y *= scaleFactor
#i am sure there is a much nicer way of iterating over all the knobs but this worked for what i quickly needed
t1 = a['track1']
t2 = a['track2']
t3 = a['track3']
t4 = a['track4']
scaleMe(t1)
scaleMe(t2)
scaleMe(t3)
scaleMe(t4) |
for a in nuke.selectedNodes():
if a.Class()=="Tracker3":
def scaleMe(track):
if track.isAnimated():
for j in range (0,2):
anim = track.animation(j)
keys = anim.keys()
scaleFactor = 4
while keys:
keys.pop().y *= scaleFactor
#i am sure there is a much nicer way of iterating over all the knobs but this worked for what i quickly needed
t1 = a['track1']
t2 = a['track2']
t3 = a['track3']
t4 = a['track4']
scaleMe(t1)
scaleMe(t2)
scaleMe(t3)
scaleMe(t4)
set bbox to “B” for nodes inside all Group nodes
import nuke
def bboxGroup():
for b in nuke.allNodes():
if b.Class() == "Group":
for a in nuke.toNode(b.name()).nodes():
classTypes = ['Merge' , 'Keymix', 'Copy', ]
print a.name()
for n in classTypes:
if n in a.Class():
try:
for p in a['bbox'].values():
if 'B' in p:
a['bbox'].setValue(a['bbox'].values().index(p))
except:
pass |
import nuke
def bboxGroup():
for b in nuke.allNodes():
if b.Class() == "Group":
for a in nuke.toNode(b.name()).nodes():
classTypes = ['Merge' , 'Keymix', 'Copy', ]
print a.name()
for n in classTypes:
if n in a.Class():
try:
for p in a['bbox'].values():
if 'B' in p:
a['bbox'].setValue(a['bbox'].values().index(p))
except:
pass
“Autowrite” node
Copy the following line into the python “beforeRender” field in a write node.
The write node’s “file” field will be filled based on the script’s name/path.
Obviously this all depends on your pipeline etc.
For my current situation each vfx shot has it’s own directory, which is then populated with “renders” & “scripts” subdirectories.
So for me I can do this:
nuke.thisNode()["file"].setValue(nuke.root().name().replace("scripts","renders").replace(".nk",".mov")) |
nuke.thisNode()["file"].setValue(nuke.root().name().replace("scripts","renders").replace(".nk",".mov"))
delete all nodes that are not selected
s = nuke.selectedNodes()
b = nuke.allNodes()
for n in b:
if n not in s:
nuke.delete(n) |
s = nuke.selectedNodes()
b = nuke.allNodes()
for n in b:
if n not in s:
nuke.delete(n)
selects all dependencies (input nodes & their parents) from a selected node
a = nuke.selectedNode()
nodesToSelect = []
nodesToSelect.append(a)
def climb(node):
# print node.name()
for n in node.dependencies():
nodesToSelect.append(a)
climb(n)
climb(a)
for x in nodesToSelect:
print x.name()
# x.setSelected(1) |
a = nuke.selectedNode()
nodesToSelect = []
nodesToSelect.append(a)
def climb(node):
# print node.name()
for n in node.dependencies():
nodesToSelect.append(a)
climb(n)
climb(a)
for x in nodesToSelect:
print x.name()
# x.setSelected(1)
set all Read nodes to cache locally
for a in nuke.allNodes():
if a.Class()=='Read':
a['cached'].setValue(1)
a['cacheLocal'].setValue(0) |
for a in nuke.allNodes():
if a.Class()=='Read':
a['cached'].setValue(1)
a['cacheLocal'].setValue(0)
print last frame of script
print nuke.root()['last_frame'].value() |
print nuke.root()['last_frame'].value()
create a backdrop based on selected Nodes
margin = 100
xpMax = nuke.selectedNode().xpos()
xpMin = nuke.selectedNode().xpos()
ypMax = nuke.selectedNode().ypos()
ypMin = nuke.selectedNode().ypos()
for a in nuke.selectedNodes():
if a.xpos() > xpMax:
xpMax = a.xpos()
if a.xpos() < xpMin: xpMin = a.xpos() if a.ypos() > ypMax:
ypMax = a.ypos()
if a.ypos() < ypMin:
ypMin = a.ypos()
bd = nuke.nodes.BackdropNode(bdwidth=(xpMax-xpMin)+margin, bdheight=(ypMax-ypMin)+margin)
bd.setXpos(xpMin-margin/2)
bd.setYpos(ypMin-margin/2) |
margin = 100
xpMax = nuke.selectedNode().xpos()
xpMin = nuke.selectedNode().xpos()
ypMax = nuke.selectedNode().ypos()
ypMin = nuke.selectedNode().ypos()
for a in nuke.selectedNodes():
if a.xpos() > xpMax:
xpMax = a.xpos()
if a.xpos() < xpMin: xpMin = a.xpos() if a.ypos() > ypMax:
ypMax = a.ypos()
if a.ypos() < ypMin:
ypMin = a.ypos()
bd = nuke.nodes.BackdropNode(bdwidth=(xpMax-xpMin)+margin, bdheight=(ypMax-ypMin)+margin)
bd.setXpos(xpMin-margin/2)
bd.setYpos(ypMin-margin/2)
disable “postage stamps” on only “Read” nodes
for a in nuke.allNodes():
if a.Class()=='Read':
a['postage_stamp'].setValue(0) |
for a in nuke.allNodes():
if a.Class()=='Read':
a['postage_stamp'].setValue(0)
disable “postage stamps” on all nodes
for a in nuke.allNodes():
try:
a['postage_stamp'].setValue(0)
except:
pass |
for a in nuke.allNodes():
try:
a['postage_stamp'].setValue(0)
except:
pass
“unhide” all nodes’ inputs – useful when receiving a sneaky comp/lighting script
for a in nuke.allNodes():
try:
a['hide_input'].setValue(0)
except:
pass |
for a in nuke.allNodes():
try:
a['hide_input'].setValue(0)
except:
pass
change the “first” frame of all selected nodes that are “Read” nodes:
(example changes the first frame to 1018)
for a in nuke.selectedNodes():
if a.Class() == 'Read':
a['first'].setValue(1018) |
for a in nuke.selectedNodes():
if a.Class() == 'Read':
a['first'].setValue(1018)
print a selected nodes’ methods
import struct
node = nuke.selectedNode()
for a in node['lookup'].animations():
print dir(a) |
import struct
node = nuke.selectedNode()
for a in node['lookup'].animations():
print dir(a)
print inputs (dependencies) of a selected node:
for a in nuke.selectedNode().dependencies():
print a.name() |
for a in nuke.selectedNode().dependencies():
print a.name()
print outputs (dependents) of a selected node:
for a in nuke.selectedNode().dependent():
print a.name() |
for a in nuke.selectedNode().dependent():
print a.name()
find all the TimeOffset nodes in a Group called “Group2”, and change the value of each offset based on it’s position in the array of found time offsets
tos = []
for a in nuke.toNode('Group2').nodes():
if a.Class()=='TimeOffset':
tos.append(a)
for b in tos:
b['time_offset'].setValue(tos.index(b)) |
tos = []
for a in nuke.toNode('Group2').nodes():
if a.Class()=='TimeOffset':
tos.append(a)
for b in tos:
b['time_offset'].setValue(tos.index(b))
set the ‘bbox’ for any selected Merge, Keymix & Copy nodes to “B”
for a in nuke.selectedNodes():
classTypes = ['Merge' , 'Keymix', 'Copy', ]
for n in classTypes:
if n in a.Class():
for p in a['bbox'].values():
if 'B' in p:
a['bbox'].setValue(a['bbox'].values().index(p)) |
for a in nuke.selectedNodes():
classTypes = ['Merge' , 'Keymix', 'Copy', ]
for n in classTypes:
if n in a.Class():
for p in a['bbox'].values():
if 'B' in p:
a['bbox'].setValue(a['bbox'].values().index(p))
remove all animation from a selected nodes
for a in nuke.selectedNode().knobs():
nuke.selectedNode()[a].clearAnimated() |
for a in nuke.selectedNode().knobs():
nuke.selectedNode()[a].clearAnimated()
add keyframes – animate a mix
for a in nuke.selectedNodes():
a['mix'].setAnimated()
a['mix'].setValueAt(1,nuke.frame())
a['mix'].setValueAt(0,(nuke.frame() - 1)) |
for a in nuke.selectedNodes():
a['mix'].setAnimated()
a['mix'].setValueAt(1,nuke.frame())
a['mix'].setValueAt(0,(nuke.frame() - 1))
half the colour value of all the Constant nodes in a script
for a in nuke.allNodes():
if a.Class() == "Constant":
a['color'].setValue(a['color'].value()[0] / 2 , 0)
a['color'].setValue(a['color'].value()[1] / 2 , 1)
a['color'].setValue(a['color'].value()[2] / 2 , 2) |
for a in nuke.allNodes():
if a.Class() == "Constant":
a['color'].setValue(a['color'].value()[0] / 2 , 0)
a['color'].setValue(a['color'].value()[1] / 2 , 1)
a['color'].setValue(a['color'].value()[2] / 2 , 2)
find all the transform nodes in a script, and if their input is a Crop, set the ‘scale’ value to be twice it’s current value (also checks if the scale is a list/array or a float)
for a in nuke.allNodes():
if a.Class() == "Transform":
if a.input(0).Class() == "Crop":
x = a['scale'].value()
if type(x).__name__ == 'list':
a['scale'].setValue(x[0] * 2 , 0)
a['scale'].setValue(x[1] * 2 , 1)
if type(x).__name__ == 'float':
a['scale'].setValue(x*2) |
for a in nuke.allNodes():
if a.Class() == "Transform":
if a.input(0).Class() == "Crop":
x = a['scale'].value()
if type(x).__name__ == 'list':
a['scale'].setValue(x[0] * 2 , 0)
a['scale'].setValue(x[1] * 2 , 1)
if type(x).__name__ == 'float':
a['scale'].setValue(x*2)
set all the gain values of all ColorCorrect nodes to be twice their current value
for a in nuke.allNodes():
if a.Class() == "ColorCorrect":
a['gain'].setValue(a['gain'].value() * 2) |
for a in nuke.allNodes():
if a.Class() == "ColorCorrect":
a['gain'].setValue(a['gain'].value() * 2)
print files with ‘mov’ in filename
for a in nuke.allNodes():
if 'Read' in a['name'].value():
if 'mov' in a['file'].value():
print a['file'].value() |
for a in nuke.allNodes():
if 'Read' in a['name'].value():
if 'mov' in a['file'].value():
print a['file'].value()
change font size of all “write” nodes in script
for a in nuke.selectedNodes():
if "Write" in a['name'].value():
a['note_font_size'].setValue(60) |
for a in nuke.selectedNodes():
if "Write" in a['name'].value():
a['note_font_size'].setValue(60)
create 20 constants with incrementing colour values
def makeConstants(amount):
for i in range(amount):
a= nuke.nodes.Constant()
color= float( float(i) / float(amount) )
a['color'].setValue(color)
makeConstants(20) |
def makeConstants(amount):
for i in range(amount):
a= nuke.nodes.Constant()
color= float( float(i) / float(amount) )
a['color'].setValue(color)
makeConstants(20)
change the name of all Text nodes to contents the text “message”
for a in nuke.allNodes():
if a.Class()=='Text':
a.setName(a['message'].value()) |
for a in nuke.allNodes():
if a.Class()=='Text':
a.setName(a['message'].value())
##Expressions
(in an expression node) – alpha channel – if the y value of the pixel is even, make it 0, else make it 1 (for viewing fields?)
y%2==1?0:1