From 921a7556fbc4c66267137b767ce93c85d9b4cbd8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 1 Mar 2012 22:17:04 +0000 Subject: bmesh - changes to mempool allocations * double default edge allocation size (double the number of verts/faces). * CustomData_bmesh_init_pool was using allocsize & chunksize as the same variable. Now use type specific chunk size. * bmesh copy and editmode conversion now allocate the BMesh mempool size needed for the entire vert/edge/loop/face arrays since its known already. --- source/blender/blenkernel/BKE_customdata.h | 4 +- source/blender/blenkernel/intern/customdata.c | 24 ++++++-- source/blender/bmesh/intern/bmesh_construct.c | 84 ++++++++++++++------------ source/blender/bmesh/intern/bmesh_construct.h | 2 +- source/blender/bmesh/intern/bmesh_interp.c | 44 ++++++++------ source/blender/bmesh/intern/bmesh_mesh.c | 2 +- source/blender/bmesh/operators/bmo_mesh_conv.c | 8 +-- source/blender/editors/mesh/bmesh_tools.c | 30 ++++----- 8 files changed, 113 insertions(+), 85 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 99676e444f3..b414f36b8c8 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -110,7 +110,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, then goes through the mesh and makes sure all the customdata blocks are consistent with the new layout.*/ void CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest, - int mask, int alloctype, struct BMesh *bm, int type); + int mask, int alloctype, struct BMesh *bm, const char htype); /* frees data associated with a CustomData object (doesn't free the object * itself, though) @@ -319,7 +319,7 @@ void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int totloop, int totpoly); void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total); void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata); -void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize); +void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, const char htype); /* External file storage */ diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 09525e23c6b..a3c4b943215 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2111,19 +2111,33 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata, } } -void CustomData_bmesh_init_pool(CustomData *data, int allocsize) +void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype) { + int chunksize; + /* Dispose old pools before calling here to avoid leaks */ BLI_assert(data->pool == NULL); + switch (htype) { + case BM_VERT: chunksize = 512; break; + case BM_EDGE: chunksize = 1024; break; + case BM_LOOP: chunksize = 2048; break; + case BM_FACE: chunksize = 512; break; + case BM_ALL: chunksize = 512; break; /* use this when its undefined */ + default: + BLI_assert(0); + chunksize = 512; + break; + } + /* If there are no layers, no pool is needed just yet */ if (data->totlayer) { - data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, TRUE, FALSE); + data->pool = BLI_mempool_create(data->totsize, totelem, chunksize, TRUE, FALSE); } } void CustomData_bmesh_merge(CustomData *source, CustomData *dest, - int mask, int alloctype, BMesh *bm, int type) + int mask, int alloctype, BMesh *bm, const char htype) { BMHeader *h; BMIter iter; @@ -2132,9 +2146,9 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest, int t; CustomData_merge(source, dest, mask, alloctype, 0); - CustomData_bmesh_init_pool(dest, 512); + CustomData_bmesh_init_pool(dest, 512, htype); - switch (type) { + switch (htype) { case BM_VERT: t = BM_VERTS_OF_MESH; break; case BM_EDGE: diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index a0fd3ec9250..b498fa73a73 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -575,9 +575,9 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour } } -BMesh *BM_mesh_copy(BMesh *bmold) +BMesh *BM_mesh_copy(BMesh *bm_old) { - BMesh *bm; + BMesh *bm_new; BMVert *v, *v2, **vtable = NULL; BMEdge *e, *e2, **edges = NULL, **etable = NULL; BLI_array_declare(edges); @@ -587,57 +587,61 @@ BMesh *BM_mesh_copy(BMesh *bmold) BMEditSelection *ese; BMIter iter, liter; int i, j; + BMAllocTemplate allocsize = {bm_old->totvert, + bm_old->totedge, + bm_old->totloop, + bm_old->totface}; /* allocate a bmesh */ - bm = BM_mesh_create(bmold->ob, &bm_mesh_allocsize_default); + bm_new = BM_mesh_create(bm_old->ob, &allocsize); - CustomData_copy(&bmold->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bmold->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bmold->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bmold->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_bmesh_init_pool(&bm->vdata, bm_mesh_allocsize_default.totvert); - CustomData_bmesh_init_pool(&bm->edata, bm_mesh_allocsize_default.totedge); - CustomData_bmesh_init_pool(&bm->ldata, bm_mesh_allocsize_default.totloop); - CustomData_bmesh_init_pool(&bm->pdata, bm_mesh_allocsize_default.totface); + CustomData_bmesh_init_pool(&bm_new->vdata, allocsize.totvert, BM_VERT); + CustomData_bmesh_init_pool(&bm_new->edata, allocsize.totedge, BM_EDGE); + CustomData_bmesh_init_pool(&bm_new->ldata, allocsize.totloop, BM_LOOP); + CustomData_bmesh_init_pool(&bm_new->pdata, allocsize.totface, BM_FACE); - vtable = MEM_mallocN(sizeof(BMVert *) * bmold->totvert, "BM_mesh_copy vtable"); - etable = MEM_mallocN(sizeof(BMEdge *) * bmold->totedge, "BM_mesh_copy etable"); - ftable = MEM_mallocN(sizeof(BMFace *) * bmold->totface, "BM_mesh_copy ftable"); + vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable"); + etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable"); + ftable = MEM_mallocN(sizeof(BMFace *) * bm_old->totface, "BM_mesh_copy ftable"); - v = BM_iter_new(&iter, bmold, BM_VERTS_OF_MESH, NULL); + 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, v->co, NULL); /* copy between meshes so cant use 'example' argument */ - BM_elem_attrs_copy(bmold, bm, v, v2); + v2 = BM_vert_create(bm_new, v->co, NULL); /* 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 */ BM_elem_index_set(v2, i); /* set_inline */ } - bmold->elem_index_dirty &= ~BM_VERT; - bm->elem_index_dirty &= ~BM_VERT; + bm_old->elem_index_dirty &= ~BM_VERT; + bm_new->elem_index_dirty &= ~BM_VERT; /* safety check */ - BLI_assert(i == bmold->totvert); + BLI_assert(i == bm_old->totvert); - e = BM_iter_new(&iter, bmold, BM_EDGES_OF_MESH, NULL); + e = BM_iter_new(&iter, bm_old, BM_EDGES_OF_MESH, NULL); for (i = 0; e; e = BM_iter_step(&iter), i++) { - e2 = BM_edge_create(bm, + e2 = BM_edge_create(bm_new, vtable[BM_elem_index_get(e->v1)], vtable[BM_elem_index_get(e->v2)], e, FALSE); - BM_elem_attrs_copy(bmold, bm, e, e2); + BM_elem_attrs_copy(bm_old, bm_new, e, e2); etable[i] = e2; BM_elem_index_set(e, i); /* set_inline */ BM_elem_index_set(e2, i); /* set_inline */ } - bmold->elem_index_dirty &= ~BM_EDGE; - bm->elem_index_dirty &= ~BM_EDGE; + bm_old->elem_index_dirty &= ~BM_EDGE; + bm_new->elem_index_dirty &= ~BM_EDGE; /* safety check */ - BLI_assert(i == bmold->totedge); + BLI_assert(i == bm_old->totedge); - f = BM_iter_new(&iter, bmold, BM_FACES_OF_MESH, NULL); + f = BM_iter_new(&iter, bm_old, BM_FACES_OF_MESH, NULL); for (i = 0; f; f = BM_iter_step(&iter), i++) { BM_elem_index_set(f, i); /* set_inline */ @@ -646,7 +650,7 @@ BMesh *BM_mesh_copy(BMesh *bmold) BLI_array_growitems(loops, f->len); BLI_array_growitems(edges, f->len); - l = BM_iter_new(&liter, bmold, BM_LOOPS_OF_FACE, f); + l = BM_iter_new(&liter, bm_old, BM_LOOPS_OF_FACE, f); for (j = 0; j < f->len; j++, l = BM_iter_step(&liter)) { loops[j] = l; edges[j] = etable[BM_elem_index_get(l->e)]; @@ -660,32 +664,32 @@ BMesh *BM_mesh_copy(BMesh *bmold) v2 = vtable[BM_elem_index_get(loops[0]->v)]; } - f2 = BM_face_create_ngon(bm, v, v2, edges, f->len, FALSE); + f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE); if (!f2) continue; /* use totface incase adding some faces fails */ - BM_elem_index_set(f2, (bm->totface - 1)); /* set_inline */ + BM_elem_index_set(f2, (bm_new->totface - 1)); /* set_inline */ ftable[i] = f2; - BM_elem_attrs_copy(bmold, bm, f, f2); + BM_elem_attrs_copy(bm_old, bm_new, f, f2); copy_v3_v3(f2->no, f->no); - l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f2); + l = BM_iter_new(&liter, bm_new, BM_LOOPS_OF_FACE, f2); for (j = 0; j < f->len; j++, l = BM_iter_step(&liter)) { - BM_elem_attrs_copy(bmold, bm, loops[j], l); + BM_elem_attrs_copy(bm_old, bm_new, loops[j], l); } - if (f == bmold->act_face) bm->act_face = f2; + if (f == bm_old->act_face) bm_new->act_face = f2; } - bmold->elem_index_dirty &= ~BM_FACE; - bm->elem_index_dirty &= ~BM_FACE; + bm_old->elem_index_dirty &= ~BM_FACE; + bm_new->elem_index_dirty &= ~BM_FACE; /* safety check */ - BLI_assert(i == bmold->totface); + BLI_assert(i == bm_old->totface); /* copy over edit selection history */ - for (ese = bmold->selected.first; ese; ese = ese->next) { + for (ese = bm_old->selected.first; ese; ese = ese->next) { void *ele = NULL; if (ese->htype == BM_VERT) @@ -700,7 +704,7 @@ BMesh *BM_mesh_copy(BMesh *bmold) } if (ele) - BM_select_history_store(bm, ele); + BM_select_history_store(bm_new, ele); } MEM_freeN(etable); @@ -710,7 +714,7 @@ BMesh *BM_mesh_copy(BMesh *bmold) BLI_array_free(loops); BLI_array_free(edges); - return bm; + return bm_new; } /* ME -> BM */ diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 8d624592ae7..5c4101c9cde 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -46,7 +46,7 @@ void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type); void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target); -BMesh *BM_mesh_copy(BMesh *bmold); +BMesh *BM_mesh_copy(BMesh *bm_old); char BM_face_flag_from_mflag(const char mflag); char BM_edge_flag_from_mflag(const short mflag); diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 669426b73a6..d2af98a5e9f 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -720,11 +720,11 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) BLI_mempool *oldpool = olddata->pool; void *block; - CustomData_bmesh_init_pool(data, data == &bm->ldata ? 2048 : 512); - if (data == &bm->vdata) { BMVert *eve; - + + CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT); + BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) { block = NULL; CustomData_bmesh_set_default(data, &block); @@ -736,6 +736,8 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) else if (data == &bm->edata) { BMEdge *eed; + CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE); + BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) { block = NULL; CustomData_bmesh_set_default(data, &block); @@ -744,31 +746,39 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) eed->head.data = block; } } - else if (data == &bm->pdata || data == &bm->ldata) { + else if (data == &bm->ldata) { BMIter liter; BMFace *efa; BMLoop *l; + CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP); BM_ITER(efa, &iter, bm, BM_FACES_OF_MESH, NULL) { - if (data == &bm->pdata) { + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) { block = NULL; CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block); - CustomData_bmesh_free_block(olddata, &efa->head.data); - efa->head.data = block; + CustomData_bmesh_copy_data(olddata, data, l->head.data, &block); + CustomData_bmesh_free_block(olddata, &l->head.data); + l->head.data = block; } + } + } + else if (data == &bm->pdata) { + BMFace *efa; - if (data == &bm->ldata) { - BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) { - block = NULL; - CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, l->head.data, &block); - CustomData_bmesh_free_block(olddata, &l->head.data); - l->head.data = block; - } - } + CustomData_bmesh_init_pool(data, bm->totface, BM_FACE); + + BM_ITER(efa, &iter, bm, BM_FACES_OF_MESH, NULL) { + block = NULL; + CustomData_bmesh_set_default(data, &block); + CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block); + CustomData_bmesh_free_block(olddata, &efa->head.data); + efa->head.data = block; } } + else { + /* should never reach this! */ + BLI_assert(0); + } if (oldpool) { /* this should never happen but can when dissolve fails - [#28960] */ diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 8778dad421f..3caeb2a8fbc 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -44,7 +44,7 @@ #include "bmesh_private.h" /* used as an extern, defined in bmesh.h */ -BMAllocTemplate bm_mesh_allocsize_default = {512, 512, 2048, 512}; +BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512}; static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) { diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c index 9cab8cd5f91..ddec92e5754 100644 --- a/source/blender/bmesh/operators/bmo_mesh_conv.c +++ b/source/blender/bmesh/operators/bmo_mesh_conv.c @@ -137,10 +137,10 @@ void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) printf("shapekey <-> mesh mismatch!\n"); } - CustomData_bmesh_init_pool(&bm->vdata, bm_mesh_allocsize_default.totvert); - CustomData_bmesh_init_pool(&bm->edata, bm_mesh_allocsize_default.totedge); - CustomData_bmesh_init_pool(&bm->ldata, bm_mesh_allocsize_default.totloop); - CustomData_bmesh_init_pool(&bm->pdata, bm_mesh_allocsize_default.totface); + CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT); + CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE); + CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); + CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL); diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 8cf798e4a4a..4b053b21a8b 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -3201,28 +3201,28 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO Object *obedit = editbase->object; Mesh *me = obedit->data; BMEditMesh *em = me->edit_btmesh; - BMesh *bmnew; + BMesh *bm_new; if (!em) return OPERATOR_CANCELLED; - bmnew = BM_mesh_create(obedit, &bm_mesh_allocsize_default); - CustomData_copy(&em->bm->vdata, &bmnew->vdata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&em->bm->edata, &bmnew->edata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&em->bm->ldata, &bmnew->ldata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&em->bm->pdata, &bmnew->pdata, CD_MASK_BMESH, CD_CALLOC, 0); - - CustomData_bmesh_init_pool(&bmnew->vdata, bm_mesh_allocsize_default.totvert); - CustomData_bmesh_init_pool(&bmnew->edata, bm_mesh_allocsize_default.totedge); - CustomData_bmesh_init_pool(&bmnew->ldata, bm_mesh_allocsize_default.totloop); - CustomData_bmesh_init_pool(&bmnew->pdata, bm_mesh_allocsize_default.totface); + bm_new = BM_mesh_create(obedit, &bm_mesh_allocsize_default); + CustomData_copy(&em->bm->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&em->bm->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&em->bm->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&em->bm->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT); + CustomData_bmesh_init_pool(&bm_new->edata, bm_mesh_allocsize_default.totedge, BM_EDGE); + CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP); + CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE); basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH); /* 0 = fully linked */ assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */ ED_base_object_select(basenew, BA_DESELECT); - EDBM_CallOpf(em, wmop, "dupe geom=%hvef dest=%p", BM_ELEM_SELECT, bmnew); + EDBM_CallOpf(em, wmop, "dupe geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new); EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES); /* clean up any loose edges */ @@ -3248,11 +3248,11 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS); - BM_mesh_normals_update(bmnew, TRUE); - BMO_op_callf(bmnew, "bmesh_to_mesh mesh=%p object=%p notesselation=%b", + BM_mesh_normals_update(bm_new, TRUE); + BMO_op_callf(bm_new, "bmesh_to_mesh mesh=%p object=%p notesselation=%b", basenew->object->data, basenew->object, TRUE); - BM_mesh_free(bmnew); + BM_mesh_free(bm_new); ((Mesh *)basenew->object->data)->edit_btmesh = NULL; return 1; -- cgit v1.2.3