[Bf-blender-cvs] [a7e540d] free-refcount-ids: Clean up `BKE_object_free()` and add `BKE_object_release_datablocks()`.

Bastien Montagne noreply at git.blender.org
Thu Sep 24 20:46:37 CEST 2015


Commit: a7e540d7c8fc0afd060ab8968d441027a1f670cd
Author: Bastien Montagne
Date:   Thu Sep 24 20:43:35 2015 +0200
Branches: free-refcount-ids
https://developer.blender.org/rBa7e540d7c8fc0afd060ab8968d441027a1f670cd

Clean up `BKE_object_free()` and add `BKE_object_release_datablocks()`.

Similar changed to those done for mesh/curve/mball.

Also, systematically nullify pointers in `_free()` functions, this does not cost
much and can help troubleshooting later.

And tag `BKE_object_unlink()` as an horrible piece of code...

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

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/mball.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/object.c

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

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 6c5081d..5ba8335 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -64,8 +64,8 @@ void BKE_object_free_bulletsoftbody(struct Object *ob);
 void BKE_object_free_curve_cache(struct Object *ob);
 void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
 
-void BKE_object_free(struct Object *ob);
-void BKE_object_free_ex(struct Object *ob, bool do_id_user);
+void BKE_object_release_datablocks(struct Object *ob);
+void BKE_object_free(struct Object *ob, const bool do_id_user);
 void BKE_object_free_derived_caches(struct Object *ob);
 void BKE_object_free_caches(struct Object *object);
 
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 8428ae4..4321142 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -167,16 +167,26 @@ void BKE_curve_free(Curve *cu, const bool do_id_user)
 
 	BKE_animdata_free((ID *)cu);
 
-	if (cu->mat)
+	if (cu->mat) {
 		MEM_freeN(cu->mat);
-	if (cu->str)
+		cu->mat = NULL;
+	}
+	if (cu->str) {
 		MEM_freeN(cu->str);
-	if (cu->strinfo)
+		cu->str = NULL;
+	}
+	if (cu->strinfo) {
 		MEM_freeN(cu->strinfo);
-	if (cu->bb)
+		cu->strinfo = NULL;
+	}
+	if (cu->bb) {
 		MEM_freeN(cu->bb);
-	if (cu->tb)
+		cu->bb = NULL;
+	}
+	if (cu->tb) {
 		MEM_freeN(cu->tb);
+		cu->tb = NULL;
+	}
 }
 
 Curve *BKE_curve_add(Main *bmain, const char *name, int type)
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 11abd2c..18e9c2b 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -946,7 +946,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
 			BKE_library_free((Library *)id);
 			break;
 		case ID_OB:
-			BKE_object_free_ex((Object *)id, do_id_user);
+			BKE_object_free((Object *)id, do_id_user);
 			break;
 		case ID_ME:
 			BKE_mesh_free((Mesh *)id, do_id_user);
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 33e0933..4ff964f 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -101,9 +101,13 @@ void BKE_mball_free(MetaBall *mb, const bool do_id_user)
 		BKE_animdata_free((ID *)mb);
 		mb->adt = NULL;
 	}
-	if (mb->mat) MEM_freeN(mb->mat);
+	if (mb->mat) {
+		MEM_freeN(mb->mat);
+		mb->mat = NULL;
+	}
+
 	BLI_freelistN(&mb->elems);
-	if (mb->disp.first) BKE_displist_free(&mb->disp);
+	BKE_displist_free(&mb->disp);
 }
 
 MetaBall *BKE_mball_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f0da793..cf69df7 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -485,12 +485,22 @@ void BKE_mesh_free(Mesh *me, const bool do_id_user)
 		BKE_animdata_free(&me->id);
 		me->adt = NULL;
 	}
-	
-	if (me->mat) MEM_freeN(me->mat);
-	
-	if (me->bb) MEM_freeN(me->bb);
-	if (me->mselect) MEM_freeN(me->mselect);
-	if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
+	if (me->mat) {
+		MEM_freeN(me->mat);
+		me->mat = NULL;
+	}
+	if (me->bb) {
+		MEM_freeN(me->bb);
+		me->bb = NULL;
+	}
+	if (me->mselect) {
+		MEM_freeN(me->mselect);
+		me->mselect = NULL;
+	}
+	if (me->edit_btmesh) {
+		MEM_freeN(me->edit_btmesh);
+		me->edit_btmesh = NULL;
+	}
 }
 
 static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7231ca7..fd62464 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -40,6 +40,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_group_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lamp_types.h"
@@ -379,55 +380,84 @@ void BKE_object_free_caches(Object *object)
 	}
 }
 
