Weird fcurves when creating keys through python

Hello!

Short summary:
I’m working on a script to transfer camera movements from after effects to blender.
It seems to work fine. But afterwards when I look in the fcurve editor the curves look really weird. All interpolations look like 'u’s pulled down (or up) towards frame 0 and when all key frames are selected there are pink lines going from each of them towards frame 0 and value 0. Have I missed something? Am I supposed to manually (ie programmatically) set which key frame is the one before and the one following each keyframe somewhere?

If I from the gui just either add a keyframe (anywhere, does not even have to be on all curves - on one of the curves is enough, but it can’t be on a separately created object) or delete a keyframe for all curves the interpolation immediately turns to look like I expect. Any ideas on the reason, or what I have set wrong? Interpolation mode? Where do I set it and how? And why does creating a keyframe or deleting a keyframe make things look right? What’s happening there ‘behind the hood’?

Long version:

I’m working on a script to transfer camera movements from after effects to blender. I have a free script which exports cameras to maya, 3dsmax and some other program which I’m planning to modify to support blender as well. Currently as a first step my script is loading empties, cameras and animation curves from the .ma file exported by the script I downloaded but I’m hoping to skip that step in the future. (However, the blend format seems… like a headache. I think I’ll rather have my exporter create a python script which sets up the cameras and nulls.) Now to my problem: it currently loads the empties, cameras and animation curves (I do expect to have to check the rotations as there might be differencies using degrees vs radians between the programs). I don’t understand all the fields and different types of animation curves from the ma file, so I’m just importing the ones with .ktv (seems to be the values) [the limited support is not a problem for the intended use, as the camera is exported with a keyframe for each frame - to be clear: I have no intention to create a script to fully translate .ma files, it will only have the minimal support I need to get things to work, and once I have it working I plan to remove that so it creates a python script file directly instead].

This is the code principle I’m using to create the curve:

object.animation_data_create()
object.animation_data.action = bpy.data.actions.new(name=...) # the name itself is not important here
curve = obj.animation_data.action.fcurves.new(data_path="rotation_euler", index=0)  # or data_path="location", index 0 for x, 1 for y and 2 for z
# read amount of keys from file
curve.keyframe_points.add(no_keys)
#for each keyframe read frame and value from file
curve.keyframe_points[i].co = frame,value

It seems to work fine. (I expect some possible degrees/radians problems, but that will be easy to fix, and some axes differencies, I’m not sure I’ll bother to fix that though as by then I’ll have learned all the python needed to not need the middle step of going through the exported ma file.) But afterwards when I look in the fcurve editor the curves look really weird. All interpolations look like 'u’s pulled down towards frame 0 and when all key frames are selected there are pink lines going from each of them towards frame 0 and value 0. Have I missed something? Am I supposed to manually (ie programmatically) set which key frame is the one before and the one following each keyframe somewhere?

If I from the gui just either add a keyframe (anywhere, does not even have to be on all curves - on one of the curves is enough, but it can’t be on a separately created object) or delete a keyframe for all curves the interpolation immediately turns to look like I expect. Any ideas on the reason, or what I have set wrong? Interpolation mode? Where do I set it and how? And why does creating a keyframe or deleting a keyframe make things look right? What’s happening there ‘behind the hood’?

I appreciate your help. (I have googled and been unable to find any already existing scripts to export cameras from ae to blender, but if you know of a working one that I have missed please let me know and I’ll scrap this project immediately, but I’d still be happy if you could help me understand what goes wrong with my fcurves.)

Best wishes,
Torbjörn

not sure but might be similar to a problem i discovered myself when working with fcurves:
if you create a new fcurve, it already has 1 (!) keyframe point. So you need to add number_of_keyframes - 1 (minus one!!!) or there will be an abandoned extra point that breaks the fcurve

Thank you for your input! You may be right. To be safe I added - len(curve.keyframe_points). It did however not solve my problem. After some sleep I looked through the structure of a keyframe, and started setting the left and right handles and types thereof instead of keeping them at the default (probably that was 0, and the reason of the weird pulling). I still don’t understand how just selecting a keyframe, pressing ‘g’ and then rightclicking to cancel could have it solved though. As I understand it it must mean it’s interpreting the value of interpolation (which from the docs is supposed to default to ‘constant’) incorrectly before this refresh.

what i meant was:
curve.keyframe_points.add(no_keys-1)

Yes, I understood that, and I appreciate your help. If you are right (never checked, but believe you) I had a miss there as well, and I’m glad for your help in resolving that one, though I had not even noticed that one yet. To me it seems weird though that a new curve begins with one point, so to be safe for changes in the future I went with curve.keyframe_points.add(no_keys - len(curve.keyframe_points) ). I hope if they’d change so a new curve has 0 points or 2 points hopefully it will still work (I’m quite new to python, even if having a background in java, C++ and C#).

not sure why it starts with one, there seem to be a few types that automatically add something, might be required for other pieces of internal code