[Bf-blender-cvs] [266f0d3] missing-libs: Very first step to handle missing libs/datablocks when reading a file.

Bastien Montagne noreply at git.blender.org
Wed Jul 15 20:46:11 CEST 2015


Commit: 266f0d3e77705dea394a36b5e2117bc60634e1e8
Author: Bastien Montagne
Date:   Wed Jun 17 19:56:44 2015 +0200
Branches: missing-libs
https://developer.blender.org/rB266f0d3e77705dea394a36b5e2117bc60634e1e8

Very first step to handle missing libs/datablocks when reading a file.

Idea is, instead of ignoring completely missing linked datablocks, to
create void placeholders for them.

That way, you can work on your file, save it, and find again your missing data once
lib becomes available again.

Plans are also to be able to locate missing libs and reload them at runtime.

To support all that, we must be able to make Blender survive those missing data
(i.e. empty datablocks) all over the place. This commit contains some early work
in that direction, but this will need much much more work!

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

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/intern/action.c
M	source/blender/blenkernel/intern/anim_sys.c
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/camera.c
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/image.c
M	source/blender/blenkernel/intern/lamp.c
M	source/blender/blenkernel/intern/lattice.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/mball.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/node.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/speaker.c
M	source/blender/blenkernel/intern/texture.c
M	source/blender/blenkernel/intern/world.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/space_outliner/outliner_tools.c
M	source/blender/makesdna/DNA_ID.h

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

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 6ecc955..e78713f 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -47,6 +47,7 @@ struct bContext;
 struct PointerRNA;
 struct PropertyRNA;
 
+struct ID *BKE_liblock_alloc_notest(short type);
 void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL();
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 1b73978..4c6bd82 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -133,7 +133,7 @@ void BKE_action_make_local(bAction *act)
 	tMakeLocalActionContext mlac = {act, NULL, false, false};
 	Main *bmain = G.main;
 	
-	if (act->id.lib == NULL)
+	if ((act->id.lib == NULL) || ID_MISSING(&act->id))
 		return;
 	
 	/* XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index d5a8b8f..3eb1399 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -82,7 +82,7 @@
 bool id_type_can_have_animdata(ID *id)
 {
 	/* sanity check */
-	if (id == NULL)
+	if ((id == NULL) || ID_MISSING(id))
 		return false;
 
 	/* Only some ID-blocks have this info for now */
@@ -126,8 +126,9 @@ AnimData *BKE_animdata_from_id(ID *id)
 		IdAdtTemplate *iat = (IdAdtTemplate *)id;
 		return iat->adt;
 	}
-	else
+	else {
 		return NULL;
+	}
 }
 
 /* Add AnimData to the given ID-block. In order for this to work, we assume that 
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 27d3d1c..c058f87 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -139,7 +139,7 @@ void BKE_armature_make_local(bArmature *arm)
 	bool is_local = false, is_lib = false;
 	Object *ob;
 
-	if (arm->id.lib == NULL)
+	if ((arm->id.lib == NULL) || ID_MISSING(&arm->id))
 		return;
 	if (arm->id.us == 1) {
 		id_clear_lib_data(bmain, &arm->id);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 2464b3b..32dc5fe 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -223,7 +223,8 @@ void BKE_brush_make_local(Brush *brush)
 	Scene *scene;
 	bool is_local = false, is_lib = false;
 
-	if (brush->id.lib == NULL) return;
+	if ((brush->id.lib == NULL) || ID_MISSING(&brush->id))
+		return;
 
 	if (brush->clone.image) {
 		/* special case: ima always local immediately. Clone image should only
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index b308dc7..fe1a3de 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -108,7 +108,9 @@ void BKE_camera_make_local(Camera *cam)
 	 * - mixed: make copy
 	 */
 	
