[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59469] trunk/blender/source/blender/ blenkernel/intern/cloth.c: fix for leak in cloth modifier

Campbell Barton ideasman42 at gmail.com
Sat Aug 24 16:32:43 CEST 2013


Revision: 59469
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59469
Author:   campbellbarton
Date:     2013-08-24 14:32:43 +0000 (Sat, 24 Aug 2013)
Log Message:
-----------
fix for leak in cloth modifier
- any error in cloth_build_springs wasn't freeing the edge-hash.
- was checking BLI_edgehash_haskey on matching vertices.
- was looping over setting NULL for all elements of a calloc'd array.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/cloth.c

Modified: trunk/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cloth.c	2013-08-24 14:01:07 UTC (rev 59468)
+++ trunk/blender/source/blender/blenkernel/intern/cloth.c	2013-08-24 14:32:43 UTC (rev 59469)
@@ -332,11 +332,13 @@
 	if (clmd->clothObject == NULL) {
 		if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
 			BKE_ptcache_invalidate(cache);
+			modifier_setError(&(clmd->modifier), "Can't initialize cloth");
 			return 0;
 		}
 	
 		if (clmd->clothObject == NULL) {
 			BKE_ptcache_invalidate(cache);
+			modifier_setError(&(clmd->modifier), "Null cloth object");
 			return 0;
 		}
 	
@@ -1004,10 +1006,20 @@
 	return 0;
 }
 
-static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *UNUSED(edgehash), LinkNode **edgelist)
+static void cloth_free_edgelist(LinkNode **edgelist, unsigned int numverts)
 {
-	unsigned int i = 0;
-	
+	if (edgelist) {
+		unsigned int i;
+		for (i = 0; i < numverts; i++) {
+			BLI_linklist_free(edgelist[i], NULL);
+		}
+
+		MEM_freeN(edgelist);
+	}
+}
+
+static void cloth_free_errorsprings(Cloth *cloth,  LinkNode **edgelist)
+{
 	if ( cloth->springs != NULL ) {
 		LinkNode *search = cloth->springs;
 		while (search) {
@@ -1020,17 +1032,13 @@
 		
 		cloth->springs = NULL;
 	}
+
+	cloth_free_edgelist(edgelist, cloth->numverts);
 	
-	if (edgelist) {
-		for ( i = 0; i < cloth->numverts; i++ ) {
-			BLI_linklist_free ( edgelist[i], NULL );
-		}
-
-		MEM_freeN ( edgelist );
+	if (cloth->edgehash) {
+		BLI_edgehash_free(cloth->edgehash, NULL);
+		cloth->edgehash = NULL;
 	}
-	
-	if (cloth->edgehash)
-		BLI_edgehash_free ( cloth->edgehash, NULL );
 }
 
 /* update stiffness if vertex group values are changing from frame to frame */
@@ -1094,23 +1102,19 @@
 	if ( numedges==0 )
 		return 0;
 
+	/* NOTE: handling ownership of sptings and edgehash is quite sloppy
+	 * currenlty they are never initialized but assert just to be sure */
+	BLI_assert(cloth->springs == NULL);
+	BLI_assert(cloth->edgehash == NULL);
+
 	cloth->springs = NULL;
+	cloth->edgehash = NULL;
 
 	edgelist = MEM_callocN ( sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc" );
 	
 	if (!edgelist)
 		return 0;
-	
-	for ( i = 0; i < numverts; i++ ) {
-		edgelist[i] = NULL;
-	}
 
-	if ( cloth->springs )
-		MEM_freeN ( cloth->springs );
-
-	// create spring network hash
-	edgehash = BLI_edgehash_new(__func__);
-
 	// structural springs
 	for ( i = 0; i < numedges; i++ ) {
 		spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
@@ -1132,11 +1136,11 @@
 			BLI_linklist_prepend ( &cloth->springs, spring );
 		}
 		else {
-			cloth_free_errorsprings(cloth, edgehash, edgelist);
+			cloth_free_errorsprings(cloth, edgelist);
 			return 0;
 		}
 	}
-	
+
 	if (struct_springs > 0)
 		clmd->sim_parms->avg_spring_len /= struct_springs;
 	
@@ -1153,7 +1157,7 @@
 		spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
 		
 		if (!spring) {
-			cloth_free_errorsprings(cloth, edgehash, edgelist);
+			cloth_free_errorsprings(cloth, edgelist);
 			return 0;
 		}
 
@@ -1174,7 +1178,7 @@
 		spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 		
 		if (!spring) {
-			cloth_free_errorsprings(cloth, edgehash, edgelist);
+			cloth_free_errorsprings(cloth, edgelist);
 			return 0;
 		}
 
@@ -1191,6 +1195,9 @@
 		BLI_linklist_prepend ( &cloth->springs, spring );
 	}
 
+	edgehash = BLI_edgehash_new_ex(__func__, numedges);
+	cloth->edgehash = edgehash;
+
 	if (numfaces) {
 		// bending springs
 		search2 = cloth->springs;
@@ -1206,13 +1213,13 @@
 
 				// check for existing spring
 				// check also if startpoint is equal to endpoint
-				if (!BLI_edgehash_haskey(edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2)) &&
-				    (index2 != tspring2->ij))
+				if ((index2 != tspring2->ij) &&
+				    !BLI_edgehash_haskey(edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2)))
 				{
 					spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 
 					if (!spring) {
-						cloth_free_errorsprings(cloth, edgehash, edgelist);
+						cloth_free_errorsprings(cloth, edgelist);
 						return 0;
 					}
 
@@ -1249,7 +1256,7 @@
 				spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 				
 				if (!spring) {
-					cloth_free_errorsprings(cloth, edgehash, edgelist);
+					cloth_free_errorsprings(cloth, edgelist);
 					return 0;
 				}
 
@@ -1284,18 +1291,12 @@
 	
 	cloth->numsprings = struct_springs + shear_springs + bend_springs;
 	
-	if ( edgelist ) {
-		for ( i = 0; i < numverts; i++ ) {
-			BLI_linklist_free ( edgelist[i], NULL );
-		}
-	
-		MEM_freeN ( edgelist );
-	}
-	
-	cloth->edgehash = edgehash;
-	
+	cloth_free_edgelist(edgelist, numverts);
+
+#if 0
 	if (G.debug_value > 0)
 		printf("avg_len: %f\n", clmd->sim_parms->avg_spring_len);
+#endif
 
 	return 1;
 




More information about the Bf-blender-cvs mailing list