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...
This commit is contained in:
parent
e30d94bb3b
commit
bd42987399
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue