[Bf-blender-cvs] [013eee7ec62] temp_bmesh_multires: * The dyntopo remesher is now a bit smarter about avoiding certain degenerate cases that produce lots of bad geometry (and also bad PBVHs that slows down the whole mesh). + A very small amount of surface smoothing is now applied by dyntopo. + The recursive functions that expand the region considered by dyntopo now ignore "front face only" for depths less then 5. + The number of edges dyntopo can split or collapse in one run has been cut in half to 4k. - This limit is also now dynamically adjusted by a measure of how skinny the edges are.

Joseph Eagar noreply at git.blender.org
Thu Apr 29 04:19:15 CEST 2021


Commit: 013eee7ec62ebb39f28f0f949e1e0ccd8e5d07ef
Author: Joseph Eagar
Date:   Wed Apr 28 19:11:23 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB013eee7ec62ebb39f28f0f949e1e0ccd8e5d07ef

* The dyntopo remesher is now a bit smarter about avoiding
  certain degenerate cases that produce lots of bad geometry (and
  also bad PBVHs that slows down the whole mesh).
 + A very small amount of surface smoothing is now applied by dyntopo.
 + The recursive functions that expand the region considered by dyntopo
   now ignore "front face only" for depths less then 5.
 + The number of edges dyntopo can split or collapse in one run has been cut in
   half to 4k.
   - This limit is also now dynamically adjusted by a measure
     of how skinny the edges are.

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

M	source/blender/blenkernel/intern/pbvh_bmesh.c

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

diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index a6052390d7b..69e982f83fe 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -50,6 +50,7 @@ Topology rake:
 #include "BLI_task.h"
 #include "BLI_utildefines.h"
 #include "PIL_time.h"
+#include "atomic_ops.h"
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_ccg.h"
@@ -60,7 +61,7 @@ Topology rake:
 #include "bmesh.h"
 #include "pbvh_intern.h"
 
-#define DYNTOPO_MAX_ITER 8192
+#define DYNTOPO_MAX_ITER 4096
 
 #define DYNTOPO_USE_HEAP
 
@@ -72,6 +73,24 @@ Topology rake:
 /* Avoid skinny faces */
 #define USE_EDGEQUEUE_EVEN_SUBDIV
 
+
+/* How much longer we need to be to consider for subdividing
+ * (avoids subdividing faces which are only *slightly* skinny) */
+#define EVEN_EDGELEN_THRESHOLD 1.2f
+/* How much the limit increases per recursion
+ * (avoids performing subdivisions too far away). */
+#define EVEN_GENERATION_SCALE 1.1f
+
+//recursion depth to start applying front face test
+#define DEPTH_START_LIMIT 5
+
+//#define FANCY_EDGE_WEIGHTS
+#define SKINNY_EDGE_FIX
+
+//slightly relax geometry by this factor along surface tangents
+//to improve convergence of remesher
+#define DYNTOPO_SAFE_SMOOTH_FAC 0.05f
+
 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
 #  include "BKE_global.h"
 #endif
@@ -174,6 +193,46 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
   } \
   ((void)0)
 
