diff options
-rw-r--r-- | source/blender/bmesh/intern/bmesh_iterators.c | 36 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_iterators.h | 4 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_mirror.c | 25 |
3 files changed, 47 insertions, 18 deletions
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 89348f23b9d..cd66617bbf9 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -186,6 +186,42 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, } } +void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, + int *r_len, + /* optional args to avoid an alloc (normally stack array) */ + void **stack_array, int stack_array_size) +{ + BMOIter iter; + BMElem *ele; + int count = BMO_slot_buffer_count(slot_args, slot_name); + + BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array)); + + if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && count > 0) { + BMElem **array = count > stack_array_size ? + MEM_mallocN(sizeof(ele) * count, __func__) : + stack_array; + int i = 0; + + do { + array[i++] = ele; + } while ((ele = BMO_iter_step(&iter))); + BLI_assert(i <= count); + + if (i != count) { + if ((void **)array != stack_array) { + array = MEM_reallocN(array, sizeof(ele) * i); + } + } + *r_len = i; + return array; + } + else { + *r_len = 0; + return NULL; + } +} + /** * \brief Elem Iter Flag Count * diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index c90fba7898a..b32b191e5c4 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -133,6 +133,10 @@ __attribute__((warn_unused_result)) ; int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, void **array, const int len); +void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, + int *r_len, + /* optional args to avoid an alloc (normally stack array) */ + void **stack_array, int stack_array_size); int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value); int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value); diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 6aff41b47d1..cd35ea67914 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -31,7 +31,6 @@ #include "DNA_meshdata_types.h" #include "BLI_math.h" -#include "BLI_array.h" #include "BKE_customdata.h" @@ -45,22 +44,19 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMOperator dupeop, weldop; BMOIter siter; BMIter iter; - BMVert *v /* , *v2 */ /* UNUSED */, **vmap = NULL; - BLI_array_declare(vmap); - BMEdge /* *e, */ **emap = NULL; - BLI_array_declare(emap); + BMVert *v, **vmap; + int vmap_size = 0; float mtx[4][4]; float imtx[4][4]; float scale[3] = {1.0f, 1.0f, 1.0f}; float dist = BMO_slot_float_get(op->slots_in, "merge_dist"); - int i, ototvert /*, ototedge */; + int i, ototvert; int axis = BMO_slot_int_get(op->slots_in, "axis"); bool mirror_u = BMO_slot_bool_get(op->slots_in, "mirror_u"); bool mirror_v = BMO_slot_bool_get(op->slots_in, "mirror_v"); BMOpSlot *slot_targetmap; ototvert = bm->totvert; - /* ototedge = bm->totedge; */ /* UNUSED */ BMO_slot_mat4_get(op->slots_in, "matrix", mtx); invert_m4_m4(imtx, mtx); @@ -71,15 +67,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); /* create old -> new mappin */ - i = 0; - /* v2 = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); */ /* UNUSED */ - BMO_ITER (v, &siter, dupeop.slots_out, "geom.out", BM_VERT) { - BLI_array_grow_one(vmap); - vmap[i] = v; - /* v2 = BM_iter_step(&iter); */ /* UNUSED */ - i++; - } - bm->elem_index_dirty |= BM_VERT; + vmap = BMO_iter_as_arrayN(dupeop.slots_out, "geom.out", BM_VERT, &vmap_size, NULL, 0); /* feed old data to transform bmo */ scale[axis] = -1.0f; @@ -94,6 +82,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); for (i = 0; i < ototvert; i++) { if (fabsf(v->co[axis]) <= dist) { + BLI_assert(vmap_size >= i); BMO_slot_map_elem_insert(&weldop, slot_targetmap, vmap[i], v); } v = BM_iter_step(&iter); @@ -127,6 +116,6 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW); - BLI_array_free(vmap); - BLI_array_free(emap); + if (vmap) + MEM_freeN(vmap); } |