[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56893] trunk/blender/source/blender: Fix #35404: crash in file save with python code that accesses mesh from panel.

Brecht Van Lommel brechtvanlommel at pandora.be
Sat May 18 12:24:35 CEST 2013


Revision: 56893
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56893
Author:   blendix
Date:     2013-05-18 10:24:34 +0000 (Sat, 18 May 2013)
Log Message:
-----------
Fix #35404: crash in file save with python code that accesses mesh from panel.

On file save the mesh gets loads from the editmesh but the derived mesh caches
wer not cleared. This usually happens through the depsgraph but it needs to be
done manually here. Most changes are some refactoring to deduplicate derived
mesh freeing code.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_object.h
    trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
    trunk/blender/source/blender/blenkernel/intern/depsgraph.c
    trunk/blender/source/blender/blenkernel/intern/multires.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenkernel/intern/paint.c
    trunk/blender/source/blender/editors/mesh/editmesh_utils.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c

Modified: trunk/blender/source/blender/blenkernel/BKE_object.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_object.h	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/BKE_object.h	2013-05-18 10:24:34 UTC (rev 56893)
@@ -66,7 +66,7 @@
 void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
 
 void BKE_object_free(struct Object *ob);
-void BKE_object_free_display(struct Object *ob);
+void BKE_object_free_derived_caches(struct Object *ob);
 
 bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
 

Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -2163,38 +2163,6 @@
 		MEM_freeN(deformedVerts);
 }
 
