[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54223] trunk/blender/source/blender: patch [#33985] Added FModifierEnvelope control_point add remove to API

Campbell Barton ideasman42 at gmail.com
Thu Jan 31 09:19:15 CET 2013


Revision: 54223
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54223
Author:   campbellbarton
Date:     2013-01-31 08:19:11 +0000 (Thu, 31 Jan 2013)
Log Message:
-----------
patch [#33985] Added FModifierEnvelope control_point add remove to API
from Peter Staples (batfinger)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_fcurve.h
    trunk/blender/source/blender/blenkernel/intern/fmodifier.c
    trunk/blender/source/blender/editors/animation/fmodifier_ui.c
    trunk/blender/source/blender/makesrna/intern/rna_fcurve.c

Modified: trunk/blender/source/blender/blenkernel/BKE_fcurve.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_fcurve.h	2013-01-31 06:38:35 UTC (rev 54222)
+++ trunk/blender/source/blender/blenkernel/BKE_fcurve.h	2013-01-31 08:19:11 UTC (rev 54223)
@@ -41,6 +41,7 @@
 struct ChannelDriver;
 struct DriverVar;
 struct DriverTarget;
+struct FCM_EnvelopeData;
 
 struct bAction;
 struct BezTriple;
@@ -181,6 +182,8 @@
 
 void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
 
+int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int arraylen, short *exists);
+
 /* ************** F-Curves API ******************** */
 
 /* -------- Data Managemnt  --------  */

Modified: trunk/blender/source/blender/blenkernel/intern/fmodifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/fmodifier.c	2013-01-31 06:38:35 UTC (rev 54222)
+++ trunk/blender/source/blender/blenkernel/intern/fmodifier.c	2013-01-31 08:19:11 UTC (rev 54223)
@@ -480,6 +480,92 @@
 	fcm_envelope_evaluate /* evaluate */
 };
 
+/* exported function for finding points */
+
+/* Binary search algorithm for finding where to insert Envelope Data Point.
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001f
+
+int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
+{
+	int start = 0, end = arraylen;
+	int loopbreaker = 0, maxloop = arraylen * 2;
+
+	/* initialize exists-flag first */
+	*exists = 0;
+
+	/* sneaky optimizations (don't go through searching process if...):
+	 * - keyframe to be added is to be added out of current bounds
+	 * - keyframe to be added would replace one of the existing ones on bounds
+	 */
+	if ((arraylen <= 0) || (array == NULL)) {
+		printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array\n");
+		return 0;
+	}
+	else {
+		/* check whether to add before/after/on */
+		float framenum;
+
+		/* 'First' Point (when only one point, this case is used) */
+		framenum = array[0].time;
+		if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+			*exists = 1;
+			return 0;
+		}
+		else if (frame < framenum) {
+			return 0;
+		}
+
+		/* 'Last' Point */
+		framenum = array[(arraylen - 1)].time;
+		if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+			*exists = 1;
+			return (arraylen - 1);
+		}
+		else if (frame > framenum) {
+			return arraylen;
+		}
+	}
+
+
+	/* most of the time, this loop is just to find where to put it
+	 * - 'loopbreaker' is just here to prevent infinite loops
+	 */
+	for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
+		/* compute and get midpoint */
+		int mid = start + ((end - start) / 2);  /* we calculate the midpoint this way to avoid int overflows... */
+		float midfra = array[mid].time;
+
+		/* check if exactly equal to midpoint */
+		if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
+			*exists = 1;
+			return mid;
+		}
+
+		/* repeat in upper/lower half */
+		if (frame > midfra) {
+			start = mid + 1;
+		}
+		else if (frame < midfra) {
+			end = mid - 1;
+		}
+	}
+
+	/* print error if loop-limit exceeded */
+	if (loopbreaker == (maxloop - 1)) {
+		printf("Error: binarysearch_fcm_envelopedata_index() was taking too long\n");
+
+		// include debug info
+		printf("\tround = %d: start = %d, end = %d, arraylen = %d\n", loopbreaker, start, end, arraylen);
+	}
+
+	/* not found, so return where to place it */
+	return start;
+}
+#undef BINARYSEARCH_FRAMEEQ_THRESH
+
+
 /* Cycles F-Curve Modifier  --------------------------- */
 
 /* This modifier changes evaltime to something that exists within the curve's frame-range, 

Modified: trunk/blender/source/blender/editors/animation/fmodifier_ui.c
===================================================================
--- trunk/blender/source/blender/editors/animation/fmodifier_ui.c	2013-01-31 06:38:35 UTC (rev 54222)
+++ trunk/blender/source/blender/editors/animation/fmodifier_ui.c	2013-01-31 08:19:11 UTC (rev 54223)
@@ -327,88 +327,7 @@
 	uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
 }
 
-/* --------------- */
-
-#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001f
-
-/* Binary search algorithm for finding where to insert Envelope Data Point.
- * Returns the index to insert at (data already at that index will be offset if replace is 0)
- */
-static int binarysearch_fcm_envelopedata_index(FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
-{
-	int start = 0, end = arraylen;
-	int loopbreaker = 0, maxloop = arraylen * 2;
-	
-	/* initialize exists-flag first */
-	*exists = 0;
-	
-	/* sneaky optimizations (don't go through searching process if...):
-	 *	- keyframe to be added is to be added out of current bounds
-	 *	- keyframe to be added would replace one of the existing ones on bounds
-	 */
-	if ((arraylen <= 0) || (array == NULL)) {
-		printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array\n");
-		return 0;
-	}
-	else {
-		/* check whether to add before/after/on */
-		float framenum;
-		
-		/* 'First' Point (when only one point, this case is used) */
-		framenum = array[0].time;
-		if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
-			*exists = 1;
-			return 0;
-		}
-		else if (frame < framenum)
-			return 0;
-			
-		/* 'Last' Point */
-		framenum = array[(arraylen - 1)].time;
-		if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
-			*exists = 1;
-			return (arraylen - 1);
-		}
-		else if (frame > framenum)
-			return arraylen;
-	}
-	
-	
-	/* most of the time, this loop is just to find where to put it
-	 *  - 'loopbreaker' is just here to prevent infinite loops
-	 */
-	for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
-		/* compute and get midpoint */
-		int mid = start + ((end - start) / 2);  /* we calculate the midpoint this way to avoid int overflows... */
-		float midfra = array[mid].time;
-		
-		/* check if exactly equal to midpoint */
-		if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
-			*exists = 1;
-			return mid;
-		}
-		
-		/* repeat in upper/lower half */
-		if (frame > midfra)
-			start = mid + 1;
-		else if (frame < midfra)
-			end = mid - 1;
-	}
-	
-	/* print error if loop-limit exceeded */
-	if (loopbreaker == (maxloop - 1)) {
-		printf("Error: binarysearch_fcm_envelopedata_index() was taking too long\n");
-		
-		// include debug info 
-		printf("\tround = %d: start = %d, end = %d, arraylen = %d\n", loopbreaker, start, end, arraylen);
-	}
-	
-	/* not found, so return where to place it */
-	return start;
-}
-
 /* callback to add new envelope data point */
