Python and TCL

Python and TCL: Tips and Tricks for Nuke

Helpful Python and TCL snippets to use inside The Foundry Nuke

In this tutorial you will find some tips and tricks that I've wrote and catch up from other websites. It will be really useful for all the Nuke artist because it's a complete guide by categories. I've also created a Gizmo to check directly inside Nuke the various commands in Python and the TCL expressions.



You can download the Gizmo for Nuke here:
Download from Nukepedia





00. Python and TCL Overview

  • PYTHON:
#-------------------------------------------------------
#PRINT and VARIABLES
print 'Hello World'

name = 'Andrea'
print 'Hello' + name

#-------------------------------------------------------
#VARIABLES TYPES

int(x)
long(x)
float(x)
str(x)

#convert string o int
int (stringa)

#convert int to string
str(integer)

#-------------------------------------------------------
#STRINGS

var1 = 'Hello World!'
print "Updated String : ", var1[:6] + 'Python'
#Result: Updated String :  Hello Python

var2 = "Hello, Ciao, Halo,"
list = var2.split(',')
for x  in list:
    print(x)
#RESULT 	Hello
#	Ciao
# 	Halo

#-------------------------------------------------------
#IF CONDITION

if expression:
   statement(s)
else:
   statement(s)

#EXAMPLE 01
if var == 200:
	print 'ciao'
elif var<200:
	print 'ok'

#EXAMPLE 02
answer = 'y'
if answer is 'y':
    print("answer is equal to 'y'")

#EXAMPLE 03
if answer in ['y', 'Y', 'yes', 'Yes', 'YES']:
    print("answer is in this list")

#-------------------------------------------------------
#IF CONDITION IN 1 LINE
("some string" if expression else "another string")

#if size > 100 then print 'big', otherwise print 'small'
(' big!' if nuke.thisNode()['size'].value()>100 else ' small')

#-------------------------------------------------------
#FOR LOOP

#simple structure
for x in range(0, 3):
print x

#Lists as an iterable
collection = ['hey', 5, 'd']
for x in collection:
    print x

#-------------------------------------------------------
#WHILE LOOP

count = 0
while (count < 9):
   print 'The count is:', count
   count = count + 1

print "Good bye!"

# RESULT: The count is: 0
#The count is: 1
#The count is: 2
#The count is: 3
#The count is: 4
#The count is: 5
#The count is: 6
#The count is: 7
#The count is: 8
#Good bye!
  • TCL:
#GETTING A KNOB’S VALUE OF A SPECIFIC NODE:

#First frame of current read/write:
[value Read1.first]

#Getting a knob’s value of current node:
[value this.first_frame]

#Return label value of the input node:
[value this.size]

#Name of the input node:
[value this.input0.label]

#Name of the node before the group (Outside):
[value this.input.name]

#Return 1 if the node is on error otherwise 0:
[value this.parent.input.name]

#Get the bounding Box from the input of the node:
[value error]


#Here some expression for the Format
format.x
format.y
width
height
bbox.x
bbox.y
bbox.w
bbox.h

#Get the format from the input of the node:
#left boundary
[value input.bbox.x] 
#right boundary
[value input.bbox.r] 

#Get the format from the input of the node:
#width
[value input.format.r]
#height
[value input.format.t]

#Get the x position of the point #3 of the Bezier1 of the Roto1 node:
[value Roto1.curves.Bezier1.curve_points.3.main.x]

#Return sample pixel value of the node Add1 reading in the red at position of knob Center:
[sample Add1 Red Center.x Center.y]

#Get the value of the channel of a node, at a specific pixelcoordinates (e.g.: 10,10):
[sample [node input] red 10 10]

#---------------------------------------------------------------------
#SET VALUES

#Setting a knob’s value of a specific node:
[knob Read1.first 10]

#Setting a variable, without returning that (useful in a textnode):
[set seq [value Read1.file]; return]

#---------------------------------------------------------------------
#STRING

#Replace string in current node file knob with regex (string “proj” to “projects” in all occurences):
[regsub -all "proj" [value [node this].file] "projects"] 

#String map (replace multiple stringpairs) (this returns: xxffffxxyy):
[string map {"aa" "xx" "bb" "yy"} "aaffffaabb" ]

#Compare strings:
[string equal [value Text1.message] "bla"]