-/* do not free object itself */
-void BKE_object_free_ex(Object *ob, bool do_id_user)
+/**
+ * Release all datablocks (ID) used by this object (datablocks are never freed, they are just unreferenced).
+ *
+ * \param ob The object which has to release its data.
+ */
+void BKE_object_release_datablocks(Object *ob)
 {
 	int a;
-	
-	BKE_object_free_derived_caches(ob);
-	
-	/* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */
+
 	if (ob->data) {
 		ID *id = ob->data;
 		id->us--;
-		if (id->us == 0 && id->lib == NULL) {
-			switch (ob->type) {
-				case OB_MESH:
-					BKE_mesh_release_datablocks((Mesh *)id);
-					break;
-				case OB_CURVE:
-					BKE_curve_release_datablocks((Curve *)id);
-					break;
-				case OB_MBALL:
-					BKE_mball_release_datablocks((MetaBall *)id);
-					break;
-			}
-		}
 		ob->data = NULL;
 	}
 
 	if (ob->mat) {
 		for (a = 0; a < ob->totcol; a++) {
-			if (ob->mat[a]) ob->mat[a]->id.us--;
+			if (ob->mat[a]) {
+				ob->mat[a]->id.us--;
+				ob->mat[a] = NULL;
+			}
 		}
+	}
+
+	if (ob->poselib) {
+		ob->poselib->id.us--;
+		ob->poselib = NULL;
+	}
+	if (ob->gpd) {
+		ob->gpd->id.us--;
+		ob->gpd = NULL;
+	}
+}
+
+/**
+ * Free (or release) any data used by this object (does not free the object itself).
+ *
+ * \param ob The object to free.
+ * \param do_id_user When \a true, ID datablocks used (referenced) by this object are 'released'
+ *                   (their user count is decreased).
+ */
+void BKE_object_free(Object *ob, const bool do_id_user)
+{
+	BKE_object_free_derived_caches(ob);
+
+	if (do_id_user) {
+		BKE_object_release_datablocks(ob);
+	}
+
+	if (ob->mat) {
 		MEM_freeN(ob->mat);
+		ob->mat = NULL;
 	}
-	if (ob->matbits) MEM_freeN(ob->matbits);
-	ob->mat = NULL;
-	ob->matbits = NULL;
-	if (ob->iuser) MEM_freeN(ob->iuser);
-	ob->iuser = NULL;
-	if (ob->bb) MEM_freeN(ob->bb); 
-	ob->bb = NULL;
-	if (ob->adt) BKE_animdata_free((ID *)ob);
-	if (ob->poselib) ob->poselib->id.us--;
-	if (ob->gpd) ((ID *)ob->gpd)->us--;
-	if (ob->defbase.first)
-		BLI_freelistN(&ob->defbase);
-	if (ob->pose)
+	if (ob->matbits) {
+		MEM_freeN(ob->matbits);
+		ob->matbits = NULL;
+	}
+	if (ob->iuser) {
+		MEM_freeN(ob->iuser);
+		ob->iuser = NULL;
+	}
+	if (ob->bb) {
+		MEM_freeN(ob->bb);
+		ob->bb = NULL;
+	}
+	if (ob->adt) {
+		BKE_animdata_free((ID *)ob);
+		ob->adt = NULL;
+	}
+	BLI_freelistN(&ob->defbase);
+	if (ob->pose) {
 		BKE_pose_free_ex(ob->pose, do_id_user);
-	if (ob->mpath)
+		ob->pose = NULL;
+	}
+	if (ob->mpath) {
 		animviz_free_motionpath(ob->mpath);
+		ob->mpath = NULL;
+	}
 	BKE_bproperty_free_list(&ob->prop);
 	BKE_object_free_modifiers(ob);
 	
@@ -441,13 +471,19 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
 	BKE_rigidbody_free_object(ob);
 	BKE_rigidbody_free_constraint(ob);
 
-	if (ob->soft) sbFree(ob->soft);
-	if (ob->bsoft) bsbFree(ob->bsoft);
-	if (ob->gpulamp.first) GPU_lamp_free(ob);
+	if (ob->soft) {
+		sbFree(ob->soft);
+		ob->soft = NULL;
+	}
+	if (ob->bsoft) {
+		bsbFree(ob->bsoft);
+		ob->bsoft = NULL;
+	}
+	GPU_lamp_free(ob);
 
 	BKE_sculptsession_free(ob);
 
-	if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
+	BLI_freelistN(&ob->pc_ids);
 
 	BLI_freelistN(&ob->lodlevels);
 
@@ -457,16 +493,12 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
 		if (ob->curve_cache->path)
 			free_path(ob->curve_cache->path);
 		MEM_freeN(ob->curve_cache);
+		ob->curve_cache = NULL;
 	}
 
 	BKE_previewimg_free(&ob->preview);
 }
 
-void BKE_object_free(Object *ob)
-{
-	BKE_object_free_ex(ob, true);
-}
-
 static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
 {
 	Object *unlinkOb = userData;
@@ -478,6 +510,9 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
 	}
 }
 
+/* XXX Horrific! This pretty much re-does BKE_library_foreach_ID_link() and
+ *     BKE_library_callback_free_editor_id_reference_set() & co...
+ * TODO This is to be replaced by/merged in more generic 'id-remap' process being worked on in same-named branch... */
 void BKE_object_unlink(Object *ob)
 {
 	Main *bmain = G.main;




More information about the Bf-blender-cvs mailing list