[Bf-blender-cvs] [1fbd742] master: Graph Editor: "Add at Cursor" options for Insert Key operator in Graph Editor

Joshua Leung noreply at git.blender.org
Mon Dec 14 16:06:28 CET 2015


Commit: 1fbd74296df79fff2b4fd3234ea20b0ade51b0f9
Author: Joshua Leung
Date:   Tue Dec 15 04:03:25 2015 +1300
Branches: master
https://developer.blender.org/rB1fbd74296df79fff2b4fd3234ea20b0ade51b0f9

Graph Editor: "Add at Cursor" options for Insert Key operator in Graph Editor

* Added the ability to add a keyframe at the current cursor location in the
  Graph Editor. This is useful for precisely defining the shape of driver F-Curves.

* Fixed a bug where the wrong cursor-x time was being used in Drivers mode
  (i.e. it was still using time, and not just any time-value, but the NLA-mapped time!)

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

M	source/blender/editors/space_graph/graph_edit.c

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

diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 5011b03..6042100 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -483,57 +483,125 @@ void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot)
 
 /* ******************** Insert Keyframes Operator ************************* */
 
-/* defines for insert keyframes tool */
+/* Mode defines for insert keyframes tool */
+typedef enum eGraphKeys_InsertKey_Types {
+	GRAPHKEYS_INSERTKEY_ALL    = (1 << 0),
+	GRAPHKEYS_INSERTKEY_SEL    = (1 << 1),
+	GRAPHKEYS_INSERTKEY_CURSOR = (1 << 2),
+	GRAPHKEYS_INSERTKEY_ACTIVE = (1 << 3),
+} eGraphKeys_InsertKey_Types;
+
+/* RNA mode types for insert keyframes tool */
 static EnumPropertyItem prop_graphkeys_insertkey_types[] = {
-	{1, "ALL", 0, "All Channels", ""},
-	{2, "SEL", 0, "Only Selected Channels", ""},
+	{GRAPHKEYS_INSERTKEY_ALL,   "ALL", 0, "All Channels",
+	 "Insert a keyframe on all visible and editable F-Curves using each curve's current value"},
+	{GRAPHKEYS_INSERTKEY_SEL,   "SEL", 0, "Only Selected Channels",
+	 "Insert a keyframe on selected F-Curves using each curve's current value"},
+	{0, "", 0, "", ""},
+	{GRAPHKEYS_INSERTKEY_ACTIVE | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_ACTIVE", 0,
+	 "Active Channels At Cursor", "Insert a keyframe for the active F-Curve at the cursor point"},
+	{GRAPHKEYS_INSERTKEY_SEL | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_SEL", 0,
+	 "Selected Channels At Cursor", "Insert a keyframe for selected F-Curves at the cursor point"},
 	{0, NULL, 0, NULL, NULL}
 };
 
 /* this function is responsible for snapping keyframes to frame-times */
-static void insert_graph_keys(bAnimContext *ac, short mode) 
+static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) 
 {
 	ListBase anim_data = {NULL, NULL};
 	bAnimListElem *ale;
 	int filter;
+	size_t num_items;
 	
 	ReportList *reports = ac->reports;
+	SpaceIpo *sipo = (SpaceIpo *)ac->sl;
 	Scene *scene = ac->scene;
 	short flag = 0;
 	
 	/* filter data */
 	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
-	if (mode == 2) filter |= ANIMFILTER_SEL;
-	
-	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+	if (mode & GRAPHKEYS_INSERTKEY_SEL)
+		filter |= ANIMFILTER_SEL;
+	else if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
+		filter |= ANIMFILTER_ACTIVE;
+	
+	num_items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+	if (num_items == 0) {
+		if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
+			BKE_report(reports, RPT_ERROR, "No active F-Curve to add a keyframe to. Select an editable F-Curve first");
+		else if (mode & GRAPHKEYS_INSERTKEY_SEL)
+			BKE_report(reports, RPT_ERROR, "No selected F-Curves to add keyframes to");
+		else
+			BKE_report(reports, RPT_ERROR, "No channels to add keyframes to");
+		
+		return;
+	}
 	
 	/* init keyframing flag */
 	flag = ANIM_get_keyframing_flags(scene, 1);
 	
 	/* insert keyframes */
-	for (ale = anim_data.first; ale; ale = ale->next) {
-		AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-		FCurve *fcu = (FCurve *)ale->key_data;
-		float cfra;
-		
-		/* adjust current frame for NLA-mapping */
-		if (adt)
-			cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-		else 
-			cfra = (float)CFRA;
+	if (mode & GRAPHKEYS_INSERTKEY_CURSOR) {
+		for (ale = anim_data.first; ale; ale = ale->next) {
+			AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+			FCurve *fcu = (FCurve *)ale->key_data;
 			
-		/* read value from property the F-Curve represents, or from the curve only?
-		 * - ale->id != NULL:    Typically, this means that we have enough info to try resolving the path
-		 * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
-		 *                       so it's easier for now to just read the F-Curve directly.
-		 *                       (TODO: add the full-blown PointerRNA relative parsing case here...)
-		 */
-		if (ale->id && !ale->owner)
-			insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
-		else
-			insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
-		
-		ale->update |= ANIM_UPDATE_DEFAULT;
+			short mapping_flag = ANIM_get_normalization_flags(ac);
+			float offset;
+			float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
+			
+			float x, y;
+			
+			
+			/* perform time remapping for x-coordinate (if necessary) */
+			if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
+				x = sipo->cursorTime;
+			else if (adt)
+				x = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+			else
+				x = (float)CFRA;
+			
+			/* normalise units of cursor's value */
+			if (sipo)
+				y = (sipo->cursorVal / unit_scale) - offset;
+			else
+				y = 0.0f;
+				
+			/* insert keyframe directly into the F-Curve */
+			insert_vert_fcurve(fcu, x, y, 0);
+			
+			ale->update |= ANIM_UPDATE_DEFAULT;
+		}
+	}
+	else {
+		for (ale = anim_data.first; ale; ale = ale->next) {
+			AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+			FCurve *fcu = (FCurve *)ale->key_data;
+			float cfra;
+			
+			/* adjust current frame for NLA-mapping */
+			if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
+				cfra = sipo->cursorTime;
+			else if (adt)
+				cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+			else 
+				cfra = (float)CFRA;
+				
+			/* read value from property the F-Curve represents, or from the curve only?
+			 * - ale->id != NULL:    Typically, this means that we have enough info to try resolving the path
+			 * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
+			 *                       so it's easier for now to just read the F-Curve directly.
+			 *                       (TODO: add the full-blown PointerRNA relative parsing case here...)
+			 * - fcu->driver != NULL: If this is set, then it's a driver. If we don't check for this, we'd end
+			 *                        up adding the keyframes on a new F-Curve in the action data instead.
+			 */
+			if (ale->id && !ale->owner && !fcu->driver)
+				insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+			else
+				insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
+			
+			ale->update |= ANIM_UPDATE_DEFAULT;
+		}
 	}
 	
 	ANIM_animdata_update(ac, &anim_data);
@@ -545,7 +613,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
 static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
 {
 	bAnimContext ac;
-	short mode;
+	eGraphKeys_InsertKey_Types mode;
 	
 	/* get editor data */
 	if (ANIM_animdata_get_context(C, &ac) == 0)




More information about the Bf-blender-cvs mailing list