bmesh - changes to mempool allocations
authorCampbell Barton <ideasman42@gmail.com>
Thu, 1 Mar 2012 22:17:04 +0000 (22:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 1 Mar 2012 22:17:04 +0000 (22:17 +0000)
* 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
source/blender/blenkernel/intern/customdata.c
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_construct.h
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/operators/bmo_mesh_conv.c
source/blender/editors/mesh/bmesh_tools.c

index 99676e444f3473e6602ae9c66b804e613e645c2c..b414f36b8c8b552783d965facd198002b36eccb2 100644 (file)
@@ -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 */
 
index 09525e23c6b01b3c5e56a458eda47f49cc9b0f9a..a3c4b943215fa42c60bbaec0fb41b76272a7405d 100644 (file)
@@ -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:
index a0fd3ec9250c372b934e7356292860d9ae603794..b498fa73a73c75dca29cae8c84500287405ab062 100644 (file)
@@ -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 */
index 8d624592ae79d7eeec3ee2f924330fecaa3d424d..5c4101c9cdef61d659da487e16949a5b8ca6b258 100644 (file)
@@ -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);
index 669426b73a6d496471738118722c1fa624332880..d2af98a5e9f3be322761e48315bc92f3132f9edf 100644 (file)
@@ -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] */
index 8778dad421fe476834a244602165ed04fe0a5816..3caeb2a8fbc80785f6fbb749822bf3904c4d743a 100644 (file)
@@ -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)
 {
index 9cab8cd5f91181305e30e34d71de5eec085d295d..ddec92e5754ebd57239d13aa9cc1a984cb3fa565 100644 (file)
@@ -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);
index 8cf798e4a4ac77665e906259b69e8b9f92485a09..4b053b21a8bb6f4b4479e22419b8df2ece81acef 100644 (file)
@@ -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;