diff options
Diffstat (limited to 'source/blender/editors/animation/keyframes_general.c')
-rw-r--r-- | source/blender/editors/animation/keyframes_general.c | 116 |
1 files changed, 52 insertions, 64 deletions
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index ec33a42af3b..dc5d71b5a1e 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -63,11 +63,6 @@ /* **************************************************** */ -/** - * Only delete the nominated keyframe from provided F-Curve. - * Not recommended to be used many times successively. For that - * there is #delete_fcurve_keys(). - */ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc) { /* sanity check */ @@ -101,7 +96,6 @@ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc) } } -/* Delete selected keyframes in given F-Curve */ bool delete_fcurve_keys(FCurve *fcu) { bool changed = false; @@ -140,7 +134,6 @@ void clear_fcurve_keys(FCurve *fcu) /* ---------------- */ -/* duplicate selected keyframes for the given F-Curve */ void duplicate_fcurve_keys(FCurve *fcu) { /* this can only work when there is an F-Curve, and also when there are some BezTriples */ @@ -176,10 +169,6 @@ void duplicate_fcurve_keys(FCurve *fcu) /* **************************************************** */ /* Various Tools */ -/** - * Basic F-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on - * linear-segments only optionally clears up curve if one keyframe with default value remains. - */ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault) { FCurve *fcu = (FCurve *)ale->key_data; @@ -318,6 +307,44 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo } } +/** Find the first segment of consecutive selected curve points, starting from \a start_index. + * Keys that have BEZT_FLAG_IGNORE_TAG set are treated as unselected. + * \param r_segment_start_idx: returns the start index of the segment. + * \param r_segment_len: returns the number of curve points in the segment. + * \return whether such a segment was found or not.*/ +static bool find_fcurve_segment(FCurve *fcu, + const int start_index, + int *r_segment_start_idx, + int *r_segment_len) +{ + *r_segment_start_idx = 0; + *r_segment_len = 0; + + bool in_segment = false; + + for (int i = start_index; i < fcu->totvert; i++) { + const bool point_is_selected = fcu->bezt[i].f2 & SELECT; + const bool point_is_ignored = fcu->bezt[i].f2 & BEZT_FLAG_IGNORE_TAG; + + if (point_is_selected && !point_is_ignored) { + if (!in_segment) { + *r_segment_start_idx = i; + in_segment = true; + } + (*r_segment_len)++; + } + else if (in_segment) { + /* If the curve point is not selected then we have reached the end of the selected curve + * segment. */ + return true; /* Segment found. */ + } + } + + /* If the last curve point was in the segment, `r_segment_len` and `r_segment_start_idx` + * are already updated and true is returned. */ + return in_segment; +} + /* ---------------- */ /* Check if the keyframe interpolation type is supported */ @@ -391,17 +418,9 @@ static void decimate_fcurve_segment(FCurve *fcu, target_fcurve_verts); } -/** - * F-Curve 'decimate' function that removes a certain ratio of curve - * points that will affect the curves overall shape the least. - * If you want to remove based on a error margin, set remove_ratio to 1 and - * simply specify the desired error_sq_max. Otherwise, set the error margin to - * FLT_MAX. - */ bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max) { FCurve *fcu = (FCurve *)ale->key_data; - /* Check if the curve actually has any points. */ if (fcu == NULL || fcu->bezt == NULL || fcu->totvert == 0) { return true; @@ -409,46 +428,26 @@ bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max) BezTriple *old_bezts = fcu->bezt; - /* Only decimate the individual selected curve segments. */ - int bezt_segment_start_idx = 0; - int bezt_segment_len = 0; - - bool selected; bool can_decimate_all_selected = true; - bool in_segment = false; for (int i = 0; i < fcu->totvert; i++) { - selected = fcu->bezt[i].f2 & SELECT; - /* Make sure that the temp flag is unset as we use it to determine what to remove. */ - fcu->bezt[i].f2 &= ~BEZT_FLAG_TEMP_TAG; - - if (selected && !prepare_for_decimate(fcu, i)) { - /* This keyframe is not supported, treat them as if they were unselected. */ - selected = false; + /* Ignore keyframes that are not supported. */ + if (!prepare_for_decimate(fcu, i)) { can_decimate_all_selected = false; + fcu->bezt[i].f2 |= BEZT_FLAG_IGNORE_TAG; } - - if (selected) { - if (!in_segment) { - bezt_segment_start_idx = i; - in_segment = true; - } - bezt_segment_len++; - } - else if (in_segment) { - /* If the curve point is not selected then we have reached the end of the selected curve - * segment. */ - decimate_fcurve_segment( - fcu, bezt_segment_start_idx, bezt_segment_len, remove_ratio, error_sq_max); - in_segment = false; - bezt_segment_len = 0; - } + /* Make sure that the temp flag is unset as we use it to determine what to remove. */ + fcu->bezt[i].f2 &= ~BEZT_FLAG_TEMP_TAG; } - /* Did the segment run to the end of the curve? */ - if (in_segment) { - decimate_fcurve_segment( - fcu, bezt_segment_start_idx, bezt_segment_len, remove_ratio, error_sq_max); + /* Only decimate the individual selected curve segments. */ + int segment_start_idx = 0; + int segment_len = 0; + int current_index = 0; + + while (find_fcurve_segment(fcu, current_index, &segment_start_idx, &segment_len)) { + decimate_fcurve_segment(fcu, segment_start_idx, segment_len, remove_ratio, error_sq_max); + current_index = segment_start_idx + segment_len; } uint old_totvert = fcu->totvert; @@ -457,6 +456,7 @@ bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max) for (int i = 0; i < old_totvert; i++) { BezTriple *bezt = (old_bezts + i); + bezt->f2 &= ~BEZT_FLAG_IGNORE_TAG; if ((bezt->f2 & BEZT_FLAG_TEMP_TAG) == 0) { insert_bezt_fcurve(fcu, bezt, 0); } @@ -477,8 +477,6 @@ typedef struct tSmooth_Bezt { float y1, y2, y3; /* averaged before/new/after y-values */ } tSmooth_Bezt; -/* Use a weighted moving-means method to reduce intensity of fluctuations */ -/* TODO: introduce scaling factor for weighting falloff */ void smooth_fcurve(FCurve *fcu) { int totSel = 0; @@ -582,7 +580,6 @@ typedef struct TempFrameValCache { float frame, val; } TempFrameValCache; -/* Evaluates the curves between each selected keyframe on each frame, and keys the value. */ void sample_fcurve(FCurve *fcu) { BezTriple *bezt, *start = NULL, *end = NULL; @@ -691,7 +688,6 @@ typedef struct tAnimCopybufItem { bool is_bone; /* special flag for armature bones */ } tAnimCopybufItem; -/* This function frees any MEM_calloc'ed copy/paste buffer data */ void ANIM_fcurves_copybuf_free(void) { tAnimCopybufItem *aci, *acn; @@ -722,7 +718,6 @@ void ANIM_fcurves_copybuf_free(void) /* ------------------- */ -/* This function adds data to the keyframes copy/paste buffer, freeing existing data first */ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data) { bAnimListElem *ale; @@ -1081,8 +1076,6 @@ static void paste_animedit_keys_fcurve( calchandles_fcurve(fcu); } -/* ------------------- */ - const EnumPropertyItem rna_enum_keyframe_paste_offset_items[] = { {KEYFRAME_PASTE_OFFSET_CFRA_START, "START", @@ -1115,11 +1108,6 @@ const EnumPropertyItem rna_enum_keyframe_paste_merge_items[] = { {0, NULL, 0, NULL, NULL}, }; -/** - * This function pastes data from the keyframes copy/paste buffer - * - * \return Status code is whether the method FAILED to do anything - */ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data, const eKeyPasteOffset offset_mode, |