[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33660] trunk/blender/source/blender: graph editor & action keyframe paste options.

Campbell Barton ideasman42 at gmail.com
Tue Dec 14 16:14:16 CET 2010


Revision: 33660
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33660
Author:   campbellbarton
Date:     2010-12-14 16:14:16 +0100 (Tue, 14 Dec 2010)

Log Message:
-----------
graph editor & action keyframe paste options.

- Offset, so you can paste at the same time of the original frames, at the current frame or relative to the current frame at time of copying.
- Merge method, so the pasted keys can overwrite keys in their range or the entire curve.

Currently there is no redo panel for these space types so the only way to access these options is with F6 redo popup.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/animation/keyframes_general.c
    trunk/blender/source/blender/editors/include/ED_keyframes_edit.h
    trunk/blender/source/blender/editors/space_action/action_edit.c
    trunk/blender/source/blender/editors/space_graph/graph_edit.c
    trunk/blender/source/blender/makesrna/RNA_enum_types.h

Modified: trunk/blender/source/blender/editors/animation/keyframes_general.c
===================================================================
--- trunk/blender/source/blender/editors/animation/keyframes_general.c	2010-12-14 14:45:56 UTC (rev 33659)
+++ trunk/blender/source/blender/editors/animation/keyframes_general.c	2010-12-14 15:14:16 UTC (rev 33660)
@@ -117,13 +117,20 @@
 	}
 	
 	/* Free the array of BezTriples if there are not keyframes */
-	if (fcu->totvert == 0) {
-		if (fcu->bezt) 
-			MEM_freeN(fcu->bezt);
-		fcu->bezt= NULL;
-	}
+	if(fcu->totvert == 0)
+		clear_fcurve_keys(fcu);
 }
 
+
+void clear_fcurve_keys(FCurve *fcu)
+{
+	if (fcu->bezt)
+		MEM_freeN(fcu->bezt);
+	fcu->bezt= NULL;
+
+	fcu->totvert= 0;
+}
+
 /* ---------------- */
 
 /* duplicate selected keyframes for the given F-Curve */
@@ -446,6 +453,8 @@
 /* globals for copy/paste data (like for other copy/paste buffers) */
 ListBase animcopybuf = {NULL, NULL};
 static float animcopy_firstframe= 999999999.0f;
+static float animcopy_lastframe= -999999999.0f;
+static float animcopy_cfra= 0.0;
 
 /* datatype for use in copy/paste buffer */
 typedef struct tAnimCopybufItem {
@@ -488,14 +497,16 @@
 	/* restore initial state */
 	animcopybuf.first= animcopybuf.last= NULL;
 	animcopy_firstframe= 999999999.0f;
+	animcopy_lastframe= -999999999.0f;
 }
 
 /* ------------------- */
 
 /* This function adds data to the keyframes copy/paste buffer, freeing existing data first */
-short copy_animedit_keys (bAnimContext *UNUSED(ac), ListBase *anim_data)
+short copy_animedit_keys (bAnimContext *ac, ListBase *anim_data)
 {	
 	bAnimListElem *ale;
+	Scene *scene= ac->scene;
 	
 	/* clear buffer first */
 	free_anim_copybuf();
@@ -545,6 +556,8 @@
 				/* check if this is the earliest frame encountered so far */
 				if (bezt->vec[1][0] < animcopy_firstframe)
 					animcopy_firstframe= bezt->vec[1][0];
+				if (bezt->vec[1][0] > animcopy_lastframe)
+					animcopy_lastframe= bezt->vec[1][0];
 			}
 		}
 		
@@ -553,7 +566,10 @@
 	/* check if anything ended up in the buffer */
 	if (ELEM(NULL, animcopybuf.first, animcopybuf.last))
 		return -1;
-	
+
+	/* incase 'relative' paste method is used */
+	animcopy_cfra= CFRA;
+
 	/* everything went fine */
 	return 0;
 }
@@ -636,11 +652,58 @@
 	return aci;
 }
 
