Commit: bd42987399f1e2decf259cce21a91e39c7a0a50d
Author: Bastien Montagne
Date:   Mon Dec 19 16:28:41 2016 +0100
Branches: master
https://developer.blender.org/rBbd42987399f1e2decf259cce21a91e39c7a0a50d

Fix (unreported) linked datablocks going through do_versions several times.

When linking data-blocks from same library in several steps, the already
linked data-blocks of same lib would go again through versionning code...

Note: only fixed for libraries, I can't imagine how this could happen
with local data...

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

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

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

diff --git a/source/blender/blenloader/intern/readfile.c 
b/source/blender/blenloader/intern/readfile.c
index 03c5d08..a154d28 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8112,7 +8112,10 @@ static BHead *read_libblock(FileData *fd, Main *main, 
BHead *bhead, const short
        if (bhead->code == ID_ID) {
                return blo_nextbhead(fd, bhead);
        }
-       
+
+       /* That way, we know which datablock needs do_versions (required 
currently for linking). */
+       id->tag |= LIB_TAG_NEW;
+
        /* need a name for the mallocN, just for debugging and sane prints on 
leaks */
        allocname = dataname(GS(id->name));
        
@@ -8578,7 +8581,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, 
const char *filepath)
        blo_join_main(&mainlist);
        
        lib_link_all(fd, bfd->main);
+
        //do_versions_after_linking(fd, NULL, bfd->main); // XXX: not here (or 
even in this function at all)! this causes crashes on many files - Aligorith 
(July 04, 2010)
+       BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
+
        lib_verify_nodetree(bfd->main, true);
        fix_relpaths_library(fd->relabase, bfd->main); /* make all relative 
paths, relative to the open blend file */
        
@@ -10142,6 +10148,9 @@ static void library_link_end(Main *mainl, FileData 
**fd, const short flag, Scene
        mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
 
        lib_link_all(*fd, mainvar);
+
+       BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false);
+
        lib_verify_nodetree(mainvar, false);
        fix_relpaths_library(G.main->name, mainvar); /* make all relative 
paths, relative to the open blend file */
 
@@ -10212,6 +10221,32 @@ static int mainvar_id_tag_any_check(Main *mainvar, 
const short tag)
        return false;
 }
 
+static void split_main_newid(Main *mainptr, Main *main_newid)
+{
+       /* We only copy the necessary subset of data in this temp main. */
+       main_newid->versionfile = mainptr->versionfile;
+       main_newid->subversionfile = mainptr->subversionfile;
+       BLI_strncpy(main_newid->name, mainptr->name, sizeof(main_newid->name));
+       main_newid->curlib = mainptr->curlib;
+
+       ListBase *lbarray[MAX_LIBARRAY];
+       ListBase *lbarray_newid[MAX_LIBARRAY];
+       int i = set_listbasepointers(mainptr, lbarray);
+       set_listbasepointers(main_newid, lbarray_newid);
+       while (i--) {
+               BLI_listbase_clear(lbarray_newid[i]);
+
+               for (ID *id = lbarray[i]->first, *idnext; id; id = idnext) {
+                       idnext = id->next;
+
+                       if (id->tag & LIB_TAG_NEW) {
+                               BLI_remlink(lbarray[i], id);
+                               BLI_addtail(lbarray_newid[i], id);
+                       }
+               }
+       }
+}
+
 static void read_libraries(FileData *basefd, ListBase *mainlist)
 {
        Main *mainl = mainlist->first;
@@ -10381,14 +10416,19 @@ static void read_libraries(FileData *basefd, ListBase 
*mainlist)
        }
        
        /* do versions, link, and free */
+       Main main_newid = {0};
        for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
-               /* some mains still have to be read, then
-                * versionfile is still zero! */
+               /* some mains still have to be read, then versionfile is still 
zero! */
                if (mainptr->versionfile) {
+                       /* We need to split out IDs already existing, or they 
will go again through do_versions - bad, very bad! */
+                       split_main_newid(mainptr, &main_newid);
+
                        if (mainptr->curlib->filedata) // can be zero... with 
shift+f1 append
-                               do_versions(mainptr->curlib->filedata, 
mainptr->curlib, mainptr);
+                               do_versions(mainptr->curlib->filedata, 
mainptr->curlib, &main_newid);
                        else
-                               do_versions(basefd, NULL, mainptr);
+                               do_versions(basefd, NULL, &main_newid);
+
+                       add_main_to_main(mainptr, &main_newid);
                }
                
                if (mainptr->curlib->filedata)
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 59fd0c7..9a8f3da 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -336,7 +336,8 @@ enum {
        /* tag datablock has having actually increased usercount for the extra 
virtual user. */
        LIB_TAG_EXTRAUSER_SET   = 1 << 7,
 
-       /* RESET_AFTER_USE tag newly duplicated/copied IDs. */
+       /* RESET_AFTER_USE tag newly duplicated/copied IDs.
+        * Also used internally in readfile.c to mark datablocks needing 
do_versions. */
        LIB_TAG_NEW             = 1 << 8,
        /* RESET_BEFORE_USE free test flag.
      * TODO make it a RESET_AFTER_USE too. */

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to