[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22982] branches/blender2.5/blender/source /blender/editors: 2.5 - Keyframing Bugfixes + Code Cleanups

Joshua Leung aligorith at gmail.com
Fri Sep 4 06:27:07 CEST 2009


Revision: 22982
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22982
Author:   aligorith
Date:     2009-09-04 06:27:06 +0200 (Fri, 04 Sep 2009)

Log Message:
-----------
2.5 - Keyframing Bugfixes + Code Cleanups

* DopeSheet + Graph Editor - 'Sample Keyframes' option now tags newly created keyframes as being breakdowns. Also moved reduced the code duplication here by moving the core code for this to the animation module.

* Keyframing (Standard/Auto) - Added proper 'replace' option
Keyframes can now be rekeyed non-destructively when the INSERTKEY_REPLACE flag is provided to the keyframing API functions, since this option will make sure that only the values of the handles get altered.

For the Auto-Keyframing 'Replace/Edit Keys' option, this means that it truly works as it describes now, since it will now only replace the values of the keyframes on the current frame, and won't create new keyframes in the process or destroy the tangents already created for those keys.

For things like the sliders in animation editors, keyframes changing the value won't destroy existing tangents.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/animation/anim_channels_defines.c
    branches/blender2.5/blender/source/blender/editors/animation/keyframes_general.c
    branches/blender2.5/blender/source/blender/editors/animation/keyframing.c
    branches/blender2.5/blender/source/blender/editors/animation/keyingsets.c
    branches/blender2.5/blender/source/blender/editors/include/ED_keyframes_draw.h
    branches/blender2.5/blender/source/blender/editors/include/ED_keyframes_edit.h
    branches/blender2.5/blender/source/blender/editors/include/ED_keyframing.h
    branches/blender2.5/blender/source/blender/editors/interface/interface_anim.c
    branches/blender2.5/blender/source/blender/editors/space_action/action_edit.c
    branches/blender2.5/blender/source/blender/editors/space_action/action_header.c
    branches/blender2.5/blender/source/blender/editors/space_graph/graph_edit.c
    branches/blender2.5/blender/source/blender/editors/transform/transform_conversions.c

Modified: branches/blender2.5/blender/source/blender/editors/animation/anim_channels_defines.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/anim_channels_defines.c	2009-09-04 04:05:29 UTC (rev 22981)
+++ branches/blender2.5/blender/source/blender/editors/animation/anim_channels_defines.c	2009-09-04 04:27:06 UTC (rev 22982)
@@ -2003,6 +2003,8 @@
 		flag |= INSERTKEY_NEEDED;
 	if (IS_AUTOKEY_FLAG(AUTOMATKEY))
 		flag |= INSERTKEY_MATRIX;
+	if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+		flag |= INSERTKEY_REPLACE;
 	
 	
 	/* get RNA pointer, and resolve the path */
@@ -2010,6 +2012,10 @@
 	
 	/* try to resolve the path stored in the F-Curve */
 	if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+		/* set the special 'replace' flag if on a keyframe */
+		if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+			flag |= INSERTKEY_REPLACE;
+		
 		/* insert a keyframe for this F-Curve */
 		done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
 		

Modified: branches/blender2.5/blender/source/blender/editors/animation/keyframes_general.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/keyframes_general.c	2009-09-04 04:05:29 UTC (rev 22981)
+++ branches/blender2.5/blender/source/blender/editors/animation/keyframes_general.c	2009-09-04 04:27:06 UTC (rev 22982)
@@ -357,6 +357,76 @@
 	calchandles_fcurve(fcu);
 }
 
+/* ---------------- */
+
+/* little cache for values... */
+typedef struct tempFrameValCache {
+	float frame, val;
+} tempFrameValCache;
+
+
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value  */
+void sample_fcurve (FCurve *fcu)
+{
+	BezTriple *bezt, *start=NULL, *end=NULL;
+	tempFrameValCache *value_cache, *fp;
+	int sfra, range;
+	int i, n, nIndex;
+	
+	/* find selected keyframes... once pair has been found, add keyframes  */
+	for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+		/* check if selected, and which end this is */
+		if (BEZSELECTED(bezt)) {
+			if (start) {
+				/* set end */
+				end= bezt;
+				
+				/* cache values then add keyframes using these values, as adding
+				 * keyframes while sampling will affect the outcome...
+				 *	- only start sampling+adding from index=1, so that we don't overwrite original keyframe
+				 */
+				range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+				sfra= (int)( floor(start->vec[1][0]) );
+				
+				if (range) {
+					value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
+					
+					/* 	sample values 	*/
+					for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
+						fp->frame= (float)(sfra + n);
+						fp->val= evaluate_fcurve(fcu, fp->frame);
+					}
+					
+					/* 	add keyframes with these, tagging as 'breakdowns' 	*/
+					for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
+						nIndex= insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
+						BEZKEYTYPE(fcu->bezt + nIndex)= BEZT_KEYTYPE_BREAKDOWN;
+					}
+					
+					/* free temp cache */
+					MEM_freeN(value_cache);
+					
+					/* as we added keyframes, we need to compensate so that bezt is at the right place */
+					bezt = fcu->bezt + i + range - 1;
+					i += (range - 1);
+				}
+				
+				/* bezt was selected, so it now marks the start of a whole new chain to search */
+				start= bezt;
+				end= NULL;
+			}
+			else {
+				/* just set start keyframe */
+				start= bezt;
+				end= NULL;
+			}
+		}
+	}
+	
+	/* recalculate channel's handles? */
+	calchandles_fcurve(fcu);
+}
+
 /* **************************************************** */
 /* Copy/Paste Tools */
 /* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes 
@@ -529,8 +599,10 @@
 				bezt->vec[1][0] += offset;
 				bezt->vec[2][0] += offset;
 				
-				/* insert the keyframe */
-				insert_bezt_fcurve(fcu, bezt);
+				/* insert the keyframe
+				 * NOTE: no special flags here for now
+				 */
+				insert_bezt_fcurve(fcu, bezt, 0); 
 				
 				/* un-apply offset from src beztriple after copying */
 				bezt->vec[0][0] -= offset;

Modified: branches/blender2.5/blender/source/blender/editors/animation/keyframing.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/keyframing.c	2009-09-04 04:05:29 UTC (rev 22981)
+++ branches/blender2.5/blender/source/blender/editors/animation/keyframing.c	2009-09-04 04:27:06 UTC (rev 22982)
@@ -262,9 +262,8 @@
  * NOTE: any recalculate of the F-Curve that needs to be done will need to 
  * 		be done by the caller.
  */