#Regexp matching:
[regexp -inline "_v\[0-9]{3}" [value Read2.file]] 

#Evaluating string
[python os.getenv('rotate') == 'xavierb']

#---------------------------------------------------------------------
#IF CONDITION

[if {condition} {expr1} else {expr2}]

#Example:
[if {[value blackpoint]==1} {return 2} {return 3}]
[if {[value blackpoint]==1} {return True} {return False}]
[if {[value blackpoint]==1} {return blackpoint} {return whitepoint}]
[if {[value filter]=="gaussian"} {return filter} {return False}]

#OTHER METHOD
condition ? then : else

#Example:
#if (r==1)? return 0: else (return r*2)
r ==1 ? 0 : r*2

#---------------------------------------------------------------------
#PATH MANIPULATIONS:

#Filepath without extension:
[file rootname [value [topnode].file]]

#Filename only:
[basename [value [topnode].file ]]

#Filename only without extension:
[basename[file rootname [value [topnode].file]]]



01. CREATE NODE

  • PYTHON:
#CREATE NODE WITH NUKE.NODES.XXX()
nuke.nodes.Blur()
nuke.createNode("Grade")

#CREATE 3 BLUR NODES
for x in range(0, 3):
    nuke.nodes.Blur()

#----------------------------------------------------------------------------------
#PYTHON BUTTON IN A GROUP CREATE A BLUR NODE OUTSIDE THE GROUP
#COPY THIS IN A PYTHON BUTTON IN A GROUP
#EXAMPLE01
nuke.root().begin()
stickyNote = nuke.createNode('Blur')


#PYTHON BUTTON IN A GROUP CREATE A STICKYNODE OUTSIDE THE GROUP, READING THE VALUE IN THE KNOB 'PYTHON'
#EXAMPLE02
n=nuke.thisNode()
name = n.name()
text=nuke.toNode(name)['python'].getValue()

nuke.root().begin()
stickyNote = nuke.createNode('StickyNote')
stickyNote["label"].setValue(text)



02. SELECT NODE

  • PYTHON:
#GET SELECTED NODE
nuke.selectedNode()

#GET MULTIPLE NODES SELECTED
nuke.selectedNodes()

#SELECT NODE BY NAME
node = nuke.toNode("Blur1")
node.knob('selected').setValue(True)

#SELECT ALL THE NODES
for node in nuke.allNodes(): # The 'for loop'
node['selected'].setValue(True) #Attribute 'selected' becomes True

#-------------------------------------------------------------------------------------
#SELECT NODES THAT START WITH A SPECIFIC "STRING"
for node in nuke.allNodes():
if node['name'].value().startswith("ColorCor"): #Instead of 'ColorCor' put the name that you want
node['selected'].setValue(True)

#-------------------------------------------------------------------------------------
#SELECT NODE BY CLASS
for node in nuke.allNodes():
if node.Class() == "Blur": #Select all the Blur nodes
node['selected'].setValue(True)


#-------------------------------------------------------------------------------------
#RUN A SCRIPT FOR EVERY SELECTED NODE
sn = nuke.selectedNodes() # The list of nodes.
for node in sn: 
print nodes['name'].getValue() # Put your code here.

#-------------------------------------------------------------------------------------
#ADD NAME OF NODES INTO A ARRAY (LIST). SELECT NODES AND CREATE A LIST OF ALL THE NAMES
array = [] #create the array
for node in nuke.selectedNodes(): 
n = node['name'].value()
array.append(n) #Add the value to the list
print array #print the list

#---------------------------------------------------------------------------------------
#DESELECT ALL SELECTED NODES
if nuke.selectedNodes():
for i in nuke.selectedNodes():
i['selected'].setValue(False)



03. CONNECT NODE

  • PYTHON:
#CONNECT THE OUTPUT OF THE SELECT NODE TO THE INPUT 0 OF COLORCORRECT
nuke.toNode('ColorCorrect3').setInput( 0, nuke.selectedNode() )

#CONNECT THE OUTPUT OF THE SELECT NODE TO THE INPUT 1 (MASK) OF COLORCORRECT
nuke.toNode('ColorCorrect3').setInput( 1, nuke.selectedNode() )

#CONNECT OUTPUT OF COLORCORRECTION TO ALL THE SELECTED NODES
for i in nuke.selectedNodes():
i.setInput( 0, nuke.toNode('ColorCorrect3'))

#-------------------------------------------------------------------------------------
#CREATE A MERGE NODE E CONNECT THE INPUTS TO THE SELECTED NODES
a = nuke.createNode('Merge')
b = nuke.selectedNodes()
x=0
for i in b:
if x==2:
x+=1
continue
a.setInput(x,i)
x+=1

#-------------------------------------------------------------------------------------

#DISCONNECT INPUT
nuke.selectedNode().setInput(1, None)

#DISCONNECT ALL THE INPUTS OF THE SELECTED NODE
for i in range(0, nuke.selectedNode().maxInputs()):
nuke.selectedNode().setInput(i, None)

#-------------------------------------------------------------------------------------
#DEPENDENT AND DEPENDENCIES

#LIST OF NODES DEPENDENT AND DEPENDENCIES
nuke.selectedNode().dependent()
nuke.selectedNode().dependencies()

#PRINT THE NAME OF THE NODES
for i in nuke.selectedNode().dependencies():
print i.name()



04. READ FROM KNOB

  • PYTHON:
# LIST ALL KNOBS FOR SELECTED NODE
print( nuke.toNode('Read1') )

# LIST ALL KNOBS FOR SPECIFIC NODE
print( nuke.selectedNode() )

# GET VALUE FROM SPECIFIC NODE, METHOD 01
value = nuke.toNode('Read1').knob('file').getValue()

#PRINT VALUE FROM SPECIFIC NODE, METHOD 02
node = nuke.toNode("Blur1")
print node['size'].value()

# GET VALUE FROM SELECTED NODE
value = nuke.selectedNode().knob('file').getValue()

#GET DEFAULT VALUE
nuke.toNode('Blur6').knob('size').defaultValue()

# GET VALUE FROM SPECIFIC NODE AND EVALUATE IT (GOOD FOR EXPRESSIONS)
value = nuke.toNode('Read1').knob('file').evaluate()

#GET THE EXPRESSION OF A KNOB
if nuke.toNode('Blur6').knob('size').hasExpression():
print nuke.toNode('Blur6').knob('size').toScript()

#GET VALUE XY_KNOB INDIVIDUALLY
nuke.toNode('Transform1').knob('scale').getValue(0) #w
nuke.toNode('Transform1').knob('scale').getValue(1) #h

#GET ME THE HEIGHT AND WIDTH FROM A SELECTED NODE
nuke.selectedNode().height()
nuke.selectedNode().width()
nuke.selectedNode().pixelAspect

#--------------------------------------------------------------------------------
#DROPDOWN MENU / PULLDOWN CHOICE

#GET VALUE FROM PULLDOWN CHOICE (NAME)
nuke.selectedNode()['attribute'].value()

#GET INDEX FROM PULLDOWN CHOICE (NAME)
int(nuke.toNode('Blur6').knob('filter').getValue())
int(nuke.selectedNode().knob('filter').getValue())

#--------------------------------------------------------------------------------
#CHECK THE NAME OF A KNOB (WILL BE USEFUL LATER)
node = nuke.selectedNode()
knob = node['filter']
if('filter' in knob.name()):
print "found it!"

#CALCULATE THE MAX AND MIN VALUE IN A FRAMERANGE
ret = nuke.getFramesAndViews('get range', '1-100')
frame_range = ret[0].split('-')

min=0
max=0

for i in range(int(frame_range[0]), int(frame_range[1])+1):
knob = nuke.selectedNode()['size'].getValueAt(i)
print 'value: ' + knob
print 'frame: ' + i
if (knob > max):
max = knob

if (knob < min):
min = knob

print 'max is', max
print 'min is', min

#--------------------------------------------------------------------------------
#GET FRAME RANGE FROM NODE
first_frame = nuke.selectedNode().firstFrame()
last_frame = nuke.selectedNode().lastFrame()

#-------------------------------------------------------------------------------
#READ KNOB INSIDE GROUP
#GET A KNOB OF A NODE INSIDE A GROUP. THIS WORKS ONLY INTO A PYTHON BUTTON OF THE GROUP
n=nuke.thisNode()
name = n.name()
print nuke.toNode('StickyNote_PythonOverview')['label'].getValue()




05. WRITE INTO KNOB

  • PYTHON:
#SET DEFAULT VALUE FOR A KNOB
nuke.knobDefault( 'Blur.size', '77' )
nuke.knobDefault( 'channels', 'rgba' )

