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:
authorChristoph Lendenfeld <chris.lend@gmx.at>2021-11-24 00:38:23 +0300
committerChristoph Lendenfeld <chris.lend@gmx.at>2021-11-24 00:38:23 +0300
commit6b4405d7579da65c35d8f9424440d58002aa1f9c (patch)
tree4a3d8fba2900177c244e4467ff9aaacaff424e96 /source/blender/editors/animation/keyframes_general.c
parentd144983f8cc0405f464c0e2fb56a6419ef3eb128 (diff)
Extract keyframe segment calculation
extracts the search for keyframe segments (consecutive selection of keys) It will be reused by future graph editor operators Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D9360 Ref: D9360
Diffstat (limited to 'source/blender/editors/animation/keyframes_general.c')
-rw-r--r--source/blender/editors/animation/keyframes_general.c86
1 files changed, 52 insertions, 34 deletions
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index ec33a42af3b..6a0122f4dc4 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -318,6 +318,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 */
@@ -401,7 +439,6 @@ static void decimate_fcurve_segment(FCurve *fcu,
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 +446,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 +474,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);
}