Skip to content

Instantly share code, notes, and snippets.

@jeremybep
Last active March 7, 2023 14:02
Show Gist options
  • Save jeremybep/d747de2537a958820ef6e1b473f66c56 to your computer and use it in GitHub Desktop.
Save jeremybep/d747de2537a958820ef6e1b473f66c56 to your computer and use it in GitHub Desktop.
Foundry nuke - snippets

Nuke Snippets

note

Faire un echo des commandes Python lancé par Nuke (à la Maya) :

Edit/Preferences>Onglet Script Editor>Cocher echo python commands to output window

Préférences

Modifier les préférences de Nuke

nuke.toNode('preferences')['CacheLimit'].value()
nuke.toNode('preferences')['CacheLimit'].setValue(75)

Le nom du knob peut être obtenu en plaçant le curseur sur dessus

Modifier les préférences du projet

nuke.root()['first_frame'].value()	# renvoi le numéro de la 1er frame
nuke.root()['first_frame'].setValue(101)
nuke.root().name() # nom de la comp
nuke.root()['fps'].setValue(int(25)) # ajout de la valeur 25 au fps
nuke.root()["lock_range"].value() # renvoi la valeur si la TL est lockée
nuke.root()["lock_range"].setValue(True)
# retour clean du nom de la comp :
import os
os.path.basename(nuke.root().name()).split('.')[0]

Les formats

 # liste des formats disponibles
nuke.formats()

# créer un format 
try:
    nuke.root()['format'].setValue( '6K_PRINT' )
except:
    SixK_format = "6993 3780 1 6K_PRINT"
    nuke.addFormat( SixK_format )
    nuke.root()['format'].setValue( '6K_PRINT' )
    print "6K_PRINT format added !"
    
    
#Obtenir le format d'un node    
myNodeFormat = nuke.toNode("Blur1").format()
myNodeFormat.name()	# renvoi le nom du format de l'image en entrée.
myNodeFormat.width()	# renvoi la largeur, en pixel, de l'image en entrée.
myNodeFormat.height()	# renvoi la heuteur, en pixel, de l'image en entrée.

Les nodes

Créer un node

nuke.createNode("Blur")
nuke.nodes.Blur()

note

La première version créé un node comme si l'utilisateur l'avait créé. En utilisant le "contexte". Exemple: Si un node est sélectionné, le nouveau node sera connecté au premier. Son panel sera affiché, etc...

La seconde méthode créé un node "dans le vide". Connecté a rien, pas de comportement particulier, juste un node.

Ne pas ouvrir le panel du node créé

nuke.createNode("Blur", inpanel=False )

Attribuer des valeurs lors de la création:

nuke.nodes.Blur(size=10)

Concaténer plusieurs valeurs lors de la création

new_cam = nuke.createNode('Camera2', 'file {} read_from_file {} frame_rate {} name {}'.format(file, 'True', int(25), 'Camera_shot' ))

Supprimer un node

nuke.delete(myNode)

Selectionner node

Evitez:

nuke.selectedNode()

Préférez:

nuke.selectedNodes()
nuke.toNode("node_name")
# ou si vous avez déjà la selection
n.knob('selected').setValue(True)

Qui revoit une bête liste dans l'ordre inversé de la sélection.

Savoir si un node est sélectionné

myNode.isSelected()	# True/False

Ajouter/Enlever le node a la sélection

myNode.setSelected(True)

Récupérer tous les nodes

nuke.allNodes()	# list tout les nodes du projet en cours
nuke.allNodes("Blur")	# list tout les nodes du projet en cours de class Blur
nuke.allNodes('Read')

#ou
for b in nuke.allNodes():
        if b.Class() == "Group"
        #ect
Example

Nombres de reader :

oReadNodes = nuke.allNodes('Read')
list = []
for i in oReadNodes:
    filetes = i["file"].value().split("/")[3]
    list.append(filetes)
list.sort()
print "-----------------------------"
print "nombre de lyr:", len(list)-1
for nb in list:
    print "--", nb

Nombre de channels (layers):

myNodes = nuke.selectedNode()
channels = myNodes.channels()
layers = list( set([c.split('.')[0] for c in channels]) )
layers.sort()
print layers

Récupérer le positionnement d'un node dans le graph

myNode.xpos()
myNode.ypos()
myNode.setXpos(30)
myNode.setYpos(30)
# ou 
myNode.setXYpos( int(n['xpos'].value(), int(n['ypos'].value()))

Paramètre des nodes

Lister les dict des attributs d'un node

myNode.knobs()

Attribuer des valeurs au knobs

myNode.knob("file").setValue(PATH_FILE)
myNode.knob("fbx_node_name").setValue(NODE_NAME)
myNode.knob("frame_rate").setValue(int(25))
myNode.hideControlPanel() # Bête refresh (cache)
myNode.showControlPanel() # Bête refresh (affiche)
myNode.knob('label').setValue("resized")
myNode.knob('note_font_color').setValue(16777215)

# Bref liste de couleurs...
# Red :4278190335
# Green : 16711935
# Blue : 65535
# Cyan : 16777215
# Magenta : 4278255615
# Yellow : 4294902015

# ajout d'une image sur le node
myNode.knob('label')setValue(''<img src="//icons/rtk.png">")
myNode["icon"].setValue("/path/to/an/icon.png")

# executer si il y a un button dans le node
myNode["reload"].execute()

Lister les connections

# fonctionne par index
myNode.inputs()	# liste les input
myNode.dependent() #liste les node enfants
myNode.dependencies() #liste les node parents
Example

inputs

myNode.setInput(0, nuke.toNode("merge"))
myNode.setInput(1, nuke.toNode("shuffle"))

Dependance

premultList = []
for reader in nuke.allNodes('Read') :
  for premult in reader.dependent():
    premultList.append(premult)

Les metadata

myNode = nuke.toNode(Reader)
myNodeMetadata = myNode.metadata()

note

Dans nuke, il n'est pas possible de paraméter un node en lisant les metadata à la volée. Il faut dans un premier temps lire, puis baker l'anim sur un node (camera, axis...)

Animation

# vérifier s'il y a un anim
myNode.knob('size').isAnimated()
# modifier une anim 
myNode.knob('size').setExpression("curve*3.5")
# créer un anim
myNode.setAnimated()
# récupérer une valeur d'anim
myNode['haperture'].valueAt(25, view='R')
# ajouter un valeur d'anim
myNode['haperture'].setValueAt('hap',frame)

TCL

Premiere image du node courant

[value this.first_frame]

Valeur du knob 'size' du node courant

[value this.size]

Nom du node parent

[value this.parent.input.name]

Récupérer le format du node

[value input.format.r]#width
[value input.format.t]#height

Récupérer le point #3 du "Bezier1" du node Roto1

[value Roto1.curves.Bezier1.curve_points.3.main.x]

Retourne la valeur de pixel d'échantillon du noeud Add1 en lisant le rouge à la position du bouton Center

[sample Add1 Red Center.x Center.y]

Relative path to script

[file dirname [value root.name]]/example.jpg

Chemin du script sans extension

[file rootname [value [topnode].file]]

fileName seul

[basename [value [topnode].file ]]

fileName seul, sans extension

[basename[file rootname [value [topnode].file]]]

condition:

[if {condition} {expr1} else {expr2}]
#for example:
[if {[value Switch1.which]==1} {return "aaa"} {return "bbb"}]

vérifier s'il y a une connection sur le node :

[exists this.input0]]
if nuke.thisNode().input(0) 

Lire les metadata

[metadata input/filename]

convertir les metadata de arnold pour afficher des infos

  • affiche heurs, min, sec d'un rendu
[format “%02d:%02d:%02d” [expr int([metadata exr/arnold/stats/time/render]/3600)] [expr int(fmod([metadata exr/arnold/stats/time/render]/60,60))] [expr int(fmod([metadata exr/arnold/stats/time/render],60))]]

note il n'est pas possible d'attribuer en temps réel les valeurs metadata sur un node. il est préférable de baker une anim

Animation en mode mirroir

curve(frame >= 50 ? 50-(frame-50): frame)

Expressions

infToAverage

$$isinf(r) ? ((r(x+1,y)+r(x+1,y+1)+r(x+1,y-1)+r(x,y+1)+r(x,y-1)+r(x-1,y+1)+r(x-1,y)+r(x-1,y-1))/8) : r isinf(g) ? ((g(x+1,y)+g(x+1,y+1)+g(x+1,y-1)+g(x,y+1)+g(x,y-1)+g(x-1,y+1)+g(x-1,y)+g(x-1,y-1))/8) : g isinf(b) ? ((b(x+1,y)+b(x+1,y+1)+b(x+1,y-1)+b(x,y+1)+b(x,y-1)+b(x-1,y+1)+b(x-1,y)+b(x-1,y-1))/8) : b$$

nanToAverage

$$isnan(r) ? ((r(x+1,y)+r(x+1,y+1)+r(x+1,y-1)+r(x,y+1)+r(x,y-1)+r(x-1,y+1)+r(x-1,y)+r(x-1,y-1))/8) : r isnan(g) ? ((g(x+1,y)+g(x+1,y+1)+g(x+1,y-1)+g(x,y+1)+g(x,y-1)+g(x-1,y+1)+g(x-1,y)+g(x-1,y-1))/8) : g isnan(b) ? ((b(x+1,y)+b(x+1,y+1)+b(x+1,y-1)+b(x,y+1)+b(x,y-1)+b(x-1,y+1)+b(x-1,y)+b(x-1,y-1))/8) : b$$

fixDeadPixel

ici ça corrige les pixels mort du canal vert

$$g>.99 ? (r(x,y+1) + r(x,y-1) + r(x-1,y) + r(x+1,y) )/4 g>.99 ? (g(x,y+1) + g(x,y-1) + g(x-1,y) + g(x+1,y) )/4 g>.99 ? (b(x,y+1) + b(x,y-1) + b(x-1,y) + b(x+1,y) )/4$$

Clamp Zdepth (bbox)

$$z==0?1000000:z$$

Normalize Zdepth

$$depth.Z==0?1000:1/depth.Z$$

Creat uv map

$$(x+0.5)/width (y+0.5) / height$$

uv to VECTOR

$$-x+r*width-0.5 -y+g*height-0.5$$

vector to uv

$$(r+x+0.5)/width (g+y+0.5)/height$$

Convert depth to point

$$(x/w-.5)*blue (y/h-.5)*blue$$

noise mapping (uv, Pref, ...)

$$fBm(r,g,b,10,1.3,1)$$

random

$$(random(seed, frame * frequency) * amplitude ) + offset$$

TIPS

Ajout d'html dans les label, ou notes :

< ! -- centre -- >
<center>Lorem Ipsum</center>

< ! -- Italic -- >
<i>Lorem Ipsum</i>

< ! -- barré -- >
<s>Lorem Ipsum</s>

< ! -- changer couleur via HEX -- >
<font color=#582b00>Lorem Ipsum</font>

< ! -- enum haut -- >
Lorem <sup>Ipsum</sup>

< ! -- Aligner sur la droite -- >
<p style="text-align:right">Lorem Ipsum</p>

< ! -- Strong -- >
<strong>Lorem Ipsum</strong>

< ! -- petit -- >
<small>Lorem Ipsum</small>

< ! -- gras -- >
<b>Lorem Ipsum</b>

< ! -- sous ligne -- >
<u>Lorem Ipsum</u>

< ! -- Font size -- >
<font size="5">Lorem Ipsum</font>

< ! -- changer couleur via nom (white, black, red, orange, blue...) -- >
<font color=aqua>Lorem Ipsum</font>

< ! -- enum basse -- >
Lorem <sub>Ipsum</sub>

< ! -- Aligner le script sur la droite -- >
<p align="right">Lorem Ipsum</p>

< ! -- Gros -- >
<big>Lorem Ipsum</big>

< ! -- Emphasized -- >
<em>Lorem Ipsum</em>

ouvrir une page web :

import webbrowser
webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open("http://google.com")

Possibilité de récupérer toutes les data du script :

nukescripts.get_script_data()

Jolie print technique dans une fenetre :

nuke.display("nukescripts.getallnodeinfo()", nuke.root())

Passer du code python via TCL dans le node "Text"

[python nuke.root()knob('name').value()]

Feinte pour pouvoir rafraichir un load ABC sur une camera ou un axis

new_filepath = '//server/data/file/camera.ABC'
orig_node=nuke.selectedNode()
# set knob flag NO_KNOB_CHANGED to avoid popup message
orig_node.knob("file").setFlag(0x00020000)
orig_node.knob("reload").setFlag(0x00020000)
# set new values for file path
orig_node.knob("read_from_file").setValue(True)
orig_node.knob("file").setValue(new_filepath)
orig_node.knob("reload").execute()
# remove previously set flag NO_KNOB_CHANGED
orig_node.knob("reload").clearFlag(0x00020000)
orig_node.knob("file").clearFlag(0x00020000)
# here is the trick to force Nuke node
# update his animation curves
orig_frame_rate=orig_node.knob("frame_rate").getValue()
orig_node.knob("frame_rate").setValue(12)
orig_node.knob("frame_rate").setValue(orig_frame_rate)

Créez une fausse map thermique

utilisez une couleurs présente dans une normal map, puis appliquer un ColorSpace et paramétrer le en HSV > sRGB

Ajoutez une image en temp que label

<img src="//server/misc/proj/icons/icon.png">

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment