[Bf-blender-cvs] [761aeb48990] master: Fix crashes caused by library placeholders.

Bastien Montagne noreply at git.blender.org
Mon Aug 12 11:59:43 CEST 2019


Commit: 761aeb48990fe3e8729de5c0826a873fb68b5497
Author: Bastien Montagne
Date:   Mon Aug 12 11:54:37 2019 +0200
Branches: master
https://developer.blender.org/rB761aeb48990fe3e8729de5c0826a873fb68b5497

Fix crashes caused by library placeholders.

This fixes inconsistencies in materials between objects and obdata
due to placeholders generation for missing libdata.

Note that we cannot do that when generating the obdata placeholder,
as not all objects using it might be already loaded...
So this has to be done near the end of the reading/linking process.

Reported here by Blender Studio.

Reviewers: brecht

Subscribers: jbakker, zeddb

Tags: #datablocks_and_libraries

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

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

M	source/blender/blenloader/intern/readfile.c

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 737a70615ae..9a4fde8cc42 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8940,6 +8940,37 @@ static void direct_link_linestyle(FileData *fd, FreestyleLineStyle *linestyle)
 /** \name Read Library Data Block
  * \{ */
 
+static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag)
+{
+  ListBase *lb = which_libbase(mainvar, idcode);
+  ID *ph_id = BKE_libblock_alloc_notest(idcode);
+
+  *((short *)ph_id->name) = idcode;
+  BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
+  BKE_libblock_init_empty(ph_id);
+  ph_id->lib = mainvar->curlib;
+  ph_id->tag = tag | LIB_TAG_MISSING;
+  ph_id->us = ID_FAKE_USERS(ph_id);
+  ph_id->icon_id = 0;
+
+  BLI_addtail(lb, ph_id);
+  id_sort_by_name(lb, ph_id);
+
+  return ph_id;
+}
+
+static void placeholders_ensure_valid(Main *bmain)
+{
+  /* Placeholder ObData IDs won't have any material, we have to update their objects for that,
+   * otherwise the inconsistency between both will lead to crashes (especially in Eevee?). */
+  for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
+    ID *obdata = ob->data;
+    if (obdata != NULL && obdata->tag & LIB_TAG_MISSING) {
+      test_object_materials(bmain, ob, obdata);
+    }
+  }
+}
+
 static const char *dataname(short id_code)
 {
   switch (id_code) {
@@ -9775,6 +9806,8 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
       ntreeUpdateAllNew(bfd->main);
     }
 
+    placeholders_ensure_valid(bfd->main);
+
     BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
 
     /* Now that all our data-blocks are loaded,
@@ -11259,25 +11292,6 @@ static void add_collections_to_scene(Main *mainvar,
   }
 }
 
-static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag)
-{
-  ListBase *lb = which_libbase(mainvar, idcode);
-  ID *ph_id = BKE_libblock_alloc_notest(idcode);
-
-  *((short *)ph_id->name) = idcode;
-  BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
-  BKE_libblock_init_empty(ph_id);
-  ph_id->lib = mainvar->curlib;
-  ph_id->tag = tag | LIB_TAG_MISSING;
-  ph_id->us = ID_FAKE_USERS(ph_id);
-  ph_id->icon_id = 0;
-
-  BLI_addtail(lb, ph_id);
-  id_sort_by_name(lb, ph_id);
-
-  return ph_id;
-}
-
 /* returns true if the item was found
  * but it may already have already been appended/linked */
 static ID *link_named_part(
@@ -11559,6 +11573,8 @@ static void library_link_end(Main *mainl,
   /* After all data has been read and versioned, uses LIB_TAG_NEW. */
   ntreeUpdateAllNew(mainvar);
 
+  placeholders_ensure_valid(mainvar);
+
   BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false);
 
   fix_relpaths_library(BKE_main_blendfile_path(mainvar),



More information about the Bf-blender-cvs mailing list