[Bf-blender-cvs] [73eb2b426a4] sculpt-dev: Sculpt: fix collapse for non-manifold edges

Joseph Eagar noreply at git.blender.org
Tue Oct 12 09:36:06 CEST 2021


Commit: 73eb2b426a4e91324636f70f5bf38d4c134eabb6
Author: Joseph Eagar
Date:   Tue Oct 12 00:34:17 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB73eb2b426a4e91324636f70f5bf38d4c134eabb6

Sculpt: fix collapse for non-manifold edges

* BM_edge_collapse now has an option to use
  a new collapse implementation that can
  handle non-manifold geometry properly.
* The aforementioned implementation is a replacement
  for bmesh_kernel_join_vert_kill_edge.  Note that
  the old code still exists as
  bmesh_kernel_join_vert_kill_edge_fast and is used
  by default.

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

M	source/blender/blenkernel/intern/brush_engine.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/mesh_remesh_voxel.cc
M	source/blender/blenkernel/intern/pbvh_bmesh.c
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/intern/bmesh_private.h
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/editors/mesh/editmesh_polybuild.c
M	source/blender/editors/sculpt_paint/sculpt_smooth.c

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

diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index f2fa8ea47ec..5c47e21f0ce 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -1450,12 +1450,12 @@ void BKE_brush_commandset_inherit_all_mappings(BrushChannelSet *chset)
   }
 }
 
-ATTR_NO_OPT static void commandlist_add_dyntopo(BrushChannelSet *chset,
-                                                BrushCommandList *cl,
-                                                Brush *brush,
-                                                int tool,
-                                                bool hard_edge_mode,
-                                                float radius_base)
+static void commandlist_add_dyntopo(BrushChannelSet *chset,
+                                    BrushCommandList *cl,
+                                    Brush *brush,
+                                    int tool,
+                                    bool hard_edge_mode,
+                                    float radius_base)
 {
 
   if (!BKE_brush_channelset_get_int(chset, "dyntopo_disabled", NULL)) {
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 7a789285f05..ce045408e28 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -670,8 +670,6 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
   atomic_cas_float(&mv1->origco[1], y, ny);
   atomic_cas_float(&mv1->origco[2], z, nz);
 
-  volatile int stroke_id = mv1->stroke_id;
-
   // atomic_cas_int32(&mv1->stroke_id, stroke_id, pbvh->stroke_id);
 }
 
@@ -1265,9 +1263,9 @@ void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, BMFace *f, bool log_face)
   pbvh_bmesh_face_remove(pbvh, f, log_face, true, true);
 }
 
-void BKE_pbvh_bmesh_remove_edge(PBVH *pbvh, BMEdge *e, bool log_vert)
+void BKE_pbvh_bmesh_remove_edge(PBVH *pbvh, BMEdge *e, bool log_edge)
 {
-  if (log_vert) {
+  if (log_edge) {
     BM_log_edge_removed(pbvh->bm_log, e);
   }
 }
@@ -1423,7 +1421,7 @@ static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
   eq_ctx->val34_verts[eq_ctx->val34_verts_tot - 1] = v;
 }
 
-ATTR_NO_OPT static float maskcb_get(EdgeQueueContext *eq_ctx, BMEdge *e)
+static float maskcb_get(EdgeQueueContext *eq_ctx, BMEdge *e)
 {
   float ret = 0.0f;
 
@@ -1443,7 +1441,7 @@ ATTR_NO_OPT static float maskcb_get(EdgeQueueContext *eq_ctx, BMEdge *e)
   return ret;
 }
 
-ATTR_NO_OPT static float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
+static float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
 {
 #ifdef FANCY_EDGE_WEIGHTS
   float l = len_squared_v3v3(v1->co, v2->co);
@@ -2099,7 +2097,7 @@ BLI_INLINE int dyntopo_thread_rand(int seed)
   // glibc
   const uint32_t multiplier = 1103515245;
   const uint32_t addend = 12345;
-  const uint32_t mask = (1 << 31) - 1;
+  const uint32_t mask = (1 << 30) - 1;
 
   return (seed * multiplier + addend) & mask;
 }
