Archives

Tiny Python Scripts

Here is an ever expanding collection of small yet useful Python scripts for Nuke:

Show all Plugin Paths

1
nuke.pluginPath()

Random Card X Pos

1
2
3
4
5
6
7
import nuke
import random
for i in nuke.selectedNodes('Card2'):
	p = i['translate'].getValue()
	p = p[2]
	t = [random.randint(1,101),0,p]
	i['translate'].setValue(t)

Disable all but selected Write Nodes

1
2
3
4
5
6
7
8
9
10
import nuke
def write_off():
	nodeClasses = ['Write','WriteTank']
	this_write = [i for i in nuke.selectedNodes() if i.Class() in nodeClasses]
	those_writes = [i for i in nuke.allNodes() if i.Class() in nodeClasses]
	for i in those_writes:
		i['disable'].setValue(1)
	for i in this_write:
		i['disable'].setValue(0)
write_off()

Label for the DeepWrite Node (callback – put in init.py)

1
2
3
4
5
6
7
8
9
10
11
12
13
def deepName():
    sel = nuke.selectedNode()
    Ftype = sel['file'].getValue()
    if sel.Class() == 'DeepWrite':
        Fname = Ftype
        Fname = os.path.basename(Fname)
        Fname = Fname.split('.')[0]
        sel['label'].setValue(Fname)
    elif sel.Class() != 'DeepWrite':
        Fname = ''
    else:
        pass     
nuke.addKnobChanged(deepName, nodeClass="DeepWrite")

Scale Transforms by 20%

1
2
3
4
5
6
def TransX(scaler):
	for i in nuke.selectedNodes('Transform'):
		ScaleX = i['scale'].getValue()
		ScaleX = ScaleX * scaler
		i['scale'].setValue(ScaleX)
TransX(1.2)

Current frame on Frame Hold creation
Written by Frank Rueter from Nukepedia – add to menu.py

1
nuke.addOnUserCreate(lambda:nuke.thisNode()['first_frame'].setValue(nuke.frame()), nodeClass='FrameHold')

Auto Create Directory
Written by Julien Chandelle from Nukepedia – add to menu.py

1
2
3
4
5
6
7
8
9
10
def CreatePath():
   file = nuke.filename(nuke.thisNode())
   dir = os.path.dirname(file)
   osdir = nuke.callbacks.filenameFilter(dir)
   try:
      os.makedirs (osdir)
   except OSError:
      pass      
 
nuke.addBeforeRender(CreatePath, nodeClass = 'Write')

Get Node Tile Colour

1
2
3
for i in nuke.selectedNodes(): 
        color = i['tile_color'].getValue() 
print int(color)

Convert Hex colours to Nuke script values
Sites like http://paletton.com/ have a great online picker tool

1
int('00ff0000', 16)

PostageStamp tool 3
Same as the other one but detects anything named deNoise and changes the colour.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import nuke
import os
 
def postNamer():
    for i in nuke.selectedNodes('PostageStamp'):
        firstInput = i.input(0)
        if firstInput.Class() == 'Read':
            Fname = nuke.filename(firstInput)
            Fname = os.path.basename(Fname)
            Fname = Fname.split('.')[0]
            loName = Fname.lower()
        elif firstInput.Class() != 'Read':
            Fname = ''
        Ilabel = firstInput['label'].getValue()
        FiLabel = Fname + '  ' + Ilabel
        if firstInput is not None: 
            i['label'].setValue(FiLabel) 
            i['hide_input'].setValue(1) 
            i['tile_color'].setValue(12345678910111213) 
        elif firstInput is not None and 'denoise' in loName:
            i['tile_color'].setValue(888888)  
        else:
            pass
#postNamer()

GPU and Render setting dual state
A is the number in GPU version of Nuke and B is for Render only Nuke.

1
($gui?A:B)

Time Offset value in Label (okay, it’s TCL)

1
[value this.time_offset]

Disable ‘Bookmark’ in all Backdrop Nodes

1
2
3
4
5
for i in nuke.allNodes('BackdropNode'):
    try:
        i['bookmark'].setValue(0)
    except:
        pass

Relative to Absolute file path converter

1
2
3
4
5
6
7
8
import nuke
import os
for i in nuke.selectedNodes():
    Fname = nuke.filename(i)
    try:
        i['file'].setValue(Fname)
    except:
        pass

Postage stamp renamer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import nuke
import os
 
