Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/bmesh/operators/bmo_removedoubles.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/bmesh/operators/bmo_removedoubles.c')
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c1190
1 files changed, 597 insertions, 593 deletions
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index e59bad0d682..144d944e939 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -36,149 +36,150 @@
static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot *slot_targetmap)
{
- BMIter liter;
- BMLoop *l, *l_tar, *l_double;
- bool split = false;
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMVert *v_tar = BMO_slot_map_elem_get(slot_targetmap, l->v);
- /* ok: if v_tar is NULL (e.g. not in the map) then it's
- * a target vert, otherwise it's a double */
- if (v_tar) {
- l_tar = BM_face_vert_share_loop(f, v_tar);
-
- if (l_tar && (l_tar != l) && !BM_loop_is_adjacent(l_tar, l)) {
- l_double = l;
- split = true;
- break;
- }
- }
- }
-
- if (split) {
- BMLoop *l_new;
- BMFace *f_new;
-
- f_new = BM_face_split(bm, f, l_double, l_tar, &l_new, NULL, false);
-
- remdoubles_splitface(f, bm, op, slot_targetmap);
- remdoubles_splitface(f_new, bm, op, slot_targetmap);
- }
+ BMIter liter;
+ BMLoop *l, *l_tar, *l_double;
+ bool split = false;
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BMVert *v_tar = BMO_slot_map_elem_get(slot_targetmap, l->v);
+ /* ok: if v_tar is NULL (e.g. not in the map) then it's
+ * a target vert, otherwise it's a double */
+ if (v_tar) {
+ l_tar = BM_face_vert_share_loop(f, v_tar);
+
+ if (l_tar && (l_tar != l) && !BM_loop_is_adjacent(l_tar, l)) {
+ l_double = l;
+ split = true;
+ break;
+ }
+ }
+ }
+
+ if (split) {
+ BMLoop *l_new;
+ BMFace *f_new;
+
+ f_new = BM_face_split(bm, f, l_double, l_tar, &l_new, NULL, false);
+
+ remdoubles_splitface(f, bm, op, slot_targetmap);
+ remdoubles_splitface(f_new, bm, op, slot_targetmap);
+ }
}
-#define ELE_DEL 1
-#define EDGE_COL 2
-#define VERT_IN_FACE 4
+#define ELE_DEL 1
+#define EDGE_COL 2
+#define VERT_IN_FACE 4
/**
* helper function for bmo_weld_verts_exec so we can use stack memory
*/
-static BMFace *remdoubles_createface(BMesh *bm, BMFace *f, BMOpSlot *slot_targetmap, bool *r_created)
+static BMFace *remdoubles_createface(BMesh *bm,
+ BMFace *f,
+ BMOpSlot *slot_targetmap,
+ bool *r_created)
{
- BMEdge *e_new;
+ BMEdge *e_new;
- BMEdge **edges = BLI_array_alloca(edges, f->len); /* new ordered edges */
- BMVert **verts = BLI_array_alloca(verts, f->len); /* new ordered verts */
- BMLoop **loops = BLI_array_alloca(loops, f->len); /* original ordered loops to copy attrs into the new face */
+ BMEdge **edges = BLI_array_alloca(edges, f->len); /* new ordered edges */
+ BMVert **verts = BLI_array_alloca(verts, f->len); /* new ordered verts */
+ BMLoop **loops = BLI_array_alloca(
+ loops, f->len); /* original ordered loops to copy attrs into the new face */
- STACK_DECLARE(edges);
- STACK_DECLARE(loops);
- STACK_DECLARE(verts);
+ STACK_DECLARE(edges);
+ STACK_DECLARE(loops);
+ STACK_DECLARE(verts);
- STACK_INIT(edges, f->len);
- STACK_INIT(loops, f->len);
- STACK_INIT(verts, f->len);
+ STACK_INIT(edges, f->len);
+ STACK_INIT(loops, f->len);
+ STACK_INIT(verts, f->len);
- *r_created = false;
+ *r_created = false;
- {
+ {
#define LOOP_MAP_VERT_INIT(l_init, v_map, is_del) \
- v_map = l_init->v; \
- is_del = BMO_vert_flag_test_bool(bm, v_map, ELE_DEL); \
- if (is_del) { \
- v_map = BMO_slot_map_elem_get(slot_targetmap, v_map); \
- } ((void)0)
-
-
- BMLoop *l_first, *l_curr, *l_next;
- BMVert *v_curr;
- bool is_del_v_curr;
-
- l_curr = l_first = BM_FACE_FIRST_LOOP(f);
- LOOP_MAP_VERT_INIT(l_curr, v_curr, is_del_v_curr);
-
- do {
- BMVert *v_next;
- bool is_del_v_next;
-
- l_next = l_curr->next;
- LOOP_MAP_VERT_INIT(l_next, v_next, is_del_v_next);
-
- /* only search for a new edge if one of the verts is mapped */
- if ((is_del_v_curr || is_del_v_next) == 0) {
- e_new = l_curr->e;
- }
- else if (v_curr == v_next) {
- e_new = NULL; /* skip */
- }
- else {
- e_new = BM_edge_exists(v_curr, v_next);
- BLI_assert(e_new); /* never fails */
- }
-
- if (e_new) {
- if (UNLIKELY(BMO_vert_flag_test(bm, v_curr, VERT_IN_FACE))) {
- /* we can't make the face, bail out */
- STACK_CLEAR(edges);
- goto finally;
- }
- BMO_vert_flag_enable(bm, v_curr, VERT_IN_FACE);
-
- STACK_PUSH(edges, e_new);
- STACK_PUSH(loops, l_curr);
- STACK_PUSH(verts, v_curr);
- }
-
- v_curr = v_next;
- is_del_v_curr = is_del_v_next;
- } while ((l_curr = l_next) != l_first);
+ v_map = l_init->v; \
+ is_del = BMO_vert_flag_test_bool(bm, v_map, ELE_DEL); \
+ if (is_del) { \
+ v_map = BMO_slot_map_elem_get(slot_targetmap, v_map); \
+ } \
+ ((void)0)
+
+ BMLoop *l_first, *l_curr, *l_next;
+ BMVert *v_curr;
+ bool is_del_v_curr;
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f);
+ LOOP_MAP_VERT_INIT(l_curr, v_curr, is_del_v_curr);
+
+ do {
+ BMVert *v_next;
+ bool is_del_v_next;
+
+ l_next = l_curr->next;
+ LOOP_MAP_VERT_INIT(l_next, v_next, is_del_v_next);
+
+ /* only search for a new edge if one of the verts is mapped */
+ if ((is_del_v_curr || is_del_v_next) == 0) {
+ e_new = l_curr->e;
+ }
+ else if (v_curr == v_next) {
+ e_new = NULL; /* skip */
+ }
+ else {
+ e_new = BM_edge_exists(v_curr, v_next);
+ BLI_assert(e_new); /* never fails */
+ }
+
+ if (e_new) {
+ if (UNLIKELY(BMO_vert_flag_test(bm, v_curr, VERT_IN_FACE))) {
+ /* we can't make the face, bail out */
+ STACK_CLEAR(edges);
+ goto finally;
+ }
+ BMO_vert_flag_enable(bm, v_curr, VERT_IN_FACE);
+
+ STACK_PUSH(edges, e_new);
+ STACK_PUSH(loops, l_curr);
+ STACK_PUSH(verts, v_curr);
+ }
+
+ v_curr = v_next;
+ is_del_v_curr = is_del_v_next;
+ } while ((l_curr = l_next) != l_first);
#undef LOOP_MAP_VERT_INIT
+ }
- }
-
-finally:
- {
- uint i;
- for (i = 0; i < STACK_SIZE(verts); i++) {
- BMO_vert_flag_disable(bm, verts[i], VERT_IN_FACE);
- }
- }
-
- if (STACK_SIZE(edges) >= 3) {
- BMFace *f_new = BM_face_exists(verts, STACK_SIZE(verts));
- if (f_new) {
- return f_new;
- }
- f_new = BM_face_create(bm, verts, edges, STACK_SIZE(edges), f, BM_CREATE_NOP);
- BLI_assert(f_new != f);
-
- if (f_new) {
- uint i = 0;
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- do {
- BM_elem_attrs_copy(bm, bm, loops[i], l_iter);
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
-
- *r_created = true;
- return f_new;
- }
- }
-
- return NULL;
+finally : {
+ uint i;
+ for (i = 0; i < STACK_SIZE(verts); i++) {
+ BMO_vert_flag_disable(bm, verts[i], VERT_IN_FACE);
+ }
}
+ if (STACK_SIZE(edges) >= 3) {
+ BMFace *f_new = BM_face_exists(verts, STACK_SIZE(verts));
+ if (f_new) {
+ return f_new;
+ }
+ f_new = BM_face_create(bm, verts, edges, STACK_SIZE(edges), f, BM_CREATE_NOP);
+ BLI_assert(f_new != f);
+
+ if (f_new) {
+ uint i = 0;
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ BM_elem_attrs_copy(bm, bm, loops[i], l_iter);
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
+
+ *r_created = true;
+ return f_new;
+ }
+ }
+
+ return NULL;
+}
/**
* \note with 'targetmap', multiple 'keys' are currently supported, though no callers should be using.
@@ -186,547 +187,550 @@ finally:
*/
void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
{
- BMIter iter, liter;
- BMVert *v;
- BMEdge *e;
- BMLoop *l;
- BMFace *f;
- BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap");
-
- /* Maintain selection history. */
- const bool has_selected = !BLI_listbase_is_empty(&bm->selected);
- const bool use_targetmap_all = has_selected;
- GHash *targetmap_all = NULL;
- if (use_targetmap_all) {
- /* Map deleted to keep elem. */
- targetmap_all = BLI_ghash_ptr_new(__func__);
- }
-
- /* mark merge verts for deletion */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMVert *v_dst = BMO_slot_map_elem_get(slot_targetmap, v);
- if (v_dst != NULL) {
- BMO_vert_flag_enable(bm, v, ELE_DEL);
-
- /* merge the vertex flags, else we get randomly selected/unselected verts */
- BM_elem_flag_merge_ex(v, v_dst, BM_ELEM_HIDDEN);
-
- if (use_targetmap_all) {
- BLI_assert(v != v_dst);
- BLI_ghash_insert(targetmap_all, v, v_dst);
- }
- }
- }
-
- /* check if any faces are getting their own corners merged
- * together, split face if so */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- remdoubles_splitface(f, bm, op, slot_targetmap);
- }
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMVert *v1, *v2;
- const bool is_del_v1 = BMO_vert_flag_test_bool(bm, (v1 = e->v1), ELE_DEL);
- const bool is_del_v2 = BMO_vert_flag_test_bool(bm, (v2 = e->v2), ELE_DEL);
-
- if (is_del_v1 || is_del_v2) {
- if (is_del_v1) {
- v1 = BMO_slot_map_elem_get(slot_targetmap, v1);
- }
- if (is_del_v2) {
- v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
- }
-
- if (v1 == v2) {
- BMO_edge_flag_enable(bm, e, EDGE_COL);
- }
- else {
- /* always merge flags, even for edges we already created */
- BMEdge *e_new = BM_edge_exists(v1, v2);
- if (e_new == NULL) {
- e_new = BM_edge_create(bm, v1, v2, e, BM_CREATE_NOP);
- }
- BM_elem_flag_merge_ex(e_new, e, BM_ELEM_HIDDEN);
- if (use_targetmap_all) {
- BLI_assert(e != e_new);
- BLI_ghash_insert(targetmap_all, e, e_new);
- }
- }
-
- BMO_edge_flag_enable(bm, e, ELE_DEL);
- }
- }
-
- /* faces get "modified" by creating new faces here, then at the
- * end the old faces are deleted */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- bool vert_delete = false;
- int edge_collapse = 0;
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (BMO_vert_flag_test(bm, l->v, ELE_DEL)) {
- vert_delete = true;
- }
- if (BMO_edge_flag_test(bm, l->e, EDGE_COL)) {
- edge_collapse++;
- }
- }
-
- if (vert_delete) {
- bool use_in_place = false;
- BMFace *f_new = NULL;
- BMO_face_flag_enable(bm, f, ELE_DEL);
-
- if (f->len - edge_collapse >= 3) {
- bool created;
- f_new = remdoubles_createface(bm, f, slot_targetmap, &created);
- /* do this so we don't need to return a list of created faces */
- if (f_new) {
- if (created) {
- bmesh_face_swap_data(f_new, f);
-
- if (bm->use_toolflags) {
- SWAP(BMFlagLayer *, ((BMFace_OFlag *)f)->oflags, ((BMFace_OFlag *)f_new)->oflags);
- }
-
- BMO_face_flag_disable(bm, f, ELE_DEL);
- BM_face_kill(bm, f_new);
- use_in_place = true;
- }
- else {
- BM_elem_flag_merge_ex(f_new, f, BM_ELEM_HIDDEN);
- }
- }
- }
-
- if ((use_in_place == false) && (f_new != NULL)) {
- BLI_assert(f != f_new);
- if (use_targetmap_all) {
- BLI_ghash_insert(targetmap_all, f, f_new);
- }
- if (bm->act_face && (f == bm->act_face)) {
- bm->act_face = f_new;
- }
- }
- }
- }
-
- if (has_selected) {
- BM_select_history_merge_from_targetmap(bm, targetmap_all, targetmap_all, targetmap_all, true);
- }
-
- if (use_targetmap_all) {
- BLI_ghash_free(targetmap_all, NULL, NULL);
- }
-
- BMO_mesh_delete_oflag_context(bm, ELE_DEL, DEL_ONLYTAGGED);
+ BMIter iter, liter;
+ BMVert *v;
+ BMEdge *e;
+ BMLoop *l;
+ BMFace *f;
+ BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap");
+
+ /* Maintain selection history. */
+ const bool has_selected = !BLI_listbase_is_empty(&bm->selected);
+ const bool use_targetmap_all = has_selected;
+ GHash *targetmap_all = NULL;
+ if (use_targetmap_all) {
+ /* Map deleted to keep elem. */
+ targetmap_all = BLI_ghash_ptr_new(__func__);
+ }
+
+ /* mark merge verts for deletion */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BMVert *v_dst = BMO_slot_map_elem_get(slot_targetmap, v);
+ if (v_dst != NULL) {
+ BMO_vert_flag_enable(bm, v, ELE_DEL);
+
+ /* merge the vertex flags, else we get randomly selected/unselected verts */
+ BM_elem_flag_merge_ex(v, v_dst, BM_ELEM_HIDDEN);
+
+ if (use_targetmap_all) {
+ BLI_assert(v != v_dst);
+ BLI_ghash_insert(targetmap_all, v, v_dst);
+ }
+ }
+ }
+
+ /* check if any faces are getting their own corners merged
+ * together, split face if so */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ remdoubles_splitface(f, bm, op, slot_targetmap);
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BMVert *v1, *v2;
+ const bool is_del_v1 = BMO_vert_flag_test_bool(bm, (v1 = e->v1), ELE_DEL);
+ const bool is_del_v2 = BMO_vert_flag_test_bool(bm, (v2 = e->v2), ELE_DEL);
+
+ if (is_del_v1 || is_del_v2) {
+ if (is_del_v1) {
+ v1 = BMO_slot_map_elem_get(slot_targetmap, v1);
+ }
+ if (is_del_v2) {
+ v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
+ }
+
+ if (v1 == v2) {
+ BMO_edge_flag_enable(bm, e, EDGE_COL);
+ }
+ else {
+ /* always merge flags, even for edges we already created */
+ BMEdge *e_new = BM_edge_exists(v1, v2);
+ if (e_new == NULL) {
+ e_new = BM_edge_create(bm, v1, v2, e, BM_CREATE_NOP);
+ }
+ BM_elem_flag_merge_ex(e_new, e, BM_ELEM_HIDDEN);
+ if (use_targetmap_all) {
+ BLI_assert(e != e_new);
+ BLI_ghash_insert(targetmap_all, e, e_new);
+ }
+ }
+
+ BMO_edge_flag_enable(bm, e, ELE_DEL);
+ }
+ }
+
+ /* faces get "modified" by creating new faces here, then at the
+ * end the old faces are deleted */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ bool vert_delete = false;
+ int edge_collapse = 0;
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BMO_vert_flag_test(bm, l->v, ELE_DEL)) {
+ vert_delete = true;
+ }
+ if (BMO_edge_flag_test(bm, l->e, EDGE_COL)) {
+ edge_collapse++;
+ }
+ }
+
+ if (vert_delete) {
+ bool use_in_place = false;
+ BMFace *f_new = NULL;
+ BMO_face_flag_enable(bm, f, ELE_DEL);
+
+ if (f->len - edge_collapse >= 3) {
+ bool created;
+ f_new = remdoubles_createface(bm, f, slot_targetmap, &created);
+ /* do this so we don't need to return a list of created faces */
+ if (f_new) {
+ if (created) {
+ bmesh_face_swap_data(f_new, f);
+
+ if (bm->use_toolflags) {
+ SWAP(BMFlagLayer *, ((BMFace_OFlag *)f)->oflags, ((BMFace_OFlag *)f_new)->oflags);
+ }
+
+ BMO_face_flag_disable(bm, f, ELE_DEL);
+ BM_face_kill(bm, f_new);
+ use_in_place = true;
+ }
+ else {
+ BM_elem_flag_merge_ex(f_new, f, BM_ELEM_HIDDEN);
+ }
+ }
+ }
+
+ if ((use_in_place == false) && (f_new != NULL)) {
+ BLI_assert(f != f_new);
+ if (use_targetmap_all) {
+ BLI_ghash_insert(targetmap_all, f, f_new);
+ }
+ if (bm->act_face && (f == bm->act_face)) {
+ bm->act_face = f_new;
+ }
+ }
+ }
+ }
+
+ if (has_selected) {
+ BM_select_history_merge_from_targetmap(bm, targetmap_all, targetmap_all, targetmap_all, true);
+ }
+
+ if (use_targetmap_all) {
+ BLI_ghash_free(targetmap_all, NULL, NULL);
+ }
+
+ BMO_mesh_delete_oflag_context(bm, ELE_DEL, DEL_ONLYTAGGED);
}
-#define VERT_KEEP 8
-#define VERT_IN 32
+#define VERT_KEEP 8
+#define VERT_IN 32
-#define EDGE_MARK 1
+#define EDGE_MARK 1
void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMIter iter;
- BMVert *v, *vert_snap;
- BMLoop *l, *l_first = NULL;
- float fac;
- int i, tot;
-
- vert_snap = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_snap"));
- tot = BM_vert_face_count(vert_snap);
-
- if (!tot) {
- return;
- }
-
- fac = 1.0f / tot;
- BM_ITER_ELEM (l, &iter, vert_snap, BM_LOOPS_OF_VERT) {
- if (l_first == NULL) {
- l_first = l;
- }
-
- for (i = 0; i < bm->ldata.totlayer; i++) {
- if (CustomData_layer_has_math(&bm->ldata, i)) {
- const int type = bm->ldata.layers[i].type;
- const int offset = bm->ldata.layers[i].offset;
- void *e1, *e2;
-
- e1 = BM_ELEM_CD_GET_VOID_P(l_first, offset);
- e2 = BM_ELEM_CD_GET_VOID_P(l, offset);
-
- CustomData_data_multiply(type, e2, fac);
-
- if (l != l_first) {
- CustomData_data_add(type, e1, e2);
- }
- }
- }
- }
-
- BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- if (l == l_first) {
- continue;
- }
-
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_first->head.data, &l->head.data);
- }
- }
+ BMOIter siter;
+ BMIter iter;
+ BMVert *v, *vert_snap;
+ BMLoop *l, *l_first = NULL;
+ float fac;
+ int i, tot;
+
+ vert_snap = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_snap"));
+ tot = BM_vert_face_count(vert_snap);
+
+ if (!tot) {
+ return;
+ }
+
+ fac = 1.0f / tot;
+ BM_ITER_ELEM (l, &iter, vert_snap, BM_LOOPS_OF_VERT) {
+ if (l_first == NULL) {
+ l_first = l;
+ }
+
+ for (i = 0; i < bm->ldata.totlayer; i++) {
+ if (CustomData_layer_has_math(&bm->ldata, i)) {
+ const int type = bm->ldata.layers[i].type;
+ const int offset = bm->ldata.layers[i].offset;
+ void *e1, *e2;
+
+ e1 = BM_ELEM_CD_GET_VOID_P(l_first, offset);
+ e2 = BM_ELEM_CD_GET_VOID_P(l, offset);
+
+ CustomData_data_multiply(type, e2, fac);
+
+ if (l != l_first) {
+ CustomData_data_add(type, e1, e2);
+ }
+ }
+ }
+ }
+
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ if (l == l_first) {
+ continue;
+ }
+
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_first->head.data, &l->head.data);
+ }
+ }
}
void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMIter iter;
- BMVert *v;
- BMLoop *l /* , *firstl = NULL */;
- CDBlockBytes min, max;
- int i;
-
- for (i = 0; i < bm->ldata.totlayer; i++) {
- const int type = bm->ldata.layers[i].type;
- const int offset = bm->ldata.layers[i].offset;
-
- if (!CustomData_layer_has_math(&bm->ldata, i)) {
- continue;
- }
-
- CustomData_data_initminmax(type, &min, &max);
-
- BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- void *block = BM_ELEM_CD_GET_VOID_P(l, offset);
- CustomData_data_dominmax(type, block, &min, &max);
- }
- }
-
- CustomData_data_multiply(type, &min, 0.5f);
- CustomData_data_multiply(type, &max, 0.5f);
- CustomData_data_add(type, &min, &max);
-
- BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- void *block = BM_ELEM_CD_GET_VOID_P(l, offset);
- CustomData_data_copy_value(type, &min, block);
- }
- }
- }
+ BMOIter siter;
+ BMIter iter;
+ BMVert *v;
+ BMLoop *l /* , *firstl = NULL */;
+ CDBlockBytes min, max;
+ int i;
+
+ for (i = 0; i < bm->ldata.totlayer; i++) {
+ const int type = bm->ldata.layers[i].type;
+ const int offset = bm->ldata.layers[i].offset;
+
+ if (!CustomData_layer_has_math(&bm->ldata, i)) {
+ continue;
+ }
+
+ CustomData_data_initminmax(type, &min, &max);
+
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ void *block = BM_ELEM_CD_GET_VOID_P(l, offset);
+ CustomData_data_dominmax(type, block, &min, &max);
+ }
+ }
+
+ CustomData_data_multiply(type, &min, 0.5f);
+ CustomData_data_multiply(type, &max, 0.5f);
+ CustomData_data_add(type, &min, &max);
+
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ void *block = BM_ELEM_CD_GET_VOID_P(l, offset);
+ CustomData_data_copy_value(type, &min, block);
+ }
+ }
+ }
}
void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
{
- BMOperator weldop;
- BMOIter siter;
- BMVert *v, *vert_snap = NULL;
- float vec[3];
- BMOpSlot *slot_targetmap;
-
- BMO_slot_vec_get(op->slots_in, "merge_co", vec);
-
- //BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
- BMO_op_init(bm, &weldop, op->flag, "weld_verts");
-
- slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
-
- BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- if (!vert_snap) {
- vert_snap = v;
- copy_v3_v3(vert_snap->co, vec);
- }
- else {
- BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, vert_snap);
- }
- }
-
- BMO_op_exec(bm, &weldop);
- BMO_op_finish(bm, &weldop);
+ BMOperator weldop;
+ BMOIter siter;
+ BMVert *v, *vert_snap = NULL;
+ float vec[3];
+ BMOpSlot *slot_targetmap;
+
+ BMO_slot_vec_get(op->slots_in, "merge_co", vec);
+
+ //BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
+ BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
+
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
+ if (!vert_snap) {
+ vert_snap = v;
+ copy_v3_v3(vert_snap->co, vec);
+ }
+ else {
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, vert_snap);
+ }
+ }
+
+ BMO_op_exec(bm, &weldop);
+ BMO_op_finish(bm, &weldop);
}
void bmo_collapse_exec(BMesh *bm, BMOperator *op)
{
- BMOperator weldop;
- BMWalker walker;
- BMIter iter;
- BMEdge *e;
- BLI_Stack *edge_stack;
- BMOpSlot *slot_targetmap;
+ BMOperator weldop;
+ BMWalker walker;
+ BMIter iter;
+ BMEdge *e;
+ BLI_Stack *edge_stack;
+ BMOpSlot *slot_targetmap;
- if (BMO_slot_bool_get(op->slots_in, "uvs")) {
- BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
- }
+ if (BMO_slot_bool_get(op->slots_in, "uvs")) {
+ BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
+ }
- BMO_op_init(bm, &weldop, op->flag, "weld_verts");
- slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
+ BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
- BMW_init(&walker, bm, BMW_VERT_SHELL,
- BMW_MASK_NOP, EDGE_MARK, BMW_MASK_NOP,
- BMW_FLAG_NOP, /* no need to use BMW_FLAG_TEST_HIDDEN, already marked data */
- BMW_NIL_LAY);
+ BMW_init(&walker,
+ bm,
+ BMW_VERT_SHELL,
+ BMW_MASK_NOP,
+ EDGE_MARK,
+ BMW_MASK_NOP,
+ BMW_FLAG_NOP, /* no need to use BMW_FLAG_TEST_HIDDEN, already marked data */
+ BMW_NIL_LAY);
- edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
+ edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- float center[3];
- int count = 0;
- BMVert *v_tar;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ float center[3];
+ int count = 0;
+ BMVert *v_tar;
- zero_v3(center);
+ zero_v3(center);
- if (!BMO_edge_flag_test(bm, e, EDGE_MARK)) {
- continue;
- }
+ if (!BMO_edge_flag_test(bm, e, EDGE_MARK)) {
+ continue;
+ }
- BLI_assert(BLI_stack_is_empty(edge_stack));
+ BLI_assert(BLI_stack_is_empty(edge_stack));
- for (e = BMW_begin(&walker, e->v1); e; e = BMW_step(&walker)) {
- BLI_stack_push(edge_stack, &e);
+ for (e = BMW_begin(&walker, e->v1); e; e = BMW_step(&walker)) {
+ BLI_stack_push(edge_stack, &e);
- add_v3_v3(center, e->v1->co);
- add_v3_v3(center, e->v2->co);
+ add_v3_v3(center, e->v1->co);
+ add_v3_v3(center, e->v2->co);
- count += 2;
+ count += 2;
- /* prevent adding to slot_targetmap multiple times */
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- }
+ /* prevent adding to slot_targetmap multiple times */
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ }
- if (!BLI_stack_is_empty(edge_stack)) {
- mul_v3_fl(center, 1.0f / count);
+ if (!BLI_stack_is_empty(edge_stack)) {
+ mul_v3_fl(center, 1.0f / count);
- /* snap edges to a point. for initial testing purposes anyway */
- e = *(BMEdge **)BLI_stack_peek(edge_stack);
- v_tar = e->v1;
+ /* snap edges to a point. for initial testing purposes anyway */
+ e = *(BMEdge **)BLI_stack_peek(edge_stack);
+ v_tar = e->v1;
- while (!BLI_stack_is_empty(edge_stack)) {
- uint j;
- BLI_stack_pop(edge_stack, &e);
+ while (!BLI_stack_is_empty(edge_stack)) {
+ uint j;
+ BLI_stack_pop(edge_stack, &e);
- for (j = 0; j < 2; j++) {
- BMVert *v_src = *((&e->v1) + j);
+ for (j = 0; j < 2; j++) {
+ BMVert *v_src = *((&e->v1) + j);
- copy_v3_v3(v_src->co, center);
- if ((v_src != v_tar) && !BM_elem_flag_test(v_src, BM_ELEM_TAG)) {
- BM_elem_flag_enable(v_src, BM_ELEM_TAG);
- BMO_slot_map_elem_insert(&weldop, slot_targetmap, v_src, v_tar);
- }
- }
- }
- }
- }
+ copy_v3_v3(v_src->co, center);
+ if ((v_src != v_tar) && !BM_elem_flag_test(v_src, BM_ELEM_TAG)) {
+ BM_elem_flag_enable(v_src, BM_ELEM_TAG);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, v_src, v_tar);
+ }
+ }
+ }
+ }
+ }
- BLI_stack_free(edge_stack);
+ BLI_stack_free(edge_stack);
- BMO_op_exec(bm, &weldop);
- BMO_op_finish(bm, &weldop);
+ BMO_op_exec(bm, &weldop);
+ BMO_op_finish(bm, &weldop);
- BMW_end(&walker);
+ BMW_end(&walker);
}
/* uv collapse function */
static void bmo_collapsecon_do_layer(BMesh *bm, const int layer, const short oflag)
{
- const int type = bm->ldata.layers[layer].type;
- const int offset = bm->ldata.layers[layer].offset;
- BMIter iter, liter;
- BMFace *f;
- BMLoop *l, *l2;
- BMWalker walker;
- BLI_Stack *block_stack;
- CDBlockBytes min, max;
-
- BMW_init(&walker, bm, BMW_LOOPDATA_ISLAND,
- BMW_MASK_NOP, oflag, BMW_MASK_NOP,
- BMW_FLAG_NOP, /* no need to use BMW_FLAG_TEST_HIDDEN, already marked data */
- layer);
-
- block_stack = BLI_stack_new(sizeof(void *), __func__);
-
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (BMO_edge_flag_test(bm, l->e, oflag)) {
- /* walk */
- BLI_assert(BLI_stack_is_empty(block_stack));
-
- CustomData_data_initminmax(type, &min, &max);
- for (l2 = BMW_begin(&walker, l); l2; l2 = BMW_step(&walker)) {
- void *block = BM_ELEM_CD_GET_VOID_P(l2, offset);
- CustomData_data_dominmax(type, block, &min, &max);
- BLI_stack_push(block_stack, &block);
- }
-
- if (!BLI_stack_is_empty(block_stack)) {
- CustomData_data_multiply(type, &min, 0.5f);
- CustomData_data_multiply(type, &max, 0.5f);
- CustomData_data_add(type, &min, &max);
-
- /* snap CD (uv, vcol) points to their centroid */
- while (!BLI_stack_is_empty(block_stack)) {
- void *block;
- BLI_stack_pop(block_stack, &block);
- CustomData_data_copy_value(type, &min, block);
- }
- }
- }
- }
- }
-
- BLI_stack_free(block_stack);
-
- BMW_end(&walker);
+ const int type = bm->ldata.layers[layer].type;
+ const int offset = bm->ldata.layers[layer].offset;
+ BMIter iter, liter;
+ BMFace *f;
+ BMLoop *l, *l2;
+ BMWalker walker;
+ BLI_Stack *block_stack;
+ CDBlockBytes min, max;
+
+ BMW_init(&walker,
+ bm,
+ BMW_LOOPDATA_ISLAND,
+ BMW_MASK_NOP,
+ oflag,
+ BMW_MASK_NOP,
+ BMW_FLAG_NOP, /* no need to use BMW_FLAG_TEST_HIDDEN, already marked data */
+ layer);
+
+ block_stack = BLI_stack_new(sizeof(void *), __func__);
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BMO_edge_flag_test(bm, l->e, oflag)) {
+ /* walk */
+ BLI_assert(BLI_stack_is_empty(block_stack));
+
+ CustomData_data_initminmax(type, &min, &max);
+ for (l2 = BMW_begin(&walker, l); l2; l2 = BMW_step(&walker)) {
+ void *block = BM_ELEM_CD_GET_VOID_P(l2, offset);
+ CustomData_data_dominmax(type, block, &min, &max);
+ BLI_stack_push(block_stack, &block);
+ }
+
+ if (!BLI_stack_is_empty(block_stack)) {
+ CustomData_data_multiply(type, &min, 0.5f);
+ CustomData_data_multiply(type, &max, 0.5f);
+ CustomData_data_add(type, &min, &max);
+
+ /* snap CD (uv, vcol) points to their centroid */
+ while (!BLI_stack_is_empty(block_stack)) {
+ void *block;
+ BLI_stack_pop(block_stack, &block);
+ CustomData_data_copy_value(type, &min, block);
+ }
+ }
+ }
+ }
+ }
+
+ BLI_stack_free(block_stack);
+
+ BMW_end(&walker);
}
void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op)
{
- const short oflag = EDGE_MARK;
- int i;
+ const short oflag = EDGE_MARK;
+ int i;
- /* check flags dont change once set */
+ /* check flags dont change once set */
#ifndef NDEBUG
- int tot_test;
+ int tot_test;
#endif
- if (!CustomData_has_math(&bm->ldata)) {
- return;
- }
+ if (!CustomData_has_math(&bm->ldata)) {
+ return;
+ }
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, oflag);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, oflag);
#ifndef NDEBUG
- tot_test = BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, oflag, true);
+ tot_test = BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, oflag, true);
#endif
- for (i = 0; i < bm->ldata.totlayer; i++) {
- if (CustomData_layer_has_math(&bm->ldata, i)) {
- bmo_collapsecon_do_layer(bm, i, oflag);
- }
- }
+ for (i = 0; i < bm->ldata.totlayer; i++) {
+ if (CustomData_layer_has_math(&bm->ldata, i)) {
+ bmo_collapsecon_do_layer(bm, i, oflag);
+ }
+ }
#ifndef NDEBUG
- BLI_assert(tot_test == BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, EDGE_MARK, true));
+ BLI_assert(tot_test == BM_iter_mesh_count_flag(BM_EDGES_OF_MESH, bm, EDGE_MARK, true));
#endif
-
}
-static void bmesh_find_doubles_common(
- BMesh *bm, BMOperator *op,
- BMOperator *optarget, BMOpSlot *optarget_slot)
+static void bmesh_find_doubles_common(BMesh *bm,
+ BMOperator *op,
+ BMOperator *optarget,
+ BMOpSlot *optarget_slot)
{
- const BMOpSlot *slot_verts = BMO_slot_get(op->slots_in, "verts");
- BMVert * const *verts = (BMVert **)slot_verts->data.buf;
- const int verts_len = slot_verts->len;
-
- bool has_keep_vert = false;
- bool found_duplicates = false;
-
- const float dist = BMO_slot_float_get(op->slots_in, "dist");
-
- /* Test whether keep_verts arg exists and is non-empty */
- if (BMO_slot_exists(op->slots_in, "keep_verts")) {
- BMOIter oiter;
- has_keep_vert = BMO_iter_new(&oiter, op->slots_in, "keep_verts", BM_VERT) != NULL;
- }
-
- /* Flag keep_verts */
- if (has_keep_vert) {
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "keep_verts", BM_VERT, VERT_KEEP);
- }
-
- int *duplicates = MEM_mallocN(sizeof(int) * verts_len, __func__);
- {
- KDTree_3d *tree = BLI_kdtree_3d_new(verts_len);
- for (int i = 0; i < verts_len; i++) {
- BLI_kdtree_3d_insert(tree, i, verts[i]->co);
- if (has_keep_vert && BMO_vert_flag_test(bm, verts[i], VERT_KEEP)) {
- duplicates[i] = i;
- }
- else {
- duplicates[i] = -1;
- }
- }
-
- BLI_kdtree_3d_balance(tree);
- found_duplicates = BLI_kdtree_3d_calc_duplicates_fast(tree, dist, false, duplicates) != 0;
- BLI_kdtree_3d_free(tree);
- }
-
- if (found_duplicates) {
- for (int i = 0; i < verts_len; i++) {
- BMVert *v_check = verts[i];
- if (duplicates[i] == -1) {
- /* nop (others can use as target) */
- }
- else if (duplicates[i] == i) {
- /* keep (others can use as target) */
- }
- else {
- BMVert *v_other = verts[duplicates[i]];
- BLI_assert(ELEM(duplicates[duplicates[i]], -1, duplicates[i]));
- BMO_slot_map_elem_insert(optarget, optarget_slot, v_check, v_other);
- }
- }
- }
-
- MEM_freeN(duplicates);
+ const BMOpSlot *slot_verts = BMO_slot_get(op->slots_in, "verts");
+ BMVert *const *verts = (BMVert **)slot_verts->data.buf;
+ const int verts_len = slot_verts->len;
+
+ bool has_keep_vert = false;
+ bool found_duplicates = false;
+
+ const float dist = BMO_slot_float_get(op->slots_in, "dist");
+
+ /* Test whether keep_verts arg exists and is non-empty */
+ if (BMO_slot_exists(op->slots_in, "keep_verts")) {
+ BMOIter oiter;
+ has_keep_vert = BMO_iter_new(&oiter, op->slots_in, "keep_verts", BM_VERT) != NULL;
+ }
+
+ /* Flag keep_verts */
+ if (has_keep_vert) {
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "keep_verts", BM_VERT, VERT_KEEP);
+ }
+
+ int *duplicates = MEM_mallocN(sizeof(int) * verts_len, __func__);
+ {
+ KDTree_3d *tree = BLI_kdtree_3d_new(verts_len);
+ for (int i = 0; i < verts_len; i++) {
+ BLI_kdtree_3d_insert(tree, i, verts[i]->co);
+ if (has_keep_vert && BMO_vert_flag_test(bm, verts[i], VERT_KEEP)) {
+ duplicates[i] = i;
+ }
+ else {
+ duplicates[i] = -1;
+ }
+ }
+
+ BLI_kdtree_3d_balance(tree);
+ found_duplicates = BLI_kdtree_3d_calc_duplicates_fast(tree, dist, false, duplicates) != 0;
+ BLI_kdtree_3d_free(tree);
+ }
+
+ if (found_duplicates) {
+ for (int i = 0; i < verts_len; i++) {
+ BMVert *v_check = verts[i];
+ if (duplicates[i] == -1) {
+ /* nop (others can use as target) */
+ }
+ else if (duplicates[i] == i) {
+ /* keep (others can use as target) */
+ }
+ else {
+ BMVert *v_other = verts[duplicates[i]];
+ BLI_assert(ELEM(duplicates[duplicates[i]], -1, duplicates[i]));
+ BMO_slot_map_elem_insert(optarget, optarget_slot, v_check, v_other);
+ }
+ }
+ }
+
+ MEM_freeN(duplicates);
}
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
{
- BMOperator weldop;
- BMOpSlot *slot_targetmap;
-
- BMO_op_init(bm, &weldop, op->flag, "weld_verts");
- slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
- bmesh_find_doubles_common(bm, op,
- &weldop, slot_targetmap);
- BMO_op_exec(bm, &weldop);
- BMO_op_finish(bm, &weldop);
+ BMOperator weldop;
+ BMOpSlot *slot_targetmap;
+
+ BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
+ bmesh_find_doubles_common(bm, op, &weldop, slot_targetmap);
+ BMO_op_exec(bm, &weldop);
+ BMO_op_finish(bm, &weldop);
}
-
void bmo_find_doubles_exec(BMesh *bm, BMOperator *op)
{
- BMOpSlot *slot_targetmap_out;
- slot_targetmap_out = BMO_slot_get(op->slots_out, "targetmap.out");
- bmesh_find_doubles_common(bm, op,
- op, slot_targetmap_out);
+ BMOpSlot *slot_targetmap_out;
+ slot_targetmap_out = BMO_slot_get(op->slots_out, "targetmap.out");
+ bmesh_find_doubles_common(bm, op, op, slot_targetmap_out);
}
void bmo_automerge_exec(BMesh *bm, BMOperator *op)
{
- BMOperator findop, weldop;
- BMIter viter;
- BMVert *v;
-
- /* The "verts" input sent to this op is the set of verts that
- * can be merged away into any other verts. Mark all other verts
- * as VERT_KEEP. */
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_IN);
- BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
- if (!BMO_vert_flag_test(bm, v, VERT_IN)) {
- BMO_vert_flag_enable(bm, v, VERT_KEEP);
- }
- }
-
- /* Search for doubles among all vertices, but only merge non-VERT_KEEP
- * vertices into VERT_KEEP vertices. */
- BMO_op_initf(bm, &findop, op->flag, "find_doubles verts=%av keep_verts=%fv", VERT_KEEP);
- BMO_slot_copy(op, slots_in, "dist",
- &findop, slots_in, "dist");
- BMO_op_exec(bm, &findop);
-
- /* weld the vertices */
- BMO_op_init(bm, &weldop, op->flag, "weld_verts");
- BMO_slot_copy(&findop, slots_out, "targetmap.out",
- &weldop, slots_in, "targetmap");
- BMO_op_exec(bm, &weldop);
-
- BMO_op_finish(bm, &findop);
- BMO_op_finish(bm, &weldop);
+ BMOperator findop, weldop;
+ BMIter viter;
+ BMVert *v;
+
+ /* The "verts" input sent to this op is the set of verts that
+ * can be merged away into any other verts. Mark all other verts
+ * as VERT_KEEP. */
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_IN);
+ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (!BMO_vert_flag_test(bm, v, VERT_IN)) {
+ BMO_vert_flag_enable(bm, v, VERT_KEEP);
+ }
+ }
+
+ /* Search for doubles among all vertices, but only merge non-VERT_KEEP
+ * vertices into VERT_KEEP vertices. */
+ BMO_op_initf(bm, &findop, op->flag, "find_doubles verts=%av keep_verts=%fv", VERT_KEEP);
+ BMO_slot_copy(op, slots_in, "dist", &findop, slots_in, "dist");
+ BMO_op_exec(bm, &findop);
+
+ /* weld the vertices */
+ BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+ BMO_slot_copy(&findop, slots_out, "targetmap.out", &weldop, slots_in, "targetmap");
+ BMO_op_exec(bm, &weldop);
+
+ BMO_op_finish(bm, &findop);
+ BMO_op_finish(bm, &weldop);
}