@@ -2119,7 +2117,6 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
 
   BMFace *f, **faces = NULL;
   BLI_array_declare(faces);
-  const int cd_sculpt_vert = tdata->pbvh->cd_sculpt_vert;
   bool do_smooth = eq_ctx->surface_smooth_fac > 0.0f;
 
   BKE_pbvh_bmesh_check_tris(tdata->pbvh, node);
@@ -2334,8 +2331,6 @@ static void short_edge_queue_task_cb_local(void *__restrict userdata,
 
 static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
 {
-  bool origlen = f->len;
-
   if (f->len == 3) {
     return true;
   }
@@ -2456,6 +2451,8 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
 
 static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
 {
+  // return false;
+
   static int max_faces = 64;
   BMFace **stack = NULL;
   BLI_array_staticdeclare(stack, 32);
@@ -2639,6 +2636,10 @@ static bool check_for_fins(PBVH *pbvh, BMVert *v)
   }
 
   do {
+    if (!e) {
+      printf("%s: e was NULL\n", __func__);
+      break;
+    }
     if (e->l) {
       BMLoop *l = e->l->f->l_first;
 
@@ -3046,10 +3047,6 @@ static void edge_queue_create_local(EdgeQueueContext *eq_ctx,
   pbvh->bm->elem_index_dirty |= BM_EDGE;
   float sign = is_collapse ? 1.0f : -1.0f;
 
-  const float detail_range = pbvh->bm_min_edge_len == 0.0f ?
-                                 0.0f :
-                                 pbvh->bm_max_edge_len / pbvh->bm_min_edge_len;
-
   for (int i = 0; i < BLI_array_len(edges); i++) {
     BMEdge *e = edges[i];
     MSculptVert *mv1, *mv2;
@@ -3279,7 +3276,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
   MV_ADD_FLAG(mv1, SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_BOUNDARY | SCULPTVERT_NEED_DISK_SORT);
   MV_ADD_FLAG(mv2, SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_BOUNDARY | SCULPTVERT_NEED_DISK_SORT);
 
-  bool boundary = (mv1->flag & SCULPTVERT_ALL_BOUNDARY) && (mv2->flag & SCULPTVERT_ALL_BOUNDARY);
+  // bool boundary = (mv1->flag & SCULPTVERT_ALL_BOUNDARY) && (mv2->flag &
+  // SCULPTVERT_ALL_BOUNDARY);
 
   /* Get all faces adjacent to the edge */
   pbvh_bmesh_edge_loops(edge_loops, e);
@@ -3738,10 +3736,6 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     return;
   }
 
-  if (bm_edge_collapse_is_degenerate_topology(e)) {
-    // return;
-  }
-
   pbvh_check_vert_boundary(pbvh, v1);
   pbvh_check_vert_boundary(pbvh, v2);
 
@@ -3800,127 +3794,9 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
   bool snap = !(mv2->flag & SCULPTVERT_ALL_CORNER);
 
-#if 0
-  // don't allow non-manifold case of
-  // there being 3-valence verts
-  // in neighborhood around edge
-  bool bad = false;
-  for (int i = 0; i < 2; i++) {
-    BMVert *v = i ? v_conn : v_del;
-
-    BMEdge *e2 = v->e;
-
-    do {
-      BMVert *v2 = v == e2->v1 ? e2->v2 : e2->v1;
-
-      int val = BM_vert_edge_count(v);
-      if (val < 4) {
-        bad = true;
-        break;
-      }
-    } while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
-
-    if (bad) {
-      break;
-    }
-  }
-
-  if (bad) {
-    return;  // bad edge
-  }
-#endif
-
-#if 0
-  // remove all faces from pbvh
-  for (int i = 0; i < 2; i++) {
-    BMVert *v = i ? v_conn : v_del;
-
-    BMEdge *e = v->e;
-    do {
-      BMLoop *l = e->l;
-
-      if (!l) {
-        continue;
-      }
-
-      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) != e->l);
-    } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
-  }
-
-  // repeatedly dissolve 3-valence verts
-  while (1) {
-    bool bad = false;
-
-    for (int i = 0; i < 2; i++) {
-      BMVert *v = i ? v_conn : v_del;
-
-      BMEdge *e2 = v->e;
-
-      if (!e2) {
-        continue;
-      }
-      BMEdge *enext;
-
-      do {
-        BMVert *v2 = BM_edge_other_vert(e2, v);
-        enext = BM_DISK_EDGE_NEXT(e2, v);
-
-        if (v2 == v_conn || v2 == v_del) {
-          continue;
-        }
-
-        if (BM_vert_edge_count(v2) < 4) {
-          BMEdge *e3 = v2->e;
-
-          do {
-            BMLoop *l = e3->l;
-            if (e3 == e) {
-              e = NULL;
-            }
-
-            if (!l) {
-              continue;
-            }
-
-            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) != e3->l);
-
-            BM_log_edge_removed(pbvh->bm_log, e3);
-          } while ((e3 = BM_DISK_EDGE_NEXT(e3, v2)) != v2->e);
-
-          pbvh_bmesh_vert_remove(pbvh, v2);
-          BM_log_vert_removed(pbvh->bm_log, v2, pbvh->cd_vert_mask_offset);
-
-          BLI_ghash_insert(deleted_verts, v, NULL);
-
-          BM_vert_dissolve(pbvh->bm, v);
-          bad = true;
-          break;
-        }
-      } while ((e2 = enext) != v->e);
-    }
-
-    if (!bad) {
-      break;
-    }
-  }
-
-  if (!e || bm_elem_is_free((BMElem *)v_conn, BM_VERT) ||
-      bm_elem_is_free((BMElem *)v_del, BM_VERT)) {
-    return;
-  }
-#endif
-
   BMLoop *l;
 
-  // snap customdata
+  /* snap customdata */
   if (snap) {
     int ni_conn = BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset);
 
@@ -3933,9 +3809,6 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
   // deal with UVs
   if (e->l) {
-    const int lflag = BM_ELEM_TAG_ALT;
-
-    int totl = 0;
     BMLoop *l = e->l;
 
     for (int step = 0; step < 2; step++) {
@@ -3954,7 +3827,6 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
         }
 
         do {
-          bool ok = true;
           BMLoop *l3 = l2->v != v ? l2->next : l2;
 
           /* store visit bits for each uv layer in l3->head.index */
@@ -3963,8 +3835,6 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
       } while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
     }
 
-    float(*uv)[2] = alloca(sizeof(float) * 4 * totuv);
-
     do {
       const void *ls2[2] = {l->head.data, l->next->head.data};
       float ws2[2] = {0.5f, 0.5f};
@@ -4127,7 +3997,10 @@ 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, true);
+
+    // full non-manifold collapse
+    BM_edge_collapse(pbvh->bm, e, v_del, true, true, true, true);
+    // non_manifold_collapse(pbvh->bm, e, v_conn);
     copy_v3_v3(v_conn->co, co);
   }
   else {
@@ -4136,7 +4009,9 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     add_v3_v3v3(co, v_del->co, v_conn->co);
     mul_v3_fl(co, 0.5f);
 
-    BM_edge_collapse(pbvh->bm, e, v_del, true, true, true);
+    // full non-manifold collapse
+    BM_edge_collapse(pbvh->bm, e, v_del, true, true, true, true);
+    // non_manifold_collapse(pbvh->bm, e, v_conn);
     copy_v3_v3(v_conn->co, co);
   }
 
@@ -4344,12 +4219,8 @@ static void pbvh_bmesh_collapse_edge1(PBVH *pbvh,
   while ((l_adj = e->l)) {
     BMFace *f_adj = l_adj->f;
 
-    int eflag = 0;
-
     BMLoop *l = f_adj->l_first;
     do {
-      BMEdge *e2 = l->e;
-
       MSculptVert *mv_l = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l->v);
     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list