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 /source/blender/editors/space_graph
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
Diffstat (limited to 'source/blender/editors/space_graph')
-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
3 files changed, 125 insertions, 0 deletions
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);
+}
+
+/** \} */