[Bf-blender-cvs] [d27fb467151] master: EditMesh: Improve AutoMerge with Split Edges & Faces

mano-wii noreply at git.blender.org
Thu Jan 2 01:08:56 CET 2020


Commit: d27fb4671512a3834b61c5c350f428ddccc4669e
Author: mano-wii
Date:   Wed Jan 1 21:06:59 2020 -0300
Branches: master
https://developer.blender.org/rBd27fb4671512a3834b61c5c350f428ddccc4669e

EditMesh: Improve AutoMerge with Split Edges & Faces

Previously, compared to `Auto Merge` without `Split Edges & Faces`,
`Auto Merge` with this option ignored duplicates between selected
vertices. It only considered duplicates between selected vertices and
unselected vertices.

This is a regress and not a progress.

This commit implements this behavior, so this option matches the other
`Auto Merge`.

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

M	source/blender/bmesh/tools/bmesh_intersect_edges.c
M	source/blender/editors/include/ED_mesh.h
M	source/blender/editors/mesh/editmesh_automerge.c

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

diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c
index 82e2151dc01..27102694e88 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.c
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c
@@ -240,20 +240,15 @@ struct EDBMSplitElem {
 struct EDBMSplitData {
   BMesh *bm;
   BLI_Stack *pair_stack;
-  int cut_edges_a_len;
-  int cut_edges_b_len;
+  int cut_edges_len;
   float dist_sq;
   float dist_sq_sq;
 };
 
 /* Utils */
 
-static void bm_vert_pair_elem_setup_ex(BMVert *v,
-                                       float edge_index,
-                                       struct EDBMSplitElem *r_pair_elem)
+static void bm_vert_pair_elem_setup_ex(BMVert *v, struct EDBMSplitElem *r_pair_elem)
 {
-  BLI_assert(v->head.index == -1);
-  v->head.index = edge_index;
   r_pair_elem->vert = v;
 }
 
@@ -274,21 +269,23 @@ static void bm_edge_pair_elem_setup(BMEdge *e,
 }
 
 /* Util for Vert x Edge and Edge x Edge callbacks */
-static bool bm_vertxedge_isect_impl_ex(BMVert *v,
-                                       BMEdge *e,
-                                       int edge_index,
-                                       const float co[3],
-                                       const float dir[3],
-                                       float lambda,
-                                       float data_dist_sq,
-                                       int *data_cut_edges_len,
-                                       struct EDBMSplitElem r_pair[2])
+static bool bm_edgexvert_isect_impl(BMVert *v,
+                                    BMEdge *e,
+                                    const float co[3],
+                                    const float dir[3],
+                                    float lambda,
+                                    float data_dist_sq,
+                                    int *data_cut_edges_len,
+                                    struct EDBMSplitElem r_pair[2])
 {
-  BLI_assert(v->head.index == -1);
-
   BMVert *e_v;
   float dist_sq_vert_factor;
 
+  if (!IN_RANGE_INCL(lambda, 0.0f, 1.0f)) {
+    /* Vert x Vert is already handled elsewhere. */
+    return false;
+  }
+
   if (lambda < 0.5f) {
     e_v = e->v1;
     dist_sq_vert_factor = lambda;
@@ -299,27 +296,19 @@ static bool bm_vertxedge_isect_impl_ex(BMVert *v,
   }
 
   if (v != e_v) {
-    CLAMP(lambda, 0.0f, 1.0f);
+    float dist_sq_vert = SQUARE(dist_sq_vert_factor) * len_squared_v3(dir);
+    if (dist_sq_vert < data_dist_sq) {
+      /* Vert x Vert is already handled elsewhere. */
+      return false;
+    }
 
     float near[3];
     madd_v3_v3v3fl(near, co, dir, lambda);
 
     float dist_sq = len_squared_v3v3(v->co, near);
     if (dist_sq < data_dist_sq) {
-      float dist_sq_vert = SQUARE(dist_sq_vert_factor) * len_squared_v3(dir);
-      if (dist_sq_vert < data_dist_sq) {
-        if (e_v->head.index != -1) {
-          /* Vertex already has an intersection. */
-          return false;
-        }
-
-        bm_vert_pair_elem_setup_ex(e_v, -2, &r_pair[1]);
-      }
-      else {
-        bm_edge_pair_elem_setup(e, lambda, data_cut_edges_len, &r_pair[1]);
-      }
-
-      bm_vert_pair_elem_setup_ex(v, edge_index, &r_pair[0]);
+      bm_edge_pair_elem_setup(e, lambda, data_cut_edges_len, &r_pair[0]);
+      bm_vert_pair_elem_setup_ex(v, &r_pair[1]);
       return true;
     }
   }
@@ -340,75 +329,48 @@ static bool bm_vertxvert_isect_cb(void *userdata, int index_a, int index_b, int
   BLI_assert(v_a->head.index == -1);
 
   /* Set index -2 for sure that it will not repeat keys in `targetmap`. */
-  bm_vert_pair_elem_setup_ex(v_a, -2, &pair[0]);
-  bm_vert_pair_elem_setup_ex(v_b, -1, &pair[1]);
+  bm_vert_pair_elem_setup_ex(v_a, &pair[0]);
+  bm_vert_pair_elem_setup_ex(v_b, &pair[1]);
 
   return true;
 }
 
+static bool bm_vertxvert_self_isect_cb(void *userdata, int index_a, int index_b, int thread)
+{
+  if (index_a < index_b) {
+    return bm_vertxvert_isect_cb(userdata, index_a, index_b, thread);
+  }
+  return false;
+}
+
 /* Vertex x Edge and Edge x Vertex Callbacks */
 
-static int bm_vertxedge_isect_impl(BMesh *bm,
-                                   int vert_index,
-                                   int edge_index,
-                                   float data_dist_sq,
-                                   int *data_cut_edges_len,
-                                   struct EDBMSplitElem r_pair[2])
+static bool bm_edgexvert_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
 {
-  BMVert *v = BM_vert_at_index(bm, vert_index);
-  BMEdge *e = BM_edge_at_index(bm, edge_index);
-
-  if (v->head.index != -1) {
-    /* Only one vertex per edge. */
-    return false;
-  }
+  struct EDBMSplitData *data = userdata;
+  BMEdge *e = BM_edge_at_index(data->bm, index_a);
+  BMVert *v = BM_vert_at_index(data->bm, index_b);
 
   float co[3], dir[3], lambda;
   copy_v3_v3(co, e->v1->co);
   sub_v3_v3v3(dir, e->v2->co, co);
   lambda = ray_point_factor_v3_ex(v->co, co, dir, 0.0f, -1.0f);
 
-  return bm_vertxedge_isect_impl_ex(
-      v, e, edge_index, co, dir, lambda, data_dist_sq, data_cut_edges_len, r_pair);
-}
-
-static bool bm_vertxedge_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
-{
-  struct EDBMSplitData *data = userdata;
   struct EDBMSplitElem pair_tmp[2];
-  if (bm_vertxedge_isect_impl(
-          data->bm, index_a, index_b, data->dist_sq, &data->cut_edges_b_len, pair_tmp)) {
+  if (bm_edgexvert_isect_impl(
+          v, e, co, dir, lambda, data->dist_sq, &data->cut_edges_len, pair_tmp)) {
     struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack);
     pair[0] = pair_tmp[0];
     pair[1] = pair_tmp[1];
-
-    return true;
-  }
-
-  return false;
-}
-
-static bool bm_edgexvert_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
-{
-  struct EDBMSplitData *data = userdata;
-  struct EDBMSplitElem pair_tmp[2];
-  if (bm_vertxedge_isect_impl(
-          data->bm, index_b, index_a, data->dist_sq, &data->cut_edges_a_len, pair_tmp)) {
-    struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack);
-    pair[0] = pair_tmp[1];
-    pair[1] = pair_tmp[0];
-
-    return true;
   }
 
+  /* Always return false with edges. */
   return false;
 }
 
 /* Edge x Edge Callbacks */
 
 static void bm_edgexedge_isect_impl(struct EDBMSplitData *data,
-                                    int index_a,
-                                    int index_b,
                                     BMEdge *e_a,
                                     BMEdge *e_b,
                                     const float co_a[3],
@@ -439,8 +401,18 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data,
   }
 
   if (e_a_v != e_b_v) {
-    CLAMP(lambda_a, 0.0f, 1.0f);
-    CLAMP(lambda_b, 0.0f, 1.0f);
+    if (!IN_RANGE_INCL(lambda_a, 0.0f, 1.0f) || !IN_RANGE_INCL(lambda_b, 0.0f, 1.0f)) {
+      /* Vert x Edge is already handled elsewhere. */
+      return;
+    }
+
+    float dist_sq_va = SQUARE(dist_sq_va_factor) * len_squared_v3(dir_a);
+    float dist_sq_vb = SQUARE(dist_sq_vb_factor) * len_squared_v3(dir_b);
+
+    if (dist_sq_va < data->dist_sq || dist_sq_vb < data->dist_sq) {
+      /* Vert x Edge is already handled elsewhere. */
+      return;
+    }
 
     float near_a[3], near_b[3];
     madd_v3_v3v3fl(near_a, co_a, dir_a, lambda_a);
@@ -450,32 +422,8 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data,
     if (dist_sq < data->dist_sq) {
       struct EDBMSplitElem pair_tmp[2];
 
-      float dist_sq_va = SQUARE(dist_sq_va_factor) * len_squared_v3(dir_a);
-      float dist_sq_vb = SQUARE(dist_sq_vb_factor) * len_squared_v3(dir_b);
-
-      if (dist_sq_va < data->dist_sq) {
-        if (e_a_v->head.index != -1) {
-          /* Only one vertex per edge. */
-          return;
-        }
-        bm_vert_pair_elem_setup_ex(e_a_v, index_b, &pair_tmp[0]);
-      }
-
-      if (dist_sq_vb < data->dist_sq) {
-        if (e_b_v->head.index != -1) {
-          /* Only one vertex per edge. */
-          return;
-        }
-        bm_vert_pair_elem_setup_ex(e_b_v, index_a, &pair_tmp[1]);
-      }
-      else {
-        bm_edge_pair_elem_setup(e_b, lambda_b, &data->cut_edges_b_len, &pair_tmp[1]);
-      }
-
-      /* Don't setup edges before a return. */
-      if (dist_sq_va >= data->dist_sq) {
-        bm_edge_pair_elem_setup(e_a, lambda_a, &data->cut_edges_a_len, &pair_tmp[0]);
-      }
+      bm_edge_pair_elem_setup(e_a, lambda_a, &data->cut_edges_len, &pair_tmp[0]);
+      bm_edge_pair_elem_setup(e_b, lambda_b, &data->cut_edges_len, &pair_tmp[1]);
 
       struct EDBMSplitElem *pair = BLI_stack_push_r(data->pair_stack);
       pair[0] = pair_tmp[0];
@@ -486,11 +434,15 @@ static void bm_edgexedge_isect_impl(struct EDBMSplitData *data,
 
 static bool bm_edgexedge_isect_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
 {
-  bool ret = false;
   struct EDBMSplitData *data = userdata;
   BMEdge *e_a = BM_edge_at_index(data->bm, index_a);
   BMEdge *e_b = BM_edge_at_index(data->bm, index_b);
 
+  if (BM_edge_share_vert_check(e_a, e_b)) {
+    /* The other vertices may intersect but Vert x Edge is already handled elsewhere. */
+    return false;
+  }
+
   float co_a[3], dir_a[3], co_b[3], dir_b[3];
   copy_v3_v3(co_a, e_a->v1->co);
   sub_v3_v3v3(dir_a, e_a->v2->co, co_a);
@@ -501,99 +453,19 @@ static bool bm_edgexedge_isect_cb(void *userdata, int index_a, int index_b, int
   float lambda_a, lambda_b;
   /* Using with dist^4 as `epsilon` is not the best solution, but it fits in most cases. */
   if (isect_ray_ray_epsilon_v3(co_a, dir_a, co_b, dir_b, data->dist_sq_sq, &lambda_a, &lambda_b)) {
-    if (ELEM(index_b, e_a->v1->head.index, e_a->v2->head.index) ||
-        ELEM(index_a, e_b->v1->head.index, e_b->v2->head.index)) {
-      return ret;
-    }
-
-    /* Edge x Edge returns always false. */
-    bm_edgexedge_isect_impl(
-        data, index_a, index_b, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b);
+    bm_edgexedge_isect_impl(data, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b);
   }
-  else {
-    /* Parallel */
-    struct EDBMSplitElem pair_tmp[2];
-    float vec[3], len_sq_a, len_sq_b, lambda;
-   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list