re: edge split with edges only connected to 2 faces (with no other faces around the...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 03:58:23 +0000 (03:58 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 03:58:23 +0000 (03:58 +0000)
turns out old code also had the same bug (just coincidance it was noticed after my change)

now boundry verts are tagged so edges connected to them are not seen is missing a tagged, adjacent edge.

this fixes [#30471]

source/blender/bmesh/operators/bmo_edgesplit.c

index a390313ed369722d2970519c1fc8cc97b2c04f34..8af80a184c017f38a9d0e1fbdd815eb70b207c6e 100644 (file)
@@ -223,7 +223,7 @@ void bmo_edgesplit_exec(BMesh *bm, BMOperator *op)
        BMFace *f, *f2;
        BMLoop *l, *l2, *l3;
        BMLoop *l_next, *l_prev;
-       BMEdge *e, *e2;
+       BMEdge *e;
        BMVert *v, *v2;
 
        /* face/vert aligned vert array */
@@ -236,23 +236,41 @@ void bmo_edgesplit_exec(BMesh *bm, BMOperator *op)
 
        BMO_slot_buffer_flag_enable(bm, op, "edges", EDGE_SEAM, BM_EDGE);
 
-       /* single marked edges unconnected to any other marked edges
-        * are illegal, go through and unmark them */
-       BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
-               for (i = 0; i < 2; i++) {
-                       BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, i ? e->v2 : e->v1) {
-                               if (e != e2 && BMO_elem_flag_test(bm, e2, EDGE_SEAM)) {
-                                       break;
-                               }
-                       }
-                       if (e2) {
-                               break;
+       /* untag edges not connected to other tagged edges */
+       {
+               unsigned char *vtouch;
+               unsigned char *vt;
+
+               BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+               vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
+
+               /* tag all boundry verts so as not to untag an edge which is inbetween only 2 faces [] */
+               BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+                       if (BM_edge_is_boundary(e)) {
+                               vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+                               vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
                        }
                }
 
-               if (!e2) {
-                       BMO_elem_flag_disable(bm, e, EDGE_SEAM);
+               /* single marked edges unconnected to any other marked edges
+                * are illegal, go through and unmark them */
+               BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+                       /* lame, but we dont want the count to exceed 255,
+                        * so just count to 2, its all we need */
+                       unsigned char *vt;
+                       vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+                       vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
                }
+               BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+                       if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
+                           vtouch[BM_elem_index_get(e->v2)] == 1)
+                       {
+                               BMO_elem_flag_disable(bm, e, EDGE_SEAM);
+                       }
+               }
+
+               MEM_freeN(vtouch);
        }
 
        etags = MEM_callocN(sizeof(EdgeTag) * bm->totedge, "EdgeTag");