AnimationCurve and AnimationKey objects

Written by Nathan Rusch on .

AnimationCurve Objects

AnimationCurve objects contain the animation data of a given animated knob, and can be accessed using a knob’s .animation() or .animations() methods.

NOTE: AnimationCurves can be created manually using Python, but for the purposes of this article, we will assume they all come from pre-animated knobs.

1
2
3
4
5
6
7
g1 = nuke.toNode("Grade1")
 
gBlack = g1['blackpoint']
 
anim = gBlack.animation(0)
 
print anim

CurvesAndKeys_01

Here is the curve in question, as shown in Nuke's curve editor:

CurvesAndKeys_015

 

Like nodes and knobs, these objects have their own set of methods for interpreting and modifying the data they contain.

One of the simplest (and most useful) of these is the .evaluate() method. This simply takes a numeric frame argument (int or float) and returns the curve’s value at that frame. This can be used to perform manual subframe sampling, since non-integer frame values are perfectly legal.

9
anim.evaluate(30)

CurvesAndKeys_02

 

11
anim.evaluate(28.75)
CurvesAndKeys_03

 

Another basic yet useful method is .setKey(). It takes two arguments: a frame number and a key value, and adds an animation key at the specified frame with (you guessed it) the specified value.

13
anim.setKey(48, .044)

And here is the modified curve:

CurvesAndKeys_04

This method can also be used to modify an existing key. If a key exists at the frame specified, its value will simply be changed to the new input value.

 

Just like knobs, AnimationCurves can also be tested to see if they contain expressions, or whether the knob they are attached to is being driven by a set of keys. However, contrary to a knob’s .hasExpression() method, AnimationCurve objects use the method .noExpression(). This returns True if the animation is driven by keys, or False if the animation is linked by an expression.

15
anim.noExpression()

CurvesAndKeys_05

 

You can also manually attach an expression to an AnimationCurve, just like you would a knob, using the .setExpression() method. The argument is a string in Nuke expression syntax.

17
18
19
20
21
22
23
gWhite = g1['whitepoint']
 
gWhite.setAnimated()
 
anim2 = gWhite.animation(0)
 
anim2.setExpression("blackpoint")

 

The .expression() method can be used to retrieve the expression that is providing the animation as a string. An important note is that if the parent knob isn’t linked using an expression, this method will still return the value ‘curve.’ Otherwise, the expression will be returned in the familiar Nuke syntax.

25
anim.expression()

CurvesAndKeys_06

 

27
anim2.expression()

CurvesAndKeys_07

 

 

To retrieve all the keys contained in an AnimationCurve, use the .keys() method. This returns a list of AnimationKey objects; however, if the AnimationCurve is expression-driven, it will return an empty list.

29
30
31
keys = anim.keys()
 
print keys


CurvesAndKeys_08


Similar to .setKey(), the .addKey() method can also be used to add keys to an animation curve. However, instead of simple numeric arguments, this method takes a sequence (list or tuple) of AnimationKey objects, and simply drops them into the curve. Since these AnimationKey objects contain their own x and y values (i.e. they know where to place themselves in time and space), no additional arguments are needed.

33
anim2.addKey(keys)

These AnimationKey objects are covered in more detail below.

Other useful AnimationCurve methods

35
anim.knob()
Returns the knob object the AnimationCurve is attached to.


37
anim.knobAndFieldName()
Returns a string containing the knob and field the AnimationCurve is attached to, in Nuke expression syntax (i.e. “blackpoint.r”)


39
anim.knobIndex()
Returns the knob index the AnimationCurve is attached to. In a typical rgba knob (Grade.blackpoint, for example), this will return 0, 1, 2, or 3 for r, g, b, and a respectively. If the knob is set to a single value, it will return 0.


41
anim.selected()
Returns a boolean indicating whether or not the curve is selected in the Curve Editor. This can be useful for performing automated operations on a user-defined set of curves.


43
anim.size()
Returns the number of keys on the curve. Will return 0 if the curve is expression-linked.


45
anim.constant()
Returns True if the animation is a horizontal line, or is default with all points at the same y value.


47
anim.clear()
Deletes all keys from the curve.


AnimationKey Objects

These are returned by an AnimationCurve object’s .keys() method, as described above. They are a simpler type, however, so rather than a list of methods for interacting with or modifying them, they simply contain a set of values that describe how a curve passing through them should behave.

NOTE: AnimationKeys can also be created manually using Python, but for the purposes of this article, we will assume they all come from AnimationCurve objects.

49
key = keys[1]

The simplest of these values are pretty much what you would expect: .x and .y. These define when and where the key exists, respectively, and are Read/Write, meaning you can either access the values by name, or set them equal to a new value.

51
key.x
CurvesAndKeys_09
53
key.y
CurvesAndKeys_10
55
key.y = -.05

Since these key objects typically exist inside an AnimationCurve, any changes to the key will modify the parent curve directly.


The .selected value returns a boolean indicating whether or not the key is selected in the curve editor. This can also be set to a boolean to select or deselect the key, and can be useful for performing operations on a user-defined set of keys.

57
key.selected

CurvesAndKeys_11

59
key.selected = True

CurvesAndKeys_12

Each key also contains a .interpolation value, which determines how to calculate the curve’s slope between the key and another key. This can be assigned to any of a list of predefined interpolation constants, or their corresponding integers, from the following list:

nuke.SMOOTH – 0
nuke.CONSTANT – 1
nuke.LINEAR – 3
nuke.CUBIC – 4

When accessed directly, it will return only the integer. A return value other than those in the list about indicates the interpolation has been modified by the user.

61
key.interpolation

CurvesAndKeys_13

63
key.interpolation = nuke.CONSTANT

CurvesAndKeys_14


More advanced control of the key’s influence on the curve can be gained using the .la and .ra values, which define the key’s left and right bicubic values, and the .lslope and .rslope values, which define the curve’s derivative immediately to the left and right of the key. However, these will not be covered in detail here.


And always remember: the dir() and help() functions are your best friends when venturing into new Python territory in Nuke.

Comments   

 
0 # Scott Willman 2010-07-27 15:03
This is fantastic, exactly what I was looking for. Thank you Nathan!
 
 
0 # Howard Jones 2011-03-01 11:05
Great! Like Scott said.
 
 
0 # Howard Jones 2011-03-01 11:06
p.s. meant to vote 5 out of 5 but my pen slipped
 
 
0 # nick Grobler 2011-06-14 18:31
Hey Nathan

Great tutorial, you mentioned at the start "AnimationCurve s can be created manually using Python" I was just wondering how you would do that.
 
 
0 # Nathan Rusch 2011-06-15 21:49
Here's a quick example:

g = nuke.nodes.Grade()
a = nuke.AnimationC urve(g['blackpo int'], 0, 'r')
a.setKey(1, .1)
a.setKey(10, .125)

And so on...

Note that even though you create the AnimationCurve object with an existing knob as an argument, it isn't actually attached to that knob; rather, as near as I can tell, Nuke uses the knob's type to set or test the validity of some properties. Once you have your curve object, however, attaching it to a knob is trivial:

g['blackpoint'].copyAnimation(0, a)

Hope this helps.
 

You have no rights to post comments

We have 2851 guests and 129 members online