[Bf-blender-cvs] [a0dfa320cdd] blender2.8: Dope Sheet: new option to display keyframe interpolation mode and extremes.

Alexander Gavrilov noreply at git.blender.org
Mon Oct 29 20:13:17 CET 2018


Commit: a0dfa320cddd8396911058bae7c3a0eb52e7f2ee
Author: Alexander Gavrilov
Date:   Fri Oct 19 18:55:19 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBa0dfa320cddd8396911058bae7c3a0eb52e7f2ee

Dope Sheet: new option to display keyframe interpolation mode and extremes.

With the new automatic handle algorithm, it is possible to do a lot
of the animation via keyframes without touching the curves. It is
however necessary to change the keyframe interpolation and handle
types in certain cases. Currently the dopesheet/action editor
allows changing the types, but does not show them in any way.

To fix, add a new menu option to display this information. For handle
type, it is represented using the shape of the key icons: diamond for
Free, clipped diamond for Aligned, square for Vector, circle for Auto
Clamp, and cirle with dot for Automatic.

Non-bezier interpolation is a property of intervals between keys,
so it is marked by drawing lines, similar to holds. In this initial
version, only the fact of non-bezier interpolation is displayed,
without distinguishing types. For summaries, the line is drawn at
half alpha if not all curves in the group are non-bezier.

In addition, it is sometimes helpful to know the general direction
of change of the curve, and which keys are extremes. This commit
also adds an option to highlight extremes, based on comparing the
keyed values with adjacent keys. Half-intensity display is used
for overshot bezier extremes, or non-uniform summaries.

Reviewers: brecht, aligorith, billreynish

Differential Revision: https://developer.blender.org/D3788

===================================================================

M	release/datafiles/userdef/userdef_default_theme.c
M	release/scripts/startup/bl_ui/space_dopesheet.py
M	source/blender/blenkernel/BKE_blender_version.h
M	source/blender/blenkernel/intern/anim.c
M	source/blender/blenloader/intern/versioning_userdef.c
M	source/blender/editors/animation/anim_draw.c
M	source/blender/editors/animation/keyframes_draw.c
M	source/blender/editors/armature/pose_lib.c
M	source/blender/editors/armature/pose_slide.c
M	source/blender/editors/include/ED_keyframes_draw.h
M	source/blender/editors/include/UI_icons.h
M	source/blender/editors/include/UI_resources.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/interface/resources.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/space_action/action_draw.c
M	source/blender/editors/space_action/action_select.c
M	source/blender/editors/space_clip/clip_dopesheet_draw.c
M	source/blender/editors/space_nla/nla_draw.c
M	source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl
M	source/blender/makesdna/DNA_action_types.h
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_curve.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/makesrna/intern/rna_userdef.c

===================================================================

diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c
index daf4b1eb1bc..99744022813 100644
--- a/release/datafiles/userdef/userdef_default_theme.c
+++ b/release/datafiles/userdef/userdef_default_theme.c
@@ -512,6 +512,7 @@ const bTheme U_theme_default = {
 		.cframe = RGBA(0x5680c2ff),
 		.ds_channel = RGBA(0x547ca624),
 		.ds_subchannel = RGBA(0x748da624),
+		.ds_ipoline = RGBA(0x94e575cc),
 		.keytype_keyframe = RGBA(0xe8e8e8ff),
 		.keytype_extreme = RGBA(0xe8b3ccff),
 		.keytype_breakdown = RGBA(0xb3dbe8ff),
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 145eea66d0a..fb8a59097d6 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -335,6 +335,8 @@ class DOPESHEET_MT_view(Menu):
         layout.prop(st, "show_frame_indicator")
         layout.prop(st, "show_sliders")
         layout.prop(st, "show_group_colors")
+        layout.prop(st, "show_interpolation")
+        layout.prop(st, "show_extremes")
         layout.prop(st, "use_auto_merge_keyframes")
         layout.prop(st, "use_marker_sync")
 
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index b5e20671cac..6435fe461cc 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -28,7 +28,7 @@
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         280
-#define BLENDER_SUBVERSION      27
+#define BLENDER_SUBVERSION      28
 /* Several breakages with 280, e.g. collections vs layers */
 #define BLENDER_MINVERSION      280
 #define BLENDER_MINSUBVERSION   0
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index d70f3459324..89291b158b7 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -65,8 +65,8 @@
 
 // XXX bad level call...
 extern short compare_ak_cfraPtr(void *node, void *data);
-extern void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys);
-extern void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys);
+extern void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys, int saction_flag);
+extern void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, int saction_flag);
 
 /* --------------------- */
 /* forward declarations */
@@ -485,11 +485,11 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
 				bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
 
 				if (agrp) {
-					agroup_to_keylist(adt, agrp, &mpt->keys);
+					agroup_to_keylist(adt, agrp, &mpt->keys, 0);
 				}
 			}
 			else {
-				action_to_keylist(adt, adt->action, &mpt->keys);
+				action_to_keylist(adt, adt->action, &mpt->keys, 0);
 			}
 		}
 	}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 2f98d068e7d..b622bc016f5 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -77,6 +77,10 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme)
 		copy_v4_v4_char(btheme->tact.keytype_movehold, U_theme_default.tact.keytype_movehold);
 		copy_v4_v4_char(btheme->tact.keytype_movehold_select, U_theme_default.tact.keytype_movehold_select);
 	}
+
+	if (!USER_VERSION_ATLEAST(280, 28)) {
+		copy_v4_v4_char(btheme->tact.ds_ipoline, U_theme_default.tact.ds_ipoline);
+	}
 #undef USER_VERSION_ATLEAST
 
 }
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 48dd310e2b4..a2046985a36 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -551,11 +551,11 @@ static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prev
 	}
 
 	/* populate tree with keyframe nodes */
