[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19159] branches/blender2.5/blender/source /blender: Graph Editor: Added operator to 'bake' keyframe-based F-Curves to be composed of samples.

Joshua Leung aligorith at gmail.com
Sun Mar 1 12:28:31 CET 2009


Revision: 19159
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19159
Author:   aligorith
Date:     2009-03-01 12:27:31 +0100 (Sun, 01 Mar 2009)

Log Message:
-----------
Graph Editor: Added operator to 'bake' keyframe-based F-Curves to be composed of samples. 

This operator can be activated using the 'Alt-C' hotkey for now, and operates on selected + editable F-Curves. This is currently still highly experimental, and does crash

I've implemented this as a way to test out the FPoints/samples code, which will be used to provide better support of the dense F-Curves which result from importing Mocap/BVH data. These should use considerably less memory + have a few additional benefits over keyframes when they're working in a stable fashion.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/BKE_fcurve.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c
    branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c
    branches/blender2.5/blender/source/blender/editors/space_graph/graph_edit.c
    branches/blender2.5/blender/source/blender/editors/space_graph/graph_intern.h
    branches/blender2.5/blender/source/blender/editors/space_graph/graph_ops.c

Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_fcurve.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_fcurve.h	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_fcurve.h	2009-03-01 11:27:31 UTC (rev 19159)
@@ -108,5 +108,26 @@
 /* evaluate fcurve and store value */
 void calculate_fcurve(struct FCurve *fcu, float ctime);
 
+/* ************* F-Curve Samples API ******************** */
 
+/* -------- Defines --------  */
+
+/* Basic signature for F-Curve sample-creation function 
+ *	- fcu: the F-Curve being operated on
+ *	- data: pointer to some specific data that may be used by one of the callbacks
+ */
+typedef float (*FcuSampleFunc)(struct FCurve *fcu, void *data, float evaltime);
+
+/* ----- Sampling Callbacks ------  */
+
+/* Basic sampling callback which acts as a wrapper for evaluate_fcurve() */
+float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime);
+
+/* -------- Main Methods --------  */
+
+/* Main API function for creating a set of sampled curve data, given some callback function 
+ * used to retrieve the values to store.
+ */
+void fcurve_store_samples(struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb);
+
 #endif /* BKE_FCURVE_H*/

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c	2009-03-01 11:27:31 UTC (rev 19159)
@@ -294,6 +294,60 @@
 	cen->sel= bezt->f2;
 }
 
+/* ***************************** Samples Utilities ******************************* */
+/* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as
+ * data imported from BVH/Mocap files), which are specialised for use with high density datasets,
+ * which BezTriples/Keyframe data are ill equipped to do.
+ */
+ 
+ 
+/* Basic sampling callback which acts as a wrapper for evaluate_fcurve() 
+ *	'data' arg here is unneeded here...
+ */
+float fcurve_samplingcb_evalcurve (FCurve *fcu, void *data, float evaltime)
+{
+	/* assume any interference from drivers on the curve is intended... */
+	return evaluate_fcurve(fcu, evaltime);
+} 
+
+ 
+/* Main API function for creating a set of sampled curve data, given some callback function 
+ * used to retrieve the values to store.
+ */
+void fcurve_store_samples (FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb)
+{
+	FPoint *fpt, *new_fpt;
+	int cfra;
+	
+	/* sanity checks */
+	// TODO: make these tests report errors using reports not printf's
+	if ELEM(NULL, fcu, sample_cb) {
+		printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
+		return;
+	}
+	if (start >= end) {
+		printf("Error: Frame range for Sampled F-Curve creation is inappropriate \n");
+		return;
+	}
+	
+	/* set up sample data */
+	fpt= new_fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "FPoint Samples");
+	
+	/* use the sampling callback at 1-frame intervals from start to end frames */
+	for (cfra= start; cfra <= end; cfra++, fpt++) {
+		fpt->vec[0]= (float)cfra;
+		fpt->vec[1]= sample_cb(fcu, data, (float)cfra);
+	}
+	
+	/* free any existing sample/keyframe data on curve  */
+	if (fcu->bezt) MEM_freeN(fcu->bezt);
+	if (fcu->fpt) MEM_freeN(fcu->fpt);
+	
+	/* store the samples */
+	fcu->fpt= new_fpt;
+	fcu->totvert= end - start + 1;
+}
+
 /* ***************************** F-Curve Sanity ********************************* */
 /* The functions here are used in various parts of Blender, usually after some editing
  * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
@@ -1596,8 +1650,7 @@
  */
 void fcurve_bake_modifiers (FCurve *fcu, int start, int end)
 {
-	FPoint *fpt, *new_fpt;
-	int cfra;
+	ChannelDriver *driver;
 	
 	/* sanity checks */
 	// TODO: make these tests report errors using reports not printf's
@@ -1605,30 +1658,19 @@
 		printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
 		return;
 	}
-	if (start >= end) {
-		printf("Error: Frame range for F-Curve Modifier Baking inappropriate \n");
-		return;
-	}
 	
-	/* set up sample data */
-	fpt= new_fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "FPoint FModifier Samples");
+	/* temporarily, disable driver while we sample, so that they don't influence the outcome */
+	driver= fcu->driver;
+	fcu->driver= NULL;
 	