-int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
+int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
 {
-	BezTriple *newb;
 	int i= 0;
 	
 	if (fcu->bezt) {
@@ -273,14 +272,35 @@
 		
 		if (replace) {			
 			/* sanity check: 'i' may in rare cases exceed arraylen */
-			// FIXME: do not overwrite handletype if just replacing...?
-			if ((i >= 0) && (i < fcu->totvert))
-				*(fcu->bezt + i) = *bezt;
+			if ((i >= 0) && (i < fcu->totvert)) {
+				/* take care with the handletypes and other info if the replacement flags are set */
+				if (flag & INSERTKEY_REPLACE) {
+					BezTriple *dst= (fcu->bezt + i);
+					float dy= bezt->vec[1][1] - dst->vec[1][1];
+					
+					/* just apply delta value change to the handle values */
+					dst->vec[0][1] += dy;
+					dst->vec[1][1] += dy;
+					dst->vec[2][1] += dy;
+					
+					// TODO: perform some other operations?
+				}
+				else {
+					/* just brutally replace the values */
+					*(fcu->bezt + i) = *bezt;
+				}
+			}
 		}
-		else {
-			/* add new */
-			newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
+		else if ((flag & INSERTKEY_REPLACE) == 0) {
+			/* add new - if we're not restricted to replacing keyframes only */
+			BezTriple *newb;
 			
+			/* allocate a new array only if we have to */
+			if ((flag & INSERTKEY_FASTR) == 0)
+				newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
+			else
+				newb= fcu->bezt;
+			
 			/* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
 			if (i > 0)
 				memcpy(newb, fcu->bezt, i*sizeof(BezTriple));
@@ -292,9 +312,11 @@
 			if (i < fcu->totvert) 
 				memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple));
 			
-			/* replace (+ free) old with new */
-			MEM_freeN(fcu->bezt);
-			fcu->bezt= newb;
+			/* replace (+ free) old with new, only if necessary to do so */
+			if ((flag & INSERTKEY_FASTR) == 0) {
+				MEM_freeN(fcu->bezt);
+				fcu->bezt= newb;
+			}
 			
 			fcu->totvert++;
 		}
@@ -313,13 +335,11 @@
 	return i;
 }
 
-/* This function is a wrapper for insert_bezt_icu, and should be used when
- * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
- * else yet. 
- * 
- * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
+/* This function is a wrapper for insert_bezt_fcurve_internal(), and should be used when
+ * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. 
+ * It returns the index at which the keyframe was added.
  */
-void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
+int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag)
 {
 	BezTriple beztr;
 	int a;
@@ -337,21 +357,22 @@
 	beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one?
 	
 	/* add temp beztriple to keyframes */
-	a= insert_bezt_fcurve(fcu, &beztr);
+	a= insert_bezt_fcurve(fcu, &beztr, flag);
 	
 	/* what if 'a' is a negative index? 
 	 * for now, just exit to prevent any segfaults
 	 */
-	if (a < 0) return;
+	if (a < 0) return -1;
 	
 	/* don't recalculate handles if fast is set
 	 *	- this is a hack to make importers faster
-	 *	- we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
+	 *	- we may calculate twice (due to autohandle needing to be calculated twice)
 	 */
-	if (!fast) calchandles_fcurve(fcu);
+	if ((flag & INSERTKEY_FAST) == 0) 
+		calchandles_fcurve(fcu);
 	
 	/* set handletype and interpolation */
-	if (fcu->totvert > 2) {
+	if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE)==0) {
 		BezTriple *bezt= (fcu->bezt + a);
 		char h1, h2;
 		
@@ -370,10 +391,14 @@
 			
 		/* don't recalculate handles if fast is set
 		 *	- this is a hack to make importers faster
-		 *	- we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
+		 *	- we may calculate twice (due to autohandle needing to be calculated twice)
 		 */
-		if (!fast) calchandles_fcurve(fcu);
+		if ((flag & INSERTKEY_FAST) == 0) 
+			calchandles_fcurve(fcu);
 	}
+	
+	/* return the index at which the keyframe was added */
+	return a;
 }
 
 /* -------------- 'Smarter' Keyframing Functions -------------------- */
@@ -812,7 +837,7 @@
 		
 		/* insert new keyframe at current frame */
 		if (insert_mode)
-			insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
+			insert_vert_fcurve(fcu, cfra, curval, flag);
 		
 		/* delete keyframe immediately before/after newly added */
 		switch (insert_mode) {
@@ -830,7 +855,7 @@
 	}
 	else {
 		/* just insert keyframe */
-		insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
+		insert_vert_fcurve(fcu, cfra, curval, flag);
 		
 		/* return success */
 		return 1;
@@ -1303,7 +1328,16 @@
 	float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
 	short success= 0;
 	int a, index, length, all= RNA_boolean_get(op->ptr, "all");
+	short flag = 0;
 	
+	/* flags for inserting keyframes */
+	if (IS_AUTOKEY_FLAG(AUTOMATKEY))
+		flag |= INSERTKEY_MATRIX;
+	if (IS_AUTOKEY_FLAG(INSERTNEEDED))
+		flag |= INSERTKEY_NEEDED;
+	if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+		flag |= INSERTKEY_REPLACE;
+	
 	/* try to insert keyframe using property retrieved from UI */
 	memset(&ptr, 0, sizeof(PointerRNA));
 	uiAnimContextProperty(C, &ptr, &prop, &index);
@@ -1322,14 +1356,14 @@
 				length= 1;
 			
 			for (a=0; a<length; a++)
-				success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, 0);
+				success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, flag);
 			
 			MEM_freeN(path);
 		}
 		else if (ptr.type == &RNA_NlaStrip) {
 			/* handle special vars for NLA-strips */
 			NlaStrip *strip= (NlaStrip *)ptr.data;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list