-static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset)
+static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode)
 {
 	BezTriple *bezt;
 	int i;
 
+	/* First de-select existing FCuvre */
+	for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+		bezt->f2 &= ~SELECT;
+	}
+
+	/* mix mode with existing data */
+	switch(merge_mode) {
+		case KEYFRAME_PASTE_MERGE_MIX:
+			/* do-nothing */
+			break;
+		case KEYFRAME_PASTE_MERGE_OVER:
+			/* remove all keys */
+			clear_fcurve_keys(fcu);
+			break;
+		case KEYFRAME_PASTE_MERGE_OVER_RANGE:
+		case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL:
+		{
+			float f_min;
+			float f_max;
+
+			if(merge_mode==KEYFRAME_PASTE_MERGE_OVER_RANGE) {
+				f_min= aci->bezt[0].vec[1][0] + offset;
+				f_max= aci->bezt[aci->totvert-1].vec[1][0] + offset;
+			}
+			else { /* Entire Range */
+				f_min= animcopy_firstframe + offset;
+				f_max= animcopy_lastframe + offset;
+			}
+
+			/* remove keys in range */
+
+			if(f_min < f_max) {
+				/* select verts in range for removal */
+				for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+					if((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) {
+						bezt->f2 |= SELECT;
+					}
+				}
+
+				/* remove frames in the range */
+				delete_fcurve_keys(fcu);
+			}
+			break;
+		}
+	}
+
+
 	/* just start pasting, with the the first keyframe on the current frame, and so on */
 	for (i=0, bezt=aci->bezt; i < aci->totvert; i++, bezt++) {						
 		/* temporarily apply offset to src beztriple while copying */
@@ -663,22 +726,54 @@
 	calchandles_fcurve(fcu);
 }
 
+EnumPropertyItem keyframe_paste_offset_items[] = {
+	{KEYFRAME_PASTE_OFFSET_CFRA_START, "START", 0, "Frame Start", "Paste keys starting at current frame"},
+	{KEYFRAME_PASTE_OFFSET_CFRA_END, "END", 0, "Frame End", "Paste keys ending at current frame"},
+	{KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE, "RELATIVE", 0, "Frame Relative", "Paste keys relative to the current frame when copying"},
+	{KEYFRAME_PASTE_OFFSET_NONE, "NONE", 0, "No Offset", "Paste keys from original time"},
+	{0, NULL, 0, NULL, NULL}};
+
+EnumPropertyItem keyframe_paste_merge_items[] = {
+	{KEYFRAME_PASTE_MERGE_MIX, "MIX", 0, "Mix", "Overlay existing with new keys"},
+	{KEYFRAME_PASTE_MERGE_OVER, "OVER_ALL", 0, "Overwrite All", "Replace all keys"},
+	{KEYFRAME_PASTE_MERGE_OVER_RANGE, "OVER_RANGE", 0, "Overwrite Range", "Overwrite keys in pasted range"},
+	{KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL, "OVER_RANGE_ALL", 0, "Overwrite Entire Range", "Overwrite keys in pasted range, using the range of all copied keys."},
+	{0, NULL, 0, NULL, NULL}};
+
+
 /* This function pastes data from the keyframes copy/paste buffer */
-short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data)
+short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data,
+	const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode)
 {
 	bAnimListElem *ale;
 	const Scene *scene= (ac->scene);
-	const float offset = (float)(CFRA - animcopy_firstframe);
+	float offset;
 	const short from_single= (animcopybuf.first == animcopybuf.last);
 	const short to_simple= (anim_data->first == anim_data->last);
 	int pass;
-	
+
 	/* check if buffer is empty */
 	if (ELEM(NULL, animcopybuf.first, animcopybuf.last)) {
 		BKE_report(ac->reports, RPT_WARNING, "No data in buffer to paste");
 		return -1;
 	}
 
+	/* mathods of offset */
+	switch(offset_mode) {
+		case KEYFRAME_PASTE_OFFSET_CFRA_START:
+			offset= (float)(CFRA - animcopy_firstframe);
+			break;
+		case KEYFRAME_PASTE_OFFSET_CFRA_END:
+			offset= (float)(CFRA - animcopy_lastframe);
+			break;
+		case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
+			offset= (float)(CFRA - animcopy_cfra);
+			break;
+		case KEYFRAME_PASTE_OFFSET_NONE:
+			offset= 0.0f;
+			break;
+	}
+
 	if(from_single && to_simple) {
 		/* 1:1 match, no tricky checking, just paste */
 		FCurve *fcu;
@@ -688,7 +783,7 @@
 		fcu= (FCurve *)ale->data;		/* destination F-Curve */
 		aci= animcopybuf.first;
 
-		paste_animedit_keys_fcurve(fcu, aci, offset);		
+		paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode);
 	}
 	else {
 		/* from selected channels */
@@ -724,7 +819,7 @@
 				/* copy the relevant data from the matching buffer curve */
 				if (aci) {
 					totmatch++;
-					paste_animedit_keys_fcurve(fcu, aci, offset);
+					paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode);
 				}
 			}
 			

