Page Menu
Home
Search
Configure Global Search
Log In
Files
F26741
fmodenv.diff
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Peter Staples (batfinger)
Nov 13 2013, 5:38 PM
Size
12 KB
Subscribers
None
fmodenv.diff
View Options
Index: source/blender/blenkernel/BKE_animsys.h
===================================================================
--- source/blender/blenkernel/BKE_animsys.h (revision 54202)
+++ source/blender/blenkernel/BKE_animsys.h (working copy)
@@ -44,6 +44,8 @@
struct bActionGroup;
struct AnimMapper;
+struct FCM_EnvelopeData;
+
/* ************************************* */
/* AnimData API */
@@ -136,6 +138,13 @@
/* ************************************* */
/* Evaluation API */
+
+/* FModifiers API */
+/* binary search to find control point used in fmodifiers_ui.c and rna_fcurve.c */
+/* TODO refactor to use bsearch() */
+
+int BKE_binarysearch_fcm_envelopedata_index(struct FCM_EnvelopeData array[], float frame, int arraylen, short *exists);
+
/* ------------- Main API -------------------- */
/* In general, these ones should be called to do all animation evaluation */
Index: source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- source/blender/blenkernel/intern/anim_sys.c (revision 54202)
+++ source/blender/blenkernel/intern/anim_sys.c (working copy)
@@ -2294,6 +2294,90 @@
adt->recalc = 0;
}
+/* --------------- */
+
+#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)
+ */
+
+int BKE_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;
+}
+
+
+
+
/* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only
*
* This will evaluate only the animation info available in the animation data-blocks
Index: source/blender/editors/animation/fmodifier_ui.c
===================================================================
--- source/blender/editors/animation/fmodifier_ui.c (revision 54202)
+++ source/blender/editors/animation/fmodifier_ui.c (working copy)
@@ -52,6 +52,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_animsys.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -327,88 +328,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 +345,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_binarysearch_fcm_envelopedata_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)
Index: source/blender/makesrna/intern/rna_fcurve.c
===================================================================
--- source/blender/makesrna/intern/rna_fcurve.c (revision 54202)
+++ source/blender/makesrna/intern/rna_fcurve.c (working copy)
@@ -43,6 +43,7 @@
#include "BKE_action.h"
+
#include "WM_types.h"
#include "ED_keyframing.h"
@@ -105,9 +106,11 @@
/* ****************************** */
#include "BKE_fcurve.h"
+#include "BKE_animsys.h"
#include "BKE_depsgraph.h"
-#include "BKE_animsys.h"
+
+
static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -633,6 +636,97 @@
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;
+ FCM_EnvelopeData *fedn;
+ /* init template data */
+ fed.min = -1.0f;
+ fed.max = 1.0f;
+ fed.time = frame;
+ fed.f1 = fed.f2 = 0;
+ if (env->data) {
+ /* add point to end of control points ^/
+ /* XXX deal with this later if needs to be ordered */
+ short exists = -1;
+ int i = BKE_binarysearch_fcm_envelopedata_index(env->data, frame, env->totvert, &exists);
+ if (exists) {
+ BKE_reportf(reports, RPT_ERROR, "Already a control point at frame %.6f", frame);
+ return NULL;
+ }
+ /* add new */
+ fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+
+ /* add the points that should occur before the point to be pasted */
+ if (i > 0) {
+ memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
+ }
+
+ /* add point to paste at index i */
+ *(fedn + i) = fed;
+
+ /* add the points that occur after the point to be pasted */
+ if (i < env->totvert) {
+ memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
+ }
+
+ /* replace (+ free) old with new */
+ MEM_freeN(env->data);
+ env->data = fedn;
+
+ env->totvert++;
+ return (env->data + i);
+
+ }
+ else {
+ env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+ *(env->data) = fed;
+ env->totvert = 1;
+ return env->data;
+ }
+
+ return NULL;
+}
+
+void rna_FModifierEnvelope_points_remove(FModifier *fmod, ReportList *reports, PointerRNA *point)
+{
+ FCM_EnvelopeData *cp = point->data;
+ FMod_Envelope *env = (FMod_Envelope *)fmod->data;
+ FCM_EnvelopeData *fedn;
+
+ 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) {
+ /* allocate a new smaller array */
+ fedn = MEM_callocN(sizeof(FCM_EnvelopeData) * (env->totvert - 1), "FCM_EnvelopeData");
+
+ memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
+ memcpy(fedn + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
+
+ /* free old array, and set the new */
+ MEM_freeN(env->data);
+ env->data = fedn;
+ env->totvert--;
+ }
+ 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 +864,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");
+
+ RNA_def_struct_ui_text(srna, "Control Points", "Control points defining the shape of the envelope");
+
+ func = RNA_def_function(srna, "add", "rna_FModifierEnvelope_points_add");
+ RNA_def_function_ui_description(func, "Add a control point to a FModifierEnvelope");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_float(func, "frame", 0.0f, -FLT_MAX, FLT_MAX, "",
+ "Frame to add this control-point", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "point", "FModifierEnvelopeControlPoint", "", "Newly created control-point");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_FModifierEnvelope_points_remove");
+ RNA_def_function_ui_description(func, "Remove a control-point from an FModifierEnvelope");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "point", "FModifierEnvelopeControlPoint", "", "Control-point to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+}
+
+
static void rna_def_fmodifier_envelope(BlenderRNA *brna)
{
StructRNA *srna;
@@ -784,6 +908,7 @@
RNA_def_property_collection_sdna(prop, NULL, "data", "totvert");
RNA_def_property_struct_type(prop, "FModifierEnvelopeControlPoint");
RNA_def_property_ui_text(prop, "Control Points", "Control points defining the shape of the envelope");
+ rna_def_fmodifier_envelope_control_points(brna, prop);
/* Range Settings */
prop = RNA_def_property(srna, "reference_value", PROP_FLOAT, PROP_NONE);
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
48/3d/a6a4f21a493f8fb6d62ce0b6eab9
Event Timeline
Log In to Comment