-// TODO: should we have a separate file for things like this?
 static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
 {
 	Scene *scene = CTX_data_scene(C);
@@ -425,7 +344,7 @@
 	/* check that no data exists for the current frame... */
 	if (env->data) {
 		short exists = -1;
-		int i = binarysearch_fcm_envelopedata_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
+		int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
 		
 		/* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
 		if (exists)

Modified: trunk/blender/source/blender/makesrna/intern/rna_fcurve.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_fcurve.c	2013-01-31 06:38:35 UTC (rev 54222)
+++ trunk/blender/source/blender/makesrna/intern/rna_fcurve.c	2013-01-31 08:19:11 UTC (rev 54223)
@@ -633,6 +633,82 @@
 	calc_fcurve_range(fcu, range, range + 1, FALSE, FALSE);
 }
 
+
+static FCM_EnvelopeData *rna_FModifierEnvelope_points_add(FModifier *fmod, ReportList *reports, float frame)
+{
+	FCM_EnvelopeData fed;
+	FMod_Envelope *env = (FMod_Envelope *)fmod->data;
+
+	/* init template data */
+	fed.min = -1.0f;
+	fed.max = 1.0f;
+	fed.time = frame;
+	fed.f1 = fed.f2 = 0;
+	int i;
+
+	if (env->data) {
+		/* add point to end of control points */
+		short exists = -1;
+		i = BKE_fcm_envelope_find_index(env->data, frame, env->totvert, &exists);
+		if (exists) {
+			BKE_reportf(reports, RPT_ERROR, "Already a control point at frame %.6f", frame);
+			return NULL;
+		}
+
+		/* realloc memory for extra point */
+		env->data = (FCM_EnvelopeData *) MEM_reallocN((void *)env->data, (env->totvert + 1) * sizeof(FCM_EnvelopeData));
+
+		/* move the points after the added point */
+		if (i < env->totvert) {
+			memmove(env->data + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
+		}
+
+		env->totvert++;
+	}
+	else {
+		env->data = MEM_mallocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+		env->totvert = 1;
+		i = 0;
+	}
+
+	/* add point to paste at index i */
+	*(env->data + i) = fed;
+	return (env->data + i);
+}
+
+void rna_FModifierEnvelope_points_remove(FModifier *fmod, ReportList *reports, PointerRNA *point)
+{
+	FCM_EnvelopeData *cp = point->data;
+	FMod_Envelope *env = (FMod_Envelope *)fmod->data;
+
+	int index = (int)(cp - env->data);
+
+	/* test point is in range */
+	if (index < 0 || index >= env->totvert) {
+		BKE_report(reports, RPT_ERROR, "Control Point not in FEnvelopeModifier");
+		return;
+	}
+
+	if (env->totvert > 1) {
+		/* move data after the removed point */
+
+		memmove(env->data + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
+
+		/* realloc smaller array */
+		env->totvert--;
+		env->data = (FCM_EnvelopeData *) MEM_reallocN((void *)env->data, (env->totvert) * sizeof(FCM_EnvelopeData));
+	}
+	else {
+		/* just free array, since the only vert was deleted */
+		if (env->data) {
+			MEM_freeN(env->data);
+			env->data = NULL;
+		}
+		env->totvert = 0;
+	}
+	RNA_POINTER_INVALIDATE(point);
+}
+
 #else
 
 static void rna_def_fmodifier_generator(BlenderRNA *brna)
@@ -770,6 +846,36 @@
 	/*	- selection flags (not implemented in UI yet though) */
 }
 
+static void rna_def_fmodifier_envelope_control_points(BlenderRNA *brna, PropertyRNA *cprop)
+{
+	StructRNA *srna;
+
+	FunctionRNA *func;
+	PropertyRNA *parm;
+
+	RNA_def_property_srna(cprop, "FModifierEnvelopeControlPoints");
+	srna = RNA_def_struct(brna, "FModifierEnvelopeControlPoints", NULL);
+	RNA_def_struct_sdna(srna, "FModifier");
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list