+ATTR_NO_OPT void surface_smooth_v_safe(BMVert *v)
+{
+  float co[3];
+  float tan[3];
+  float tot = 0.0;
+
+  zero_v3(co);
+
+  // this is a manual edge walk
+
+  BMEdge *e = v->e;
+  if (!e) {
+    return;
+  }
+
+  do {
+    BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
+
+    sub_v3_v3v3(tan, v2->co, v->co);
+    float d = dot_v3v3(tan, v->no);
+
+    madd_v3_v3fl(tan, v->no, -d * 0.99f);
+    add_v3_v3(co, tan);
+    tot += 1.0f;
+    e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
+  } while (e != v->e);
+
+  if (tot == 0.0f) {
+    return;
+  }
+
+  mul_v3_fl(co, 1.0f / tot);
+  float x = v->co[0], y = v->co[1], z = v->co[2];
+
+  //conflicts here should be pretty rare.
+  atomic_cas_float(&v->co[0], x, x + co[0] * DYNTOPO_SAFE_SMOOTH_FAC);
+  atomic_cas_float(&v->co[1], y, y + co[1] * DYNTOPO_SAFE_SMOOTH_FAC);
+  atomic_cas_float(&v->co[2], z, z + co[2] * DYNTOPO_SAFE_SMOOTH_FAC);
+}
+
 static void bm_edges_from_tri(BMesh *bm, BMVert *v_tri[3], BMEdge *e_tri[3])
 {
   e_tri[0] = BM_edge_create(bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
@@ -610,12 +669,13 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
   if (v_example) {
     v->head.hflag = v_example->head.hflag;
 
-    CustomData_bmesh_copy_data(&pbvh->bm->vdata, &pbvh->bm->vdata, v_example->head.data, &v->head.data);
+    CustomData_bmesh_copy_data(
+        &pbvh->bm->vdata, &pbvh->bm->vdata, v_example->head.data, &v->head.data);
 
     /* This value is logged below */
     copy_v3_v3(v->no, no);
 
-    //keep MDynTopoVert copied from v_example as-is
+    // keep MDynTopoVert copied from v_example as-is
   }
   else {
     MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
@@ -958,7 +1018,11 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
   int f_node_index_prev = DYNTOPO_NODE_NONE;
 
   PBVHNode *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
-  BLI_table_gset_remove(v_node->bm_unique_verts, v, NULL);
+
+  if (v_node) {
+    BLI_table_gset_remove(v_node->bm_unique_verts, v, NULL);
+  }
+
   BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
 
   /* Have to check each neighboring face's node */
@@ -1090,19 +1154,23 @@ typedef struct {
   int cd_vert_mask_offset;
   int cd_vert_node_offset;
   int cd_face_node_offset;
+  float avg_elen;
+  float max_elen;
+  float min_elen;
+  float totedge;
 } EdgeQueueContext;
 
 BLI_INLINE float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
 {
-#if 0
+#ifdef FANCY_EDGE_WEIGHTS
   float l = len_squared_v3v3(v1->co, v2->co);
-  float n;
-
-  n = (float)(BM_vert_edge_count(v1) + BM_vert_edge_count(v2)) * 0.5f;
-  n = MAX2(n - 6.0f, 1.0f);
+  float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+  val = MAX2(val * 0.5 - 6.0f, 1.0f);
+  val = powf(val, 0.5);
+  l *= val;
 
-  return l * (n);
-#elif 1  // penalize 4-valence verts
+  return l;
+#elif 0  // penalize 4-valence verts
   float l = len_squared_v3v3(v1->co, v2->co);
   if (BM_vert_edge_count(v1) == 4 || BM_vert_edge_count(v2) == 4) {
     l *= 0.25f;
@@ -1116,16 +1184,13 @@ BLI_INLINE float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1,
 
 BLI_INLINE float calc_weighted_edge_collapse(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
 {
-#if 0
+#ifdef FANCY_EDGE_WEIGHTS
   float l = len_squared_v3v3(v1->co, v2->co);
-  float n;
-
-  n = (float)(BM_vert_edge_count(v1) + BM_vert_edge_count(v2)) * 0.5f;
-  n = MAX2(n - 5.0f, 1.0f);
+  float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+  val = MAX2(val*0.5 - 6.0f, 1.0f);
+  val = powf(val, 0.5);
+  l /= val;
 
-  return l * (n*n*4.0f);
-#elif 1  // penalize 4-valence verts
-  float l = len_squared_v3v3(v1->co, v2->co);
   // if (BM_vert_edge_count(v1) == 4 || BM_vert_edge_count(v2) == 4) {
   //  l *= 0.25f;
   //}
@@ -1620,6 +1685,13 @@ static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, float priorit
        (check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2))) &&
       !(BM_elem_flag_test_bool(e->v1, BM_ELEM_HIDDEN) ||
         BM_elem_flag_test_bool(e->v2, BM_ELEM_HIDDEN))) {
+
+    float dis = len_v3v3(e->v1->co, e->v2->co);
+    eq_ctx->avg_elen += dis;
+    eq_ctx->max_elen = MAX2(eq_ctx->max_elen, dis);
+    eq_ctx->min_elen = MIN2(eq_ctx->min_elen, dis);
+    eq_ctx->totedge += 1.0f;
+
     BMVert **pair = BLI_mempool_alloc(eq_ctx->pool);
     pair[0] = e->v1;
     pair[1] = e->v2;
@@ -1653,12 +1725,12 @@ static void long_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
 
 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
 static void long_edge_queue_edge_add_recursive(
-    EdgeQueueContext *eq_ctx, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len)
+    EdgeQueueContext *eq_ctx, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len, int depth)
 {
   BLI_assert(len_sq > square_f(limit_len));
 
 #  ifdef USE_EDGEQUEUE_FRONTFACE
-  if (eq_ctx->q->use_view_normal) {
+  if (depth > DEPTH_START_LIMIT && eq_ctx->q->use_view_normal) {
     if (dot_v3v3(l_edge->f->no, eq_ctx->q->view_normal) < 0.0f) {
       return;
     }
@@ -1678,13 +1750,6 @@ static void long_edge_queue_edge_add_recursive(
   }
 
   if ((l_edge->radial_next != l_edge)) {
-    /* How much longer we need to be to consider for subdividing
-     * (avoids subdividing faces which are only *slightly* skinny) */
-#  define EVEN_EDGELEN_THRESHOLD 1.2f
-    /* How much the limit increases per recursion
-     * (avoids performing subdivisions too far away). */
-#  define EVEN_GENERATION_SCALE 1.6f
-
     const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
 
     limit_len *= EVEN_GENERATION_SCALE;
@@ -1698,13 +1763,10 @@ static void long_edge_queue_edge_add_recursive(
         if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
           //                  edge_queue_insert(eq_ctx, l_adjacent[i]->e, -len_sq_other);
           long_edge_queue_edge_add_recursive(
-              eq_ctx, l_adjacent[i]->radial_next, l_adjacent[i], len_sq_other, limit_len);
+              eq_ctx, l_adjacent[i]->radial_next, l_adjacent[i], len_sq_other, limit_len, depth+1);
         }
       }
     } while ((l_iter = l_iter->radial_next) != l_end);
-
-#  undef EVEN_EDGELEN_THRESHOLD
-#  undef EVEN_GENERATION_SCALE
   }
 }
 #endif /* USE_EDGEQUEUE_EVEN_SUBDIV */
@@ -1722,10 +1784,10 @@ static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
   }
 }
 
-static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
+static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f, bool ignore_frontface)
 {
 #ifdef USE_EDGEQUEUE_FRONTFACE
-  if (eq_ctx->q->use_view_normal) {
+  if (!ignore_frontface && eq_ctx->q->use_view_normal) {
     if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) {
       return;
     }
@@ -1741,7 +1803,7 @@ static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
       const float len_sq = BM_edge_calc_length_squared(l_iter->e);
       if (len_sq > eq_ctx->q->limit_len_squared) {
         long_edge_queue_edge_add_recursive(
-            eq_ctx, l_iter->radial_next, l_iter, len_sq, eq_ctx->q->limit_len);
+            eq_ctx, l_iter->radial_next, l_iter, len_sq, eq_ctx->q->limit_len, DEPTH_START_LIMIT+1);//ignore_frontface ? 0 : DEPTH_START_LIMIT+1);
       }
 #else
       long_edge_queue_edge_add(eq_ctx, l_iter->e);
@@ -1772,8 +1834,13 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
   }
 }
 
