forked from bartvdbraak/blender
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
This commit is contained in:
parent
e68144aed7
commit
51f5c994e9
@ -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()
|
||||
|
@ -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) &&
|
||||
|
@ -80,6 +80,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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* *********************** */
|
||||
|
Loading…
Reference in New Issue
Block a user