[Bf-blender-cvs] [c168092014e] master: Fix T69792: Auto-merge split faces creates faces with unrelated wire edges.

mano-wii noreply at git.blender.org
Thu Sep 12 15:58:53 CEST 2019


Commit: c168092014ef117abb1a6d38c6f6827dab181f09
Author: mano-wii
Date:   Thu Sep 12 10:52:03 2019 -0300
Branches: master
https://developer.blender.org/rBc168092014ef117abb1a6d38c6f6827dab181f09

Fix T69792: Auto-merge split faces creates faces with unrelated wire edges.

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

M	source/blender/editors/mesh/editmesh_automerge.c

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

diff --git a/source/blender/editors/mesh/editmesh_automerge.c b/source/blender/editors/mesh/editmesh_automerge.c
index 82f53aafad8..1d342c7e9a2 100644
--- a/source/blender/editors/mesh/editmesh_automerge.c
+++ b/source/blender/editors/mesh/editmesh_automerge.c
@@ -120,32 +120,35 @@ struct EDBMSplitEdgeData {
 };
 
 static bool edbm_vert_pair_share_best_splittable_face_cb(BMFace *f,
-                                                         BMLoop *UNUSED(l_a),
-                                                         BMLoop *UNUSED(l_b),
+                                                         BMLoop *l_a,
+                                                         BMLoop *l_b,
                                                          void *userdata)
 {
   struct EDBMSplitBestFaceData *data = userdata;
-  float no[3], min = FLT_MAX, max = -FLT_MAX;
+  float no[3];
   copy_v3_v3(no, f->no);
 
-  BMVert *verts[2] = {NULL};
+  float min = dot_v3v3(l_a->v->co, no);
+  float max = dot_v3v3(l_b->v->co, no);
+  if (min > max) {
+    SWAP(float, min, max);
+  }
+
+  BMVert *v_test = l_b->v;
   BMEdge **e_iter = &data->edgenet[0];
-  for (int i = data->edgenet_len; i--; e_iter++) {
-    BMIter iter;
-    BMVert *v;
-    BM_ITER_ELEM (v, &iter, *e_iter, BM_VERTS_OF_EDGE) {
-      if (!ELEM(v, verts[0], verts[1])) {
-        float dot = dot_v3v3(v->co, no);
-        if (dot < min) {
-          min = dot;
-        }
-        if (dot > max) {
-          max = dot;
-        }
-      }
+  int verts_len = data->edgenet_len - 1;
+  for (int i = verts_len; i--; e_iter++) {
+    v_test = BM_edge_other_vert(*e_iter, v_test);
+    if (!BM_face_point_inside_test(f, v_test->co)) {
+      return false;
+    }
+    float dot = dot_v3v3(v_test->co, no);
+    if (dot < min) {
+      min = dot;
+    }
+    if (dot > max) {
+      max = dot;
     }
-    verts[0] = (*e_iter)->v1;
-    verts[1] = (*e_iter)->v2;
   }
 
   const float test_face_range_on_normal_axis = max - min;
@@ -179,10 +182,8 @@ static bool edbm_vert_pair_share_splittable_face_cb(BMFace *UNUSED(f),
   return false;
 }
 
-static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
-                                                                    BMVert *v,
-                                                                    BMEdge **r_edgenet[],
-                                                                    int *r_edgenet_alloc_len)
+static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(
+    BMesh *bm, BMVert *v, const float epsilon, BMEdge **r_edgenet[], int *r_edgenet_alloc_len)
 {
   BMEdge **edgenet = *r_edgenet;
   int edgenet_alloc_len = *r_edgenet_alloc_len;
@@ -206,15 +207,26 @@ static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
 
       BMEdge *e_next = BM_DISK_EDGE_NEXT(e, v_other);
       if (e_next == e) {
-        /* Vert is wire_endpoint */
+        /* Vert is wire_endpoint. */
         edgenet_len = 0;
         break;
       }
+
+      BMEdge *e_test = e_next;
+      while ((e_test = BM_DISK_EDGE_NEXT(e_test, v_other)) != e) {
+        if (e_test->l) {
+          /* Vert is linked to a face. */
+          goto l_break;
+        }
+      }
+
       e = e_next;
     }
 
     BMLoop *dummy;
     BMFace *best_face;
+
+  l_break:
     if (edgenet_len == 0) {
       /* Nothing to do. */
       continue;
@@ -236,6 +248,25 @@ static void edbm_automerge_weld_linked_wire_edges_into_linked_faces(BMesh *bm,
       BM_vert_pair_shared_face_cb(
           v_other, v, true, edbm_vert_pair_share_best_splittable_face_cb, &data, &dummy, &dummy);
 
+      if (data.r_best_face) {
+        float no[3], min = FLT_MAX, max = -FLT_MAX;
+        copy_v3_v3(no, data.r_best_face->no);
+        BMVert *v_test;
+        BMIter f_iter;
+        BM_ITER_ELEM (v_test, &f_iter, data.r_best_face, BM_VERTS_OF_FACE) {
+          float dot = dot_v3v3(v_test->co, no);
+          if (dot < min) {
+            min = dot;
+          }
+          if (dot > max) {
+            max = dot;
+          }
+        }
+        float range = max - min + 2 * epsilon;
+        if (range < data.best_face_range_on_normal_axis) {
+          data.r_best_face = NULL;
+        }
+      }
       best_face = data.r_best_face;
     }
 
@@ -498,7 +529,8 @@ void EDBM_automerge_and_split(Object *obedit,
     GHASH_ITER (gh_iter, ghash_targetmap) {
       v = BLI_ghashIterator_getValue(&gh_iter);
       BLI_assert(BM_elem_flag_test(v, hflag) || hflag == BM_ELEM_TAG);
-      edbm_automerge_weld_linked_wire_edges_into_linked_faces(bm, v, &edgenet, &edgenet_alloc_len);
+      edbm_automerge_weld_linked_wire_edges_into_linked_faces(
+          bm, v, dist, &edgenet, &edgenet_alloc_len);
     }
   }



More information about the Bf-blender-cvs mailing list