Modified: trunk/blender/source/blender/editors/include/ED_keyframes_edit.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_keyframes_edit.h	2010-12-14 14:45:56 UTC (rev 33659)
+++ trunk/blender/source/blender/editors/include/ED_keyframes_edit.h	2010-12-14 15:14:16 UTC (rev 33660)
@@ -152,6 +152,29 @@
 	float newMin, newMax;			/* new range */
 } KeyframeEditCD_Remap;
 
+/* Paste options */
+typedef enum eKeyPasteOffset {
+		/* paste keys starting at current frame */
+	KEYFRAME_PASTE_OFFSET_CFRA_START,
+		/* paste keys ending at current frame */
+	KEYFRAME_PASTE_OFFSET_CFRA_END,
+		/* paste keys relative to the current frame when copying */
+	KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE,
+		/* paste keys from original time */
+	KEYFRAME_PASTE_OFFSET_NONE
+} eKeyPasteOffset;
+
+typedef enum eKeyMergeMode {
+		/* overlay existing with new keys */
+	KEYFRAME_PASTE_MERGE_MIX,
+		/* replace entire fcurve */
+	KEYFRAME_PASTE_MERGE_OVER,
+		/* overwrite keys in pasted range */
+	KEYFRAME_PASTE_MERGE_OVER_RANGE,
+		/* overwrite keys in pasted range (use all keyframe start & end for range) */
+	KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL
+} eKeyMergeMode;
+
 /* ---------------- Looping API --------------------- */
 
 /* functions for looping over keyframes */
@@ -212,6 +235,7 @@
 
 void delete_fcurve_key(struct FCurve *fcu, int index, short do_recalc);
 void delete_fcurve_keys(struct FCurve *fcu);
+void clear_fcurve_keys(struct FCurve *fcu);
 void duplicate_fcurve_keys(struct FCurve *fcu);
 
 void clean_fcurve(struct FCurve *fcu, float thresh);
@@ -222,7 +246,8 @@
 
 void free_anim_copybuf(void);
 short copy_animedit_keys(struct bAnimContext *ac, ListBase *anim_data);
-short paste_animedit_keys(struct bAnimContext *ac, ListBase *anim_data);
+short paste_animedit_keys(struct bAnimContext *ac, ListBase *anim_data,
+	const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode);
 
 /* ************************************************ */
 

Modified: trunk/blender/source/blender/editors/space_action/action_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_action/action_edit.c	2010-12-14 14:45:56 UTC (rev 33659)
+++ trunk/blender/source/blender/editors/space_action/action_edit.c	2010-12-14 15:14:16 UTC (rev 33660)
@@ -291,7 +291,8 @@
 }
 
 
-static short paste_action_keys (bAnimContext *ac)
+static short paste_action_keys (bAnimContext *ac,
+	const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode)
 {	
 	ListBase anim_data = {NULL, NULL};
 	int filter, ok=0;
@@ -301,7 +302,7 @@
 	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
 	
 	/* paste keyframes */
-	ok= paste_animedit_keys(ac, &anim_data);
+	ok= paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode);
 	
 	/* clean up */
 	BLI_freelistN(&anim_data);
@@ -341,11 +342,15 @@
 	ot->description= "Copy selected keyframes to the copy/paste buffer";
 	
 	/* api callbacks */
+//	ot->invoke= WM_operator_props_popup; // better wait for graph redo panel
 	ot->exec= actkeys_copy_exec;
 	ot->poll= ED_operator_action_active;
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_enum(ot->srna, "offset", keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
+	RNA_def_enum(ot->srna, "merge", keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merking pasted keys and existing");
 }
 
 
@@ -353,6 +358,9 @@
 static int actkeys_paste_exec(bContext *C, wmOperator *op)
 {
 	bAnimContext ac;
+
+	const eKeyPasteOffset offset_mode= RNA_enum_get(op->ptr, "offset");
+	const eKeyMergeMode merge_mode= RNA_enum_get(op->ptr, "merge");
 	
 	/* get editor data */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list