[Bf-blender-cvs] [bb860070185] blender-v3.4-release: Fix T102232: bridge edge loop crash

Campbell Barton noreply at git.blender.org
Fri Nov 4 11:59:14 CET 2022


Commit: bb860070185f6ed4d06593feae2095aeb45d7a23
Author: Campbell Barton
Date:   Fri Nov 4 21:38:15 2022 +1100
Branches: blender-v3.4-release
https://developer.blender.org/rBbb860070185f6ed4d06593feae2095aeb45d7a23

Fix T102232: bridge edge loop crash

Many connected edge loops could result in two edge loops sharing
vertices. This is more of a workaround, the reason for two edge loops
sharing vertices could be prevented some other way.
Add this check since it's a straightforward solution,
furthered investigation noted as a TODO.

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

M	source/blender/bmesh/operators/bmo_bridge.c

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

diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index 8240fbc53c1..b6520fb48b3 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -14,6 +14,13 @@
 
 #include "intern/bmesh_operators_private.h" /* own include */
 
+/**
+ * TODO(@campbellbarton): Many connected edge loops can cause an error attempting
+ * to create faces with duplicate vertices. While this needs to be investigated,
+ * it's simple enough to check for this case, see: T102232.
+ */
+#define USE_DUPLICATE_FACE_VERT_CHECK
+
 #define EDGE_MARK 4
 #define EDGE_OUT 8
 #define FACE_OUT 16
@@ -386,61 +393,84 @@ static void bridge_loop_pair(BMesh *bm,
       f_example = l_a ? l_a->f : (l_b ? l_b->f : NULL);
 
       if (v_b != v_b_next) {
-        BMVert *v_arr[4] = {v_b, v_b_next, v_a_next, v_a};
-        f = BM_face_exists(v_arr, 4);
-        if (f == NULL) {
-          /* copy if loop data if its is missing on one ring */
-          f = BM_face_create_verts(bm, v_arr, 4, NULL, BM_CREATE_NOP, true);
-
-          l_iter = BM_FACE_FIRST_LOOP(f);
-          if (l_b) {
-            BM_elem_attrs_copy(bm, bm, l_b, l_iter);
-          }
-          l_iter = l_iter->next;
-          if (l_b_next) {
-            BM_elem_attrs_copy(bm, bm, l_b_next, l_iter);
-          }
-          l_iter = l_iter->next;
-          if (l_a_next) {
-            BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
-          }
-          l_iter = l_iter->next;
-          if (l_a) {
-            BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK /* Only check for duplicates between loops. */
+        BLI_assert((v_b != v_b_next) && (v_a_next != v_a));
+        if (UNLIKELY(ELEM(v_b, v_a_next, v_a) || ELEM(v_b_next, v_a_next, v_a))) {
+          f = NULL;
+        }
+        else
+#endif
+        {
+          BMVert *v_arr[4] = {v_b, v_b_next, v_a_next, v_a};
+          f = BM_face_exists(v_arr, 4);
+          if (f == NULL) {
+            /* copy if loop data if its is missing on one ring */
+            f = BM_face_create_verts(bm, v_arr, 4, NULL, BM_CREATE_NOP, true);
+
+            l_iter = BM_FACE_FIRST_LOOP(f);
+            if (l_b) {
+              BM_elem_attrs_copy(bm, bm, l_b, l_iter);
+            }
+            l_iter = l_iter->next;
+            if (l_b_next) {
+              BM_elem_attrs_copy(bm, bm, l_b_next, l_iter);
+            }
+            l_iter = l_iter->next;
+            if (l_a_next) {
+              BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
+            }
+            l_iter = l_iter->next;
+            if (l_a) {
+              BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+            }
           }
         }
       }
       else {
-        BMVert *v_arr[3] = {v_b, v_a_next, v_a};
-        f = BM_face_exists(v_arr, 3);
-        if (f == NULL) {
-          /* fan-fill a triangle */
-          f = BM_face_create_verts(bm, v_arr, 3, NULL, BM_CREATE_NOP, true);
-
-          l_iter = BM_FACE_FIRST_LOOP(f);
-          if (l_b) {
-            BM_elem_attrs_copy(bm, bm, l_b, l_iter);
-          }
-          l_iter = l_iter->next;
-          if (l_a_next) {
-            BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
-          }
-          l_iter = l_iter->next;
-          if (l_a) {
-            BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK /* Only check for duplicates between loops. */
+        BLI_assert(v_a_next != v_a);
+        if (UNLIKELY(ELEM(v_b, v_a_next, v_a))) {
+          f = NULL;
+        }
+        else
+#endif
+        {
+          BMVert *v_arr[3] = {v_b, v_a_next, v_a};
+          f = BM_face_exists(v_arr, 3);
+          if (f == NULL) {
+            /* fan-fill a triangle */
+            f = BM_face_create_verts(bm, v_arr, 3, NULL, BM_CREATE_NOP, true);
+
+            l_iter = BM_FACE_FIRST_LOOP(f);
+            if (l_b) {
+              BM_elem_attrs_copy(bm, bm, l_b, l_iter);
+            }
+            l_iter = l_iter->next;
+            if (l_a_next) {
+              BM_elem_attrs_copy(bm, bm, l_a_next, l_iter);
+            }
+            l_iter = l_iter->next;
+            if (l_a) {
+              BM_elem_attrs_copy(bm, bm, l_a, l_iter);
+            }
           }
         }
       }
 
-      if (f_example && (f_example != f)) {
-        BM_elem_attrs_copy(bm, bm, f_example, f);
-      }
-      BMO_face_flag_enable(bm, f, FACE_OUT);
-      BM_elem_flag_enable(f, BM_ELEM_TAG);
+#ifdef USE_DUPLICATE_FACE_VERT_CHECK
+      if (f != NULL)
+#endif
+      {
+        if (f_example && (f_example != f)) {
+          BM_elem_attrs_copy(bm, bm, f_example, f);
+        }
+        BMO_face_flag_enable(bm, f, FACE_OUT);
+        BM_elem_flag_enable(f, BM_ELEM_TAG);
 
-      /* tag all edges of the face, untag the loop edges after */
-      if (use_edgeout) {
-        bm_face_edges_tag_out(bm, f);
+        /* tag all edges of the face, untag the loop edges after */
+        if (use_edgeout) {
+          bm_face_edges_tag_out(bm, f);
+        }
       }
 
       if (el_a_next == el_a_first) {



More information about the Bf-blender-cvs mailing list