[Bf-blender-cvs] [51f5c99] master: Fix T37103: Keyframing custom properties issue (FCurve would not reflect Custom props type changes).

Bastien Montagne noreply at git.blender.org
Tue Dec 17 09:51:11 CET 2013


Commit: 51f5c994e9f03ec2c488ac3a2af02b43c34d7ca6
Author: Bastien Montagne
Date:   Tue Dec 17 09:40:52 2013 +0100
http://developer.blender.org/rB51f5c994e9f03ec2c488ac3a2af02b43c34d7ca6

Fix T37103: Keyframing custom properties issue (FCurve would not reflect Custom props type changes).

Add an helper func to re-compute integer-only fcurve flags, and call it when editing custom props.

Reviewed by aligorith, thanks!

Summary: Proposal fix for "keyframing custom properties issue" (T37103).

Reviewers: aligorith

Maniphest Tasks: T37103

Differential Revision: http://developer.blender.org/D111

===================================================================

M	release/scripts/startup/bl_operators/wm.py
M	source/blender/editors/animation/keyframing.c
M	source/blender/editors/include/ED_keyframing.h
M	source/blender/makesrna/intern/rna_fcurve.c

===================================================================

diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 4b954e8..6a54a1e 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1045,6 +1045,7 @@ class WM_OT_properties_edit(Operator):
 
         # First remove
         item = eval("context.%s" % data_path)
+        prop_type_old = type(item[prop_old])
 
         rna_idprop_ui_prop_clear(item, prop_old)
         exec_str = "del item['%s']" % prop_old
@@ -1067,6 +1068,33 @@ class WM_OT_properties_edit(Operator):
 
         prop_ui["description"] = self.description
 
+        # If we have changed the type of the property, update its potential anim curves!
+        if prop_type_old != prop_type:
+            data_path = '["%s"]' % prop
+            done = set()
+            def _update(fcurves):
+                for fcu in fcurves:
+                    if fcu not in done and fcu.data_path == data_path:
+                        fcu.update_autoflags(item)
+                        done.add(fcu)
+
+            def _update_strips(strips):
+                for st in strips:
+                    if st.type in {'CLIP'} and st.action:
+                        _update(st.action.fcurves)
+                    elif st.type in {'META'}:
+                        _update_strips(st.strips)
+
+            adt = getattr(item, "animation_data", None)
+            if adt is not None:
+                if adt.action:
+                    _update(adt.action.fcurves)
+                if adt.drivers:
+                    _update(adt.drivers)
+                if adt.nla_tracks:
+                    for nt in adt.nla_tracks:
+                        _update_strips(nt.strips)
+
         # otherwise existing buttons which reference freed
         # memory may crash blender [#26510]
         # context.area.tag_redraw()
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 07cc16a..0c45364 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -229,6 +229,63 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
 	return fcu;
 }
 
+/* Helper */
+static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
+{
+	/* set additional flags for the F-Curve (i.e. only integer values) */
+	fcu->flag &= ~(FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES);
+	switch (RNA_property_type(prop)) {
+		case PROP_FLOAT:
+			/* do nothing */
+			break;
+		case PROP_INT:
+			/* do integer (only 'whole' numbers) interpolation between all points */
+			fcu->flag |= FCURVE_INT_VALUES;
+			break;
+		default:
+			/* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
+			 * values at all) interpolation between all points
+			 *    - however, we must also ensure that evaluated values are only integers still
+			 */
+			fcu->flag |= (FCURVE_DISCRETE_VALUES | FCURVE_INT_VALUES);
+			break;
+	}
+}
+
+/*  Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
+ *  but also through RNA when editing an ID prop, see T37103).
+ */
+void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, struct PointerRNA *ptr)
+{
+	PointerRNA tmp_ptr;
+	PropertyRNA *prop;
+	int old_flag = fcu->flag;
+
+	if ((ptr->id.data == NULL) && (ptr->data == NULL)) {
+		BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for this fcurve");
+		return;
+	}
+
+	/* try to get property we should be affecting */
+	if (RNA_path_resolve_property(ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
+		/* property not found... */
+		const char *idname = (ptr->id.data) ? ((ID *)ptr->id.data)->name : TIP_("<No ID pointer>");
+
+		BKE_reportf(reports, RPT_ERROR,
+		            "Could not update flags for this fcurve, as RNA path is invalid for the given ID "
+		            "(ID = %s, path = %s)",
+		            idname, fcu->rna_path);
+		return;
+	}
+
+	update_autoflags_fcurve_direct(fcu, prop);
+
+	if (old_flag != fcu->flag) {
+		/* Same as if keyframes had been changed */
+		WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+	}
+}
+
 /* ************************************************** */
 /* KEYFRAME INSERTION */
 
@@ -835,24 +892,7 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p
 		}
 	}
 	
-	/* set additional flags for the F-Curve (i.e. only integer values) */
-	fcu->flag &= ~(FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES);
-	switch (RNA_property_type(prop)) {
-		case PROP_FLOAT:
-			/* do nothing */
-			break;
-		case PROP_INT:
-			/* do integer (only 'whole' numbers) interpolation between all points */
-			fcu->flag |= FCURVE_INT_VALUES;
-			break;
-		default:
-			/* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
-			 * values at all) interpolation between all points
-			 *	- however, we must also ensure that evaluated values are only integers still
-			 */
-			fcu->flag |= (FCURVE_DISCRETE_VALUES | FCURVE_INT_VALUES);
-			break;
-	}
+	update_autoflags_fcurve_direct(fcu, prop);
 	
 	/* obtain value to give keyframe */
 	if ( (flag & INSERTKEY_MATRIX) && 
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index dc40efc..82cf216 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -81,6 +81,15 @@ struct FCurve *verify_fcurve(struct bAction *act, const char group[], struct Poi
 /* -------- */
 
 /* Lesser Keyframing API call:
+ *  Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
+ *  but also through RNA when editing an ID prop, see T37103).
+ */
+void update_autoflags_fcurve(struct FCurve *fcu, struct bContext *C, struct ReportList *reports,
+                             struct PointerRNA *ptr);
+
+/* -------- */
+
+/* Lesser Keyframing API call:
  *  Use this when validation of necessary animation data isn't necessary as it already
  *  exists, and there is a beztriple that can be directly copied into the array.
  */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 2036257..e2eff5c 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1858,6 +1858,14 @@ static void rna_def_fcurve(BlenderRNA *brna)
 	                            "Min/Max values", -FLT_MAX, FLT_MAX);
 	RNA_def_property_flag(parm, PROP_THICK_WRAP);
 	RNA_def_function_output(func, parm);
+
+	func = RNA_def_function(srna, "update_autoflags", "update_autoflags_fcurve"); /* calls the C/API direct */
+	RNA_def_function_ui_description(func, "Update FCurve flags set automatically from affected property "
+	                                      "(currently, integer/discrete flags set when the property is not a float)");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+	parm = RNA_def_pointer(func, "data", "AnyType", "Data",
+	                       "Data containing the property controlled by given FCurve");
+	RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
 }
 
 /* *********************** */




More information about the Bf-blender-cvs mailing list