Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/anim_sys.c')
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c343
1 files changed, 202 insertions, 141 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index d04b950c043..1a5d77bbc07 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -97,6 +97,7 @@ bool id_type_can_have_animdata(const short id_type)
case ID_MC:
case ID_MSK:
case ID_GD:
+ case ID_CF:
return true;
/* no AnimData */
@@ -1160,6 +1161,9 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
/* grease pencil */
ANIMDATA_IDS_CB(mainptr->gpencil.first);
+
+ /* cache files */
+ ANIMDATA_IDS_CB(mainptr->cachefiles.first);
}
/* Fix all RNA-Paths throughout the database (directly access the Global.main version)
@@ -1250,6 +1254,9 @@ void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const cha
/* grease pencil */
RENAMEFIX_ANIM_IDS(mainptr->gpencil.first);
+
+ /* cache files */
+ RENAMEFIX_ANIM_IDS(mainptr->cachefiles.first);
/* scenes */
RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene);
@@ -1482,161 +1489,193 @@ static bool animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst
return false;
}
+static bool animsys_store_rna_setting(
+ PointerRNA *ptr, AnimMapper *remap,
+ /* typically 'fcu->rna_path', 'fcu->array_index' */
+ const char *rna_path, const int array_index,
+ PathResolvedRNA *r_result)
+{
+ bool success = false;
+
+ char *path = NULL;
+ bool free_path;
+
+ /* get path, remapped as appropriate to work in its new environment */
+ free_path = animsys_remap_path(remap, (char *)rna_path, &path);
+
+ /* write value to setting */
+ if (path) {
+ /* get property to write to */
+ if (RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
+ if ((ptr->id.data == NULL) || RNA_property_animateable(&r_result->ptr, r_result->prop)) {
+ int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
+
+ if (array_len && array_index >= array_len) {
+ if (G.debug & G_DEBUG) {
+ printf("Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d\n",
+ (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+ path, array_index, array_len - 1);
+ }
+ }
+ else {
+ r_result->prop_index = array_len ? array_index : -1;
+ success = true;
+ }
+ }
+ }
+ else {
+ /* failed to get path */
+ /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
+ * where some channels will not exist, but shouldn't lock up Action */
+ if (G.debug & G_DEBUG) {
+ printf("Animato: Invalid path. ID = '%s', '%s[%d]'\n",
+ (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
+ path, array_index);
+ }
+ }
+ }
+
+ /* free temp path-info */
+ if (free_path) {
+ MEM_freeN((void *)path);
+ }
+
+ return success;
+}
+
/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
/* Write the given value to a setting using RNA, and return success */
-static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_index, float value)
+static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
{
- PropertyRNA *prop;
- PointerRNA new_ptr;
+ PropertyRNA *prop = anim_rna->prop;
+ PointerRNA *ptr = &anim_rna->ptr;
+ int array_index = anim_rna->prop_index;
- //printf("%p %s %i %f\n", ptr, path, array_index, value);
-
- /* get property to write to */
- if (RNA_path_resolve_property(ptr, path, &new_ptr, &prop)) {
- /* set value for animatable numerical values only
- * HACK: some local F-Curves (e.g. those on NLA Strips) are evaluated
- * without an ID provided, which causes the animateable test to fail!
- */
- if (RNA_property_animateable(&new_ptr, prop) || (ptr->id.data == NULL)) {
- int array_len = RNA_property_array_length(&new_ptr, prop);
- bool written = false;
-
- if (array_len && array_index >= array_len) {
- if (G.debug & G_DEBUG) {
- printf("Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d\n",
- (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
- path, array_index, array_len - 1);
+ /* caller must ensure this is animatable */
+ BLI_assert(RNA_property_animateable(ptr, prop) || ptr->id.data == NULL);
+
+ /* set value for animatable numerical values only
+ * HACK: some local F-Curves (e.g. those on NLA Strips) are evaluated
+ * without an ID provided, which causes the animateable test to fail!
+ */
+ bool written = false;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ {
+ const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
+ if (array_index != -1) {
+ if (RNA_property_boolean_get_index(ptr, prop, array_index) != value_coerce) {
+ RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
+ written = true;
}
-
- return false;
}
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- if (array_len) {
- if (RNA_property_boolean_get_index(&new_ptr, prop, array_index) != ANIMSYS_FLOAT_AS_BOOL(value)) {
- RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value));
- written = true;
- }
- }
- else {
- if (RNA_property_boolean_get(&new_ptr, prop) != ANIMSYS_FLOAT_AS_BOOL(value)) {
- RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value));
- written = true;
- }
- }
- break;
- case PROP_INT:
- if (array_len) {
- if (RNA_property_int_get_index(&new_ptr, prop, array_index) != (int)value) {
- RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
- written = true;
- }
- }
- else {
- if (RNA_property_int_get(&new_ptr, prop) != (int)value) {
- RNA_property_int_set(&new_ptr, prop, (int)value);
- written = true;
- }
- }
- break;
- case PROP_FLOAT:
- if (array_len) {
- if (RNA_property_float_get_index(&new_ptr, prop, array_index) != value) {
- RNA_property_float_set_index(&new_ptr, prop, array_index, value);
- written = true;
- }
- }
- else {
- if (RNA_property_float_get(&new_ptr, prop) != value) {
- RNA_property_float_set(&new_ptr, prop, value);
- written = true;
- }
- }
- break;
- case PROP_ENUM:
- if (RNA_property_enum_get(&new_ptr, prop) != (int)value) {
- RNA_property_enum_set(&new_ptr, prop, (int)value);
- written = true;
- }
- break;
- default:
- /* nothing can be done here... so it is unsuccessful? */
- return false;
+ else {
+ if (RNA_property_boolean_get(ptr, prop) != value_coerce) {
+ RNA_property_boolean_set(ptr, prop, value_coerce);
+ written = true;
+ }
}
-
- /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
-#if 0
- /* buffer property update for later flushing */
- if (written && RNA_property_update_check(prop)) {
- short skip_updates_hack = 0;
-
- /* optimization hacks: skip property updates for those properties
- * for we know that which the updates in RNA were really just for
- * flushing property editing via UI/Py
- */
- if (new_ptr.type == &RNA_PoseBone) {
- /* bone transforms - update pose (i.e. tag depsgraph) */
- skip_updates_hack = 1;
+ break;
+ }
+ case PROP_INT:
+ {
+ const int value_coerce = (int)value;
+ if (array_index != -1) {
+ if (RNA_property_int_get_index(ptr, prop, array_index) != value_coerce) {
+ RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
+ written = true;
}
-
- if (skip_updates_hack == 0)
- RNA_property_update_cache_add(&new_ptr, prop);
}
-#endif
-
- /* as long as we don't do property update, we still tag datablock
- * as having been updated. this flag does not cause any updates to
- * be run, it's for e.g. render engines to synchronize data */
- if (written && new_ptr.id.data) {
- ID *id = new_ptr.id.data;
-
- /* for cases like duplifarmes it's only a temporary so don't
- * notify anyone of updates */
- if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
- id->tag |= LIB_TAG_ID_RECALC;
- DAG_id_type_tag(G.main, GS(id->name));
+ else {
+ if (RNA_property_int_get(ptr, prop) != value_coerce) {
+ RNA_property_int_set(ptr, prop, value_coerce);
+ written = true;
}
}
+ break;
}
-
- /* successful */
- return true;
+ case PROP_FLOAT:
+ {
+ if (array_index != -1) {
+ if (RNA_property_float_get_index(ptr, prop, array_index) != value) {
+ RNA_property_float_set_index(ptr, prop, array_index, value);
+ written = true;
+ }
+ }
+ else {
+ if (RNA_property_float_get(ptr, prop) != value) {
+ RNA_property_float_set(ptr, prop, value);
+ written = true;
+ }
+ }
+ break;
+ }
+ case PROP_ENUM:
+ {
+ const int value_coerce = (int)value;
+ if (RNA_property_enum_get(ptr, prop) != value_coerce) {
+ RNA_property_enum_set(ptr, prop, value_coerce);
+ written = true;
+ }
+ break;
+ }
+ default:
+ /* nothing can be done here... so it is unsuccessful? */
+ return false;
}
- else {
- /* failed to get path */
- /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
- * where some channels will not exist, but shouldn't lock up Action */
- if (G.debug & G_DEBUG) {
- printf("Animato: Invalid path. ID = '%s', '%s[%d]'\n",
- (ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
- path, array_index);
+
+ /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
+#if 0
+ /* buffer property update for later flushing */
+ if (written && RNA_property_update_check(prop)) {
+ short skip_updates_hack = 0;
+
+ /* optimization hacks: skip property updates for those properties
+ * for we know that which the updates in RNA were really just for
+ * flushing property editing via UI/Py
+ */
+ if (new_ptr.type == &RNA_PoseBone) {
+ /* bone transforms - update pose (i.e. tag depsgraph) */
+ skip_updates_hack = 1;
+ }
+
+ if (skip_updates_hack == 0)
+ RNA_property_update_cache_add(ptr, prop);
+ }
+#endif
+
+ /* as long as we don't do property update, we still tag datablock
+ * as having been updated. this flag does not cause any updates to
+ * be run, it's for e.g. render engines to synchronize data */
+ if (written && ptr->id.data) {
+ ID *id = ptr->id.data;
+
+ /* for cases like duplifarmes it's only a temporary so don't
+ * notify anyone of updates */
+ if (!(id->tag & LIB_TAG_ANIM_NO_RECALC)) {
+ id->tag |= LIB_TAG_ID_RECALC;
+ DAG_id_type_tag(G.main, GS(id->name));
}
- return false;
}
+
+ /* successful */
+ return true;
}
/* Simple replacement based data-setting of the FCurve using RNA */
bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu, float curval)
{
- char *path = NULL;
- bool free_path = false;
+ PathResolvedRNA anim_rna;
bool ok = false;
-
- /* get path, remapped as appropriate to work in its new environment */
- free_path = animsys_remap_path(remap, fcu->rna_path, &path);
-
- /* write value to setting */
- if (path)
- ok = animsys_write_rna_setting(ptr, path, fcu->array_index, curval);
-
- /* free temp path-info */
- if (free_path)
- MEM_freeN(path);
-
+
+ if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ ok = animsys_write_rna_setting(&anim_rna, curval);
+ }
+
/* return whether we were successful */
return ok;
}
@@ -1654,8 +1693,11 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper
if ((fcu->grp == NULL) || (fcu->grp->flag & AGRP_MUTED) == 0) {
/* check if this curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
- const float curval = calculate_fcurve(fcu, ctime);
- BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
+ PathResolvedRNA anim_rna;
+ if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ animsys_write_rna_setting(&anim_rna, curval);
+ }
}
}
}
@@ -1684,8 +1726,12 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
/* evaluate this using values set already in other places
* NOTE: for 'layering' option later on, we should check if we should remove old value before adding
* new to only be done when drivers only changed */
- const float curval = calculate_fcurve(fcu, ctime);
- ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu, curval);
+
+ PathResolvedRNA anim_rna;
+ if (animsys_store_rna_setting(ptr, NULL, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ ok = animsys_write_rna_setting(&anim_rna, curval);
+ }
/* clear recalc flag */
driver->flag &= ~DRIVER_FLAG_RECALC;
@@ -1753,8 +1799,11 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
/* check if this curve should be skipped */
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
- const float curval = calculate_fcurve(fcu, ctime);
- BKE_animsys_execute_fcurve(ptr, remap, fcu, curval);
+ PathResolvedRNA anim_rna;
+ if (animsys_store_rna_setting(ptr, remap, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ animsys_write_rna_setting(&anim_rna, curval);
+ }
}
}
}
@@ -2612,8 +2661,12 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
AnimOverride *aor;
/* for each override, simply execute... */
- for (aor = adt->overrides.first; aor; aor = aor->next)
- animsys_write_rna_setting(ptr, aor->rna_path, aor->array_index, aor->value);
+ for (aor = adt->overrides.first; aor; aor = aor->next) {
+ PathResolvedRNA anim_rna;
+ if (animsys_store_rna_setting(ptr, NULL, aor->rna_path, aor->array_index, &anim_rna)) {
+ animsys_write_rna_setting(&anim_rna, aor->value);
+ }
+ }
}
/* ***************************************** */
@@ -2827,6 +2880,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
/* grease pencil */
EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
+
+ /* cache files */
+ EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
@@ -2888,8 +2944,13 @@ void BKE_animsys_eval_driver(EvaluationContext *eval_ctx,
* NOTE: for 'layering' option later on, we should check if we should remove old value before adding
* new to only be done when drivers only changed */
//printf("\told val = %f\n", fcu->curval);
- const float curval = calculate_fcurve(fcu, eval_ctx->ctime);
- ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu, curval);
+
+ PathResolvedRNA anim_rna;
+ if (animsys_store_rna_setting(&id_ptr, NULL, fcu->rna_path, fcu->array_index, &anim_rna)) {
+ const float curval = calculate_fcurve(&anim_rna, fcu, eval_ctx->ctime);
+ ok = animsys_write_rna_setting(&anim_rna, curval);
+ }
+
//printf("\tnew val = %f\n", fcu->curval);
/* clear recalc flag */