Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2019-08-12 12:54:37 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2019-08-12 12:54:37 +0300
commit761aeb48990fe3e8729de5c0826a873fb68b5497 (patch)
treed170e31d7ecf13bdeee21f3c212495379e59545b
parent35a9a85b27087f253100e7c66e8878a3ab015449 (diff)
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
-rw-r--r--source/blender/blenloader/intern/readfile.c54
1 files changed, 35 insertions, 19 deletions
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),