-	scene_to_keylist(&ads, scene, &keys);
+	scene_to_keylist(&ads, scene, &keys, 0);
 	gpencil_to_keylist(&ads, scene->gpd, &keys, false);
 
 	if (ob) {
-		ob_to_keylist(&ads, ob, &keys);
+		ob_to_keylist(&ads, ob, &keys, 0);
 		gpencil_to_keylist(&ads, ob->data, &keys, false);
 	}
 
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 33e2a11f4c5..008160e2459 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -42,6 +42,7 @@
 #include "BLI_dlrbTree.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+#include "BLI_rect.h"
 
 #include "DNA_anim_types.h"
 #include "DNA_cachefile_types.h"
@@ -96,24 +97,108 @@ short compare_ak_cfraPtr(void *node, void *data)
 
 /* --------------- */
 
-/* Comparator callback used for ActKeyColumns and BezTriple */
+/* Set of references to three logically adjacent keys. */
+typedef struct BezTripleChain {
+	/* Current keyframe. */
+	BezTriple *cur;
+
+	/* Logical neighbors. May be NULL. */
+	BezTriple *prev, *next;
+} BezTripleChain;
+
+/* Categorize the interpolation & handle type of the keyframe. */
+static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
+{
+	if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
+		return KEYFRAME_HANDLE_AUTO_CLAMP;
+	}
+	else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
+		return KEYFRAME_HANDLE_AUTO;
+	}
+	else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
+		return KEYFRAME_HANDLE_VECTOR;
+	}
+	else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
+		return KEYFRAME_HANDLE_FREE;
+	}
+	else {
+		return KEYFRAME_HANDLE_ALIGNED;
+	}
+}
+
+/* Determine if the keyframe is an extreme by comparing with neighbors.
+ * Ends of fixed-value sections and of the whole curve are also marked.
+ */
+static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain)
+{
+	if (chain->prev == NULL && chain->next == NULL) {
+		return KEYFRAME_EXTREME_NONE;
+	}
+
+	/* Keyframe values for the current one and neighbors. */
+	float cur_y = chain->cur->vec[1][1];
+	float prev_y = cur_y, next_y = cur_y;
+
+	if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) {
+		prev_y = chain->prev->vec[1][1];
+	}
+	if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
+		next_y = chain->next->vec[1][1];
+	}
+
+	/* Static hold. */
+	if (prev_y == cur_y && next_y == cur_y) {
+		return KEYFRAME_EXTREME_FLAT;
+	}
+
+	/* Middle of an incline. */
+	if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
+		return KEYFRAME_EXTREME_NONE;
+	}
+
+	/* Bezier handle values for the overshoot check. */
+	bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ;
+	bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ;
+	float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y;
+	float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y;
+
+	/* Detect extremes. One of the neighbors is allowed to be equal to current. */
+	if (prev_y < cur_y || next_y < cur_y) {
+		bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
+
+		return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
+	}
+
+	if (prev_y > cur_y || next_y > cur_y) {
+		bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
+
+		return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
+	}
+
+	return KEYFRAME_EXTREME_NONE;
+}
+
+/* Comparator callback used for ActKeyColumns and BezTripleChain */
 static short compare_ak_bezt(void *node, void *data)
 {
-	BezTriple *bezt = (BezTriple *)data;
+	BezTripleChain *chain = (BezTripleChain*)data;
 
-	return compare_ak_cfraPtr(node, &bezt->vec[1][0]);
+	return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
 }
 
-/* New node callback used for building ActKeyColumns from BezTriples */
+/* New node callback used for building ActKeyColumns from BezTripleChain */
 static DLRBT_Node *nalloc_ak_bezt(void *data)
 {
 	ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
-	BezTriple *bezt = (BezTriple *)data;
+	BezTripleChain *chain = (BezTripleChain*)data;
+	BezTriple *bezt = chain->cur;
 
 	/* store settings based on state of BezTriple */
 	ak->cfra = bezt->vec[1][0];
 	ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
 	ak->key_type = BEZKEYTYPE(bezt);
+	ak->handle_type = bezt_handle_type(bezt);
+	ak->extreme_type = bezt_extreme_type(chain);
 
 	/* count keyframes in this column */
 	ak->totkey = 1;
@@ -121,11 +206,12 @@ static DLRBT_Node *nalloc_ak_bezt(void *data)
 	return (DLRBT_Node *)ak;
 }
 
-/* Node updater callback used for building ActKeyColumns from BezTriples */
+/* Node updater callback used for building ActKeyColumns from BezTripleChain */
 static void nupdate_ak_bezt(void *node, void *data)
 {
 	ActKeyColumn *ak = (ActKeyColumn *)node;
-	BezTriple *bezt = (BezTriple *)data;
+	BezTripleChain *chain = (BezTripleChain*)data;
+	BezTriple *bezt = chain->cur;
 
 	/* set selection status and 'touched' status */
 	if (BEZT_ISSEL_ANY(bezt)) ak->sel = SELECT;
@@ -136,6 +222,22 @@ static void nupdate_ak_bezt(void *node, void *data)
 	/* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
 	if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
 		ak->key_type = BEZT_KEYTYPE_KEYFRAME;
+
+	/* For interpolation type, select the highest value (enum is sorted). */
+	ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
+
+	/* For extremes, detect when combining different states. */
+	char new_extreme = bezt_extreme_type(chain);
+
+	if (new_extreme != ak->extreme_type) {
+		/* Replace the flat status without adding mixed. */
+		if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
+			ak->extreme_type = new_extreme;
+		}
+		else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
+			ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
+		}
+	}
 }
 
 /* ......... */
@@ -225,7 +327,7 @@ static void nupdate_ak_masklayshape(void *node, void *data)
 /* --------------- */
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list