def postNamer():
    for i in nuke.selectedNodes('PostageStamp'):
        firstInput = i.input(0)
        if firstInput.Class() == 'Read':
            Fname = nuke.filename(firstInput)
            Fname = os.path.basename(Fname)
            Fname = Fname.split('.')[0]
        elif firstInput.Class() != 'Read':
            Fname = ''
        Ilabel = firstInput['label'].getValue()
        FiLabel = Fname + '  ' + Ilabel
        if firstInput is not None: 
            i['label'].setValue(FiLabel) 
            i['hide_input'].setValue(1) 
            i['tile_color'].setValue(12345678910111213) 
        else: 
            pass
postNamer()

Set Label in Tracker to current Transform Type (add to init.py)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def Tlabel():
    try:
        sel = nuke.selectedNode()
        Ttype = sel['transform'].getValue()
        if Ttype == 0:
            sel['label'].setValue('')
        elif Ttype == 1:
            sel['label'].setValue('STABILIZE')
        elif Ttype == 2:
            sel['label'].setValue('STABILIZE 1pt')
        elif Ttype == 3:
            sel['label'].setValue('MATCH-MOVE')
        elif Ttype == 4:
            sel['label'].setValue('MATCH-MOVE 1pt')
        elif Ttype == 5:
            sel['label'].setValue('REMOVE JITTER')    
        elif Ttype == 6:
            sel['label'].setValue('ADD JITTER')    
        else:    
            pass
    except:
        pass
nuke.addKnobChanged(Tlabel, nodeClass="Tracker4")

Delete everything except Read Nodes

1
2
3
for i in nuke.allNodes():
    if i.Class() != 'Read':
         nuke.delete(i)

Controls for enabling/disabling RSMB nodes in GUI and render

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import nuke
 
def disableGui( nodetype ):
    for a in nodetype:
        a['disable'].setExpression('$gui')
 
def enableGui( nodetype ):
    for a in nodetype:
        a['disable'].clearAnimated()
        a['disable'].setValue(0)
 
def disableRender( nodetype ):
    for a in nodetype:
        a['disable'].clearAnimated()
        a['disable'].setValue(1)
 
def menu():
    nodeArray = []
    p = nuke.Panel('RSMB GUI controls')
    p.addEnumerationPulldown('RSMB GUI', 'Enabled Disabled_GUI Disabled_Render')
    p.addBooleanCheckBox('selected Nodes Only', False)
    p.show()
 
    if p.value('selected Nodes Only') == True:
        nodeArray = nuke.selectedNodes('OFXcom.revisionfx.rsmb_v3')
    else:
        nodeArray = nuke.allNodes('OFXcom.revisionfx.rsmb_v3')
 
    if p.value('RSMB GUI') == 'Enabled':
        enableGui( nodeArray )
    elif p.value('RSMB GUI') == 'Disabled_GUI':
        disableGui( nodeArray )
    elif p.value('RSMB GUI') == 'Disabled_Render':
        disableRender( nodeArray )
menu()

Random colour on selected nodes (okay maybe not super useful but you never know!)

1
2
3
4
5
6
7
8
9
10
11
12
import random
 
def totesRandom():
    r = (float(random.randint( 20, 40)))/100
    g = (float(random.randint( 10, 50)))/100
    b = (float(random.randint( 15, 60)))/100
    hexColour = int('%02x%02x%02x%02x' % (r*255,g*255,b*255,1),16)
    hexColour = hexColour +11010000
    return hexColour
 
for a in nuke.selectedNodes():
    a['tile_color'].setValue(totesRandom())

Copy a ‘Read’ node path to clipboard from selection and convert it to work in Windows.
Now works with Nuke 11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os
import nuke
try:
    nuke.NUKE_VERSION_MAJOR < 11
    import PySide.QtGui as QtGuiWidgets
except:
    nuke.NUKE_VERSION_MAJOR >= 11
    import PySide2.QtWidgets as QtGuiWidgets
 
def run():
    if len(nuke.selectedNodes()) == 1:
        clipboard = QtGui.QApplication.clipboard() 
        if nuke.selectedNode().Class() == 'Read':
            readFile = nuke.selectedNode()['file'].getValue()    
            readFile = readFile.replace ( '/' , '\\' )
            readpath = os.path.dirname(readFile)
            clipboard.setText(readpath) # set clipboard 
    else:
        nuke.message('Please select a read node')

