diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 16:59:56 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 16:59:56 +0400 |
commit | f554c264da7d0f53a2519079a2e670ecb4e8629d (patch) | |
tree | 8158335342913fc59dd1be69e35a3d65a0491bbe | |
parent | c6702a3b917894bf150e19526e1eedd8d5f2e91b (diff) |
speedup for freeing bmeshes, skip calling free on every
vert/edge/face/loop if there are no free functions for the customdata
layers.
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 17 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.c | 36 |
3 files changed, 44 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index ffab95ea3f5..266dc3e66f7 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -88,6 +88,7 @@ bool CustomData_layer_has_interp(struct CustomData *data, int layer_n); */ bool CustomData_has_math(struct CustomData *data); bool CustomData_has_interp(struct CustomData *data); +bool CustomData_bmesh_has_free(struct CustomData *data); /* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to * another, while not overwriting anything else (e.g. flags). probably only diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index b0ecec21049..11c8ca5d3c4 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2552,6 +2552,23 @@ bool CustomData_has_math(struct CustomData *data) return false; } +/* a non bmesh version would have to check layer->data */ +bool CustomData_bmesh_has_free(struct CustomData *data) +{ + const LayerTypeInfo *typeInfo; + int i; + + for (i = 0; i < data->totlayer; ++i) { + if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { + typeInfo = layerType_getInfo(data->layers[i].type); + if (typeInfo->free) { + return true; + } + } + } + return false; +} + bool CustomData_has_interp(struct CustomData *data) { int i; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index c98c4f372f1..f3da337f653 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -164,21 +164,37 @@ void BM_mesh_data_free(BMesh *bm) BMEdge *e; BMLoop *l; BMFace *f; - BMIter iter; BMIter itersub; - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - CustomData_bmesh_free_block(&(bm->vdata), &(v->head.data)); + + bool is_ldata_free; + bool is_pdata_free; + + + /* Check if we have to call free, if not we can avoid a lot of looping */ + if (CustomData_bmesh_has_free(&(bm->vdata))) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + CustomData_bmesh_free_block(&(bm->vdata), &(v->head.data)); + } } - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - CustomData_bmesh_free_block(&(bm->edata), &(e->head.data)); + if (CustomData_bmesh_has_free(&(bm->edata))) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + CustomData_bmesh_free_block(&(bm->edata), &(e->head.data)); + } } - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - CustomData_bmesh_free_block(&(bm->pdata), &(f->head.data)); - BM_ITER_ELEM (l, &itersub, f, BM_LOOPS_OF_FACE) { - CustomData_bmesh_free_block(&(bm->ldata), &(l->head.data)); + + if ((is_ldata_free = CustomData_bmesh_has_free(&(bm->ldata))) || + (is_pdata_free = CustomData_bmesh_has_free(&(bm->pdata)))) + { + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (is_pdata_free) + CustomData_bmesh_free_block(&(bm->pdata), &(f->head.data)); + if (is_ldata_free) { + BM_ITER_ELEM (l, &itersub, f, BM_LOOPS_OF_FACE) { + CustomData_bmesh_free_block(&(bm->ldata), &(l->head.data)); + } + } } } |