-	/* sample the curve at 1-frame intervals from start to end frames 
-	 *	- assume that any ChannelDriver possibly present did not interfere in any way
-	 */
-	for (cfra= start; cfra <= end; cfra++, fpt++) {
-		fpt->vec[0]= (float)cfra;
-		fpt->vec[1]= evaluate_fcurve(fcu, (float)cfra);
-	}
+	/* bake the modifiers, by sampling the curve at each frame */
+	fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
 	
-	/* free any existing sample/keyframe data on curve, and all modifiers */
-	if (fcu->bezt) MEM_freeN(fcu->bezt);
-	if (fcu->fpt) MEM_freeN(fcu->fpt);
+	/* free the modifiers now */
 	fcurve_free_modifiers(fcu);
 	
-	/* store the samples */
-	fcu->fpt= new_fpt;
-	fcu->totvert= end - start + 1;
+	/* restore driver */
+	fcu->driver= driver;
 }
 
 /* ***************************** F-Curve - Evaluation ********************************* */

Modified: branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c	2009-03-01 11:27:31 UTC (rev 19159)
@@ -84,7 +84,7 @@
 	int b;
 	
 	/* sanity check */
-	if (fcu == NULL)
+	if (ELEM(NULL, fcu, fcu->bezt))
 		return 0;
 	
 	/* if function to apply to bezier curves is set, then loop through executing it on beztriples */

Modified: branches/blender2.5/blender/source/blender/editors/space_graph/graph_edit.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_graph/graph_edit.c	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/editors/space_graph/graph_edit.c	2009-03-01 11:27:31 UTC (rev 19159)
@@ -554,7 +554,90 @@
 	RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
 }
 
+/* ******************** Bake F-Curve Operator *********************** */
+/* This operator bakes the data of the selected F-Curves to F-Points */
+
+/* Bake each F-Curve into a set of samples */
+static void bake_graph_curves (bAnimContext *ac, int start, int end)
+{	
+	ListBase anim_data = {NULL, NULL};
+	bAnimListElem *ale;
+	int filter;
+	
+	/* filter data */
+	filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+	
+	/* loop through filtered data and add keys between selected keyframes on every frame  */
+	for (ale= anim_data.first; ale; ale= ale->next) {
+		FCurve *fcu= (FCurve *)ale->key_data;
+		ChannelDriver *driver= fcu->driver;
+		
+		/* disable driver so that it don't muck up the sampling process */
+		fcu->driver= NULL;
+		
+		/* create samples */
+		fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
+		
+		/* restore driver */
+		fcu->driver= driver;
+	}
+	
+	/* admin and redraws */
+	BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int graphkeys_bake_exec(bContext *C, wmOperator *op)
+{
+	bAnimContext ac;
+	Scene *scene= NULL;
+	int start, end;
+	
+	/* get editor data */
+	if (ANIM_animdata_get_context(C, &ac) == 0)
+		return OPERATOR_CANCELLED;
+		
+	/* for now, init start/end from preview-range extents */
+	// TODO: add properties for this 
+	scene= ac.scene;
+	start= PSFRA;
+	end= PEFRA;
+	
+	/* bake keyframes */
+	bake_graph_curves(&ac, start, end);
+	
+	/* validate keyframes after editing */
+	ANIM_editkeyframes_refresh(&ac);
+	
+	/* set notifier tha things have changed */
+	ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+	
+	return OPERATOR_FINISHED;
+}
+ 
+void GRAPHEDIT_OT_keyframes_bake (wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake Curve";
+	ot->idname= "GRAPHEDIT_OT_keyframes_bake";
+	
+	/* api callbacks */
+	ot->invoke= WM_operator_confirm; // FIXME...
+	ot->exec= graphkeys_bake_exec;
+	ot->poll= ED_operator_areaactive;
+	
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	
+	// todo: add props for start/end frames
+}
+
 /* ******************** Sample Keyframes Operator *********************** */
+/* This operator 'bakes' the values of the curve into new keyframes between pairs
+ * of selected keyframes. It is useful for creating keyframes for tweaking overlap.
+ */
 
 // XXX some of the common parts (with DopeSheet) should be unified in animation module...
 

Modified: branches/blender2.5/blender/source/blender/editors/space_graph/graph_intern.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_graph/graph_intern.h	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/editors/space_graph/graph_intern.h	2009-03-01 11:27:31 UTC (rev 19159)
@@ -87,6 +87,7 @@
 void GRAPHEDIT_OT_keyframes_delete(struct wmOperatorType *ot);
 void GRAPHEDIT_OT_keyframes_clean(struct wmOperatorType *ot);
 void GRAPHEDIT_OT_keyframes_sample(struct wmOperatorType *ot);
+void GRAPHEDIT_OT_keyframes_bake(struct wmOperatorType *ot);
 void GRAPHEDIT_OT_keyframes_smooth(struct wmOperatorType *ot);
 
 void GRAPHEDIT_OT_keyframes_handletype(struct wmOperatorType *ot);

Modified: branches/blender2.5/blender/source/blender/editors/space_graph/graph_ops.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_graph/graph_ops.c	2009-03-01 09:12:34 UTC (rev 19158)
+++ branches/blender2.5/blender/source/blender/editors/space_graph/graph_ops.c	2009-03-01 11:27:31 UTC (rev 19159)
@@ -116,6 +116,7 @@
 	WM_operatortype_append(GRAPHEDIT_OT_keyframes_interpolation_type);
 	WM_operatortype_append(GRAPHEDIT_OT_keyframes_extrapolation_type);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list