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-12-25 22:58:47 +0300
committerChristoph Lendenfeld <chris.lend@gmx.at>2021-12-25 22:58:47 +0300
commitf7ddb1ed8a2a646e3d04d5e2e46929673084149c (patch)
treed84ae6df91d7935a61c3737605820382dd8d9929
parentfbd01624e3feb10add9d04672a3db0f52817423a (diff)
Breakdown Implementation
This patch adds the breakdown (or tween) functionality to the graph editor. The factor defines the linear interpolation from left key to right key. Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D9375 Ref: D9375
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py3
-rw-r--r--source/blender/editors/animation/keyframes_general.c12
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h3
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c1
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c123
6 files changed, 142 insertions, 1 deletions
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 497d68f88ca..3a668f61539 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -344,7 +344,8 @@ class GRAPH_MT_slider(Menu):
def draw(self, _context):
layout = self.layout
-
+
+ layout.operator("graph.breakdown", text="Breakdown")
layout.operator("graph.blend_to_neighbor", text="Blend To Neighbor")
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 3c2e66d9367..8aac1e9b779 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -400,6 +400,18 @@ void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const
/* ---------------- */
+void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor)
+{
+ BezTriple left_bezt = fcurve_segment_start_get(fcu, segment->start_index);
+ BezTriple right_bezt = fcurve_segment_end_get(fcu, segment->start_index + segment->length);
+
+ for (int i = segment->start_index; i < segment->start_index + segment->length; i++) {
+ fcu->bezt[i].vec[1][1] = interpf(right_bezt.vec[1][1], left_bezt.vec[1][1], factor);
+ }
+}
+
+/* ---------------- */
+
/* Check if the keyframe interpolation type is supported */
static bool prepare_for_decimate(FCurve *fcu, int i)
{
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 084da038604..c54fb93e495 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -392,6 +392,9 @@ void clean_fcurve(struct bAnimContext *ac,
void blend_to_neighbor_fcurve_segment(struct FCurve *fcu,
struct FCurveSegment *segment,
const float factor);
+void breakdown_fcurve_segment(struct FCurve *fcu,
+ struct FCurveSegment *segment,
+ const float factor);
bool decimate_fcurve(struct bAnimListElem *ale, float remove_ratio, float error_sq_max);
/**
* Use a weighted moving-means method to reduce intensity of fluctuations.
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index ed52e684eb7..286580b5629 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -127,6 +127,7 @@ void GRAPH_OT_duplicate(struct wmOperatorType *ot);
void GRAPH_OT_delete(struct wmOperatorType *ot);
void GRAPH_OT_clean(struct wmOperatorType *ot);
void GRAPH_OT_blend_to_neighbor(struct wmOperatorType *ot);
+void GRAPH_OT_breakdown(struct wmOperatorType *ot);
void GRAPH_OT_decimate(struct wmOperatorType *ot);
void GRAPH_OT_sample(struct wmOperatorType *ot);
void GRAPH_OT_bake(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 724d5351283..fe4cffcb3b8 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -471,6 +471,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_clean);
WM_operatortype_append(GRAPH_OT_decimate);
WM_operatortype_append(GRAPH_OT_blend_to_neighbor);
+ WM_operatortype_append(GRAPH_OT_breakdown);
WM_operatortype_append(GRAPH_OT_euler_filter);
WM_operatortype_append(GRAPH_OT_delete);
WM_operatortype_append(GRAPH_OT_duplicate);
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index a78e65aa3d6..733313dd06b 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -681,3 +681,126 @@ void GRAPH_OT_blend_to_neighbor(wmOperatorType *ot)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Breakdown Operator
+ * \{ */
+
+static void breakdown_graph_keys(bAnimContext *ac, float factor)
+{
+ ListBase anim_data = {NULL, NULL};
+ ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
+
+ bAnimListElem *ale;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ ListBase segments = find_fcurve_segments(fcu);
+ LISTBASE_FOREACH (FCurveSegment *, segment, &segments) {
+ breakdown_fcurve_segment(fcu, segment, factor);
+ }
+ BLI_freelistN(&segments);
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+}
+
+static void breakdown_draw_status_header(bContext *C, tGraphSliderOp *gso)
+{
+ char status_str[UI_MAX_DRAW_STR];
+ char mode_str[32];
+ char slider_string[UI_MAX_DRAW_STR];
+
+ ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
+
+ strcpy(mode_str, TIP_("Breakdown"));
+
+ if (hasNumInput(&gso->num)) {
+ char str_ofs[NUM_STR_REP_LEN];
+
+ outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
+
+ BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
+ }
+ else {
+ BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
+ }
+
+ ED_workspace_status_text(C, status_str);
+}
+
+static void breakdown_modal_update(bContext *C, wmOperator *op)
+{
+ tGraphSliderOp *gso = op->customdata;
+
+ breakdown_draw_status_header(C, gso);
+
+ /* Reset keyframe data to the state at invoke. */
+ reset_bezts(gso);
+ breakdown_graph_keys(&gso->ac, ED_slider_factor_get(gso->slider));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+}
+
+static int breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const int invoke_result = graph_slider_invoke(C, op, event);
+
+ if (invoke_result == OPERATOR_CANCELLED) {
+ return invoke_result;
+ }
+
+ tGraphSliderOp *gso = op->customdata;
+ gso->modal_update = breakdown_modal_update;
+ breakdown_draw_status_header(C, gso);
+
+ return invoke_result;
+}
+
+static int breakdown_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const float factor = RNA_float_get(op->ptr, "factor");
+
+ breakdown_graph_keys(&ac, factor);
+
+ /* Set notifier that keyframes have changed. */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_breakdown(wmOperatorType *ot)
+{
+ /* Identifiers. */
+ ot->name = "Breakdown";
+ ot->idname = "GRAPH_OT_breakdown";
+ ot->description = "Move selected keyframes to an inbetween position relative to adjacent keys";
+
+ /* API callbacks. */
+ ot->invoke = breakdown_invoke;
+ ot->modal = graph_slider_modal;
+ ot->exec = breakdown_exec;
+ ot->poll = graphop_editable_keyframes_poll;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_float_factor(ot->srna,
+ "factor",
+ 1.0f / 3.0f,
+ -FLT_MAX,
+ FLT_MAX,
+ "Factor",
+ "Favor either the left or the right key",
+ 0.0f,
+ 1.0f);
+}
+
+/** \} */