From 76f7b229890dd5d23b6683d12f743347ac0a2eef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jul 2021 13:52:53 +1000 Subject: Cleanup: minor improvements to BMesh dissolve faces - Only create arrays with groups of two or more faces. - Remove raising exception for zero length arrays. - Remove redundant exception check (assert there is no exception). - Use a struct for face array & it's length instead of a NULL terminated array (removes the need to count faces in a loop). --- source/blender/bmesh/operators/bmo_dissolve.c | 74 ++++++++++++++------------- 1 file changed, 39 insertions(+), 35 deletions(-) (limited to 'source') diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 30c80d43b9c..62eaa690077 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -128,7 +128,11 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) { BMOIter oiter; BMFace *f; - BMFace ***regions = NULL; + /* List of face arrays, the first element in each array in the length. */ + struct { + BMFace **faces; + int faces_len; + } *regions = NULL, *region; BMFace **faces = NULL; BLI_array_declare(regions); BLI_array_declare(faces); @@ -158,9 +162,6 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) continue; } - BLI_array_clear(faces); - faces = NULL; /* Forces different allocation. */ - BMW_init(®walker, bm, BMW_ISLAND_MANIFOLD, @@ -171,46 +172,53 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) BMW_FLAG_NOP, BMW_NIL_LAY); - for (f_iter = BMW_begin(®walker, f); f_iter; f_iter = BMW_step(®walker)) { - BLI_array_append(faces, f_iter); - } - BMW_end(®walker); + /* Check there are at least two faces before creating the array. */ + BMFace *faces_init[2]; + if ((faces_init[0] = BMW_begin(®walker, f)) && (faces_init[1] = BMW_step(®walker))) { + + BLI_assert(BLI_array_len(faces) == 0); + + BLI_array_append(faces, faces_init[0]); + BLI_array_append(faces, faces_init[1]); + + while ((f_iter = BMW_step(®walker))) { + BLI_array_append(faces, f_iter); + } + + for (i = 0; i < BLI_array_len(faces); i++) { + f_iter = faces[i]; + BMO_face_flag_disable(bm, f_iter, FACE_TAG); + BMO_face_flag_enable(bm, f_iter, FACE_ORIG); + } - for (i = 0; i < BLI_array_len(faces); i++) { - f_iter = faces[i]; - BMO_face_flag_disable(bm, f_iter, FACE_TAG); - BMO_face_flag_enable(bm, f_iter, FACE_ORIG); + region = BLI_array_append_ret(regions); + region->faces = faces; + region->faces_len = BLI_array_len(faces); + + BLI_array_clear(faces); + /* Forces a new allocation. */ + faces = NULL; } - BLI_array_append(faces, NULL); - BLI_array_append(regions, faces); + BMW_end(®walker); } /* track how many faces we should end up with */ int totface_target = bm->totface; for (i = 0; i < BLI_array_len(regions); i++) { - BMFace *f_new; - int tot = 0; + region = ®ions[i]; - faces = regions[i]; - if (!faces[0]) { - BMO_error_raise(bm, op, "Could not find boundary of dissolve region"); - goto cleanup; - } + const int faces_len = region->faces_len; + faces = region->faces; - while (faces[tot]) { - tot++; - } - - f_new = BM_faces_join(bm, faces, tot, true); - - if (f_new) { + BMFace *f_new = BM_faces_join(bm, faces, faces_len, true); + if (f_new != NULL) { /* maintain active face */ if (act_face && bm->act_face == NULL) { bm->act_face = f_new; } - totface_target -= tot - 1; + totface_target -= faces_len - 1; } else { BMO_error_raise(bm, op, "Could not create merged face"); @@ -241,18 +249,14 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) } } - if (BMO_error_occurred(bm)) { - goto cleanup; - } + BLI_assert(!BMO_error_occurred(bm)); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "region.out", BM_FACE, FACE_NEW); cleanup: /* free/cleanup */ for (i = 0; i < BLI_array_len(regions); i++) { - if (regions[i]) { - MEM_freeN(regions[i]); - } + MEM_freeN(regions[i].faces); } BLI_array_free(regions); -- cgit v1.2.3