Commit: 3ef27ec807bc89eed5b3a10ae9041c607ff4eacb
Author: Campbell Barton
Date:   Thu Apr 30 05:52:48 2015 +1000
Branches: master
https://developer.blender.org/rB3ef27ec807bc89eed5b3a10ae9041c607ff4eacb

BMesh: add BM_face_loop_separate_multi

New utility function to handle splitting off multiple loops from a face at once.

===================================================================

M       source/blender/bmesh/intern/bmesh_core.c
M       source/blender/bmesh/intern/bmesh_core.h
M       source/blender/bmesh/intern/bmesh_mods.c
M       source/blender/bmesh/intern/bmesh_mods.h

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_core.c 
b/source/blender/bmesh/intern/bmesh_core.c
index abeecf5..81cc972 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -2360,6 +2360,151 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
 }
 
 /**
+ * A version of #bmesh_urmv_loop that disconnects multiple loops at once.
+ *
+ * Handles the task of finding fans boundaris.
+ */
+BMVert *bmesh_urmv_loop_multi(
+        BMesh *bm, BMLoop **larr, int larr_len)
+{
+       BMVert *v_sep = larr[0]->v;
+       BMVert *v_new;
+       int i;
+       bool is_mixed_any = false;
+
+       BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
+
+#define LOOP_VISIT _FLAG_WALK
+#define EDGE_VISIT _FLAG_WALK
+
+       for (i = 0; i < larr_len; i++) {
+               BMLoop *l_sep = larr[i];
+
+               /* all must be from the same vert! */
+               BLI_assert(v_sep == l_sep->v);
+
+               BLI_assert(!BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
+               BM_ELEM_API_FLAG_ENABLE(l_sep, LOOP_VISIT);
+
+               /* weak! but it makes it simpler to check for edges to split
+                * while doing a radial loop (where loops may be adjacent) */
+               BM_ELEM_API_FLAG_ENABLE(l_sep->next, LOOP_VISIT);
+               BM_ELEM_API_FLAG_ENABLE(l_sep->prev, LOOP_VISIT);
+       }
+
+       for (i = 0; i < larr_len; i++) {
+               BMLoop *l_sep = larr[i];
+
+               BMLoop *loop_pair[2] = {l_sep, l_sep->prev};
+               int j;
+               for (j = 0; j < ARRAY_SIZE(loop_pair); j++) {
+                       BMEdge *e = loop_pair[j]->e;
+                       if (!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)) {
+                               BMLoop *l_iter, *l_first;
+                               bool is_mixed = false;
+
+                               BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
+
+                               l_iter = l_first = e->l;
+                               do {
+                                       if (!BM_ELEM_API_FLAG_TEST(l_iter, 
LOOP_VISIT)) {
+                                               is_mixed = true;
+                                               is_mixed_any = true;
+                                               break;
+                                       }
+                               } while ((l_iter = l_iter->radial_next) != 
l_first);
+
+                               if (is_mixed) {
+                                       /* ensure the first loop is one we 
don't own so we can do a quick check below
+                                        * on the edge's loop-flag to see if 
the edge is mixed or not. */
+                                       e->l = l_iter;
+                               }
+                               BLI_SMALLSTACK_PUSH(edges, e);
+                       }
+               }
+       }
+
+       if (is_mixed_any == false) {
+               /* all loops in 'larr' are the soul owners of their edges.
+                * nothing to split away from, this is a no-op */
+               v_new = v_sep;
+       }
+       else {
+               BMEdge *e;
+
+               BLI_assert(!BLI_SMALLSTACK_IS_EMPTY(edges));
+
+               v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
+               while ((e = BLI_SMALLSTACK_POP(edges))) {
+                       BMLoop *l_iter, *l_first, *l_next;
+                       BMEdge *e_new;
+
+                       /* disable so copied edge isn't left dirty (loop edges 
are cleared last too) */
+                       BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
+
+                       if (!BM_ELEM_API_FLAG_TEST(e->l, LOOP_VISIT)) {
+                               /* edge has some loops owned by us, some owned 
by other loops */
+                               BMVert *e_new_v_pair[2];
+
+                               if (e->v1 == v_sep) {
+                                       e_new_v_pair[0] = v_new;
+                                       e_new_v_pair[1] = e->v2;
+                               }
+                               else {
+                                       BLI_assert(v_sep == e->v2);
+                                       e_new_v_pair[0] = e->v1;
+                                       e_new_v_pair[1] = v_new;
+                               }
+
+                               e_new = BM_edge_create(bm, 
UNPACK2(e_new_v_pair), e, BM_CREATE_NOP);
+
+                               /* now moved all loops from 'larr' to this 
newly created edge */
+                               l_iter = l_first = e->l;
+                               do {
+                                       l_next = l_iter->radial_next;
+                                       if (BM_ELEM_API_FLAG_TEST(l_iter, 
LOOP_VISIT)) {
+                                               
bmesh_radial_loop_remove(l_iter, e);
+                                               bmesh_radial_append(e_new, 
l_iter);
+                                               l_iter->e = e_new;
+                                       }
+                               } while ((l_iter = l_next) != l_first);
+                       }
+                       else {
+                               /* we own the edge entirely, replace the vert */
+                               bmesh_disk_edge_remove(e, v_sep);
+                               bmesh_disk_vert_swap(e, v_new, v_sep);
+                               bmesh_disk_edge_append(e, v_new);
+                       }
+
+                       /* loop vert is handled last! */
+               }
+       }
+
+       for (i = 0; i < larr_len; i++) {
+               BMLoop *l_sep = larr[i];
+
+               l_sep->v = v_new;
+
+               BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
+               BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->prev, LOOP_VISIT));
+               BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->next, LOOP_VISIT));
+               BM_ELEM_API_FLAG_DISABLE(l_sep, LOOP_VISIT);
+               BM_ELEM_API_FLAG_DISABLE(l_sep->prev, LOOP_VISIT);
+               BM_ELEM_API_FLAG_DISABLE(l_sep->next, LOOP_VISIT);
+
+
+               BM_ELEM_API_FLAG_DISABLE(l_sep->prev->e, EDGE_VISIT);
+               BM_ELEM_API_FLAG_DISABLE(l_sep->e, EDGE_VISIT);
+       }
+
+#undef LOOP_VISIT
+#undef EDGE_VISIT
+
+       return v_new;
+}
+
+
+/**
  * \brief Unglue Region Make Vert (URMV)
  *
  * Disconnects f_sep from the vertex fan at \a v_sep
diff --git a/source/blender/bmesh/intern/bmesh_core.h 
b/source/blender/bmesh/intern/bmesh_core.h
index 55bc6a6..85dd1de 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -99,6 +99,8 @@ BMEdge *bmesh_jekv(
 BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
 BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
 BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
+BMVert *bmesh_urmv_loop_multi(
+        BMesh *bm, BMLoop **larr, int larr_len);
 
 void    bmesh_face_swap_data(BMFace *f_a, BMFace *f_b);
 
diff --git a/source/blender/bmesh/intern/bmesh_mods.c 
b/source/blender/bmesh/intern/bmesh_mods.c
index ab6d21d..5891876 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -1650,3 +1650,9 @@ BMVert *BM_face_loop_separate(BMesh *bm, BMLoop *sl)
 {
        return bmesh_urmv_loop(bm, sl);
 }
+
+BMVert *BM_face_loop_separate_multi(
+        BMesh *bm, BMLoop **larr, int larr_len)
+{
+       return bmesh_urmv_loop_multi(bm, larr, larr_len);
+}
diff --git a/source/blender/bmesh/intern/bmesh_mods.h 
b/source/blender/bmesh/intern/bmesh_mods.h
index 2ef836a..1b826b1 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -89,5 +89,7 @@ enum {
 
 BMVert *BM_face_vert_separate(BMesh *bm, BMFace *sf, BMVert *sv);
 BMVert *BM_face_loop_separate(BMesh *bm, BMLoop *sl);
+BMVert *BM_face_loop_separate_multi(
+        BMesh *bm, BMLoop **larr, int larr_len);
 
 #endif /* __BMESH_MODS_H__ */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to