-static void clear_mesh_caches(Object *ob)
-{
-	Mesh *me = ob->data;
-
-	/* also serves as signal to remake texspace */
-	if (ob->bb) {
-		MEM_freeN(ob->bb);
-		ob->bb = NULL;
-	}
-	if (me->bb) {
-		MEM_freeN(me->bb);
-		me->bb = NULL;
-	}
-
-	BKE_displist_free(&ob->disp);
-
-	if (ob->derivedFinal) {
-		ob->derivedFinal->needsFree = 1;
-		ob->derivedFinal->release(ob->derivedFinal);
-		ob->derivedFinal = NULL;
-	}
-	if (ob->derivedDeform) {
-		ob->derivedDeform->needsFree = 1;
-		ob->derivedDeform->release(ob->derivedDeform);
-		ob->derivedDeform = NULL;
-	}
-
-	if (ob->sculpt) {
-		BKE_object_sculpt_modifiers_changed(ob);
-	}
-}
-
 static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
                             int build_shapekey_layers)
 {
@@ -2205,7 +2173,8 @@
 
 	BLI_assert(ob->type == OB_MESH);
 
-	clear_mesh_caches(ob);
+	BKE_object_free_derived_caches(ob);
+	BKE_object_sculpt_modifiers_changed(ob);
 
 	mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
 	                    &ob->derivedFinal, 0, 1,
@@ -2226,7 +2195,8 @@
 
 static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
 {
-	clear_mesh_caches(obedit);
+	BKE_object_free_derived_caches(obedit);
+	BKE_object_sculpt_modifiers_changed(obedit);
 
 	if (em->derivedFinal) {
 		if (em->derivedFinal != em->derivedCage) {

Modified: trunk/blender/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -1511,7 +1511,7 @@
 		if ((all_layer & layer) == 0) { // XXX && (ob != obedit)) {
 			/* but existing displaylists or derivedmesh should be freed */
 			if (ob->recalc & OB_RECALC_DATA)
-				BKE_object_free_display(ob);
+				BKE_object_free_derived_caches(ob);
 			
 			ob->recalc &= ~OB_RECALC_ALL;
 		}

Modified: trunk/blender/source/blender/blenkernel/intern/multires.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/multires.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/intern/multires.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -373,11 +373,8 @@
 void multires_force_update(Object *ob)
 {
 	if (ob) {
-		if (ob->derivedFinal) {
-			ob->derivedFinal->needsFree = 1;
-			ob->derivedFinal->release(ob->derivedFinal);
-			ob->derivedFinal = NULL;
-		}
+		BKE_object_free_derived_caches(ob);
+
 		if (ob->sculpt && ob->sculpt->pbvh) {
 			BKE_pbvh_free(ob->sculpt->pbvh);
 			ob->sculpt->pbvh = NULL;

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/intern/object.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -241,20 +241,34 @@
 	/* TODO: smoke?, cloth? */
 }
 
-/* here we will collect all local displist stuff */
-/* also (ab)used in depsgraph */
-void BKE_object_free_display(Object *ob)
+/* free data derived from mesh, called when mesh changes or is freed */
+void BKE_object_free_derived_caches(Object *ob)
 {
-	if (ob->derivedDeform) {
-		ob->derivedDeform->needsFree = 1;
-		ob->derivedDeform->release(ob->derivedDeform);
-		ob->derivedDeform = NULL;
+	/* also serves as signal to remake texspace */
+	if (ob->type == OB_MESH) {
+		Mesh *me = ob->data;
+
+		if (me->bb) {
+			MEM_freeN(me->bb);
+			me->bb = NULL;
+		}
 	}
+
+	if (ob->bb) {
+		MEM_freeN(ob->bb);
+		ob->bb = NULL;
+	}
+
 	if (ob->derivedFinal) {
 		ob->derivedFinal->needsFree = 1;
 		ob->derivedFinal->release(ob->derivedFinal);
 		ob->derivedFinal = NULL;
 	}
+	if (ob->derivedDeform) {
+		ob->derivedDeform->needsFree = 1;
+		ob->derivedDeform->release(ob->derivedDeform);
+		ob->derivedDeform = NULL;
+	}
 	
 	BKE_displist_free(&ob->disp);
 }
@@ -264,7 +278,7 @@
 {
 	int a;
 	
-	BKE_object_free_display(ob);
+	BKE_object_free_derived_caches(ob);
 	
 	/* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */
 	if (ob->data) {
@@ -2790,27 +2804,29 @@
 {
 	SculptSession *ss = ob->sculpt;
 
-	if (!ss->cache) {
-		/* we free pbvh on changes, except during sculpt since it can't deal with
-		 * changing PVBH node organization, we hope topology does not change in
-		 * the meantime .. weak */
-		if (ss->pbvh) {
-			BKE_pbvh_free(ss->pbvh);
-			ss->pbvh = NULL;
+	if (ss) {
+		if (!ss->cache) {
+			/* we free pbvh on changes, except during sculpt since it can't deal with
+			 * changing PVBH node organization, we hope topology does not change in
+			 * the meantime .. weak */
+			if (ss->pbvh) {
+				BKE_pbvh_free(ss->pbvh);
+				ss->pbvh = NULL;
+			}
+
+			free_sculptsession_deformMats(ob->sculpt);
 		}
+		else {
+			PBVHNode **nodes;
+			int n, totnode;
 
-		free_sculptsession_deformMats(ob->sculpt);
-	}
-	else {
-		PBVHNode **nodes;
-		int n, totnode;
+			BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
 
-		BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+			for (n = 0; n < totnode; n++)
+				BKE_pbvh_node_mark_update(nodes[n]);
 
-		for (n = 0; n < totnode; n++)
-			BKE_pbvh_node_mark_update(nodes[n]);
-
-		MEM_freeN(nodes);
+			MEM_freeN(nodes);
+		}
 	}
 }
 

Modified: trunk/blender/source/blender/blenkernel/intern/paint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/paint.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/blenkernel/intern/paint.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -51,6 +51,7 @@
 #include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
+#include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_pbvh.h"
 #include "BKE_subsurf.h"
@@ -433,11 +434,8 @@
 			 * here because this will lead to the while object
 			 * surface to disappear, so we'll release DM in place.
 			 */
-			if (object->derivedFinal) {
-				object->derivedFinal->needsFree = 1;
-				object->derivedFinal->release(object->derivedFinal);
-				object->derivedFinal = NULL;
-			}
+			BKE_object_free_derived_caches(object);
+
 			if (object->sculpt->pbvh) {
 				BKE_pbvh_free(object->sculpt->pbvh);
 				object->sculpt->pbvh = NULL;

Modified: trunk/blender/source/blender/editors/mesh/editmesh_utils.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_utils.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/editors/mesh/editmesh_utils.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -374,6 +374,11 @@
 #ifdef USE_TESSFACE_DEFAULT
 	BKE_mesh_tessface_calc(me);
 #endif
+
+	/* free derived mesh. usually this would happen through depsgraph but there
+	 * are exceptions like file save that will not cause this, and we want to
+	 * avoid ending up with an invalid derived mesh then */
+	BKE_object_free_derived_caches(ob);
 }
 
 /**

Modified: trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2013-05-18 09:44:30 UTC (rev 56892)
+++ trunk/blender/source/blender/editors/sculpt_paint/sculpt.c	2013-05-18 10:24:34 UTC (rev 56893)
@@ -4542,7 +4542,7 @@
 	ss->pbvh = NULL;
 	if (dm)
 		dm->getPBVH(NULL, dm);
-	BKE_object_free_display(ob);
+	BKE_object_free_derived_caches(ob);
 }
 
 void sculpt_update_after_dynamic_topology_toggle(bContext *C)




More information about the Bf-blender-cvs mailing list