EXPRESSIONS & TCL Tips
This is a collection of different Expression and TCL snippets ( and some python and HTML).
I picked these from various sites, among from pages of talented TDs websites ( of which I provide a list of a few at the bottom of this page ). As it's said it is not a site explaining the Expression node, which if you're interested in I recommend you the Expressions 101 by Matt Estela and Pedro Andrade.
Feel free to use and share!
So what is Expression in Nuke anyway?
- Basically, programmatic commands that you can apply as parameters in Nuke.
What is TCL?
- Tcl or Tool Command Language (pronounced as `Tickle`) is a high-level, general-purpose, dynamic programming language. ( for more info here`s a Wikipedia link )
How to apply them?
- There are multiple ways, depends on what kind of expressions you want to use and for what purpose.
I recommend a few useful links from the Foundry`s website before you start to experiment with the snippets I collected:
Expressions on Transform
So let`s start applying some expressions!
I use a `Transform` node to show the result of the first snippets but the values it produces are the same in any node where you can add expression as the knob`s value.
And the first one should look like this:
( You can double click on the videos to make full screen )
## Adding frame number as a value
x: frame OR t OR x
y: frame OR t OR x
## Adding random number as a value ( the 'random()' generates numbers between 0 and 1 )
x: random()
y: random()
## To increase the amount of movement let's
multiply the value
x: random()*100
y: random()*100
## Adding sinus to an equation.
x: sin (frame)*100
y: sin (frame)*100
##Slow down with dividing the frame number
x: sin (frame/10)*100
y: sin (frame/10)*100
x: sin(frame/10)*500
rotate: sin(frame/10)*100
x: sin(frame/10)*500
rotate: cos(frame/10)*100
x: sin(frame/10)*500
rotate: cos(sin(frame/10))*100
## Movement in a circle clockwise
x: sin(frame/5)*100
y: cos(frame/5)*100
## Movement in a circle counterclockwise
x: cos(frame/5)*100
y: sin(frame/5)*100
Displaying knob value
size: [value size]
A channels: [value Achannels]
B channels: [value Bchannels]
Range: [value range]
Range A: [value range.A]
Range B: [value range.B]
Mode: [value mode]
RGB: [value red], [value green], [value blue]
Gain: [value white]
[value first_frame] - [value last_frame]
Format expressions
## Using the input format values
x: input.format.x
y: input.format.y
r: input.format.r OR input.width OR input.w
t: input.format.t OR input.height OR input.h
## Using the input format in Reformat node. ( Only works if connected node has format information like Read node )
input.format
## Using the root values ( root values are the ones in the Project Settings which you see on the Properties if you press S on the Node Graph )
x: root.format.x
y: root.format.y
r: root.format.r OR root.width OR root.w
t: root.format.t OR root.height OR root.h
## Using a root value in a Reformat node.
root.format
## Using the bounding box values
x: bbox.x
y: bbox.y
r: bbox.r OR bbox.width
t: bbox.t OR bbox.height
Frame expressions
## To return current frame value
frame OR t OR x
## Using range values from input.
input.first_frame
input.last_frame
## Using range values from root.
root.first_frame
root.last_frame
Useful Conditional expressions
## If frame number is lower than 1010 value is 0 else 100.
frame < 1010 ? 0 : 100
## If 'Transform1' translate.x value is 100 the value is 500 else 0
[if {[value Transform1.translate.x]==100} {return "500"} {return "0"}]
## If frame number is 100 the value is 500 else 0
[if {[frame]==100} {return "500"} {return "0"}]
## If knob 'test' is '0' return "hi" else "bye" - with TCL
[if {[numvalue parent.test] == 0} {return "hi"} else {return "bye"}]
[python -eval {"hi" if nuke.thisParent()['test'].array()[0] else "bye"}]
## If Text1 node's 'message knob has "Notes:" feature the note else leave empty.
[python -eval {nuke.toNode("Text1")["message"].value().split("Notes:")[1].split("\n")[0] if "Notes:" in nuke.toNode("Text1")["message"].value() else "" }]
Conditional expressions for 'disable' knob
## If frame number is greater than 1010 value is 1 ( = node is disabled )
frame > 1010
## Between frame 1010 and 1015 value is 1 ( = node is disabled )
inrange (frame, 1010, 1015)
## You can also add multiple ranges
( formula: inrange (frame, start, end, start, end, start, end) )
inrange (frame, 1010, 1015, 1025, 1035)
## Gui ( Graphic User Interface ) returns 1 ( = node is disabled ) when Nuke is running. It works well on heavy nodes when you run your render on a renderfarm.
$gui
## When the script is in use returns 1 else 12.
$gui ? 1 : 12
TIP: You can use $gui in a Switch node putting heavy nodes like Defocus on input 1 and Blur can be used while working on input 0.
For more about $gui click here.
## True if the name item exists. ( Useful for gizmos with mask input )
![exists parent.input1]
You can find more conditional TCL functions here.
Changing knob values
[knob Blur15.size 200]
After you call a knob function you need to define the node`s then the knob`s name before you give a new value to it.
[knob Blur13.size Blur_CONTROL_2.size*3]
[knob Blur13.channels rgb]
[knob Blur13.mix .8]
You can also define multiple values from one node and can use expressions as value.
[knob rotate frame]
You can also add expression as a value like frame here that returns the
current frame number.
## Setting keyframe value with setkey
[setkey this.size 34 2]
If you want to set a keyframe in a different node use the node`s name instead of this.
After defining the knob the first number is the frame number the second is the value.
Displaying input's name
## Showing single input
Input: [value input.name]
## Showing multiple inputs using input's
Input B: [value input0.name]
Input A: [value input1.name]
## Showing all inputs with python
[python {"\n".join(["Input: %s" % node.name() for node in nuke.thisNode().dependencies()])}]
Displaying pixel value
# In the ColorWheel
R: [sample [node ColorWheel5] red 1075 378]
G: [sample [node ColorWheel5] green 1075 378] B: [sample [node ColorWheel5] blue 1075 378]
# In the Grade:
R: [sample [node this] red 1075 378]
G: [sample [node this] green 1075 378]
B: [sample [node this] blue 1075 378]
A: [sample [node this] alpha 1075 378]
Here again, you can call a node by name or with this.
After you define the channel the first number is from the X axis the second from the Y axis.
Formatting
# Setting the number of decimals
Size: [format %.1f [value size]]
# Setting the number of characters
Filter: [format %.5s [value filter]]
You can find out more about the format function here.
Displaying different values
## Showing layers
layers: [layers this]
## Showing channels
Channels: [channels this]
## Showing node
Node: [node this]
## List of knobs
Knobs: [knobs this]
## List of values
Values: [values this]
All values: [values -a this]
Non-default values: [values -d this]
## Node info - same list of information that comes up when you select
a node and press i or nukescripts.getallnodeinfo() with python.
Info: [show_info]
## Returns number of inputs
Inputs: [inputs this]
## Returns list of all plugins
Plugins: [plugins]
## Returns list of all formats
Formats: [formats]
## Returns the full name, when used in Group returns with name of Group
Full name: [full_name this]
## Dependent_nodes returns list of nodes that are connected via expression
Can use the lindex function to select item from the list.
Dependent node: [value [lindex [dependent_nodes this] 0].name]
## Dependencies returns list of nodes that are connected via inputs
Dependency: [value [lindex [dependencies this] 2].name]
## Returns filename when knob exist on node
[filename this]
Using variables
## Setting a variable
[set var1 25]
In the example above with using 'set' you can add the first argument 'var1' that is the variable and then the value '25' that it stores.
## Calling the variable
$var1
With $ before the name of the variable you can add the stored value -
In this case it is 25. You also don't need the square brackets '[ ]' here!
When assigning value you can sample a knob value too.
[set transX [value translate.x]]
$transX
When using the variable can also use the 'knob' function.
[set transX [value translate.x]]
[knob size $transX]
You can also apply mathematical functions on the numerical values.
[set transX [value translate.x]]
sin($transX * 5)
When using a different node to sample for the variable it will
be connected with an expression line! (It is green by standard but you can
change in the Preferences)
[set shotName1 [file tail [value Read1.file]]]
shot1 : $shotName1
You can also apply other functions on the stored strings.
[set shotName1 [file tail [value Read1.file]]]
shot1 : [string tolower $shotName1]
shot1 : [lrange [split $shotName2 _] 0 1]
Changing node's colour
## Changing node`s tile color with changing knob`s value.
[knob tile_color [value which]]
This one is for a Switch node that`s why it calls a`which` knob but you can use it with most knobs that generates numbers.
## Changing node`s tile color for 0 and 1.
[knob tile_color [ expr { [value which]? 814350335 : 4284416255 }]]
Displaying all root info
Root info
name: [value root.name]
project directory: [value root.project_directory]
frame range: [value root.first_frame] - [value root.last_frame]
fps: [value root.fps]
format: [value root.format]
proxy mode: [value root.proxy_type]
proxy scale: [value root.proxy_scale]
read proxy files: [value root.proxySetting]
color management: [value root.colorManagement]
OCIO config: [value root.OCIO_config]
monitor: [value root.monitorLut]
8bit files: [value root.int8Lut]
16bit files: [value root.int16Lut]
log files: [value root.logLut]
float files: [value root.floatLut]
views: [value root.views]
Commands for Text node
## Showing all metadata's name (value not included) ##
[metadata]
## Showing certain metadata ##
Input/timecode: [metadata input/timecode]
Input/ctime: [metadata input/ctime]
Input/filesize: [metadata input/filesize]
Input/filereader: [metadata input/filereader]
## Showing date in different ways ##
[clock format [clock seconds]]
[date]
## Showing frame number in different ways ##
Frame: [value frame]
Frame: [python {nuke.frame()}
## Getting value with Node`s name ##
Node name: [value Read15.name]
File name: [lrange [split [basename [value [topnode].file]] .] 0 0]
File: [value Read15.file]
Format: [value Read51.format]
Frame Range: [value Read15.origfirst] - [value Read15.origlast]
Colorspace: [value Read15.colorspace]
## Breaking down values ##
Root dir: [file dirname [knob [topnode].file]]
File name: [file tail [knob [topnode].file]]
Shot name: [lrange [split [file tail [knob [topnode].file]] _ ] 0 1 ]
File extension: [file extension [knob [topnode].file]]
## Show filtered metadata (value not included) ##
[metadata keys *time*]
## Time and Date in TCL ##
[date %%] a literal %
[date %a] weekday name (Sun..Sat)
[date %A] full weekday name (Sunday..Saturday)
[date %b] abbreviated month name (Jan..Dec)
[date %B] full month name (January..December)
[date %c] Unix style (Sat Nov 04 12:02:33 EST 1989)
[date %d] day (01..31)
[date %D] date (mm/dd/yy)
[date %e] day of month, blank padded ( 1..31)
[date %h] same as %b
[date %H] hour (00..23)
[date %I] hour (01..12)
[date %j] day of year (001..366)
[date %k] hour ( 0..23)
[date %l] hour ( 1..12)
[date %m] month (01..12)
[date %M] minute (00..59)
[date %p] AM or PM
[date %r] time, 12-hour (hh:mm:ss [AP]M)
[date %s] Unix seconds [date %S] second (00..60)
[date %T] time, 24-hour (hh:mm:ss)
[date %U] week number with Sunday as first day of week (00..53)
[date %V] week number with Monday as first day of week (01..53)
[date %W] week number with Monday as first day of week (00..53)
[date %w] day of week (0..6), Sunday = 0
[date %x] (mm/dd/yy)
[date %X] time, 24-hour (hh:mm:ss)
[date %y] year (00..99)
[date %Y] year (1970..)
[date %z] RFC-822 style numeric timezone (-0500)
[date %Z] time zone (e.g., EDT)
You can find more TCL functions that are useful in Text nodes HERE.
Display metadata
[metadata]
Display all metadata keys
[python {"/n".join(nuke.thisNode(). metadata())}]
Display all metadata keys with python
[metadata input/timecode]
Display specific metadata's value
[python {nuke.thisNode(). metadata().get("input/timecode")}]
Display specific metadata's value with python
[metadata keys *time]
Display filtered metadata keys ( ones that end with "time" here )
[python -exec {
timeMetas = []
for i in nuke.thisNode().metadata():
if i.endswith("time"):
timeMetas.append(i)
timeMeta = ('\n '.join(timeMetas))
}] [python timeMeta]
Display filtered metadata keys with python ( ones that end with "time" here )
[metadata keys]
Display all metadata keys
[metadata values]
Display all metadata keys with values
[metadata -s "\n " keys input/*]
Display filtered metadata keys with custom separator ( ones that starts with "input/" here )
[metadata -v ": " values]
Display metadata keys with values using custom separator
[metadata -v ": " values *time*]
Display filtered metadata keys with values using custom separator
( ones that includes "time" here )
[metadata -n Read15 values]
Display metadata keys with values from specific node
[metadata -n Read15 input/timecode]
Display metadata value from specific node
Referencing Foundry page.
Adding images / emojis to nodes with html
<img src= "Shuffle.png">
You can add the image of any default node icon by putting its name instead of the `Shuffle`.
<img src= "D:/gatimedia_white_logo.png">
You can also add any image to a label, just copy the path between the quotation marks.
Even more fun is that you can use emojis in Nuke!
In this example I added the code to the Text knob
<p style="font-size:100px">🦁</p>
The code is from here where you can find a lot more codes for different emojis.
There is a site also for smiley emojis and for different skin tones!
In this fomula you can adjust the size ( which is 100px here ),
and which emoji you want to display by changing the decimal code ( which is 129409 here ).
<p style="font-size:100px">🤘🏿</p>
For changing the skin tone you need to use two decimal codes - first for the type of emoji and the second one for the skin tone.
<p>I will display 🦁</p>
Can also use the decimal code without setting the size and it will be the size of the text.
Make sure you define the paragraph before and after ( <p> - start, and </p> - end ),
otherwise it will only appear as a text.
You can also add emojis to the label but it might won't look as expected.
Also can use them as name of the user knobs.
Text editing with html
## Center ##
<center>Lorem Ipsum</center>
## Italic ##
<i>Lorem Ipsum</i>
## Strikethrough ##
<s>Lorem Ipsum</s>
## Changing font colour with Hex code ##
<font color=#582b00>Lorem Ipsum</font>
## Superscript ##
Lorem <sup>Ipsum</sup>
## Align text to the right 1 ##
<p style="text-align:right">Lorem Ipsum</p>
## Strong ##
<strong>Lorem Ipsum</strong>
## Small ##
<small>Lorem Ipsum</small>
## Bold ##
<b>Lorem Ipsum</b>
## Underline ##
<u>Lorem Ipsum</u>
## Font size ##
<font size="5">Lorem Ipsum</font>
## Changing font colour with colour`s name ##
<font color=aqua>Lorem Ipsum</font>
## Subscript ##
Lorem <sub>Ipsum</sub>
## Align to the right 2 ##
<p align="right">Lorem Ipsum</p>
## Big ##
<big>Lorem Ipsum</big>
## Emphasized ##
<em>Lorem Ipsum</em>
## Headers ##
<h1>Lorem Ipsum</h1>
<h2>Lorem Ipsum</h2>
<h3>Lorem Ipsum</h3>
<h4>Lorem Ipsum</h4>
<h5>Lorem Ipsum</h5>
Lorem Ipsum
## Adding a link to a node using a Text knob ##
<a href="https://www.gatimedia.co.uk/">Visit my page!</a>
Environment variables
## Using python in the script editor to print all env variables ##
import os
for k,v in sorted(os.environ.items()):
print (k,": ",v)
You can find out more about how to use python snippets HERE.
## Using TCL to print all env variables ##
[array get env]
## Search in the array
[array get env *NUKE*]
## Using TCL to print specific env variable ##
[getenv NUKE_TEMP_DIR]
Useful links
If you want to dig deeper into the wonderful ( and often frustrating ) world of TCL commands in Nuke you should visit Nuke TCL Scripting Documentation.
Hope you will find it useful!