-	if (cam->id.lib == NULL) return;
+	if ((cam->id.lib == NULL) || ID_MISSING(&cam->id))
+		return;
+
 	if (cam->id.us == 1) {
 		id_clear_lib_data(bmain, &cam->id);
 		return;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index e769b4f..da9cff2 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -267,7 +267,7 @@ void BKE_curve_make_local(Curve *cu)
 	 * - mixed: do a copy
 	 */
 
-	if (cu->id.lib == NULL)
+	if ((cu->id.lib == NULL) || ID_MISSING(&cu->id))
 		return;
 
 	if (cu->id.us == 1) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index ef760f2..f752774 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -477,7 +477,8 @@ void BKE_image_make_local(struct Image *ima)
 	 * - mixed: make copy
 	 */
 
-	if (ima->id.lib == NULL) return;
+	if ((ima->id.lib == NULL) || ID_MISSING(&ima->id))
+		return;
 
 	/* Can't take short cut here: must check meshes at least because of bogus
 	 * texface ID refs. - z0r */
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 44e35c6..9b46415 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -170,7 +170,9 @@ void BKE_lamp_make_local(Lamp *la)
 	 * - mixed: make copy
 	 */
 	
-	if (la->id.lib == NULL) return;
+	if ((la->id.lib == NULL) || ID_MISSING(&la->id))
+		return;
+
 	if (la->id.us == 1) {
 		id_clear_lib_data(bmain, &la->id);
 		return;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 8692760..cd1d88c 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -325,7 +325,9 @@ void BKE_lattice_make_local(Lattice *lt)
 	 * - mixed: make copy
 	 */
 	
-	if (lt->id.lib == NULL) return;
+	if ((lt->id.lib == NULL) || ID_MISSING(&lt->id))
+		return;
+
 	if (lt->id.us == 1) {
 		id_clear_lib_data(bmain, &lt->id);
 		return;
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b4bb07f..3cc05a7 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -195,7 +195,7 @@ void id_us_min(ID *id)
  * if the block can be made local. */
 bool id_make_local(ID *id, bool test)
 {
-	if (id->flag & LIB_INDIRECT)
+	if (ID_MISSING(id) || (id->flag & LIB_INDIRECT))
 		return false;
 
 	switch (GS(id->name)) {
@@ -299,6 +299,10 @@ bool id_copy(ID *id, ID **newid, bool test)
 {
 	if (!test) *newid = NULL;
 
+	if (ID_MISSING(id)) {
+		return false;
+	}
+
 	/* conventions:
 	 * - make shallow copy, only this ID block
 	 * - id.us of the new ID is set to 1 */
@@ -557,7 +561,7 @@ void BKE_main_lib_objects_recalc_all(Main *bmain)
 
 	/* flag for full recalc */
 	for (ob = bmain->object.first; ob; ob = ob->id.next) {
-		if (ob->id.lib) {
+		if (ob->id.lib && !ID_MISSING(&ob->id)) {
 			DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 		}
 	}
@@ -644,7 +648,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
  * Allocates and returns memory of the right size for the specified block type,
  * initialized to zero.
  */
-static ID *alloc_libblock_notest(short type)
+ID *BKE_liblock_alloc_notest(short type)
 {
 	ID *id = NULL;
 	
@@ -766,7 +770,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
 	ID *id = NULL;
 	ListBase *lb = which_libbase(bmain, type);
 	
-	id = alloc_libblock_notest(type);
+	id = BKE_liblock_alloc_notest(type);
 	if (id) {
 		BKE_main_lock(bmain);
 		BLI_addtail(lb, id);
@@ -834,7 +838,7 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
 	ID *idn;
 	size_t idn_len;
 
-	idn = alloc_libblock_notest(GS(id->name));
+	idn = BKE_liblock_alloc_notest(GS(id->name));
 	assert(idn != NULL);
 
 	BLI_strncpy(idn->name, id->name, sizeof(idn->name));
@@ -935,110 +939,112 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 	BPY_id_release(id);
 #endif
 
-	switch (type) {    /* GetShort from util.h */
-		case ID_SCE:
-			BKE_scene_free((Scene *)id);
-			break;
-		case ID_LI:
-			BKE_library_free((Library *)id);
-			break;
-		case ID_OB:
-			BKE_object_free_ex((Object *)id, do_id_user);
-			break;
-		case ID_ME:
-			BKE_mesh_free((Mesh *)id, 1);
-			break;
-		case ID_CU:
-			BKE_curve_free((Curve *)id);
-			break;
-		case ID_MB:
-			BKE_mball_free((MetaBall *)id);
-			break;
-		case ID_MA:
-			BKE_material_free((Material *)id);
-			break;
-		case ID_TE:
-			BKE_texture_free((Tex *)id);
-			break;
-		case ID_IM:
-			BKE_image_free((Image *)id);
-			break;
-		case ID_LT:
-			BKE_lattice_free((Lattice *)id);
-			break;
-		case ID_LA:
-			BKE_lamp_free((Lamp *)id);
-			break;
-		case ID_CA:
-			BKE_camera_free((Camera *) id);
-			break;
-		case ID_IP:
-			BKE_ipo_free((Ipo *)id);
-			break;
-		case ID_KE:
-			BKE_key_free((Key *)id);
-			break;
-		case ID_WO:
-			BKE_world_free((World *)id);
-			break;
-		case ID_SCR:
-			BKE_screen_free((bScreen *)id);
-			break;
-		case ID_VF:
-			BKE_vfont_free((VFont *)id);
-			break;
-		case ID_TXT:
-			BKE_text_free((Text *)id);
-			break;
-		case ID_SCRIPT:
-			/* deprecated */
-			break;
-		case ID_SPK:
-			BKE_speaker_free((Speaker *)id);
-			break;
-		case ID_SO:
-			BKE_sound_free((bSound *)id);
-			break;
-		case ID_GR:
-			BKE_group_free((Group *)id);
-			break;
-		case ID_AR:
-			BKE_armature_free((bArmature *)id);
-			break;
-		case ID_AC:
-			BKE_action_free((bAction *)id);
-			break;
-		case ID_NT:
-			ntreeFreeTree_ex((bNodeTree *)id, do_id_user);
-			break;
-		case ID_BR:
-			BKE_brush_free((Brush *)id);
-			break;
-		case ID_PA:
-			BKE_particlesettings_free((ParticleSettings *)id);
-			break;
-		case ID_WM:
-			if (free_windowmanager_cb)
-				free_windowmanager_cb(NULL, (wmWindowManager *)id);
-			break;
-		case ID_GD:
-			BKE_gpencil_free((bGPdata *)id);
-			break;
-		case ID_MC:
-			BKE_movieclip_free((MovieClip *)id);
-			break;
-		case ID_MSK:
-			BKE_mask_free(bmain, (Mask *)id);
-			break;
-		case ID_LS:
-			BKE_linestyle_free((FreestyleLineStyle *)id);
-			break;
-		case ID_PAL:
-			BKE_palette_free((Palette *)id);
-			break;
-		case ID_PC:
-			BKE_paint_curve_free((PaintCurve *)id);
-			break;
+	if (!ID_MISSING(id)) {
+		switch (type) {    /* GetShort from util.h */
+			case ID_SCE:
+				BKE_scene_free((Scene *)id);
+				break;
+			case ID_LI:
+				BKE_library_free((Library *)id);
+				break;
+			case ID_OB:
+				BKE_object_free_ex((Object *)id, do_id_user);
+				break;
+			case ID_ME:
+				BKE_mesh_free((Mesh *)id, 1);
+				break;
+			case ID_CU:
+				BKE_curve_free((Curve *)id);
+				break;
+			case ID_MB:
+				BKE_mball_free((MetaBall *)id);
+				break;
+			case ID_MA:
+				BKE_material_free((Material *)id);
+				break;
+			case ID_TE:
+				BKE_tex

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list