Commandes de base (Nuke) : Différence entre versions

De FdWiki
Aller à : navigation, rechercher
m (add python button)
(petites corrections)
 
(47 révisions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
== Principe ==
 
 
Cette page a pour but de donner des exemples simples des commandes python les plus utilisées dans Nuke
 
Cette page a pour but de donner des exemples simples des commandes python les plus utilisées dans Nuke
  
 
== Préférences ==
 
== Préférences ==
 +
=== Modifier les préférences de Nuke ===
 +
<syntaxhighlight lang="python">
 +
nuke.toNode('preferences')['CacheLimit'].value()
 +
nuke.toNode('preferences')['CacheLimit'].setValue(75)
 +
</syntaxhighlight>
 +
Le nom du knob peut être obtenu en plaçant le curseur sur dessus:
 +
 +
[[Fichier:Nuke preferences cachelimit.png]]
 +
 +
=== Modifier les préférences du projet ===
 +
<syntaxhighlight lang="python">
 +
nuke.root()['first_frame'].value() # renvoi le numéro de la frame
 +
nuke.root()['first_frame'].setValue(101)
 +
</syntaxhighlight>
 +
 +
=== Les formats ===
 +
Les formats contiennent la résolution et la taille des pixels.
 +
 +
==== Obtenir la liste des formats disponibles ====
 +
<syntaxhighlight lang="python">
 +
nuke.formats()
 +
</syntaxhighlight>
 +
==== Modifier le format du projet ====
 +
<syntaxhighlight lang="python">
 +
nuke.root()['format'].value().name() # renvoi le nom du format
 +
nuke.root()['format'].value().setName("nomDuFormat")
 +
</syntaxhighlight>
 +
==== Et bien d'autres options ====
 +
<syntaxhighlight lang="python">
 +
nuke.root()['format'].value().width()
 +
nuke.root()['format'].value().height()
 +
</syntaxhighlight>
 +
 +
==== Obtenir le format d'un node ====
 +
<syntaxhighlight lang="python">
 +
nodeFormat = muNode.format()
 +
nodeFormat.name() # renvoi le nom du format de l'image en entrée.
 +
nodeFormat.width() # renvoi la largeur, en pixel, de l'image en entrée.
 +
nodeFormat.height() # renvoi la heuteur, en pixel, de l'image en entrée.
 +
</syntaxhighlight>
  
 
=== Faire un echo des commandes Python lancé par Nuke (à la Maya) ===
 
=== Faire un echo des commandes Python lancé par Nuke (à la Maya) ===
Ligne 12 : Ligne 51 :
 
== Les nodes ==
 
== Les nodes ==
  
Voir [[http://docs.thefoundry.co.uk/nuke/63/pythonreference/nuke.Node-class.html la doc de la classe Node]] pour plus d'informations:
+
Voir [http://docs.thefoundry.co.uk/nuke/63/pythonreference/nuke.Node-class.html la doc de la classe Node] pour plus d'informations:
  
 
=== Créer un node ===
 
=== Créer un node ===
Ligne 18 : Ligne 57 :
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.createNode("Blur")
 
nuke.createNode("Blur")
nuke.nodes.Blur() # déprécié on dirait
+
nuke.nodes.Blur()
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
D’après [http://docs.thefoundry.co.uk/nuke/63/pythondevguide/basics.html#creating-nodes-and-setting-their-controls la doc officielle]:
 +
* 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éé:
 
Ne pas ouvrir le panel du node créé:
Ligne 26 : Ligne 68 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== La selection ===
+
Setter les knobs d'un node a la création:
Eviter:
+
<syntaxhighlight lang="python">
 +
nuke.nodes.Blur(size=10)
 +
</syntaxhighlight>
 +
 
 +
=== Supprimer un node ===
 +
<syntaxhighlight lang="python">
 +
nuke.delete(myNode)
 +
</syntaxhighlight>
 +
 
 +
=== La sélection ===
 +
Éviter:
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.selectedNode()
 
nuke.selectedNode()
Ligne 37 : Ligne 89 :
 
Qui revoit une bête liste dans l'ordre inversé de la sélection.
 
Qui revoit une bête liste dans l'ordre inversé de la sélection.
  
Savoir si un node est sélectionné:
+
==== Savoir si un node est sélectionné ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.isSelected() # True/False
 
myNode.isSelected() # True/False
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ajouter/Enlever le node a la sélection:
+
==== Ajouter/Enlever le node a la sélection ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.setSelected(True)
 
myNode.setSelected(True)
Ligne 48 : Ligne 100 :
  
 
=== Depuis le projet ===
 
=== Depuis le projet ===
Recupérer tout les nodes:
+
 
 +
==== Récupérer tout les nodes ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.allNodes() # list tout les nodes du projet en cours
 
nuke.allNodes() # list tout les nodes du projet en cours
Ligne 54 : Ligne 107 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Récupérer un node depuis sont nom:
+
==== Récupérer un node depuis son nom ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.toNode("Blur1")
 
nuke.toNode("Blur1")
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Nom d'un node:
+
==== Récupérer le nom d'un node ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.name() # renvoit le nom du node "Blur1"
 
myNode.name() # renvoit le nom du node "Blur1"
Ligne 65 : Ligne 118 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Positionnement dans le graph:
+
==== Récupérer le positionnement d'un node dans le graph ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.xpos()
 
myNode.xpos()
Ligne 74 : Ligne 127 :
  
 
=== Paramètre des nodes ===
 
=== Paramètre des nodes ===
Lister les dict des attributs d'un node:
+
 
 +
==== Lister les dict des attributs d'un node ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.knobs()
 
myNode.knobs()
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Methode de base pour get/set:
+
==== Méthode de base pour get/set de variable d'un node ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.knob("size").value() # get value
 
myNode.knob("size").value() # get value
 
myNode.knob("size").setValue(2) # set value
 
myNode.knob("size").setValue(2) # set value
 +
</syntaxhighlight>
 +
Et une autre façon:
 +
<syntaxhighlight lang="python">
 +
myNode["translate"].value() # get value [2.0, 0.0, 32.0]
 +
myNode["translate"].setValue([1.0, 0.0, 16.0]) # set array value
 +
</syntaxhighlight>
 +
 +
==== Ajouter un paramètre a un node ====
 +
<syntaxhighlight lang="python">
 +
myControl = nuke.Array_Knob("name", "label") # "name" est simplement le nom du knob et "label" est ce qui sera affiché dans l'UI. Ce dernier est optionnel.
 +
myControl.setTooltip('Mon tooltip') # Ajoute un tooltip au knob
 +
myNode.addKnob(myControl)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ajouter un paramètre a un node:
+
==== Les différents types de knobs ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
myNode.addKnob(nuke.Text_Knob("divider")) # Juste une barre de separation
+
textControl = nuke.Text_Knob("divider") # Juste une barre de separation
myNode.addKnob(nuke.Color_Knob("color")) # Un knob de couleur
+
colorControl = nuke.Color_Knob("color") # Un knob de couleur
myNode.addKnob(nuke.Double_Knob("value")) # Un knob de valeur a virgule flottante
+
doubleControl = nuke.Double_Knob("value") # Un knob de valeur a virgule flottante
 +
sliderControl = nuke.WH_Knob("value") # Un knob de deux valeurs: W et H
 +
myNode.addKnob(textControl)
 +
myNode.addKnob(colorControl)
 +
myNode.addKnob(doubleControl)
 +
myNode.addKnob(sliderControl)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ajouter un bouton qui execute du Python:
+
Ajouter un bouton qui exécute du Python:
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
pyButton = nuke.PyScript_Knob("Do something")
 
pyButton = nuke.PyScript_Knob("Do something")
Ligne 99 : Ligne 170 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
D'autres type de knob sont disponible dans les sous-classe de [http://docs.thefoundry.co.uk/nuke/63/pythonreference/nuke.Knob-class.html la classe Knob].
+
Les autres type de knob sont disponible dans les sous-classe de [http://docs.thefoundry.co.uk/nuke/63/pythonreference/nuke.Knob-class.html la classe Knob].
  
 
Certains paramètres peuvent être "exécuté" (comme si on cliquait sur le bouton en fait):
 
Certains paramètres peuvent être "exécuté" (comme si on cliquait sur le bouton en fait):
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
for myNode in nuke.allNodes("Read") :
 
for myNode in nuke.allNodes("Read") :
myNode.knob("reload").execute()
+
myNode["reload"].execute()
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ligne 127 : Ligne 198 :
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
myNode.canSetInput(0, anotherNode) # Vérifie que la connection de anotherNode sur myNode a l'index 0 est possible
 
myNode.canSetInput(0, anotherNode) # Vérifie que la connection de anotherNode sur myNode a l'index 0 est possible
myNode.setInput(0, anotherNode) # Connecter un node a un autre sur l'index 0
+
myNode.setInput(0, anotherNode) # Connecter un node a un autre sur l'index 0 (myNode prend anotherNode en input, anotherNode se connecte a myNode)
 
myNode.setInput(0, None) # Déconnecter un input
 
myNode.setInput(0, None) # Déconnecter un input
 
myNode.connectInput(0, anotherNode) # connect l'output de anotherNode a l'input 0 de myNode
 
myNode.connectInput(0, anotherNode) # connect l'output de anotherNode a l'input 0 de myNode
Ligne 133 : Ligne 204 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Lister les dépendances montantes et descendantes:
+
==== Lister les dépendances montantes et descendantes ====
 +
<syntaxhighlight lang="python">
 +
myNode.dependent() # Renvoi la liste des nodes dépendants (enfant) de myNode
 +
myNode.dependencies() # Renvoi la liste des nodes dont dépendent myMode (ces parents)
 +
</syntaxhighlight>
 +
 
 +
=== Les metadatas ===
 +
Lire les metadatas:
 +
<syntaxhighlight lang="python">
 +
node = nuke.toNode("Read1")
 +
print node.metadata() # un dict de metadata
 +
 
 +
# Result:
 +
{'exr/displayWindow': [0, 0, 2047, 1555], 'input/width': 2048, 'exr/nuke/camera/vaperture': '18.672', 'input/bitsperchannel': '16-bit half float'...
 +
</syntaxhighlight>
 +
 
 +
Source: [http://docs.thefoundry.co.uk/nuke/63/pythondevguide/metadata.html Reading Metadata].
 +
 
 +
=== Label des nodes ===
 +
On peut modifier le label d'un node (ce qui est affiché dans l'interface, sous le nom du fichier) avec un syntaxe particulière:
 +
<syntaxhighlight lang="tcl">
 +
[ lindex [split [filename] /] end-1] # le nom du dossier qui contient l'image ("p099" si "s002/p099/diffuse.0001.exr")
 +
[ lindex [split [filename] /] end-2][ lindex [split [filename] /] end-1] # Variante du dessus ("s002p099" si "s002/p099/diffuse.0001.exr")
 +
[ lindex [split [lindex [split [knob [topnode].file] .] 0] /] end] # Le nom du fichier sans l'extension
 +
[date %d]/[date %m]/[date %y] # Affiche la date de l'image
 +
</syntaxhighlight>
 +
Le langage utilisé est le [http://tmml.sourceforge.net/doc/tcl/ tcl].
 +
 
 +
D'autres commandes utiles ici: [http://www.nukepedia.com/tcl/value-vs-knob-command/ Value vs knob command]
 +
 
 +
== Animation ==
 +
 
 +
==== Récupérer la valeur d'une animation a une image donnée, pour une vue donnée ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
myNode.dependent() # Renvoi la liste des nodes dépendant (enfant) de myNode
+
myNode["translate"].valueAt(25, view='R')
myNode.dependencies() # Renvoi la liste des nodes dont dépend myMode (ces parents)
+
# Result: [-26.308155060000001, 2.3234429360000002, 72.413200380000006]
 +
</syntaxhighlight>
 +
 
 +
On peut ajouter l'index du tableau (ici: 0):
 +
<syntaxhighlight lang="python">
 +
myNode["translate"].valueAt(25, 0, view='R')
 +
# Result: -26.308155060000001
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
== Interface ==
 
== Interface ==
 +
Liens intéressants:
 +
* NUKE Python Developers Guide v6.3v1 documentation: [http://docs.thefoundry.co.uk/nuke/63/pythondevguide/custom_ui.html Customizing the UI]
 +
 
=== Menus ===
 
=== Menus ===
Customiser le menu:
+
 
 +
==== Customiser le menu ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
menuBar = nuke.menu("Nuke") # La barre de menu principale
 
menuBar = nuke.menu("Nuke") # La barre de menu principale
Ligne 158 : Ligne 271 :
  
 
=== Dialog ===
 
=== Dialog ===
Une fileDialog, pour les clips. Un seul/plusieurs fichiers:
+
 
 +
==== Une fileDialog, pour les clips. Un seul/plusieurs fichiers ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.getClipname( "fileDialogName" )
 
nuke.getClipname( "fileDialogName" )
Ligne 166 : Ligne 280 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Une autre avec pattern et defaultPath:
+
==== Une fileDialog avec pattern et defaultPath ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.getFilename("fileDialogName", pattern="*.png;*.jpeg", default="/path/to/a/file" )
 
nuke.getFilename("fileDialogName", pattern="*.png;*.jpeg", default="/path/to/a/file" )
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Yes/No dialog
+
==== Yes/No dialog ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.ask("Ça roule?") # revoit True/False
 
nuke.ask("Ça roule?") # revoit True/False
Ligne 177 : Ligne 291 :
  
 
=== Icones ===
 
=== Icones ===
Appliquer une icone à un node:
+
 
 +
==== Appliquer une icône à un node ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
myNode.knob("icon").setValue("/path/to/an/icon.png")
+
myNode["icon"].setValue("/path/to/an/icon.png")
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=== Autres ===
 
=== Autres ===
Overrider la fonction de création d'un node:
+
 
 +
==== Overrider la fonction de création d'un node ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
def myCreateNode() :
 
def myCreateNode() :
Ligne 190 : Ligne 306 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Divers ==
+
==== Désactiver le thumbnail d'un node ====
Faire un print dans le terminal qui a lancé Nuke:
+
<syntaxhighlight lang="python">
 +
myNode["postage_stamp"].setValue(False)
 +
</syntaxhighlight>
 +
 
 +
=== PySide ===
 +
Des bouts de codes trouvé par ci par la.
 +
 
 +
==== Une fenêtre qui reste toujours "devant" Nuke, même si elle n'a plus le focus (ala Maya) ====
 +
Trouvé sur la mailing list nuke-python@support.thefoundry.co.uk.
 +
<syntaxhighlight lang="python">
 +
from PySide import QtCore, QtGui
 +
 
 +
class TestWindow(QtGui.QDialog):
 +
def __init__(self, parent=QtGui.QApplication.activeWindow()):
 +
QtGui.QDialog.__init__(self, parent)
 +
self.hbox=QtGui.QHBoxLayout()
 +
self.button=QtGui.QPushButton("TEST")
 +
self.hbox.addWidget(self.button)
 +
self.setLayout(self.hbox)
 +
 
 +
tw = TestWindow()
 +
tw.show()
 +
</syntaxhighlight>
 +
 
 +
Pour avoir la possibilité de la faire passer "derrière" Nuke il suffit de remplacer:
 +
<syntaxhighlight lang="python">
 +
QtGui.QApplication.activeWindow()
 +
</syntaxhighlight>
 +
Par:
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
nuke.tprint("Hello World!")
+
QtGui.QApplication.desktop()
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
Dans tout les cas, il faut lui donner un parent. Sans parent, Nuke vous gratifiera d'un ''Segmentation fault'' lorsque vous quittez.
  
Afficher les plugin path:
+
== Debug ==
 +
 
 +
==== Afficher les plugin path ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.pluginPath()
 
nuke.pluginPath()
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Lancer nuke en mode terminal (pas de GUI):
+
==== Obtenir des statistiques (performance metrics) sur les nodes calculés  ====
 +
En mode terminal ou GUI, uniquement sous Linux
 +
<syntaxhighlight lang="bash">
 +
nuke -P
 +
</syntaxhighlight>
 +
 
 +
==== Afficher tout les callbacks de Nuke dans le terminal ====
 +
Dans votre ''.nuke/init.py'', ajoutez:
 +
<syntaxhighlight lang="python">
 +
import callbacksTrace
 +
</syntaxhighlight>
 +
 
 +
==== Obtenir un debug des déchargements de la mémoire de Nuke ====
 +
Lancer le Nuke avec la variable d’environnement ''NUKE_DEBUG_MEMORY'' à ''1'' (voir page 9 [https://thefoundry.s3.amazonaws.com/downloads/Nuke5.2v1_ReleaseNotes.pdf de la doc]).
 +
 
 +
Combiné à ''-P'' cette option est très interessante.
 +
 
 +
==== Connaître l'état de Nuke lors d'un crash ====
 +
Il faut récupérer le PID de Nuke avec la commande:
 +
<syntaxhighlight lang="bash">
 +
ps aux | grep nuke
 +
</syntaxhighlight>
 +
 
 +
Puis lancer:
 +
<syntaxhighlight lang="bash">
 +
gdb -p <PID>
 +
</syntaxhighlight>
 +
 
 +
* ''gdb'' s'initialisera et Nuke s’arrêtera.
 +
* tapez ''continue'' pour que Nuke reprenne son travail.
 +
* Quand Nuke crash, ''gdb'' reprend la main.
 +
* Tapez ''bt'' (pour backtrace) et ainsi voir la liste des fonction et celle ou Nuke plante.
 +
 
 +
Vous aurez quelque hose qui ressemble a ça:
 +
 
 +
<syntaxhighlight lang="bash">
 +
(gdb) c
 +
Continuing.
 +
Program received signal SIGINT, Interrupt.
 +
0x00007f991ca63672 in select () from /lib64/libc.so.6
 +
(gdb) bt
 +
#0  0x00007f991ca63672 in select () from /lib64/libc.so.6
 +
#1  0x0000000001296115 in ?? ()
 +
#2  0x00000000012965bf in ?? ()
 +
#3  0x00000000012976d6 in ?? ()
 +
#4  0x0000000001275457 in ?? ()
 +
#5  0x0000000000714b58 in ?? ()
 +
#6  0x00000000005dabf0 in ?? ()
 +
#7  0x00000000005d846f in ?? ()
 +
#8  0x00000000005d7cbc in ?? ()
 +
#9  0x0000000000b703d8 in ?? ()
 +
#10 0x00007f991a8d2041 in PyEval_EvalFrameEx (f=0x11029010, throwflag=<value optimized out>) at Python/ceval.c:3750
 +
#11 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x20f0b70, globals=<value optimized out>, locals=<value optimized out>, args=0xb, argcount=1, kws=0x10a645d8, kwcount=10, defs=0x2125770, defcount=8, closure=0x0) at Python/ceval.c:3000
 +
#12 0x00007f991a8d2289 in PyEval_EvalFrameEx (f=0x10a64300, throwflag=<value optimized out>) at Python/ceval.c:3846
 +
#13 0x00007f991a8d2780 in PyEval_EvalFrameEx (f=0x21629d0, throwflag=<value optimized out>) at Python/ceval.c:3836
 +
#14 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x2125300, globals=<value optimized out>, locals=<value optimized out>, args=0xe, argcount=0, kws=0x2162870, kwcount=14, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3000
 +
#15 0x00007f991a8d2289 in PyEval_EvalFrameEx (f=0x21626f0, throwflag=<value optimized out>) at Python/ceval.c:3846
 +
#16 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x213aaf8, globals=<value optimized out>, locals=<value optimized out>, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3000
 +
#17 0x00007f991a8d4182 in PyEval_EvalCode (co=0x7, globals=0x1da48e8, locals=0x1da4b80) at Python/ceval.c:541
 +
#18 0x00007f991a8f7d51 in PyRun_FileExFlags (fp=0x1ebee90, filename=0x7fffb1933004 "/tmp/InKExe-20111007-61dtGE/nukeRenderer.py", start=<value optimized out>, globals=0x1e07dc0, locals=0x1e07dc0, closeit=1, flags=0x0) at Python/pythonrun.c:1339
 +
#19 0x0000000000b653bc in scriptFile(char const*) ()
 +
#20 0x0000000000b8b202 in ?? ()
 +
#21 0x00007f991c9b5586 in __libc_start_main () from /lib64/libc.so.6
 +
#22 0x00000000004a767a in ?? ()
 +
#23 0x00007fffb1930818 in ?? ()
 +
#24 0x000000000000001c in ?? ()
 +
#25 0x0000000000000006 in ?? ()
 +
</syntaxhighlight>
 +
 
 +
Ici, Nuke c'est planté sur la fonction ''select()'' de la ''libc.so.6''.
 +
 
 +
Plus de commandes ici: [http://brouits.free.fr/doc/gdb_howto.html Utiliser le debuger GDB]
 +
 
 +
== Messages d'erreur connus ==
 +
 
 +
Voici une liste des message d'erreur et leur significations/solutions.
 +
 
 +
=== "ValueError: not attached to a node" ===
 +
 
 +
Ce message:
 +
<syntaxhighlight lang="bash">
 +
"ValueError: not attached to a node"
 +
</syntaxhighlight>
 +
Arrive souvent quand on appel un node supprimé (plus haut dans le script la plupart du temps).
 +
 
 +
== Divers ==
 +
 
 +
==== Lancer nuke en mode terminal (pas de GUI) ====
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
nuke -t
 
nuke -t
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Savoir si le script s'execute en mode terminal ou en mode GUI:
+
==== Faire un print dans le terminal qui a lancé Nuke ====
 +
<syntaxhighlight lang="python">
 +
nuke.tprint("Hello World!")
 +
</syntaxhighlight>
 +
 
 +
==== Vider le cache mémoire ====
 +
<syntaxhighlight lang="python">
 +
nuke.memory("free")
 +
</syntaxhighlight>
 +
Reviens a cliquer sur ''Clear Buffers F12'':
 +
 
 +
[[Fichier:Nuke cache clearBuffers.png]]
 +
 
 +
==== Vider le cache disque ====
 +
<syntaxhighlight lang="python">
 +
nuke.clearDiskCache()
 +
</syntaxhighlight>
 +
Reviens a cliquer sur ''Clear Disk Cache''.
 +
 
 +
==== Savoir si le script s’exécute en mode terminal ou en mode GUI ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.GUI
 
nuke.GUI
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Connaitre le nombre de CPU:
+
==== Connaître le nombre de CPU ====
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
nuke.NUM_CPUS
 
nuke.NUM_CPUS
Ligne 222 : Ligne 475 :
  
 
[[Category:Nuke]]
 
[[Category:Nuke]]
 +
[[Category:Python]]

Version actuelle datée du 1 avril 2013 à 15:38

Cette page a pour but de donner des exemples simples des commandes python les plus utilisées dans Nuke

Sommaire

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:

Nuke preferences cachelimit.png

Modifier les préférences du projet

nuke.root()['first_frame'].value()	# renvoi le numéro de la frame
nuke.root()['first_frame'].setValue(101)

Les formats

Les formats contiennent la résolution et la taille des pixels.

Obtenir la liste des formats disponibles

nuke.formats()

Modifier le format du projet

nuke.root()['format'].value().name()	# renvoi le nom du format
nuke.root()['format'].value().setName("nomDuFormat")

Et bien d'autres options

nuke.root()['format'].value().width()
nuke.root()['format'].value().height()

Obtenir le format d'un node

nodeFormat = muNode.format()
nodeFormat.name()	# renvoi le nom du format de l'image en entrée.
nodeFormat.width()	# renvoi la largeur, en pixel, de l'image en entrée.
nodeFormat.height()	# renvoi la heuteur, en pixel, de l'image en entrée.

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

Aller dans:

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

Les nodes

Voir la doc de la classe Node pour plus d'informations:

Créer un node

Deux méthodes pour faire la même chose:

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

D’après la doc officielle:

  • 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 )

Setter les knobs d'un node a la création:

nuke.nodes.Blur(size=10)

Supprimer un node

nuke.delete(myNode)

La sélection

Éviter:

nuke.selectedNode()

Comportement complexe, préférer:

nuke.selectedNodes()

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)

Depuis le projet

Récupérer tout 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

Récupérer un node depuis son nom

nuke.toNode("Blur1")

Récupérer le nom d'un node

myNode.name()	# renvoit le nom du node "Blur1"
myNode.fullName()	# renvoi le nom complet du node

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

myNode.xpos()
myNode.ypos()
myNode.setXpos(30)
myNode.setYpos(30)

Paramètre des nodes

Lister les dict des attributs d'un node

myNode.knobs()

Méthode de base pour get/set de variable d'un node

myNode.knob("size").value()	# get value
myNode.knob("size").setValue(2)	# set value

Et une autre façon:

myNode["translate"].value()	# get value [2.0, 0.0, 32.0]
myNode["translate"].setValue([1.0, 0.0, 16.0])	# set array value

Ajouter un paramètre a un node

myControl = nuke.Array_Knob("name", "label")	# "name" est simplement le nom du knob et "label" est ce qui sera affiché dans l'UI. Ce dernier est optionnel.
myControl.setTooltip('Mon tooltip')	# Ajoute un tooltip au knob
myNode.addKnob(myControl)

Les différents types de knobs

textControl = nuke.Text_Knob("divider")	# Juste une barre de separation
colorControl = nuke.Color_Knob("color")	# Un knob de couleur
doubleControl = nuke.Double_Knob("value")	# Un knob de valeur a virgule flottante
sliderControl = nuke.WH_Knob("value")	# Un knob de deux valeurs: W et H
myNode.addKnob(textControl)
myNode.addKnob(colorControl)
myNode.addKnob(doubleControl)
myNode.addKnob(sliderControl)

Ajouter un bouton qui exécute du Python:

pyButton = nuke.PyScript_Knob("Do something")
pyButton.setCommand("print 'Toto'")
myNode.addKnob(pyButton)

Les autres type de knob sont disponible dans les sous-classe de la classe Knob.

Certains paramètres peuvent être "exécuté" (comme si on cliquait sur le bouton en fait):

for myNode in nuke.allNodes("Read") :
	myNode["reload"].execute()

Connections des nodes

Toute les connections se font par les index des inputs/output:

myNode.minInputs()	# 3 pour un node de merge: A, B, et Mask
myNode.maxInputs()	# 101 pour un node de merge: A2, B2, etc...
myNode.maxOutputs()	# Pas le nombre de connections, en output, du node mais le nombre d’élément que sort le node (un seul la plupart du temps)
myNode.optionalInput()	# Index de l'input optionnel (souvent le mask). 2 pour le node de merge

La taille du tableau des inputs:

myNode.inputs()	# La taille du tableau des inputs

Si mask (index 2) est connecté, la taille est de 3 (0,1,2).

Si A est connecté, la taille est de... 2 (0,1). (Apparemment, A est la seconde entrée du tableau et B la première... Allez savoir pourquoi...)

Si B est connecté, la taille est de... 1 (Juste 0).

myNode.canSetInput(0, anotherNode)	# Vérifie que la connection de anotherNode sur myNode a l'index 0 est possible
myNode.setInput(0, anotherNode)	# Connecter un node a un autre sur l'index 0 (myNode prend anotherNode en input, anotherNode se connecte a myNode)
myNode.setInput(0, None)	# Déconnecter un input
myNode.connectInput(0, anotherNode)	 # connect l'output de anotherNode a l'input 0 de myNode
myNode.channels()	# ['rgba.red', 'rgba.green', 'rgba.blue', 'rgba.alpha', 'depth.Z']

Lister les dépendances montantes et descendantes

myNode.dependent()	# Renvoi la liste des nodes dépendants (enfant) de myNode
myNode.dependencies()	# Renvoi la liste des nodes dont dépendent myMode (ces parents)

Les metadatas

Lire les metadatas:

node = nuke.toNode("Read1")
print node.metadata()	# un dict de metadata

# Result:
{'exr/displayWindow': [0, 0, 2047, 1555], 'input/width': 2048, 'exr/nuke/camera/vaperture': '18.672', 'input/bitsperchannel': '16-bit half float'...

Source: Reading Metadata.

Label des nodes

On peut modifier le label d'un node (ce qui est affiché dans l'interface, sous le nom du fichier) avec un syntaxe particulière:

[ lindex [split [filename] /] end-1]	# le nom du dossier qui contient l'image ("p099" si "s002/p099/diffuse.0001.exr")
[ lindex [split [filename] /] end-2][ lindex [split [filename] /] end-1]	# Variante du dessus ("s002p099" si "s002/p099/diffuse.0001.exr")
[ lindex [split [lindex [split [knob [topnode].file] .] 0] /] end]	# Le nom du fichier sans l'extension
[date %d]/[date %m]/[date %y]	# Affiche la date de l'image

Le langage utilisé est le tcl.

D'autres commandes utiles ici: Value vs knob command

Animation

Récupérer la valeur d'une animation a une image donnée, pour une vue donnée

myNode["translate"].valueAt(25, view='R')
# Result: [-26.308155060000001, 2.3234429360000002, 72.413200380000006]

On peut ajouter l'index du tableau (ici: 0):

myNode["translate"].valueAt(25, 0, view='R')
# Result: -26.308155060000001

Interface

Liens intéressants:

Menus

Customiser le menu

menuBar = nuke.menu("Nuke")	# La barre de menu principale
myMenu = menuBar.addMenu("&myMenu")	# Ajoute un menu custom
myMenuCommand = myMenu.addCommand("Do Something", "doSomething()")	# Ajoute une commande

mySubMenu = myMenu.addMenu("mySubMenu")	# Ajoute un sous menu a notre menu custom
mySubMenu.addCommand("Do Something", "doSomething()")	# Ajoute une commande

editMenu = menuBar.findItem("&Edit")	# Cherche un menu existant
editMenu.addCommand("Do Something", "doSomething()")	# Et y ajoute une commande
nodeSubMenu = editMenu.findItem("Node")	# Cherche le sous menu "Node"
nodeSubMenu.addSeparator()	# Y ajoute un separator
nodeSubMenu.addCommand("Do Something", "doSomething()")	# Et une commande

Dialog

Une fileDialog, pour les clips. Un seul/plusieurs fichiers

nuke.getClipname( "fileDialogName" )
# Result: '/path/to/my/file'
nuke.getClipname( "fileDialogName", multiple=True )
# Result: [/path/to/my/file1', '/path/to/my/file2', '/path/to/my/file3']

Une fileDialog avec pattern et defaultPath

nuke.getFilename("fileDialogName", pattern="*.png;*.jpeg", default="/path/to/a/file" )

Yes/No dialog

nuke.ask("Ça roule?")	# revoit True/False

Icones

Appliquer une icône à un node

myNode["icon"].setValue("/path/to/an/icon.png")

Autres

Overrider la fonction de création d'un node

def myCreateNode() :
	print "coucou"
nukescripts.create_read = myCreateNode

Désactiver le thumbnail d'un node

myNode["postage_stamp"].setValue(False)

PySide

Des bouts de codes trouvé par ci par la.

Une fenêtre qui reste toujours "devant" Nuke, même si elle n'a plus le focus (ala Maya)

Trouvé sur la mailing list nuke-python@support.thefoundry.co.uk.

from PySide import QtCore, QtGui

class TestWindow(QtGui.QDialog):
	def __init__(self, parent=QtGui.QApplication.activeWindow()):
		QtGui.QDialog.__init__(self, parent)
		self.hbox=QtGui.QHBoxLayout()
		self.button=QtGui.QPushButton("TEST")
		self.hbox.addWidget(self.button)
		self.setLayout(self.hbox)

tw = TestWindow()
tw.show()

Pour avoir la possibilité de la faire passer "derrière" Nuke il suffit de remplacer:

QtGui.QApplication.activeWindow()

Par:

QtGui.QApplication.desktop()

Dans tout les cas, il faut lui donner un parent. Sans parent, Nuke vous gratifiera d'un Segmentation fault lorsque vous quittez.

Debug

Afficher les plugin path

nuke.pluginPath()

Obtenir des statistiques (performance metrics) sur les nodes calculés

En mode terminal ou GUI, uniquement sous Linux

nuke -P

Afficher tout les callbacks de Nuke dans le terminal

Dans votre .nuke/init.py, ajoutez:

import callbacksTrace

Obtenir un debug des déchargements de la mémoire de Nuke

Lancer le Nuke avec la variable d’environnement NUKE_DEBUG_MEMORY à 1 (voir page 9 de la doc).

Combiné à -P cette option est très interessante.

Connaître l'état de Nuke lors d'un crash

Il faut récupérer le PID de Nuke avec la commande:

ps aux | grep nuke

Puis lancer:

gdb -p <PID>
  • gdb s'initialisera et Nuke s’arrêtera.
  • tapez continue pour que Nuke reprenne son travail.
  • Quand Nuke crash, gdb reprend la main.
  • Tapez bt (pour backtrace) et ainsi voir la liste des fonction et celle ou Nuke plante.

Vous aurez quelque hose qui ressemble a ça:

(gdb) c
Continuing.
Program received signal SIGINT, Interrupt.
0x00007f991ca63672 in select () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f991ca63672 in select () from /lib64/libc.so.6
#1  0x0000000001296115 in ?? ()
#2  0x00000000012965bf in ?? ()
#3  0x00000000012976d6 in ?? ()
#4  0x0000000001275457 in ?? ()
#5  0x0000000000714b58 in ?? ()
#6  0x00000000005dabf0 in ?? ()
#7  0x00000000005d846f in ?? ()
#8  0x00000000005d7cbc in ?? ()
#9  0x0000000000b703d8 in ?? ()
#10 0x00007f991a8d2041 in PyEval_EvalFrameEx (f=0x11029010, throwflag=<value optimized out>) at Python/ceval.c:3750
#11 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x20f0b70, globals=<value optimized out>, locals=<value optimized out>, args=0xb, argcount=1, kws=0x10a645d8, kwcount=10, defs=0x2125770, defcount=8, closure=0x0) at Python/ceval.c:3000
#12 0x00007f991a8d2289 in PyEval_EvalFrameEx (f=0x10a64300, throwflag=<value optimized out>) at Python/ceval.c:3846
#13 0x00007f991a8d2780 in PyEval_EvalFrameEx (f=0x21629d0, throwflag=<value optimized out>) at Python/ceval.c:3836
#14 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x2125300, globals=<value optimized out>, locals=<value optimized out>, args=0xe, argcount=0, kws=0x2162870, kwcount=14, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3000
#15 0x00007f991a8d2289 in PyEval_EvalFrameEx (f=0x21626f0, throwflag=<value optimized out>) at Python/ceval.c:3846
#16 0x00007f991a8d3e91 in PyEval_EvalCodeEx (co=0x213aaf8, globals=<value optimized out>, locals=<value optimized out>, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:3000
#17 0x00007f991a8d4182 in PyEval_EvalCode (co=0x7, globals=0x1da48e8, locals=0x1da4b80) at Python/ceval.c:541
#18 0x00007f991a8f7d51 in PyRun_FileExFlags (fp=0x1ebee90, filename=0x7fffb1933004 "/tmp/InKExe-20111007-61dtGE/nukeRenderer.py", start=<value optimized out>, globals=0x1e07dc0, locals=0x1e07dc0, closeit=1, flags=0x0) at Python/pythonrun.c:1339
#19 0x0000000000b653bc in scriptFile(char const*) ()
#20 0x0000000000b8b202 in ?? ()
#21 0x00007f991c9b5586 in __libc_start_main () from /lib64/libc.so.6
#22 0x00000000004a767a in ?? ()
#23 0x00007fffb1930818 in ?? ()
#24 0x000000000000001c in ?? ()
#25 0x0000000000000006 in ?? ()

Ici, Nuke c'est planté sur la fonction select() de la libc.so.6.

Plus de commandes ici: Utiliser le debuger GDB

Messages d'erreur connus

Voici une liste des message d'erreur et leur significations/solutions.

"ValueError: not attached to a node"

Ce message:

"ValueError: not attached to a node"

Arrive souvent quand on appel un node supprimé (plus haut dans le script la plupart du temps).

Divers

Lancer nuke en mode terminal (pas de GUI)

nuke -t

Faire un print dans le terminal qui a lancé Nuke

nuke.tprint("Hello World!")

Vider le cache mémoire

nuke.memory("free")

Reviens a cliquer sur Clear Buffers F12:

Nuke cache clearBuffers.png

Vider le cache disque

nuke.clearDiskCache()

Reviens a cliquer sur Clear Disk Cache.

Savoir si le script s’exécute en mode terminal ou en mode GUI

nuke.GUI

Connaître le nombre de CPU

nuke.NUM_CPUS

Pour une liste complète:

help(nuke)