# SET SPECIFIC NODE'S VALUE
nuke.toNode('Read1').knob('file').setValue('c:/hello.tif')
nuke.toNode('Transform2').knob('scale').setValue(2)

# SET SELECTED NODE'S VALUE
nuke.selectedNode().knob('file').setValue('c:/hello.tif')
nuke.selectedNode()['scale'].setValue(3)

# SET THIS NODE'S VALUE
nuke.thisNode().knob('file').setValue('c:/hello.tif')

#SET KNOB WITH 4 VALUES (x, y, w, h)
n = nuke.selectedNode()
n['box'].setValue((0, 150, 4096, 2010))

#SET KNOB WITH 2 VALUES (w, h)
nuke.selectedNode()['scale'].setValue(1250, 0)

#WHEN A NODE HAS XY KNOB, USE THIS CODE TO SPLIT VALUES AND ASSIGN 2 DIFFERENT VALUES
nuke.selectedNode()['scale'].setSingleValue(False)
nuke.selectedNode()['scale'].setExpression('scale.w*2',1)

# SET SPECIFIC NODE'S KNOB TO DEFAULT VALUE
nuke.toNode('Grade1').knob('gamma').setValue( nuke.toNode('Grade1').knob('gamma').defaultValue() )

#SET EXPRESSION IN A KNOB
node = nuke.selectedNode()
node.knob('mix').setExpression('size + 5')

#DISABLE A NODE
nuke.toNode('Blur7')['disable'].setValue(True)

#SINGLE OR MULTIPLE VALUES IN A KNOB
nuke.toNode('Transform2')['scale'].setSingleValue(True)

#SET A CHECKBOX
nuke.toNode('Transform2')['invert_matrix'].setValue(True)
nuke.toNode('Transform2')['invert_matrix'].setValue(1)

#--------------------------------------------------------------------------------
#DROPDOWN MENU / PULLDOWN CHOICE

#SET A PULLDOWN CHOICE
nuke.toNode('Transform2')['filter'].setValue(2)

#POPULATE PULLDOWN CHOICE (DROPDOWN MENU)
pulldown = nuke.toNode('Group1')

pulldown['id'].setValues(['a', 'b', 'c'])


#EXPRESSION IN PULLDOWN CHOICE
#TCL:
in Transform1.filter {set_expression {Transform2.filter}}

#PYTHON:
k=nuke.toNode('Transform1')['filter']
k.setExpression('Transform2.filter',0)

#--------------------------------------------------------------------------------
#SET A KNOB AS THE CURRENT FRAME
nk = nuke.thisNode()
nk.knob('translate').setValue(nuke.frame())



06. CREATE A NEW KNOB

  • PYTHON:
#FORMULA
node = nuke.toNode('Name Node')
knob = nuke.nuke.Double_Knob('name', 'Label')
node.addKnob(knob)


#CREATE A SLIDER KNOB
node = nuke.selectedNode()
knob = nuke.nuke.Double_Knob('slider', 'Slider') 
knob.setRange(1,100)
knob.setValue(10)
node.addKnob(knob)

#------------------------------------------------------------------------------
# CREATE A CHECKBOX
sn = nuke.selectedNode()

uk = nuke.nuke.Boolean_Knob('checkbox', 'Checkbox') 
uk.setValue(True)
sn.addKnob(uk)



07. ANIMATION and CURVE

  • PYTHON:
#CURRENT FRAME
print nuke.frame()

#GO TO FRAME x
nuke.frame(x)

#GET VALUE OF KNOB AT FRAME 5
knob = nuke.selectedNode()['size'].getValueAt(5)

#IF KNOB IS ANIMATED
node = nuke.createNode( 'Blur' )
k = node['size']
k.isAnimated()

#IF HAS AN EXPRESSION
k.hasExpression()

#RETURN TRUE IF THERE IS A KEYFRAME AT THE CURRENT FRAME 
k.isKey()

#RETURN TRUE IF THERE IS A KEYFRAME AT THE FRAME 5 
k.isKeyAt(5)

#GET KEY VALUE AT FRAME 3
nuke.selectedNode()['rotate'].getValueAt(3)

# PRINT KEY VALUE AT CURRENT FRAME
nk = nuke.selectedNode()
knob = nk.knob('rotate')
print knob.getValueAt(nuke.frame())

