[Bf-blender-cvs] [d1e4376f77c] undo-experiments-swap-reread-datablocks: undoexp: better handling of recalc flags in undo case.

Bastien Montagne noreply at git.blender.org
Wed Jan 29 21:38:11 CET 2020


Commit: d1e4376f77ceb29021b31b067dd09ccf38fd2db4
Author: Bastien Montagne
Date:   Wed Jan 29 21:30:06 2020 +0100
Branches: undo-experiments-swap-reread-datablocks
https://developer.blender.org/rBd1e4376f77ceb29021b31b067dd09ccf38fd2db4

undoexp: better handling of recalc flags in undo case.

Fixes the 'object that not update its position when undoing the very
first undo step' issue.

Just like with the 'unchanged' detection, when going backward, i.e.
actual undo from n to n-1 stages, the 'recalc' flag stored in ID is not
that useful, as it actually marks the updates needed from n-2 to n-1 stages.

So we need a way to get 'future' recacl flags, i.e. the last recalc
flags used by the last despgraph update, for the current ID, and set
them into the newly read ID's racalc flags.

Note that am not sure how strong this approach is, it is relatively
simple, but may require some more involved handling (like accumulating
all flags used in-between two undo steps storage, or something
similar?).

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

M	source/blender/blenloader/intern/readfile.c
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/makesdna/DNA_ID.h

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 120e4f31130..a476d37208d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9499,6 +9499,10 @@ static BHead *read_libblock(FileData *fd,
           id_old->newid = NULL;
           id_old->orig_id = NULL;
 
+          /* About recalc: since that ID did not change at all, we know that its recalc fields also
+           * remained unchanged, so no need to handle neither recalc nor recalc_undo_future here.
+           */
+
           Main *old_bmain = fd->old_mainlist->first;
           BLI_assert(old_bmain == BKE_main_idmap_main_get(fd->old_idmap));
           ListBase *old_lb = which_libbase(old_bmain, idcode);
@@ -9587,6 +9591,15 @@ static BHead *read_libblock(FileData *fd,
    * the version the file has been saved with. */
   if (!fd->memfile) {
     id->recalc = 0;
+    id->recalc_undo_future = 0;
+  }
+  else {
+    /* We are coming from the future (i.e. do an actual undo, and not a redo), and we found an old
+     * (aka existing) ID: we use its 'last saved recalc flags' as 'future undo recalc flags' of our
+     * newly read ID. */
+    if (id_old != NULL && fd->undo_direction < 0) {
+      id->recalc = id_old->recalc_undo_future;
+    }
   }
 
   /* this case cannot be direct_linked: it's just the ID part */
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index b019c079dab..2bf641964d6 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -814,12 +814,18 @@ void DEG_ids_check_recalc(
 
 static void deg_graph_clear_id_recalc_flags(ID *id)
 {
+  /* Keep track of used recalc flags, to get proper update when undoing.
+   * Note: we may actually want to accumulate those flags instead - and reset after each undo step
+   * is written ? */
+  id->recalc_undo_future = id->recalc;
   id->recalc &= ~ID_RECALC_ALL;
   bNodeTree *ntree = ntreeFromID(id);
   /* Clear embedded node trees too. */
   if (ntree) {
+    ntree->id.recalc_undo_future = ntree->id.recalc;
     ntree->id.recalc &= ~ID_RECALC_ALL;
   }
+  /* XXX And what about scene's master collection here? */
 }
 
 void DEG_ids_clear_recalc(Main *UNUSED(bmain), Depsgraph *depsgraph)
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index babc129a191..0908fb7aef0 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -261,7 +261,10 @@ typedef struct ID {
   int us;
   int icon_id;
   int recalc;
-  char _pad[4];
+  /* Used by undo code. Value of recalc is stored there when reading an ID from memfile, and not
+   * touched by anything, which means it can be used as 'reference' recalc value for the next undo
+   * step, when going backward (i.e. actual undo, redo can just use recalc value directly). */
+  int recalc_undo_future;
   IDProperty *properties;
 
   /** Reference linked ID which this one overrides. */



More information about the Bf-blender-cvs mailing list