Determine Node Class

1
nuke.selectedNode().Class()

Copy node label to other nodes(from first selected)

1
2
3
4
5
6
7
8
def copyLabel():
    sel = nuke.selectedNodes()
    first = sel.pop(-1)
    first = first['label'].getValue()
    for a in sel:
        a['label'].setValue(first)
    print first
copyLabel()

Reload all ‘Read’ nodes

1
2
for a in nuke.allNodes('Read'):
    a['reload'].execute()

Disable RotoPaint Nodes in GUI

1
2
3
if nuke.ask('Disable all RotoPaint Nodes GUI?'):
    for a in nuke.allNodes('RotoPaint'):
        a['disable'].setExpression('$gui')

Inherit tile colour from connected node

1
2
3
4
5
6
7
for i in nuke.selectedNodes(): 
        firstInput = i.input(0) 
        color = firstInput['tile_color'].getValue() 
        if firstInput is not None: 
            i['tile_color'].setValue(int(color)) 
        else: 
            pass

Set before and after to ‘Black’ on all selected read nodes

1
2
3
for a in nuke.selectedNodes('Read'):
    a['before'].setValue('black')
    a['after'].setValue('black')

Print a list of the details of all selected Read nodes

1
2
3
for a in nuke.selectedNodes():
    if 'Read' in a['name'].value():
            print a['file'].value()

Delete all disabled nodes

1
2
3
4
for a in nuke.allNodes():
    if 'disable' in a.knobs():
        if a['disable'].value():
            nuke.delete(a)

Instance expressions to other nodes based on selection(select linked expression node first)

1
2
3
4
5
6
7
8
9
10
11
def exprCopy():
    selection = nuke.selectedNodes()
    master = selection.pop(-1)
    for name, knob in master.knobs().items():
        if knob.hasExpression():
            for select in selection:
                target = select.knobs().get(name)
                if target and (target.Class() == knob.Class()):
                    target.fromScript(knob.toScript(False))
 
exprCopy()

Set frame range to selected ‘Write’ nodes from 1-170 frames:

1
2
3
4
for a in nuke.selectedNodes('Write'):
    a['use_limit'].setValue(1)
    a['first'].setValue(1)
    a['last'].setValue(170)

Set blur size on all selected ‘Blur’ nodes to match first selected ‘Blur’ Node (and it’s node colour):

1
2
3
4
5
6
7
8
9
def copyBlur():
  selection = nuke.selectedNodes()
  master = selection[-1]
  for i in selection:
    if i.Class() =='Blur':
        i.knob('tile_color').setValue(master.knob('tile_color').value())
        i.knob('size').setValue(master.knob('size').value())
 
copyBlur()

Copy colour from ‘Backdrop Node’ to other selected

1
2
3
4
5
6
7
8
def copyColor():
  selection = nuke.selectedNodes()
  master = selection[-1]
  for i in selection:
    if i.Class() =='BackdropNode':
        i.knob('tile_color').setValue(master.knob('tile_color').value())
 
copyColor()

Set ‘clip to’ to ‘bbox’ for selected ‘Roto’ nodes:

1
2
for a in nuke.selectedNodes('Roto'):
    a['cliptype'].setValue(1)

Archives

Refract to the Future

This is a short tutorial on how to use my Refract to the Future script. it’s very easy to use and probably doesn’t require a tutorial at all, but here it is anyway.

This script is designed to use a Vray Normal map to create a refraction like effect. I’ve not tested it on other renderers (arnold, mental ray etc.) so I’m not sure if it will work with them, so lets just assume you’re using Vray.

Vray seemed to be the odd one out as I had to invert various channels and not others to get it to work.

Download the gizmo from the scripts page on my site (here) and start nuke, when you load Refract_to_the_Future you will be have a few options:

Gain – affects the amount of distortion around the edges

Scale – affects the amount of distortion globally

Blur – adds blur to the edges of the normal map

Chromatic – adds chromatic aberration

Gamma – Translucency -Refraction Contrast Gain – Refraction Contrast Gamma – all these knobs control the ‘milkyness’ of the item being refracted to various degrees, play with them to see what they do!

Simply plug in the normal map into an image and there you have it!

teapots_normals

bizaro+normals

Note – ‘Bizaro’ model came from a free 3d model website and I don’t have the artist name, sorry about that. Also, any similarities to Robert Zemeckis ‘Back to the Future’ films is purely conincidental..