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
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
-rw-r--r--source/blender/editors/animation/keyframes_general.c86
-rw-r--r--source/blender/makesdna/DNA_curve_types.h2
2 files changed, 54 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);
}
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index a2433dbbbbd..341b5fee4e4 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -457,6 +457,8 @@ enum {
typedef enum eBezTriple_Flag {
/* SELECT */
BEZT_FLAG_TEMP_TAG = (1 << 1), /* always clear. */
+ /* Can be used to ignore keyframe points for certain operations. */
+ BEZT_FLAG_IGNORE_TAG = (1 << 2),
} eBezTriple_Flag;
/* h1 h2 (beztriple) */