Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c86
1 files changed, 82 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 003e926e0ae..8bfc626379f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1076,6 +1076,84 @@ void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSample
fcu->totvert = end - start + 1;
}
+static void init_unbaked_bezt_data(BezTriple *bezt)
+{
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ /* Baked FCurve points always use linear interpolation. */
+ bezt->ipo = BEZT_IPO_LIN;
+ bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
+}
+
+/* Convert baked/sampled fcurves into bezt/regular fcurves. */
+void fcurve_samples_to_keyframes(FCurve *fcu, const int start, const int end)
+{
+
+ /* Sanity checks. */
+ /* TODO: make these tests report errors using reports not CLOG's (Joshua Leung 2009). */
+ if (fcu == NULL) {
+ CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Un-Bake");
+ return;
+ }
+
+ if (start > end) {
+ CLOG_ERROR(&LOG, "Error: Frame range to unbake F-Curve is inappropriate");
+ return;
+ }
+
+ if (fcu->fpt == NULL) {
+ /* No data to unbake. */
+ CLOG_ERROR(&LOG, "Error: Curve containts no baked keyframes");
+ return;
+ }
+
+ /* Free any existing sample/keyframe data on the curve. */
+ if (fcu->bezt) {
+ MEM_freeN(fcu->bezt);
+ }
+
+ BezTriple *bezt;
+ FPoint *fpt = fcu->fpt;
+ int keyframes_to_insert = end - start;
+ int sample_points = fcu->totvert;
+
+ bezt = fcu->bezt = MEM_callocN(sizeof(*fcu->bezt) * (size_t)keyframes_to_insert, __func__);
+ fcu->totvert = keyframes_to_insert;
+
+ /* Get first sample point to 'copy' as keyframe. */
+ for (; sample_points && (fpt->vec[0] < start); fpt++, sample_points--) {
+ /* pass */
+ }
+
+ /* Current position in the timeline. */
+ int cur_pos = start;
+
+ /* Add leading dummy flat points if needed. */
+ for (; keyframes_to_insert && (fpt->vec[0] > start); cur_pos++, bezt++, keyframes_to_insert--) {
+ init_unbaked_bezt_data(bezt);
+ bezt->vec[1][0] = (float)cur_pos;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ /* Copy actual sample points. */
+ for (; keyframes_to_insert && sample_points;
+ cur_pos++, bezt++, keyframes_to_insert--, fpt++, sample_points--) {
+ init_unbaked_bezt_data(bezt);
+ copy_v2_v2(bezt->vec[1], fpt->vec);
+ }
+
+ /* Add trailing dummy flat points if needed. */
+ for (fpt--; keyframes_to_insert; cur_pos++, bezt++, keyframes_to_insert--) {
+ init_unbaked_bezt_data(bezt);
+ bezt->vec[1][0] = (float)cur_pos;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ MEM_SAFE_FREE(fcu->fpt);
+
+ /* Not strictly needed since we use linear interpolation, but better be consistent here. */
+ calchandles_fcurve(fcu);
+}
+
/* ***************************** F-Curve Sanity ********************************* */
/* The functions here are used in various parts of Blender, usually after some editing
* of keyframe data has occurred. They ensure that keyframe data is properly ordered and
@@ -1194,7 +1272,7 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
/* For automatic ease in and out. */
if (BEZT_IS_AUTOH(bezt) && !cycle) {
/* Only do this on first or last beztriple. */
- if ((a == 0) || (a == fcu->totvert - 1)) {
+ if (ELEM(a, 0, fcu->totvert - 1)) {
/* Set both handles to have same horizontal value as keyframe. */
if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
@@ -1658,7 +1736,7 @@ static float fcurve_eval_keyframes_extrapolate(
return endpoint_bezt->vec[1][1] - (fac * dx);
}
- /* Use the gradient of the second handle (later) of neighbour to calculate the gradient and thus
+ /* Use the gradient of the second handle (later) of neighbor to calculate the gradient and thus
* the value of the curve at evaluation time. */
int handle = direction_to_neighbor > 0 ? 0 : 2;
float dx = endpoint_bezt->vec[1][0] - evaltime;
@@ -1934,7 +2012,7 @@ static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, fl
return 0.0f;
}
-/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes. */
+/* Calculate F-Curve value for 'evaltime' using #BezTriple keyframes. */
static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
{
if (evaltime <= bezts->vec[1][0]) {
@@ -1949,7 +2027,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
return fcurve_eval_keyframes_interpolate(fcu, bezts, evaltime);
}
-/* Calculate F-Curve value for 'evaltime' using FPoint samples. */
+/* Calculate F-Curve value for 'evaltime' using #FPoint samples. */
static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
{
FPoint *prevfpt, *lastfpt, *fpt;