diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-09-25 12:07:32 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-09-25 15:20:59 +0300 |
commit | 64583f3e8d0f337a977c9a90b874bee733a37402 (patch) | |
tree | 3356dd4b14ed5f0cbaf0236b2ac51f7f4dad1ec0 /source/blender/blenkernel/intern/anim_data.c | |
parent | 5419f9a845ed58205ffbf38497ce9ff595499466 (diff) |
Animation: set Action `idroot` at assignment instead of just at evaluation
Actions are either locked to a specific ID type, or "floating". Actions
in the floating state are now locked when they are assigned to an ID block.
Previously (rB94b99b5d4a7c20cf2) this was done at evaluation time, which
caused various problems:
- The ID type was set on the evaluated copy, and inconsistently flushed
back to the original.
- A newly created Action could not be assigned to an Action constraint,
unless a depsgraph evaluation was be forced first.
This is now resolved by calling `BKE_animdata_set_action()` to set the
action (instead of direct assignment) where possible, and calling
`BKE_animdata_action_ensure_idroot()` otherwise.
Manifest Task: https://developer.blender.org/T80986
Diffstat (limited to 'source/blender/blenkernel/intern/anim_data.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim_data.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c index 30b75734e77..eb2cdf585c4 100644 --- a/source/blender/blenkernel/intern/anim_data.c +++ b/source/blender/blenkernel/intern/anim_data.c @@ -186,6 +186,11 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act) return false; } + if (adt->action == act) { + /* Don't bother reducing and increasing the user count when there is nothing changing. */ + return true; + } + if (!BKE_animdata_action_editable(adt)) { /* Cannot remove, otherwise things turn to custard. */ BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA"); @@ -204,7 +209,7 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act) } /* Action must have same type as owner. */ - if (!ELEM(act->idroot, 0, GS(id->name))) { + if (!BKE_animdata_action_ensure_idroot(id, act)) { /* Cannot set to this type. */ BKE_reportf( reports, @@ -230,6 +235,19 @@ bool BKE_animdata_action_editable(const AnimData *adt) return !is_tweaking_strip; } +bool BKE_animdata_action_ensure_idroot(const ID *owner, bAction *action) +{ + const int idcode = GS(owner->name); + + if (action->idroot == 0) { + /* First time this Action is assigned, lock it to this ID type. */ + action->idroot = idcode; + return true; + } + + return (action->idroot == idcode); +} + /* Freeing -------------------------------------------- */ /* Free AnimData used by the nominated ID-block, and clear ID-block's AnimData pointer */ @@ -673,6 +691,7 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa * and name it in a similar way so that it can be easily found again. */ if (dstAdt->action == NULL) { dstAdt->action = BKE_action_add(bmain, srcAdt->action->id.name + 2); + BKE_animdata_action_ensure_idroot(dstID, dstAdt->action); } else if (dstAdt->action == srcAdt->action) { CLOG_WARN(&LOG, @@ -685,6 +704,7 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa /* TODO: review this... */ id_us_min(&dstAdt->action->id); dstAdt->action = BKE_action_add(bmain, dstAdt->action->id.name + 2); + BKE_animdata_action_ensure_idroot(dstID, dstAdt->action); } /* loop over base paths, trying to fix for each one... */ |