Fix T58721: Keyframing one transform option reset other transforms
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Mar 2019 14:38:45 +0000 (15:38 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Mar 2019 14:51:44 +0000 (15:51 +0100)
Use dedicated flag to tag animation just for copy-on-write synchronization,
which makes it so copies of the original data blocks gets in sync with the
original ID. This will not flush the animation update to all objects which
depend on that animation.

If such flush is required, use ID_RECALC_ANIMATION.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D4508

source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/animation/fmodifier_ui.c
source/blender/editors/animation/keyframing.c
source/blender/editors/animation/keyingsets.c
source/blender/makesdna/DNA_ID.h
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_fcurve.c

index fe1ef81262d3029f31f5af36f6b7598946d50f21..2e78df7584adf32c7c7bc22dbba7296f08281487 100644 (file)
@@ -2635,30 +2635,12 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
                 *   copied by copy-on-write, and not preserved. PROBABLY it is better
                 *   to preserve that cache in copy-on-write, but for the time being
                 *   we allow flush to layer collections component which will ensure
-                *   that cached array fo bases exists and is up-to-date.
-                *
-                * - Action is allowed to flush as well, this way it's possible to
-                *   keep current tagging in animation editors (which tags action for
-                *   CoW update when it's changed) but yet guarantee evaluation order
-                *   with objects which are using that action. */
+                *   that cached array fo bases exists and is up-to-date. */
                if (comp_node->type == NodeType::PARAMETERS ||
                    comp_node->type == NodeType::LAYER_COLLECTIONS)
                {
                        rel_flag &= ~RELATION_FLAG_NO_FLUSH;
                }
-               if (comp_node->type == NodeType::ANIMATION && id_type == ID_AC) {
-                       rel_flag &= ~RELATION_FLAG_NO_FLUSH;
-                       /* NOTE: We only allow flush on user edits. If the action block is
-                        * just brought into the dependency graph it is either due to
-                        * initial graph construction or due to some property got animated.
-                        * In first case all the related datablocks will be tagged for an
-                        * update as well. In the second case it is up to the editing
-                        * function to tag changed datablock.
-                        *
-                        * This logic allows to preserve unkeyed changes on file load and on
-                        * undo. */
-                       rel_flag |= RELATION_FLAG_FLUSH_USER_EDIT_ONLY;
-               }
                /* All entry operations of each component should wait for a proper
                 * copy of ID. */
                OperationNode *op_entry = comp_node->get_entry_operation();
index d1cef1cfa17da0896ee2fe182ed3e72dd43e8a3e..e3138dee1a7e0327d7aacb1d9f2095715879cd94 100644 (file)
@@ -4059,13 +4059,13 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
                WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
        }
 
-       /* tag copy-on-write flushing (so that the settings will have an effect) */
+       /* Tag for full animation update, so that the settings will have an effect. */
        if (ale_setting->id) {
-               DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
+               DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION);
        }
        if (ale_setting->adt && ale_setting->adt->action) {
-               /* action is it's own datablock, so has to be tagged specifically... */
-               DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_COPY_ON_WRITE);
+               /* Action is it's own datablock, so has to be tagged specifically. */
+               DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_ANIMATION);
        }
 
        /* verify animation context */
@@ -4109,7 +4109,7 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *ale_poin, void *
        BKE_nlatrack_solo_toggle(adt, nlt);
 
        /* send notifiers */
-       DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
+       DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
        WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
 }
 
index 3bcbe2d99e30518e55d9c422d93b968e6586dbaf..acffbd56b18291887bf5bb1c448c6ec745b683e1 100644 (file)
@@ -1350,7 +1350,7 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
                        switch (ac.datatype) {
                                case ANIMCONT_NLA: /* NLA-tracks only */
                                        rearrange_nla_channels(&ac, adt, mode);
-                                       DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
+                                       DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
                                        break;
 
                                case ANIMCONT_DRIVERS: /* Drivers list only */
@@ -1637,7 +1637,7 @@ static void update_dependencies_on_delete(bAnimListElem *ale)
        if (adt != NULL) {
                DEG_id_tag_update(id, ID_RECALC_ANIMATION);
                if (adt->action != NULL) {
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
                }
        }
        /* Deals with NLA and drivers.
@@ -1693,7 +1693,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
                                /* free the group itself */
                                if (adt->action) {
                                        BLI_freelinkN(&adt->action->groups, agrp);
-                                       DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                                       DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_ANIMATION);
                                }
                                else
                                        MEM_freeN(agrp);
index 7bef42d8682ef50ee818579b3d044961945d27b6..dfb1a4563641c200428a649b0348a7a464d5ecc3 100644 (file)
@@ -72,13 +72,13 @@ void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
        if (adt) {
                DEG_id_tag_update(id, ID_RECALC_ANIMATION);
                if (adt->action != NULL) {
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
                }
        }
 
        /* Tag copy on the main object if updating anything directly inside AnimData */
        if (ELEM(ale->type, ANIMTYPE_ANIMDATA, ANIMTYPE_NLAACTION, ANIMTYPE_NLATRACK, ANIMTYPE_NLACURVE)) {
-               DEG_id_tag_update(id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
+               DEG_id_tag_update(id, ID_RECALC_ANIMATION);
                return;
        }
 
index 40454bcad0cc21874bfb8acd3ceda2341272c64c..8edad506a33ce118f56640743c018fc5b9ad7f7d 100644 (file)
@@ -100,7 +100,7 @@ static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
        /* send notifiers */
        // XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
        WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-       DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_COPY_ON_WRITE);