#SET KNOB TO ACCEPT ANIMATION
node = nuke.createNode( 'Blur' )
k = node['size']
k.setAnimated()

#SET KEY IN THE CURRENT FRAME
k.setValue( 5 )

#TWO MORE KEYS AT FRAME 10 AND 100 WITH VALUES OF 55 AND 66 RESPECTIVELY
k.setValueAt( 55, 10 )
k.setValueAt( 66, 100 )


#IF KNOB IS AN ARRAY, THIS SETS THE FIRST FIELD/CHANNEL TO 77 AND THE SECOND TO 88 AT FRAME 100
k.setValueAt( 77, 100, 0 )
k.setValueAt( 88, 100, 1 )

#------------------------------------------------------------------------------------------------
#PRINT ALL THE KEYS WITH THE VALUES FOR THE GIVEN ANIMATION CURVE
for key in animCurve.keys():
xValue = key.x
yValue = key.y
print 'ket at %s has value %s' % ( xValue, yValue )

# Result:
ket at 1.0 has value 5.0
ket at 10.0 has value 55.0
ket at 100.0 has value 77.0

#------------------------------------------------------------------------------------------------
#Clear all the animation in a node
n=nuke.selectedNode()
k=n.allKnobs()
for i in k:
i.clearAnimated()
#------------------------------------------------------------------------------------------------

#BAKE ANIMATION
https://learn.foundry.com/nuke/developers/63/pythondevguide/animation.html

#------------------------------------------------------------------------------------------------
#EXAMPLE 01: SELECT THE ANIM CURVE
g1 = nuke.toNode("Grade1")
gBlack = g1['blackpoint']
anim = gBlack.animation(0)
print anim


#------------------------------------------------------------------------------------------------
#EXAMPLE 02: CREATE A FRADE NODE WITH 2 KEYS ON THE BLACKPOINT AT FRAME 1 AND 10
g = nuke.nodes.Grade()
a = nuke.AnimationC urve(g['blackpo int'], 0, 'r')
a.setKey(1, .1)
a.setKey(10, .125)
g['blackpoint'].copyAnimation(0, a)

#------------------------------------------------------------------------------------------------
#EVALUATE: THIS SIMPLY TAKES A NUMERIC FRAME ARGUMENT (INT OR FLOAT) AND RETURNS THE CURVE’S VALUE AT THAT FRAME
anim.evaluate(30)

#FRAME NUMBER AND A KEY VALUE
anim.setKey(48, .044)

#THIS RETURNS TRUE IF THE ANIMATION IS DRIVEN BY KEYS, OR FALSE IF THE ANIMATION IS LINKED BY AN EXPRESSION. 
anim.noExpression()

#ATTACH AN EXPRESSION TO AN ANIMATIONCURVE
gWhite = g1['whitepoint']
gWhite.setAnimated()
anim2 = gWhite.animation(0)
anim2.setExpression("blackpoint")

#------------------------------------------------------------------------------------------------
#THIS METHOD WILL STILL RETURN THE VALUE ‘CURVE IF THE PARENT KNOB ISN’T LINKED USING AN EXPRESSION
anim.expression()

#THIS RETURNS A LIST OF ANIMATIONKEY OBJECTS
keys = anim.keys()
print keys
#------------------------------------------------------------------------------------------------
#DELETE ANIMATION

#DELETE ALL KEYS FROM THE CURVE
anim.clear()

#REMOVE KEY 
knob.removeKey()

#REMOVE KEY AT TIME 't' 
knob.removeKeyAt(t)

#DELETE THE ANIMATION FROM ALL THE SELECTED NODES
nodes = nuke.selectedNodes()
for n in nodes:
knobs = n.allKnobs()
for k in knobs:
k.clearAnimated()



08. EXPRESSIONS

  • PYTHON:
#EXPRESSION in PYTHON

• nuke.expression() to use a Nuke expression in Python code.

• expression to use a Nuke expression in TCL.

• nuke.tcl() to run TCL code in Python.

• python to run Python code in TCL

• [ ] (square brackets) to embed TCL in a Nuke expression (or a string knob)

• [python {...}] to embed Python in a Nuke expression.


#SET KNOB WITH AN EXPRESSION
node = nuke.selectedNode()
node.knob('mix').setExpression('size + 5')

