3

I'd like to use the Graph Editor to create animation curves for use in another software package. Is there a way to export the value of a curve for each frame?

For example, I have a keyframe at frame 1 and one at frame 24. The first keyframe has a value of 0 and the second one has a value of 24. There's a Bezier interpolation between the two keyframes. I'd like to get the value for each frame in the curve.

Is this possible? Possibly a Python solution? (I'm comfortable with programming)

enter image description here

Justin
  • 1,972
  • 4
  • 24
  • 43

3 Answers3

3

The fcurve class provides the .evaluate method to get the value for a given frame.

import bpy

action = bpy.data.actions['CubeAction']
for fc in action.fcurves:
    if fc.data_path == 'location' and fc.array_index == 0:
        break
val = fc.evaluate(5.5)
pink vertex
  • 9,896
  • 1
  • 25
  • 44
  • Is the back-end Blender Python API code available? I'd like to look at the contents of the .evaluate() function. – Justin Jun 27 '14 at 12:37
  • I found it in blender/source/blender/blenkernel/intern/fcurve.c . fcurve_eval_keyframes() seems to have the core of the logic, although evaluate_fcurve() is the wrapper that handles a couple of more details. – Mutant Bob Jun 27 '14 at 14:27
  • @Justin You can browse the source code here (and the file Mutant Bob mentioned is here) – gandalf3 Jun 27 '14 at 19:12
1

You can bake fcurves to keyframes by selecting the keyframes in the graph editor and pressing ShiftO (or Header > Key > Sample Keyframes):

enter image description here

You can also use 3D view > Header > Object > Animation > Bake action, which gives you more options (and also lets you bake constraints, drivers, rigid body simulations, etc.)

Depending on the format you want to export to, you might be able to just export it. If you need to use python, having the values as keyframes makes it pretty easy to iterate over them and collect the values.

gandalf3
  • 157,169
  • 58
  • 601
  • 1,133
  • I'll give it a try. Any idea how those values are calculated? Eventually, I'd like to write my own curve editor, but I'm having trouble finding the mathematical definitions of those curves. – Justin Jun 27 '14 at 05:42
  • @Justin See http://blender.stackexchange.com/q/6692/599 – gandalf3 Jun 27 '14 at 06:22
  • I wish it were as simple as that. "Although F-curves are very similar to Bézier curves, there are some important differences." http://wiki.blender.org/index.php/Doc:2.6/Manual/Animation/Editors/Graph/FCurves#Direction_of_time Bezier curves allow for arbitrary shapes, but an F-Curve cannot have two values at any one frame. I'm having trouble finding how to make F-Curves. – Justin Jun 27 '14 at 12:34
  • Well, step one is to sort your control points by time. The next is to make sure the handles never point in the wrong direction. Finally, you can either restrict your Bezier curves to 1 dimension such that x=t and y=B(t), or you can use a Newton's Method to find q such that B(q)_x == t. I'm not sure exactly where to find that code in the blender source, but this deserves its own question. – Mutant Bob Jun 27 '14 at 14:15
  • I asked about fcurves on the math stackexchange here: http://math.stackexchange.com/questions/850090/mathematical-definition-of-blenders-f-curves – Justin Jun 28 '14 at 15:33
  • Just for kicks and giggles, here's what I've been working on: I rendered this using a home-grown render engine (Rayito by Mike Farnsworth) with a few modifications. I used Blender to create the animation curves. https://www.youtube.com/watch?v=JSht1XBPwQE – Justin Jul 01 '14 at 16:07
1

Values that are keyframed change as the current frame changes. Using python you can step through each frame and export the keyed values with something like --

import bpy

scn = bpy.context.scene
obj = bpy.context.active_object

for f in range(scn.frame_start, scn.frame_end):
    # use frame_set() so that keyed values are updated
    scn.frame_set(f)
    print(scn.frame_current, obj.location)
sambler
  • 55,387
  • 3
  • 59
  • 192