[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52664] trunk/blender/source/blender: fix [#33029] Applying modifier leaks memory

Campbell Barton ideasman42 at gmail.com
Thu Nov 29 17:26:39 CET 2012


Revision: 52664
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52664
Author:   campbellbarton
Date:     2012-11-29 16:26:39 +0000 (Thu, 29 Nov 2012)
Log Message:
-----------
fix [#33029] Applying modifier leaks memory

Thanks for Sergey for finding the bug & patching, This fix works a bit differently.
Theres no need to allocate the customdata in the first place - since its written into. So add a flag for vert/edge/face/loop creation functions so they can skip customdata creation.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c
    trunk/blender/source/blender/bmesh/intern/bmesh_construct.c
    trunk/blender/source/blender/bmesh/intern/bmesh_construct.h
    trunk/blender/source/blender/bmesh/intern/bmesh_core.c
    trunk/blender/source/blender/bmesh/intern/bmesh_core.h
    trunk/blender/source/blender/bmesh/intern/bmesh_mesh_conv.c
    trunk/blender/source/blender/bmesh/operators/bmo_create.c
    trunk/blender/source/blender/bmesh/operators/bmo_dupe.c
    trunk/blender/source/blender/bmesh/operators/bmo_extrude.c
    trunk/blender/source/blender/bmesh/operators/bmo_hull.c
    trunk/blender/source/blender/bmesh/operators/bmo_inset.c
    trunk/blender/source/blender/bmesh/operators/bmo_primitive.c
    trunk/blender/source/blender/bmesh/operators/bmo_removedoubles.c
    trunk/blender/source/blender/bmesh/operators/bmo_symmetrize.c
    trunk/blender/source/blender/bmesh/operators/bmo_utils.c
    trunk/blender/source/blender/bmesh/operators/bmo_wireframe.c
    trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
    trunk/blender/source/blender/editors/mesh/editmesh_knife.c
    trunk/blender/source/blender/modifiers/intern/MOD_skin.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c	2012-11-29 16:11:37 UTC (rev 52663)
+++ trunk/blender/source/blender/blenkernel/intern/modifiers_bmesh.c	2012-11-29 16:26:39 UTC (rev 52664)
@@ -79,7 +79,7 @@
 	/*do verts*/
 	mv = mvert = dm->dupVertArray(dm);
 	for (i = 0; i < totvert; i++, mv++) {
-		v = BM_vert_create(bm, mv->co, NULL);
+		v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
 		normal_short_to_float_v3(v->no, mv->no);
 		v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
 		BM_elem_index_set(v, i); /* set_inline */
@@ -97,7 +97,7 @@
 	me = medge = dm->dupEdgeArray(dm);
 	for (i = 0; i < totedge; i++, me++) {
 		//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
-		e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE);
+		e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);
 
 		e->head.hflag = BM_edge_flag_from_mflag(me->flag);
 		BM_elem_index_set(e, i); /* set_inline */
@@ -134,7 +134,7 @@
 			edges[j] = etable[ml->e];
 		}
 
-		f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE);
+		f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD);
 
 		if (UNLIKELY(f == NULL)) {
 			continue;

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_construct.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2012-11-29 16:11:37 UTC (rev 52663)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2012-11-29 16:26:39 UTC (rev 52664)
@@ -105,17 +105,17 @@
 	/* make new face */
 	if ((f == NULL) && (!is_overlap)) {
 		BMEdge *edar[4] = {NULL};
-		edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
-		edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, TRUE);
+		edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
+		edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, BM_CREATE_NO_DOUBLE);
 		if (len == 4) {
-			edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, TRUE);
-			edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, TRUE);
+			edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, BM_CREATE_NO_DOUBLE);
+			edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, BM_CREATE_NO_DOUBLE);
 		}
 		else {
-			edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, TRUE);
+			edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, BM_CREATE_NO_DOUBLE);
 		}
 
-		f = BM_face_create(bm, verts, edar, len, FALSE);
+		f = BM_face_create(bm, verts, edar, len, 0);
 
 		if (example && f) {
 			BM_elem_attrs_copy(bm, bm, example, f);
@@ -171,7 +171,7 @@
  * #BM_face_create should be considered over this function as it
  * avoids some unnecessary work.
  */
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
 {
 	BMEdge **edges2 = NULL;
 	BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
@@ -282,7 +282,7 @@
 		BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
 	}
 
-	f = BM_face_create(bm, verts, edges2, len, nodouble);
+	f = BM_face_create(bm, verts, edges2, len, create_flag);
 
 	/* clean up flags */
 	for (i = 0; i < len; i++) {
@@ -338,7 +338,7 @@
  *
  * \note Since this is a vcloud there is no direction.
  */
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int nodouble)
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, const int create_flag)
 {
 	BMFace *f;
 
@@ -464,7 +464,7 @@
 
 	i_prev = totv - 1;
 	for (i = 0; i < totv; i++) {
-		edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, TRUE);
+		edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, BM_CREATE_NO_DOUBLE);
 
 		/* the edge may exist already and be attached to a face
 		 * in this case we can find the best winding to use for the new face */
@@ -493,7 +493,7 @@
 	/* --- */
 
 	/* create the face */
