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]]]

#---------------------------------------------------------------------
#RELATIVE PATH
#In the Read node you can use the relative path for your footage/Obj

#In your Read Node in the knob "file", use this:

#Read file "render.exe" in the same folder of your file nuke 
[python {nuke.script_directory()}]/render.exr

#Read file "render.exe" in the subfolder where your file nuke is  
[python {nuke.script_directory()}]/folder/render.exr

#Read file "render.exe" in the subfolder of your .nuke folder  
[python {"/Users/gere/.nuke} ]/folder/render.exr



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
#The 'for loop'
for node in nuke.allNodes():
	#Attribute 'selected' becomes True
	node['selected'].setValue(True) 

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

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


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

#-------------------------------------------------------------------------------------
#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()
	#Add the value to the list
	array.append(n) 
	#print the list
	print array 

#---------------------------------------------------------------------------------------
#DESELECT ALL SELECTED NODES
if nuke.selectedNodes():
	for i in nuke.selectedNodes():
		i['selected'].setValue(False)
		
#---------------------------------------------------------------------------------------		
#####################################################
############GET NODES FROM A GROUP:##################
#####################################################
#1. FIRST EXAMPLE
myGroup = nuke.selectedNode()
if myGroup.Class() == "Group":
    for j in myGroup.selectedNodes():
        print j.name()	
        
        
#2. OR ANOTHER WAY IS:        
with nuke.toNode( 'MyGroup' ):
	print nuke.allNodes()
	
	
	
#3. THIS IS THE WAY I USED IN MY ColorPanel code:
#nuke.selectedNode().selectedNodes()

		try:
		nodeSelected = nuke.selectedNode()
		if (nodeSelected.Class() == "Group" and nodeSelected.selectedNodes()):
			#if node selected is a group, then check if anything is selected inside
			nuke.message("Changing color of Nodes inside Group: " + nodeSelected.name())
			nodeSelected = nodeSelected.selectedNodes()
		else:
			nodeSelected = nuke.selectedNodes()
	except:
		nuke.message("SELECT A NODE.\nIf you want to change color of Nodes inside a Group, please select also the Group in the Node Graph.")



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()
	
#-------------------------------------------------------------------------------------
#CONNECT knob inside a Group with a knob in the Group
knob = nuke.toNode("NameGroup.NameNode").knob("KnobNode")
knob.setExpression("parent.knobGroup", 0)

#CONNECT Pulldown Choice (for example Filter) inside a Group
knob = nuke.toNode("NameGroup.NameNodeDestination").knob("filter")
knob.setExpression("NameNodeOrigin.filter", 0)



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()
#-------------------------------------------------------------------------------
#READ / EXECUTE KNOB OF A NODE INSIDE GROUP
n=nuke.thisNode()
n.node('CurveTool')['go'].execute()





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())
#--------------------------------------------------------------------------------

#Knob VISIBLE/INVISIBLE
n = nuke.selectedNode()
n['knob'].setVisible(False)



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 INTEGER KNOB with SLIDER
n = nuke.selectedNode()
knob = nuke.Double_Knob("test","test")

#This is a Flag
#http://www.nukepedia.com/python/some-flags
knob.setFlag(0x0000000000000008)

n.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()

#------------------------------------------------------------------------------------------------
#*******************************************************************
#***************   EXAMPLE with Corner Pin Node   ******************
#*******************************************************************

#setKeyframe at the current frame to all knobs 'TO'
n = nuke.thisNode()

#save current values
knob_to1 = n['to1'].getValue()
knob_to2 = n['to2'].getValue()
knob_to3 = n['to3'].getValue()
knob_to4 = n['to4'].getValue()

#create Animation to all the knobs
n['to1'].setAnimated()
n['to2'].setAnimated()
n['to3'].setAnimated()
n['to4'].setAnimated()

#create keyframe at the current frame with the current value
n['to1'].setValue(knob_to1)
n['to2'].setValue(knob_to2)
n['to3'].setValue(knob_to3)
n['to4'].setValue(knob_to4)	



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. CHECK NUKE VERSION
[python {nuke.thisNode().knob(\'rotate\').value()}]
[if {[python nuke.NUKE_VERSION_MAJOR]<10} {return [11]} {return 10}]
[if {[python nuke.NUKE_VERSION_MAJOR]<10} {return "CornerPin2D.copy_from"} {return "CornerPin2D.copy_from_to"}]

#GET NUKE VERSION
if nuke.NUKE_VERSION_MAJOR < 11:
	#nuke <= 10
else:
	#nuke >= 11
	
#TCL IN PYTHON
nuke.tcl('return '+nuke.selectedNode()['filter'].value())
  • TCL:
  • Use this link to check Expressions with TCL



  • 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)
    
    #------------------------------------------------------------
    #RELATIVE PATH FILE
    #This will set the project_directory path to the same one where the Nuke script is stored
    
    [python {nuke.script_directory()}] 
    

Leave a comment