[Bf-blender-cvs] [40b269f50b9] temp-test-point-cloud-simulation-depsgraph-integration: Merge branch 'master' into simulation-data-block

Jacques Lucke noreply at git.blender.org
Wed Apr 15 18:27:13 CEST 2020


Commit: 40b269f50b98f074549182ccd741ec9d5db4cb7b
Author: Jacques Lucke
Date:   Thu Apr 9 11:24:11 2020 +0200
Branches: temp-test-point-cloud-simulation-depsgraph-integration
https://developer.blender.org/rB40b269f50b98f074549182ccd741ec9d5db4cb7b

Merge branch 'master' into simulation-data-block

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



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

diff --cc source/blender/blenloader/intern/readfile.c
index 4dc44548642,799330a07bf..ed39579429a
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@@ -9681,15 -9413,357 +9435,360 @@@ static bool direct_link_id(FileData *fd
      case ID_VO:
        direct_link_volume(fd, (Volume *)id);
        break;
 +    case ID_SIM:
 +      direct_link_simulation(fd, (Simulation *)id);
 +      break;
    }
  
-   oldnewmap_free_unused(fd->datamap);
+   return success;
+ }
+ 
+ /* Read all data associated with a datablock into datamap. */
+ static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *allocname)
+ {
+   bhead = blo_bhead_next(fd, bhead);
+ 
+   while (bhead && bhead->code == DATA) {
+     void *data;
+ #if 0
+ 		/* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
+ 		short* sp = fd->filesdna->structs[bhead->SDNAnr];
+ 		char* tmp = malloc(100);
+ 		allocname = fd->filesdna->types[sp[0]];
+ 		strcpy(tmp, allocname);
+ 		data = read_struct(fd, bhead, tmp);
+ #else
+     data = read_struct(fd, bhead, allocname);
+ #endif
+ 
+     if (data) {
+       oldnewmap_insert(fd->datamap, bhead->old, data, 0);
+     }
+ 
+     bhead = blo_bhead_next(fd, bhead);
+   }
+ 
+   return bhead;
+ }
+ 
+ /* Verify if the datablock and all associated data is identical. */
+ static bool read_libblock_is_identical(FileData *fd, BHead *bhead)
+ {
+   /* Test ID itself. */
+   if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) {
+     return false;
+   }
+ 
+   /* Test any other data that is part of ID (logic must match read_data_into_datamap). */
+   bhead = blo_bhead_next(fd, bhead);
+ 
+   while (bhead && bhead->code == DATA) {
+     if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) {
+       return false;
+     }
+ 
+     bhead = blo_bhead_next(fd, bhead);
+   }
+ 
+   return true;
+ }
+ 
+ /* For undo, restore matching library datablock from the old main. */
+ static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const ID *id)
+ {
+   /* In undo case, most libs and linked data should be kept as is from previous state
+    * (see BLO_read_from_memfile).
+    * However, some needed by the snapshot being read may have been removed in previous one,
+    * and would go missing.
+    * This leads e.g. to disappearing objects in some undo/redo case, see T34446.
+    * That means we have to carefully check whether current lib or
+    * libdata already exits in old main, if it does we merely copy it over into new main area,
+    * otherwise we have to do a full read of that bhead... */
+   DEBUG_PRINTF("UNDO: restore library %s\n", id->name);
+ 
+   Main *libmain = fd->old_mainlist->first;
+   /* Skip oldmain itself... */
+   for (libmain = libmain->next; libmain; libmain = libmain->next) {
+     DEBUG_PRINTF("  compare with %s -> ", libmain->curlib ? libmain->curlib->id.name : "<NULL>");
+     if (libmain->curlib && STREQ(id->name, libmain->curlib->id.name)) {
+       Main *oldmain = fd->old_mainlist->first;
+       DEBUG_PRINTF("match!\n");
+       /* In case of a library, we need to re-add its main to fd->mainlist,
+        * because if we have later a missing ID_LINK_PLACEHOLDER,
+        * we need to get the correct lib it is linked to!
+        * Order is crucial, we cannot bulk-add it in BLO_read_from_memfile()
+        * like it used to be. */
+       BLI_remlink(fd->old_mainlist, libmain);
+       BLI_remlink_safe(&oldmain->libraries, libmain->curlib);
+       BLI_addtail(fd->mainlist, libmain);
+       BLI_addtail(&main->libraries, libmain->curlib);
+       return true;
+     }
+     DEBUG_PRINTF("no match\n");
+   }
+ 
+   return false;
+ }
+ 
+ /* For undo, restore existing linked datablock from the old main. */
+ static bool read_libblock_undo_restore_linked(FileData *fd, Main *main, const ID *id, BHead *bhead)
+ {
+   DEBUG_PRINTF("UNDO: restore linked datablock %s\n", id->name);
+   DEBUG_PRINTF("  from %s (%s): ",
+                main->curlib ? main->curlib->id.name : "<NULL>",
+                main->curlib ? main->curlib->name : "<NULL>");
+ 
+   ID *id_old = BKE_libblock_find_name(main, GS(id->name), id->name + 2);
+   if (id_old != NULL) {
+     DEBUG_PRINTF("  found!\n");
+     /* Even though we found our linked ID, there is no guarantee its address
+      * is still the same. */
+     if (id_old != bhead->old) {
+       oldnewmap_insert(fd->libmap, bhead->old, id_old, GS(id_old->name));
+     }
+ 
+     /* No need to do anything else for ID_LINK_PLACEHOLDER, it's assumed
+      * already present in its lib's main. */
+     return true;
+   }
+ 
+   DEBUG_PRINTF("  not found\n");
+   return false;
+ }
+ 
+ /* For undo, restore unchanged datablock from old main. */
+ static void read_libblock_undo_restore_identical(
+     FileData *fd, Main *main, const ID *UNUSED(id), ID *id_old, const int tag)
+ {
+   BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
+   BLI_assert(id_old != NULL);
+ 
+   id_old->tag = tag;
+   id_old->lib = main->curlib;
+   id_old->us = ID_FAKE_USERS(id_old);
+   /* Do not reset id->icon_id here, memory allocated for it remains valid. */
+   /* Needed because .blend may have been saved with crap value here... */
+   id_old->newid = NULL;
+   id_old->orig_id = NULL;
+ 
+   const short idcode = GS(id_old->name);
+   Main *old_bmain = fd->old_mainlist->first;
+   ListBase *old_lb = which_libbase(old_bmain, idcode);
+   ListBase *new_lb = which_libbase(main, idcode);
+   BLI_remlink(old_lb, id_old);
+   BLI_addtail(new_lb, id_old);
+ 
+   /* Recalc flags, mostly these just remain as they are. */
+   id_old->recalc |= direct_link_id_restore_recalc_exceptions(id_old);
+   id_old->recalc_undo_accumulated = 0;
+ 
+   /* As usual, proxies require some special love...
+    * In `blo_clear_proxy_pointers_from_lib()` we clear all `proxy_from` pointers to local IDs, for
+    * undo. This is required since we do not re-read linked data in that case, so we also do not
+    * re-'lib_link' their pointers.
+    * Those `proxy_from` pointers are then re-defined properly when lib_linking the newly read local
+    * object. However, in case of re-used data 'as-is', we never lib_link it again, so we have to
+    * fix those backward pointers here. */
+   if (GS(id_old->name) == ID_OB) {
+     Object *ob = (Object *)id_old;
+     if (ob->proxy != NULL) {
+       ob->proxy->proxy_from = ob;
+     }
+   }
+ }
+ 
+ /* For undo, store changed datablock at old address. */
+ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, ID *id, ID *id_old)
+ {
+   /* During memfile undo, if an ID changed and we cannot directly re-use existing one from old
+    * bmain, we do a full read of the new id from the memfile, and then fully swap its content
+    * with the old id. This allows us to keep the same pointer even for modified data, which
+    * helps reducing further detected changes by the depsgraph (since unchanged IDs remain fully
+    * unchanged, even if they are using/pointing to a changed one). */
+   BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
+   BLI_assert(id_old != NULL);
+ 
+   const short idcode = GS(id->name);
+ 
+   Main *old_bmain = fd->old_mainlist->first;
+   ListBase *old_lb = which_libbase(old_bmain, idcode);
+   ListBase *new_lb = which_libbase(main, idcode);
+   BLI_remlink(old_lb, id_old);
+   BLI_remlink(new_lb, id);
+ 
+   /* We do not need any remapping from this call here, since no ID pointer is valid in the data
+    * currently (they are all pointing to old addresses, and need to go through `lib_link`
+    * process). So we can pass NULL for the Main pointer parameter. */
+   BKE_lib_id_swap_full(NULL, id, id_old);
+ 
+   BLI_addtail(new_lb, id_old);
+   BLI_addtail(old_lb, id);
+ }
+ 
+ static bool read_libblock_undo_restore(
+     FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id_old)
+ {
+   /* Get pointer to memory of new ID that we will be reading. */
+   const ID *id = peek_struct_undo(fd, bhead);
+   const short idcode = GS(id->name);
+ 
+   if (bhead->code == ID_LI) {
+     /* Restore library datablock. */
+     if (read_libblock_undo_restore_library(fd, main, id)) {
+       return true;
+     }
+   }
+   else if (bhead->code == ID_LINK_PLACEHOLDER) {
+     /* Restore linked datablock. */
+     if (read_libblock_undo_restore_linked(fd, main, id, bhead)) {
+       return true;
+     }
+   }
+   else if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
+     /* Skip reading any UI datablocks, existing ones are kept. We don't
+      * support pointers from other datablocks to UI datablocks so those
+      * we also don't put UI datablocks in fd->libmap. */
+     return true;
+   }
+ 
+   /* Restore local datablocks. */
+   DEBUG_PRINTF("UNDO: read %s (uuid %d) -> ", id->name, id->session_uuid);
+ 
+   ID *id_old = NULL;
+   const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
+   if (do_partial_undo && (bhead->code != ID_LINK_PLACEHOLDER)) {
+     /* This code should only ever be reached for local data-blocks. */
+     BLI_assert(main->curlib == NULL);
+ 
+     /* Find the 'current' existing ID we want to reuse instead of the one we
+      * would read from the undo memfile. */
+     BLI_assert(fd->old_idmap != NULL);
+     id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid);
+   }
+ 
+   if (id_old != NULL && read_libblock_is_identical(fd, bhead)) {
+     /* Local datablock was unchanged, restore from the old main. */
+     DEBUG_PRINTF("keep identical datablock\n");
+ 
+     /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as
+      * this is only for do_version-like code), but for sake of consistency, and also because
+      * it will tell us which ID is re-used from old Main, and which one is actually new. */
+     const int id_tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_UNDO_OLD_ID_REUSED;
+     read_libblock_undo_restore_identical(fd, main, id, id_old, id_tag);
+ 
+     /* Insert into library map for lookup by newly read datablocks (with pointer
+      * value bhead->old) or existing datablocks in memory (pointer value id_old). */
+     oldnewmap_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list