-	f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, nodouble);
+	f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, create_flag);
 
 	MEM_freeN(edge_arr);
 	MEM_freeN(vert_arr_map);
@@ -856,7 +856,7 @@
 
 	v = BM_iter_new(&iter, bm_old, BM_VERTS_OF_MESH, NULL);
 	for (i = 0; v; v = BM_iter_step(&iter), i++) {
-		v2 = BM_vert_create(bm_new, v->co, NULL); /* copy between meshes so cant use 'example' argument */
+		v2 = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); /* copy between meshes so cant use 'example' argument */
 		BM_elem_attrs_copy(bm_old, bm_new, v, v2);
 		vtable[i] = v2;
 		BM_elem_index_set(v, i); /* set_inline */
@@ -873,7 +873,7 @@
 		e2 = BM_edge_create(bm_new,
 		                    vtable[BM_elem_index_get(e->v1)],
 		                    vtable[BM_elem_index_get(e->v2)],
-		                    e, FALSE);
+		                    e, BM_CREATE_SKIP_CD);
 
 		BM_elem_attrs_copy(bm_old, bm_new, e, e2);
 		etable[i] = e2;
@@ -909,7 +909,7 @@
 			v2 = vtable[BM_elem_index_get(loops[0]->v)];
 		}
 
-		f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE);
+		f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD);
 		if (UNLIKELY(f2 == NULL)) {
 			continue;
 		}

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_construct.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_construct.h	2012-11-29 16:11:37 UTC (rev 52663)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_construct.h	2012-11-29 16:26:39 UTC (rev 52664)
@@ -36,9 +36,9 @@
 
 void BM_face_copy_shared(BMesh *bm, BMFace *f);
 
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble);
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag);
 
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, int nodouble);
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag);
 
 void BMO_remove_tagged_faces(BMesh *bm, const short oflag);
 void BMO_remove_tagged_edges(BMesh *bm, const short oflag);

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2012-11-29 16:11:37 UTC (rev 52663)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2012-11-29 16:26:39 UTC (rev 52664)
@@ -54,7 +54,7 @@
 /**
  * \brief Main function for creating a new vertex.
  */
-BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
+BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag)
 {
 	BMVert *v = BLI_mempool_calloc(bm->vpool);
 
@@ -64,6 +64,9 @@
 	BM_elem_index_set(v, -1); /* set_ok_invalid */
 #endif
 
+	/* disallow this flag for verts - its meaningless */
+	BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
+
 	bm->elem_index_dirty |= BM_VERT; /* may add to middle of the pool */
 
 	bm->totvert++;
@@ -80,18 +83,21 @@
 		v->oflags = BLI_mempool_calloc(bm->toolflagpool);
 	}
 
-	CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
-	
-	if (example) {
-		int *keyi;
+	if (!(create_flag & BM_CREATE_SKIP_CD)) {
+		if (example) {
+			int *keyi;
 
-		BM_elem_attrs_copy(bm, bm, example, v);
+			BM_elem_attrs_copy(bm, bm, example, v);
 
-		/* exception: don't copy the original shapekey index */
-		keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
-		if (keyi) {
-			*keyi = ORIGINDEX_NONE;
+			/* exception: don't copy the original shapekey index */
+			keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
+			if (keyi) {
+				*keyi = ORIGINDEX_NONE;
+			}
 		}
+		else {
+			CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
+		}
 	}
 
 	BM_CHECK_ELEMENT(v);
@@ -105,11 +111,11 @@
  * \note Duplicate edges are supported by the API however users should _never_ see them.
  * so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE
  */
-BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble)
+BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag)
 {
 	BMEdge *e;
 	
-	if (nodouble && (e = BM_edge_exists(v1, v2)))
+	if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2)))
 		return e;
 	
 	e = BLI_mempool_calloc(bm->epool);
@@ -136,20 +142,26 @@
 	
 	BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW);
 	
-	CustomData_bmesh_set_default(&bm->edata, &e->head.data);
-	
 	bmesh_disk_edge_append(e, e->v1);
 	bmesh_disk_edge_append(e, e->v2);
 	
-	if (example)
-		BM_elem_attrs_copy(bm, bm, example, e);
+	if (!(create_flag & BM_CREATE_SKIP_CD)) {
+		if (example) {
+			BM_elem_attrs_copy(bm, bm, example, e);
+		}
+		else {
+			CustomData_bmesh_set_default(&bm->edata, &e->head.data);
+		}
+	}
+
 	
 	BM_CHECK_ELEMENT(e);
 
 	return e;
 }
 
-static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const BMLoop *example)
+static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f,
+                              const BMLoop *example, const eBMCreateFlag create_flag)
 {
 	BMLoop *l = NULL;
 
@@ -164,22 +176,24 @@
 
 	bm->totloop++;
 
-	if (example) {
-		CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
+	if (!(create_flag & BM_CREATE_SKIP_CD)) {
+		if (example) {
+			CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
+		}
+		else {
+			CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+		}
 	}
-	else {
-		CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
-	}
 
 	return l;
 }
 
-static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte)
+static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const int create_flag)
 {
 #ifdef USE_BMESH_HOLES
 	BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
 #endif
-	BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list