[Bf-blender-cvs] [1ee43c5] master: Fix T49856: Blender 2.78 crashes after loading data from a blendfile

Bastien Montagne noreply at git.blender.org
Tue Nov 1 13:42:51 CET 2016


Commit: 1ee43c5aef03c1a3218163d9450545fdb9ad4482
Author: Bastien Montagne
Date:   Tue Nov 1 13:39:31 2016 +0100
Branches: master
https://developer.blender.org/rB1ee43c5aef03c1a3218163d9450545fdb9ad4482

Fix T49856: Blender 2.78 crashes after loading data from a blendfile

Issue here was that py API code was keeping references (pointers) to the
liniked data-blocks, which can actually be duplicated and then deleted
during the 'make local' process...

Would have like to find a better way than passing optional GHash to get
the oldid->newid mapping, but could not think of a better idea.

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

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/intern/blender_copybuffer.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/editors/object/object_relations.c
M	source/blender/python/intern/bpy_library_load.c
M	source/blender/windowmanager/intern/wm_files_link.c

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

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 0d82de0..79373e3 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -39,6 +39,7 @@ extern "C" {
 #include "BLI_compiler_attrs.h"
 
 struct BlendThumbnail;
+struct GHash;
 struct ListBase;
 struct ID;
 struct ImBuf;
@@ -125,7 +126,8 @@ void BKE_id_ui_prefix(char name[66 + 1], const struct ID *id);
 void BKE_library_free(struct Library *lib);
 
 void BKE_library_make_local(
-        struct Main *bmain, const struct Library *lib, const bool untagged_only, const bool set_fake);
+        struct Main *bmain, const struct Library *lib, struct GHash *old_to_new_ids,
+        const bool untagged_only, const bool set_fake);
 
 
 /* use when "" is given to new_id() */
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index a4c2812..e57524a 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -101,7 +101,7 @@ bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *repor
 	IMB_colormanagement_check_file_config(bmain_dst);
 	/* Append, rather than linking. */
 	Library *lib = BLI_findstring(&bmain_dst->library, libname, offsetof(Library, filepath));
-	BKE_library_make_local(bmain_dst, lib, true, false);
+	BKE_library_make_local(bmain_dst, lib, NULL, true, false);
 	/* Important we unset, otherwise these object wont
 	 * link into other scenes from this blend file.
 	 */
@@ -150,7 +150,7 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
 
 	/* append, rather than linking */
 	lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
-	BKE_library_make_local(bmain, lib, true, false);
+	BKE_library_make_local(bmain, lib, NULL, true, false);
 
 	/* important we unset, otherwise these object wont
 	 * link into other scenes from this blend file */
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 1461215..622f79d 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -73,6 +73,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
+#include "BLI_ghash.h"
 #include "BLI_linklist.h"
 #include "BLI_memarena.h"
 
@@ -1640,7 +1641,8 @@ void BKE_main_id_clear_newpoins(Main *bmain)
  * We'll probably need at some point a true dependency graph between datablocks, but for now this should work
  * good enough (performances is not a critical point here anyway).
  */
-void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged_only, const bool set_fake)
+void BKE_library_make_local(
+        Main *bmain, const Library *lib, GHash *old_to_new_ids, const bool untagged_only, const bool set_fake)
 {
 	ListBase *lbarray[MAX_LIBARRAY];
 	ID *id, *id_next;
@@ -1712,6 +1714,9 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged
 		BLI_assert(id->lib != NULL);
 
 		BKE_libblock_remap(bmain, id, id->newid, ID_REMAP_SKIP_INDIRECT_USAGE);
+		if (old_to_new_ids) {
+			BLI_ghash_insert(old_to_new_ids, id, id->newid);
+		}
 	}
 
 	/* Third step: remove datablocks that have been copied to be localized and are no more used in the end...
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index d1232fd..16ee6f4 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2235,7 +2235,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
 			           "Orphan library objects added to the current scene to avoid loss");
 		}
 
-		BKE_library_make_local(bmain, NULL, false, false); /* NULL is all libs */
+		BKE_library_make_local(bmain, NULL, NULL, false, false); /* NULL is all libs */
 		WM_event_add_notifier(C, NC_WINDOW, NULL);
 		return OPERATOR_FINISHED;
 	}
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index ec69abb..15f3c66 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -33,6 +33,7 @@
 #include <stddef.h>
 
 #include "BLI_utildefines.h"
+#include "BLI_ghash.h"
 #include "BLI_string.h"
 #include "BLI_linklist.h"
 #include "BLI_path_util.h"
@@ -405,6 +406,8 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
 		BLO_blendhandle_close(self->blo_handle);
 		self->blo_handle = NULL;
 
+		GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__);
+
 		/* copied from wm_operator.c */
 		{
 			/* mark all library linked objects to be updated */
@@ -412,7 +415,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
 
 			/* append, rather than linking */
 			if ((self->flag & FILE_LINK) == 0) {
-				BKE_library_make_local(bmain, lib, true, false);
+				BKE_library_make_local(bmain, lib, old_to_new_ids, true, false);
 			}
 		}
 
@@ -439,6 +442,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
 								ID *id;
 
 								id = PyCapsule_GetPointer(item, NULL);
+								id = BLI_ghash_lookup_default(old_to_new_ids, id, id);
 								Py_DECREF(item);
 
 								RNA_id_pointer_create(id, &id_ptr);
@@ -452,6 +456,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
 		}
 #endif  /* USE_RNA_DATABLOCKS */
 
+		BLI_ghash_free(old_to_new_ids, NULL, NULL);
 		Py_RETURN_NONE;
 	}
 }
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index e872ec1..3b733f9 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -419,7 +419,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 		const bool use_recursive = RNA_boolean_get(op->ptr, "use_recursive");
 
 		if (use_recursive) {
-			BKE_library_make_local(bmain, NULL, true, set_fake);
+			BKE_library_make_local(bmain, NULL, NULL, true, set_fake);
 		}
 		else {
 			LinkNode *itemlink;
@@ -430,7 +430,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 				ID *new_id = ((WMLinkAppendDataItem *)(itemlink->link))->new_id;
 
 				if (new_id && !BLI_gset_haskey(done_libraries, new_id->lib)) {
-					BKE_library_make_local(bmain, new_id->lib, true, set_fake);
+					BKE_library_make_local(bmain, new_id->lib, NULL, true, set_fake);
 					BLI_gset_insert(done_libraries, new_id->lib);
 				}
 			}




More information about the Bf-blender-cvs mailing list