Using nuke.animation without tearing your hair out
This is quite possibly the most stubborn Nuke Python function I've ever encountered, and it took me a lot of poking and prodding to get it worked out, so I figured I should spread the knowledge around.
nuke.animation is the Python equivalent of (/wrapper for?) the TCL "animation" command. It allows you to perform operations on animation data, including the "Generate..." command found in any knob's "Edit" menu. This is the main reason I became interested in it in the first place, as I was writing a function to bake expressions to keyframes and figured Nuke already had some kind of automated process for it. Alas, the process turned out to be so painful that I just went ahead and wrote my own workaround (the script can be found here: http://www.nukepedia.com/gizmos/bake-expressions/).
In hindsight, I actually prefer my method as it avoids the funky subframe animation interpolation issues caused by the "Generate" command, but accessing these commands may prove useful in the future (though quite a few of them have much more friendly Python-native equivalents now).
Syntax
Anything enclosed in "<>" is an optional argument.
The basic syntax is:
nuke.animation("object", "command", <("param", <"param", "param", ...>)>)
Unfortunately, this is quite different from the syntax indicated by the function's docstring.
The syntax can also differ based on which command you're running, so the param sequence isn't always necessary.
Commands
Some of the possible commands and their basic syntax are listed below (I ran out of steam trying to fully document them all, but this should give you an idea of how to use the function).
For these examples, we will assume Grade1.blackpoint is the knob we want to operate on, and for any commands that operate on a frame range, the range 0-100 will be used.
IMPORTANT NOTE: Calling any of the commands that explicitly require an argument list without providing one will insta-crash Nuke. You've been warned, and so has The Foundry.
clear
nuke.animation("Grade1.blackpoint", "clear")
Takes no arguments, and deletes all keys from the animation. The knob remains in autokey mode, but no keys exist and the value is reset to default.
erase
nuke.animation("Grade1.blackpoint", "erase", ("0", "100"))
This will delete all keys between frames 0 and 100. This range is first-inclusive, last-exclusive, so in this example, the key at frame 0 would be erased, but the key at frame 100 would still exist. Also, the second "frame" argument is optional, so calling this with the argument sequence ("25", ) would only erase the key at frame 25.
expression
nuke.animation("Grade1.blackpoint", "expression")
This will simply return the current expression assigned to the knob as a string. Alternatively:
nuke.animation("Grade1.blackpoint", "expression", ("Grade2.whitepoint", ))
As you might expect, this will assign the expression "Grade2.whitepoint" to the knob.
generate
nuke.animation("Grade1.blackpoint", "generate", ("0", "100", "1", field, expression, <field, expression...>))
Probably the most complex of these commands, this will call the Generate command (found in any knob's "Edit" menu) for the frame range 0-100 (incremented by 1) and for each frame, evaluate each expression for its preceding field and store the results in the knob's animation curve. This will also break expression links.
Possible "field" values (from the docstring) include:
x: Sets the frame number for the next keyframe
y: Sets the keyframe value
dy: Sets the left slope
ldy: Sets left and right slope to the same value
la: Length of the left slope handle in the x direction. A value of 1 generates a handle that is 1/3 the distance to the next keyframe
ra: Same as la but for the right handle.
So, to simply bake the expression driving Grade1.blackpoint into keyframes using the default interpolation, you would call:
nuke.animation("Grade1.blackpoint", "generate", ("0", "100", "1", "y", "blackpoint"))
Other Commands
Since "generate" is the one I've gotten the most questions about and also wondered at the longest myself, I'll leave the detailed documentation at that. However, here are the remaining commands and a rough syntax for each (partially culled from the docstring).
-"index", ("x", ): Returns the index of the last key with x <= t. Returns -1 for none.-"is_key", ("x", ): Returns a non-zero value if there is a key with x == t. The actual return value is the index+1.
-"move", ("field", "expression", <"field", "expression", ...>): Replaces all selected keys in an animation with new ones as explained above in "generate"
-"name": Returns a user-friendly name for this animation. This will eliminate any common prefix between this animation and all other selected ones, and also replaces mangled names returned by animations with nice ones.
-"size": Returns the number of keys in the animation.
-"test": Errors if no points in the animation are selected. I don't think this actually works. -Nathan
-"y" ("frame", <"newValue">): Gets or sets the value of an animation at "frame."
-"x" ("frame", <"newXPos">): Gets or sets the horizontal postion of a key.
Hopefully this will be of use to someone.
Comments
g= nukeNodes.Grade()
how would you pass the actual node name into the "object" field? I tried
nameg = g.name()
n2 = nameg + ".blackpoint"
then
nuke.animation( n2, "generate")
Gives me an empty result..
However, keep in mind that it will always return an empty Python value, so you can't judge its success or failure based solely on what you get back from the call.
nuke.animation( n2,"generate")
If you run a multi-line statement, you need to assign the result to a variable, then print the variable ..ex:
g= nukeNodes.Grade ()
nameg = g.name()
n2 = nameg + ".blackpoint"
result = nuke.animation( n2, "generate")
print result
"...any calls to any of the operations that require a parameter sequence without passing one will crash Nuke 100% of the time."
RSS feed for comments to this post