[Bf-blender-cvs] [0676928408a] temp_bmesh_multires: Sculpt dyntopo: more collapse fixes

Joseph Eagar noreply at git.blender.org
Mon Sep 13 11:31:58 CEST 2021


Commit: 0676928408af53d6ca76690b1a9772b303ccc39d
Author: Joseph Eagar
Date:   Mon Sep 13 02:31:33 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB0676928408af53d6ca76690b1a9772b303ccc39d

Sculpt dyntopo: more collapse fixes

The edge cases just never end.

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/mesh_remesh_voxel.cc
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
M	source/blender/bmesh/operators/bmo_dupe.c
M	source/blender/bmesh/operators/bmo_extrude.c
M	source/blender/bmesh/operators/bmo_fill_grid.c
M	source/blender/bmesh/operators/bmo_primitive.c
M	source/blender/bmesh/tools/bmesh_decimate_collapse.c
M	source/blender/editors/mesh/editmesh_polybuild.c

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

diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 9ef47f0908b..2585959bdae 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -3440,13 +3440,13 @@ static bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
   return false;
 }
 
-ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
-                                                 BMEdge *e,
-                                                 BMVert *v1,
-                                                 BMVert *v2,
-                                                 GHash *deleted_verts,
-                                                 BLI_Buffer *deleted_faces,
-                                                 EdgeQueueContext *eq_ctx)
+static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
+                                     BMEdge *e,
+                                     BMVert *v1,
+                                     BMVert *v2,
+                                     GHash *deleted_verts,
+                                     BLI_Buffer *deleted_faces,
+                                     EdgeQueueContext *eq_ctx)
 {
   BMVert *v_del, *v_conn;
 
@@ -3490,6 +3490,15 @@ ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     return;
   }
 
+  /*have to check edge flags directly, vertex flag test above isn't specific enough and
+    can sometimes let bad edges through*/
+  if ((mv1->flag & DYNVERT_SHARP_BOUNDARY) && (e->head.hflag & BM_ELEM_SMOOTH)) {
+    return;
+  }
+  if ((mv1->flag & DYNVERT_SEAM_BOUNDARY) && !(e->head.hflag & BM_ELEM_SEAM)) {
+    return;
+  }
+
   bool snap = !(mv2->flag & DYNVERT_ALL_CORNER);
 
 #if 0
@@ -3730,6 +3739,7 @@ ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   const int tag = BM_ELEM_TAG_ALT;
 
   // log edges around v_conn as removed
+#if 0
   BMEdge *e2 = v_conn->e;
   do {
     e2->head.hflag &= ~tag;
@@ -3738,28 +3748,35 @@ ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
       // BM_log_edge_removed(pbvh->bm_log, e2);
     }
   } while ((e2 = BM_DISK_EDGE_NEXT(e2, v_conn)) != v_conn->e);
+#endif
+  BMEdge *e2;
 
-  e2 = v_del->e;
-  // remove faces and log edges around v_del from pbvh
-  do {
-    BMLoop *l = e2->l;
+  for (int step = 0; step < 2; step++) {
+    BMVert *v_step = step ? v_del : v_conn;
 
-    e2->head.hflag |= tag;
+    e2 = v_step->e;
 
-    if (e2 != e) {
-      BM_log_edge_removed(pbvh->bm_log, e2);
-    }
+    // remove faces and log edges around v_del from pbvh
+    do {
+      BMLoop *l = e2->l;
 
-    if (!l) {
-      continue;  // edge will be killed later
-    }
+      e2->head.hflag |= tag;
 
-    do {
-      if (BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
-        pbvh_bmesh_face_remove(pbvh, l->f, true, false, false);
+      if (e2 != e) {
+        BM_log_edge_removed(pbvh->bm_log, e2);
+      }
+
+      if (!l) {
+        continue;  // edge will be killed later
       }
-    } while ((l = l->radial_next) != e2->l);
-  } while ((e2 = BM_DISK_EDGE_NEXT(e2, v_del)) != v_del->e);
+
+      do {
+        if (BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
+          pbvh_bmesh_face_remove(pbvh, l->f, true, false, false);
+        }
+      } while ((l = l->radial_next) != e2->l);
+    } while ((e2 = BM_DISK_EDGE_NEXT(e2, v_step)) != v_step->e);
+  }
 
   pbvh_bmesh_vert_remove(pbvh, v_del);
 
@@ -3772,11 +3789,11 @@ ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     float co[3];
 
     copy_v3_v3(co, v_conn->co);
-    BM_edge_collapse(pbvh->bm, e, v_del, true, true);
+    BM_edge_collapse(pbvh->bm, e, v_del, true, true, true);
     copy_v3_v3(v_conn->co, co);
   }
   else {
-    BM_edge_collapse(pbvh->bm, e, v_del, true, true);
+    BM_edge_collapse(pbvh->bm, e, v_del, true, true, true);
   }
 
   for (int i = 0; i < BLI_array_len(delvs); i++) {
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
index 91d22058e37..d9e7afc7aec 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
@@ -449,7 +449,7 @@ struct Mesh *BKE_mesh_remesh_voxel_fix_poles(const Mesh *mesh)
     if (BM_elem_flag_test(ed, BM_ELEM_TAG)) {
       float co[3];
       mid_v3_v3v3(co, ed->v1->co, ed->v2->co);
-      BMVert *vc = BM_edge_collapse(bm, ed, ed->v1, true, true);
+      BMVert *vc = BM_edge_collapse(bm, ed, ed->v1, true, true, false);
       copy_v3_v3(vc->co, co);
     }
   }
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index d6306be9a6e..5ca4f995369 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -2044,7 +2044,7 @@ BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
     if (check_edge_exists) {
       if (e_splice) {
         /* removes e_splice */
-        BM_edge_splice(bm, e_old, e_splice);
+        BM_edge_splice(bm, e_old, e_splice, false);
       }
     }
 
@@ -2096,7 +2096,8 @@ BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
                                          BMVert *v_kill,
                                          const bool do_del,
                                          const bool check_edge_exists,
-                                         const bool kill_degenerate_faces)
+                                         const bool kill_degenerate_faces,
+                                         const bool combine_flags)
 {
   BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
   BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
@@ -2153,7 +2154,7 @@ BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
 
       if (check_edge_exists) {
         if (e_target) {
-          BM_edge_splice(bm, e_target, e);
+          BM_edge_splice(bm, e_target, e, combine_flags);
         }
       }
     }
@@ -2573,7 +2574,8 @@ static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separ
       do {
         BMEdge *e = n_step->link;
         BLI_assert(e != e_orig);
-        if ((e->v1 == e_orig->v1) && (e->v2 == e_orig->v2) && BM_edge_splice(bm, e_orig, e)) {
+        if ((e->v1 == e_orig->v1) && (e->v2 == e_orig->v2) &&
+            BM_edge_splice(bm, e_orig, e, false)) {
           /* don't visit again */
           n_prev->next = n_step->next;
         }
@@ -2700,7 +2702,7 @@ void BM_vert_separate_tested_edges(BMesh *UNUSED(bm),
  *
  * \note Edges must already have the same vertices.
  */
-bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
+bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src, bool combine_flags)
 {
   BMLoop *l;
 
@@ -2727,6 +2729,18 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
   BM_CHECK_ELEMENT(e_src);
   BM_CHECK_ELEMENT(e_dst);
 
+  if (combine_flags) {
+    /* sharp flag is inverted to BM_ELEM_SMOOTH,  which we
+       must take into account*/
+
+    if (!(e_dst->head.hflag & BM_ELEM_SMOOTH) || !(e_src->head.hflag & BM_ELEM_SMOOTH)) {
+      e_dst->head.hflag = (e_dst->head.hflag | e_src->head.hflag) & ~BM_ELEM_SMOOTH;
+    }
+    else {
+      e_dst->head.hflag |= e_src->head.hflag;
+    }
+  }
+
   /* removes from disks too */
   BM_edge_kill(bm, e_src);
 
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index c58f1921e3d..97cf2564268 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -62,7 +62,7 @@ void BM_face_kill(BMesh *bm, BMFace *f);
 void BM_edge_kill(BMesh *bm, BMEdge *e);
 void BM_vert_kill(BMesh *bm, BMVert *v);
 
-bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
+bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src, bool combine_flags);
 bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src);
 bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b);
 
@@ -123,7 +123,8 @@ BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
                                          BMVert *v_kill,
                                          const bool do_del,
                                          const bool check_edge_exists,
-                                         const bool kill_degenerate_faces);
+                                         const bool kill_degenerate_faces,
+                                         const bool combine_flags);
 BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
 
 BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 5fa12397a07..66dae665dff 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -563,10 +563,15 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm,
 /**
  * Collapse and edge into a single vertex.
  */
-BMVert *BM_edge_collapse(
-    BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
+BMVert *BM_edge_collapse(BMesh *bm,
+                         BMEdge *e_kill,
+                         BMVert *v_kill,
+                         const bool do_del,
+                         const bool kill_degenerate_faces,
+                         const bool combine_flags)
 {
-  return bmesh_kernel_join_vert_kill_edge(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
+  return bmesh_kernel_join_vert_kill_edge(
+      bm, e_kill, v_kill, do_del, true, kill_degenerate_faces, combine_flags);
 }
 
 /**
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 4328187b95e..48260b503c5 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -64,7 +64,8 @@ BMVert *BM_edge_collapse(BMesh *bm,
                          BMEdge *e_kill,
                          BMVert *v_kill,
                          const bool do_del,
-                         const bool kill_degenerate_faces);
+                         const bool kill_degenerate_faces,
+                         const bool combine_flags);
 
 BMVert

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list