2
$\begingroup$

I have 2 keyframe points on an fcurve with free bezier handles, and using Python I want to insert a point in between these keyframes whilst keeping the custom shape of the curve with the handles. I can insert a keyframe point no problem using

fCurve.keyframe_points.insert(frame, value)

but I'm not sure how to do so without affecting the shape of the fcurve. Is this possible?

$\endgroup$
7
  • $\begingroup$ You would need to read the value at that frame and then insert a keyframe with that value, if you want to insert one but not change the f-curve. $\endgroup$ Jul 7, 2016 at 19:38
  • $\begingroup$ I can get the value at a keyframe between the points no problem, but the issue is if either of the existing points has free handles which have been moved to change the shape of the fcurve, then inserting a point won't keep that shape. I'm wondering if there is a way to insert a value (which I know lies on the curve) whilst keeping the custom shape defined by the handles? $\endgroup$
    – Rajveer
    Jul 7, 2016 at 19:42
  • $\begingroup$ This is actually relatively straightforward. The Python API has access to the coordinates of the keyframe_points of the fcurve .co and the handles .handle_left and .handle_right. You can create a new point between the other two and set up the handles using De Casteljau’s Algorithm : clear.rice.edu/comp360/lectures/BezSubd.pdf $\endgroup$
    – Mutant Bob
    Jul 7, 2016 at 20:04
  • $\begingroup$ possible duplicate of blender.stackexchange.com/questions/45311/… $\endgroup$
    – Mutant Bob
    Jul 8, 2016 at 14:51
  • $\begingroup$ Thank you, I've almost got it working with the snippets. The only problem is that I want to add a point at a particular keyframe between 2 existing keyframes, rather than at a time t along the Bezier path (e.g. midway between 2 keyframes isn't necessarily midway along the curve, so I can't use t = 0.5). I can't find if the Python API exposes the time t for a point on an f-curve or if I'm just missing something obvious :) $\endgroup$
    – Rajveer
    Jul 11, 2016 at 16:21

1 Answer 1

0
$\begingroup$

Subdividing Bezier curves is normally done using De Casteljau's algorithm. However, fcurves aren't pure Bezier curves. It is not hard to make a bezier curve "run backwards" along the time axis. Since this would create ambiguities in the animation system, blender prevents that by using modified handle coordinates whenever the handles could make the curve backtrack in the time axis. Once we understand that math, we have what is needed to properly subdivide the fcurve.

The solution is already covered at https://blender.stackexchange.com/a/57453/660 . It includes an excerpt from http://web.purplefrog.com/~thoth/blender/python-cookbook/subdivide-fcurve.html . I got bored and added the logic needed to map from frame->t so it should now be a fairly complete solution. I'm not copying the code over here, because keeping it up-to-date in both articles on stackexchange is tedious.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .