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:
authorKevin C. Burke <blastframe>2022-01-25 13:40:46 +0300
committerSybren A. Stüvel <sybren@blender.org>2022-01-25 13:41:40 +0300
commit17b0c06946bef39e29e3b0b1a5faaf8faca35daa (patch)
tree8d0ce3b0f680206d5e1da36f9f3bb718dc58d64b /source/blender/editors/space_graph
parenta000de7c2a4da1fb57cb22658b29d1ac17c9cd51 (diff)
Animation: Equalize Handle Operator
The Equalize Handles operator allows users to make selected handle lengths uniform: either respecting their original angle from the key control point or by flattening their angle (removing the overshoot sometimes produced by certain handle types). Design: T94172 Reviewed by: sybren Differential Revision: https://developer.blender.org/D13702
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r--source/blender/editors/space_graph/graph_edit.c97
-rw-r--r--source/blender/editors/space_graph/graph_intern.h10
-rw-r--r--source/blender/editors/space_graph/graph_ops.c1
3 files changed, 108 insertions, 0 deletions
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 2afee277847..9675901ead3 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -2353,6 +2353,103 @@ void GRAPH_OT_snap(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Equalize Handles Operator
+ * \{ */
+
+/* Defines for equalize handles tool. */
+static const EnumPropertyItem prop_graphkeys_equalize_handles_sides[] = {
+ {GRAPHKEYS_EQUALIZE_LEFT, "LEFT", 0, "Left", "Equalize selected keyframes' left handles"},
+ {GRAPHKEYS_EQUALIZE_RIGHT, "RIGHT", 0, "Right", "Equalize selected keyframes' right handles"},
+ {GRAPHKEYS_EQUALIZE_BOTH, "BOTH", 0, "Both", "Equalize both of a keyframe's handles"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+/* ------------------- */
+
+/* Equalize selected keyframes' bezier handles. */
+static void equalize_graph_keys(bAnimContext *ac, int mode, float handle_length, bool flatten)
+{
+ /* Filter data. */
+ const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ListBase anim_data = {NULL, NULL};
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* Equalize keyframes. */
+ LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
+ ANIM_fcurve_equalize_keyframes_loop(ale->key_data, mode, handle_length, flatten);
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+}
+
+static int graphkeys_equalize_handles_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ /* Get editor data. */
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Get equalize mode. */
+ int mode = RNA_enum_get(op->ptr, "side");
+ float handle_length = RNA_float_get(op->ptr, "handle_length");
+ bool flatten = RNA_boolean_get(op->ptr, "flatten");
+
+ /* Equalize graph keyframes. */
+ equalize_graph_keys(&ac, mode, handle_length, flatten);
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_equalize_handles(wmOperatorType *ot)
+{
+ /* Identifiers */
+ ot->name = "Equalize Handles";
+ ot->idname = "GRAPH_OT_equalize_handles";
+ ot->description =
+ "Ensure selected keyframes' handles have equal length, optionally making them horizontal";
+
+ /* API callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_equalize_handles_exec;
+ ot->poll = graphop_editable_keyframes_poll;
+
+ /* Flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties */
+ ot->prop = RNA_def_enum(ot->srna,
+ "side",
+ prop_graphkeys_equalize_handles_sides,
+ 0,
+ "Side",
+ "Side of the keyframes' bezier handles to affect");
+ RNA_def_float(ot->srna,
+ "handle_length",
+ 5.0f,
+ 0.1f,
+ FLT_MAX,
+ "Handle Length",
+ "Length to make selected keyframes' bezier handles",
+ 1.0f,
+ 50.0f);
+ RNA_def_boolean(
+ ot->srna,
+ "flatten",
+ false,
+ "Flatten",
+ "Make the values of the selected keyframes' handles the same as their respective keyframes");
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Mirror Keyframes Operator
* \{ */
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 243a4ee4b95..a59fb63dd22 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -144,6 +144,7 @@ void GRAPH_OT_easing_type(struct wmOperatorType *ot);
void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
void GRAPH_OT_snap_cursor_value(struct wmOperatorType *ot);
void GRAPH_OT_snap(struct wmOperatorType *ot);
+void GRAPH_OT_equalize_handles(struct wmOperatorType *ot);
void GRAPH_OT_mirror(struct wmOperatorType *ot);
/* defines for snap keyframes
@@ -158,6 +159,15 @@ enum eGraphKeys_Snap_Mode {
GRAPHKEYS_SNAP_VALUE,
};
+/* Defines for equalize keyframe handles.
+ * NOTE: Keep in sync with eEditKeyframes_Equalize (in ED_keyframes_edit.h).
+ */
+enum eGraphKeys_Equalize_Mode {
+ GRAPHKEYS_EQUALIZE_LEFT = 1,
+ GRAPHKEYS_EQUALIZE_RIGHT,
+ GRAPHKEYS_EQUALIZE_BOTH,
+};
+
/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index fe4cffcb3b8..7606dcc60cf 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -456,6 +456,7 @@ void graphedit_operatortypes(void)
/* editing */
WM_operatortype_append(GRAPH_OT_snap);
+ WM_operatortype_append(GRAPH_OT_equalize_handles);
WM_operatortype_append(GRAPH_OT_mirror);
WM_operatortype_append(GRAPH_OT_frame_jump);
WM_operatortype_append(GRAPH_OT_snap_cursor_value);