+       DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION);
 }
 
 /* --------------- */
index 1922b876d1e7beeb58fa1460170315f4a1d0fbae..513fd29ef9b53e81cad88a727e34eeaa05c528a2 100644 (file)
@@ -157,7 +157,7 @@ bAction *verify_adt_action(Main *bmain, ID *id, short add)
                DEG_relations_tag_update(bmain);
        }
 
-       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
 
        /* return the action */
        return adt->action;
@@ -1317,10 +1317,10 @@ short insert_keyframe(
 
        if (ret) {
                if (act != NULL) {
-                       DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
                }
                if (adt != NULL && adt->action != NULL && adt->action != act) {
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
                }
        }
 
@@ -1371,11 +1371,11 @@ static void deg_tag_after_keyframe_delete(Main *bmain, ID *id, AnimData *adt)
                /* In the case last f-curve wes removed need to inform dependency graph
                 * about relations update, since it needs to get rid of animation operation
                 * for this datablock. */
-               DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
+               DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION_NO_FLUSH);
                DEG_relations_tag_update(bmain);
        }
        else {
-               DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_COPY_ON_WRITE);
+               DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
        }
 }
 
index 444e4634644a3bfa8f6b6d9a52f7481a90057a58..d532e22e7f77518ecd2d34c5086df1ab248fd199 100644 (file)
@@ -1049,7 +1049,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
                                break;
                        }
                        default:
-                               DEG_id_tag_update(ksp->id, ID_RECALC_COPY_ON_WRITE);
+                               DEG_id_tag_update(ksp->id, ID_RECALC_ANIMATION_NO_FLUSH);
                                break;
                }
 
index cd29a3c5bc4b869a44cb8481afdb693bd192cfbe..e1a83a7a5ccab00f66c8990aeb06dd9c5bcef6ff 100644 (file)
@@ -527,7 +527,8 @@ enum {
 
 /* Tag given ID for an update in all the dependency graphs. */
 typedef enum IDRecalcFlag {
-       /* Individual update tags, this is what ID gets tagged for update with. */
+       /***************************************************************************
+        * Individual update tags, this is what ID gets tagged for update with. */
 
        /* ** Object transformation changed. ** */
        ID_RECALC_TRANSFORM   = (1 << 0),
@@ -585,7 +586,16 @@ typedef enum IDRecalcFlag {
         */
        ID_RECALC_COPY_ON_WRITE = (1 << 13),
 
-       /* Aggregate flags, use only for checks on runtime.
+       /***************************************************************************
+        * Pseudonyms, to have more semantic meaning in the actual code without
+        * using too much low-level and implementation specific tags. */
+
+       /* Update animation datablock itself, without doing full re-evaluation of
+        * all dependent objects. */
+       ID_RECALC_ANIMATION_NO_FLUSH = ID_RECALC_COPY_ON_WRITE,
+
+       /***************************************************************************
+        * Aggregate flags, use only for checks on runtime.
         * Do NOT use those for tagging. */
 
        /* Identifies that SOMETHING has been changed in this ID. */
index 293ff1db505f7cb620ca91587c1a1d45593e0376..1a66a12261230ac7b3d0234f04227ad577714253 100644 (file)
@@ -98,7 +98,7 @@ static void rna_Action_groups_remove(bAction *act, ReportList *reports, PointerR
        MEM_freeN(agrp);
        RNA_POINTER_INVALIDATE(agrp_ptr);
 
-       DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
+       DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
        WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
 }
 
@@ -157,7 +157,7 @@ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, PointerR
                RNA_POINTER_INVALIDATE(fcu_ptr);
        }
 
-       DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
+       DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
        WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
 }
 
index b6cae3de3863138cd0db848772cb70c409be092d..ca4a6d2481f270f3de02c06d12eee28af3d974bf 100644 (file)
@@ -495,7 +495,7 @@ static void rna_FCurve_update_eval(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
        IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data;
        if (iat && iat->adt && iat->adt->action) {
                /* action is separate datablock, needs separate tag */
-               DEG_id_tag_update(&iat->adt->action->id, ID_RECALC_COPY_ON_WRITE);
+               DEG_id_tag_update(&iat->adt->action->id, ID_RECALC_ANIMATION);
        }
 }
 
@@ -618,7 +618,7 @@ static void rna_FModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poin
        if (adt != NULL) {
                if (adt->action != NULL) {
                        /* action is separate datablock, needs separate tag */
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
                }
        }
 
@@ -955,7 +955,7 @@ static void rna_Keyframe_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
        if (adt != NULL) {
                if (adt->action != NULL) {
                        /* action is separate datablock, needs separate tag */
-                       DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE);
+                       DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
                }
        }
 }