-static void long_edge_queue_edge_add_recursive_2(
-    EdgeQueueThreadData *tdata, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len)
+
+static void short_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
+                                                 BMLoop *l_edge,
+                                                 BMLoop *l_end,
+                                                 const float len_sq,
+                                                 float limit_len,
+                                                 int depth)
 {
   BLI_assert(len_sq > square_f(limit_len));
 
@@ -1782,7 +1849,7 @@ static void long_edge_queue_edge_add_recursive_2(
   }
 
 #ifdef USE_EDGEQUEUE_FRONTFACE
-  if (tdata->eq_ctx->q->use_view_normal) {
+  if (depth > DEPTH_START_LIMIT && tdata->eq_ctx->q->use_view_normal) {
     if (dot_v3v3(l_edge->f->no, tdata->eq_ctx->q->view_normal) < 0.0f) {
       return;
     }
@@ -1797,13 +1864,58 @@ static void long_edge_queue_edge_add_recursive_2(
   }
 
   if ((l_edge->radial_next != l_edge)) {
-    /* How much longer we need to be to consider for subdividing
-     * (avoids subdividing faces which are only *slightly* skinny) */
-#define EVEN_EDGELEN_THRESHOLD 1.2f
-    /* How much the limit increases per recursion
-     * (avoids performing

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list