How to set keyframe handles to be interpolated via script on the fly (low-level variant: keyframe_points.add(int) + keyframe_points[i].co=..)? When I do this in a script, both left and right handles begin at the (0.0, 0.0) point, so the animation curve looks like this:


Handles fix themselves if I do sth, like dragging just one of them. Seems like the api is so low-level that setting keyframes that way doesn't let some callback for interpolation to be called.
Here is the python script:

import bpy, re, sys

obj = bpy.context.active_object
obj.animation_data_create()
obj.animation_data.action = bpy.data.actions.new(name="MyAction")
fcu_x = obj.animation_data.action.fcurves.new(data_path="location", index=0)
fcu_y = obj.animation_data.action.fcurves.new(data_path="location", index=1)
fcu_z = obj.animation_data.action.fcurves.new(data_path="location", index=2)
f = open(".../example", "r")
for i in range(30):
    print(str(i))
    ln = f.readline()
    try:
        vec = [float(m) for m in re.split(r"[ \t\n]", ln)[:-1]]
    except ValueError:
        sys.stderr.write("ERROR")
    fcu_x.keyframe_points.add(1)
    fcu_x.keyframe_points[i].co = 24*vec[3], vec[0]
    fcu_y.keyframe_points.add(1)
    fcu_y.keyframe_points[i].co = 24*vec[3], vec[1]
    fcu_z.keyframe_points.add(1)
    fcu_z.keyframe_points[i].co = 24*vec[3], vec[2]


Here I parse a file string-by-string (3 coords + time in sec) and create corresponding location keyframes. I need to create animation in real-time and play it simultaneously, so moving the animated object and setting keyframes based on its real position is out of the question.

I could change the interpolation manually after each frame adding (for Blender to recalculate every handle each time), but I'm afraid that when the number of keyframes is in the thousands, it'll take too long.

Is there a way to set and calculate the interpolation for only the last keyframe point when adding it?
When using keyframe_insert() the default interpolation set in preferences is applied to each keyframe as it is added, this doesn't happen when using fcurves.new(), which always leaves it at bezier. If you don't want to use bezier interpolation then you will need to set the interpolation for each point as you create them.

fcu_x.keyframe_points[i].interpolation = 'LINEAR'


Then you will want to call fcurve.update().


  update()
  Ensure keyframes are sorted in chronological order and handles are set correctly