#ANOTHER EXAMPLE
node = nuke.toNode('Grade1')
node.knob('whitepoint').setExpression('gain + 1')

#USE PYTHON IN THE EXPRESSION (WITH TCL)
[python nuke.thisNode().metadata().keys()]

[python nuke.thisNode().metadata()\['input/filename'\]]

[python {nuke.thisNode().metadata['input/filename']}]

[python {nuke.thisNode().metadata['input/filename']}]

#USE PYTHON IN EXPRESSION
[python {nuke.thisNode().knob(\'rotate\').value()}]


#TCL IN PYTHON
nuke.tcl('return '+nuke.selectedNode()['filter'].value())
  • TCL:
EXPRESSION TCL

GETTING A KNOB’S VALUE OF A SPECIFIC NODE:

#FIRST FRAME OF CURRENT READ/WRITE:
[value Read1.first]

#GETTING A KNOB’S VALUE OF CURRENT NODE:
[value this.first_frame]

#RETURN LABEL VALUE OF THE INPUT NODE:
[value this.size]

#NAME OF THE INPUT NODE:
[value this.input0.label]

#NAME OF THE NODE BEFORE THE GROUP (OUTSIDE):
[value this.input.name]

#RETURN 1 IF THE NODE IS ON ERROR OTHERWISE 0:
[value this.parent.input.name]

#GET THE BOUNDING BOX FROM THE INPUT OF THE NODE:
[value error]


#HERE SOME EXPRESSION FOR THE FORMAT
format.x
format.y
width
height
bbox.x
bbox.y
bbox.w
bbox.h

#GET THE FORMAT FROM THE INPUT OF THE NODE:
[value input.bbox.x]#left boundary
[value input.bbox.r]#right boundary

#GET THE FORMAT FROM THE INPUT OF THE NODE:
[value input.format.r]#width
[value input.format.t]#height

#GET THE X POSITION OF THE POINT #3 OF THE BEZIER1 OF THE ROTO1 NODE:
[value Roto1.curves.Bezier1.curve_points.3.main.x]

#RETURN SAMPLE PIXEL VALUE OF THE NODE ADD1 READING IN THE RED AT POSITION OF KNOB CENTER:
[sample Add1 Red Center.x Center.y]

#GET THE VALUE OF THE CHANNEL OF A NODE, AT A SPECIFIC PIXELCOORDINATES (E.G.: 10,10):
[sample [node input] red 10 10]

#---------------------------------------------------------------------
#SET VALUES

#SETTING A KNOB’S VALUE OF A SPECIFIC NODE:
[knob Read1.first 10]

#SETTING A VARIABLE, WITHOUT RETURNING THAT (USEFUL IN A TEXTNODE):
[set seq [value Read1.file]; return]

#---------------------------------------------------------------------
#STRING

#REPLACE STRING IN CURRENT NODE FILE KNOB WITH REGEX (STRING “PROJ” TO “PROJECTS” IN ALL OCCURENCES):
[regsub -all "proj" [value [node this].file] "projects"] 

#STRING MAP (REPLACE MULTIPLE STRINGPAIRS) (THIS RETURNS: xxffffxxyy):
[string map {"aa" "xx" "bb" "yy"} "aaffffaabb" ]

#COMPARE STRINGS:
[string equal [value Text1.message] "bla"]

#REGEXP MATCHING:
[regexp -inline "_v\[0-9]{3}" [value Read2.file]] 

#EVALUATING STRING
[python os.getenv('rotate') == 'xavierb']

#---------------------------------------------------------------------
#IF CONDITION

[if {condition} {expr1} else {expr2}]

#Example:
[if {[value blackpoint]==1} {return 2} {return 3}]
[if {[value blackpoint]==1} {return True} {return False}]
[if {[value blackpoint]==1} {return blackpoint} {return whitepoint}]
[if {[value filter]=="gaussian"} {return filter} {return False}]

#OTHER METHOD
condition ? then : else

#EXAMPLE:
#if (r==1)? return 0: else (return r*2)
r ==1 ? 0 : r*2

#---------------------------------------------------------------------
#PATH MANIPULATIONS:

#FILEPATH WITHOUT EXTENSION:
[file rootname [value [topnode].file]]

#FILENAME ONLY:
[basename [value [topnode].file ]]

#FILENAME ONLY WITHOUT EXTENSION:
[basename[file rootname [value [topnode].file]]]




09. MATH FUNCTIONS and WAVE GENERATOR

  • PYTHON:
#MATH FUNCTIONS AND WAVE GENERATOR
#PYTHON
#--------------------------------------------------------

#IMPORT THE MATH LIBRARY
import math

#--------------------------------------------------------
#WAVE GENERATOR

#RANDOM WAVE
random((frame+offset)/waveLength) * (maxVal-minVal) + minVal

#NOISE WAVE
(noise((frame+offset)/waveLength)+1)/2 * (maxVal-minVal) + minVal

#SINE WAVE
(sin(2*pi*(frame+offset)/waveLength)+1)/2 * (maxVal-minVal) + minVal

#TRIANGLE WAVE
(asin(sin(2*pi*(frame+offset)/waveLength))/pi+0.5) * (maxVal-minVal) + minVal

#SQUARE WAVE
int(sin(2*pi*(frame+offset)/waveLength)+1) * (maxVal-minVal) + minVal

#SAWTOOTH WAVE
((frame+offset) % waveLength)/waveLength * (maxVal-minVal) + minVal

#SAWTOOTH (PARABOLIC) WAVE
sin((pi*(frame+offset)/(2*waveLength)) % (pi/2)) * (maxVal-minVal) + minVal

#SAWTOOTH (PARABOLIC REVERSED) WAVE
cos((pi*(frame+offset)/(2*waveLength)) % (pi/2)) * (maxVal-minVal) + minVal

#SAWTOOTH (EXPONENTIAL) WAVE
(exp(2*pi*((frame+offset) % waveLength)/waveLength)-1)/exp(2*pi) * (maxVal-minVal) + minVal

#BOUNCE WAVE
abs(sin(pi*(frame + offset)/waveLength))* (maxVal-minVal) + minVal

#BLIP
((frame+(offset+waveLength)) % (waveLength+blipLength)/(waveLength)) *(waveLength/blipLength) - (waveLength/blipLength) >= 0 ? maxVal : minVa

#SINEBLIP
((int((frame+offset) % waveLength)) >= 0 ? ((int((frame+offset) % waveLength)) <= (0+(blipLength-1)) ? ((sin(pi*((frame+offset) % waveLength)/blipLength)/2+1/2) * (2*maxVal-2*minVal) + (2*minVal-maxVal)) : minVal)  : minVal)


  • TCL:
#MATH FUNCTIONS
#TCL

#RETURNS THE ABSOLUTE VALUE OF THE FLOATING-POINT NUMBER X.
abs (x)

#ROUND X UP TO THE NEAREST INTEGER.
ceil (x)

#ROUND X DOWN TO THE NEAREST INTEGER.
floor (x)

#ROUND X TO THE NEAREST INTEGER NOT LARGER IN ABSOLUTE VALUE
int (x)

#ROUND X TO THE NEAREST INTEGER
rint (x)

#RETURN X CLAMPED TO [0.0 ... 1.0].
clamp (x)

#RETURNS THE COSINE OF X.
cos(x)

#RETURNS THE SINE OF X.
sin (x)

#RETURNS A POINT ON THE LINE F(X) WHERE F(0)==A AND F(1)==B. MATCHES THE LERP FUNCTION IN OTHER SHADING LANGUAGES.
lerp (a, b, x)

#RETURNS THE Y VALUE OF THE ANIMATION CURVE AT THE GIVEN FRAME
curve (frame)
rotate(frame)

#RETURNS THE CURRENT FRAME
frame

#CONVERT THE ANGLE X FROM RADIANS INTO DEGREES
degrees (x)

#CONVERT THE ANGLE X FROM DEGREES INTO RADIANS
radians (x)

#RETURN THE GREATEST OF ALL VALUES
max (x, y, ... )

#RETURN THE SMALLEST OF ALL VALUES
min (x, y, ... )

#RETURN THE VALUE FOR PI (3.141592654...)
pi

#RETURNS THE VALUE OF X RAISED TO THE POWER OF Y.
pow (x, y)

#RETURNS THE NON-NEGATIVE SQUARE ROOT OF X.
sqrt (x)

#EVALUATES THE Y VALUE FOR AN ANIMATION AT THE GIVEN FRAME
value (frame)




10. FUNCTIONS def()

  • PYTHON:
#SINTAX
def function_name( parameters ):
"function_docstring"
function_suite
return [expression]

#EXAMPLE
def printme( str ):
"This prints a passed string into this function"
print str
return

def sum(a, b)
c = a+b 
return c
---------------------
print "the sum is " + sum(10, 5)




11. CALLBACKS

  • PYTHON:
#CALLBACKS

#----------------------------------------------------------------
#KNOB CHANGED

#SINTAX
#copy this in the Script Editor in Nuke, select your node (or subsistute nuke.selectedNode() with nuke.toNode("NodeName")) and launch the script
#Example 01

nuke.selectedNode().knob('knobChanged').setValue("
nk = nuke.thisNode()
k = nuke.thisKnob()
if ('rotate' in k.name()):
#YOUR CODE")


#EVERY TIME THAT ROTATE WILL CHANGE, IT WILL EXECUTE YOUR CODE
#THIS WAS JUST AN EXAMPLE, IN YOUR SCRIPT EDITOR USE THIS VERSION WITH \N FOR A NEW LINE
nuke.selectedNode().knob('knobChanged').setValue("nk = nuke.thisNode()\nk =nuke.thisKnob()\nif ('rotate' in k.name()): #YOUR CODE")

#----------------------------------------------------------------
#EXAMPLE 02
#TO AVOID THE \N TO EVERY LINE, JUST USE """
nuke.selectedNode().knob('knobChanged').setValue("""
nk = nuke.thisNode()
k = nuke.thisKnob()
if ('gain' in k.name()):
print 'ciao'
""")

#----------------------------------------------------------------
nuke.selectedNode()['knobChanged'].setValue("if nuke.thisKnob().name() == 'inputChange': print 'input has Changed'")

#REMEMBER TO USE THE ' ' INSTEAD OF " " INSIDE THE PYTHON CODE

#----------------------------------------------------------------
#ON CREATE
nuke.selectedNode().knob('onCreate').setValue("nk = nuke.thisNode()\nk = nk['first_frame']\nk.setValue(nuke.frame())")




12. CUSTOM PANELS

  • PYTHON:
CUSTOM PANELS

#----------------------------------------------------------------
pan = nuke.Panel('test')
choices = 'fistchoice secondchoice thridchoice'
pan.addEnumerationPulldown('choice:', choices)
pan.show()




13. TRICKS

  • PYTHON:
TRICKS

#-----------------------------------------------------------------------------
#IN CASE YOU WOULD LIKE TO SWITCH THE ANTIALIASING INSIDE A SCANLINE RENDERER TO “HIGH” WHEN rendering on the farm, but keep working in the GUI with “none”, you could use a line like this:
nuke.selectedNode()['antialiasing'].setExpression('$gui? 0:3')

#-----------------------------------------------------------------------------
TCL:
in Transform1.filter {set_expression {Transform2.filter}}

PYTHON:
k=nuke.toNode('Transform1')['filter']
k.setExpression('Transform2.filter',0)

#-----------------------------------------------------------------------------
#SWITCH NODE CHANGE ONLY IN THE FRAMES IN THE LIST
# If you use this inside a Switch Node, it can change value only in those frames
nuke.frame() in [1025,1072,1074]

#CURRENT FRAME
print nuke.frame()

#GO TO FRAME x
nuke.frame(x)

#------------------------------------------------------------------------------------------
#AUTOLABEL

n = nuke.selectedNodes()
for p in n:
p['autolabel'].setValue("nuke.thisNode().name()")

#EXAMPLE01
#Try this with a Grade Node
n = nuke.selectedNodes()
for p in n:
p['autolabel'].setValue("nuke.thisNode().name() + \"\\n\" + '(' + str(nuke.thisNode()['white'].value()) + ')' ")

#EXAMPLE02
#Try this with a Blur Node
n = nuke.selectedNodes()
for p in n:
p['autolabel'].setValue("nuke.thisNode().name() + \"\\n\" + '(' + nuke.thisNode()['filter'].value() + ')' ")

#EXAMPLE03
#When you create a Blur node, every time you will see this autolabel
def BlurLabel():
n = nuke.thisNode()
if n.Class() == "Blur":
autoLabel = n.name() + (' big!' if n['size'].value()>100 else ' small')
if n['label'].value():
autoLabel = autoLabel + '\n' + str(n['size'].value())
return autoLabel
nuke.addAutolabel(BlurLabel)


Leave a comment