[Bf-blender-cvs] [8bfbbc467a3] temp_bmesh_multires: Sculpt dyntopo

Joseph Eagar noreply at git.blender.org
Wed Sep 1 20:49:13 CEST 2021


Commit: 8bfbbc467a3b6cb958c21ef68ae408705748ee3b
Author: Joseph Eagar
Date:   Wed Sep 1 11:47:03 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB8bfbbc467a3b6cb958c21ef68ae408705748ee3b

Sculpt dyntopo

* Wrote a simple fix for drawing face sets
  in inverse (ctrl) mode with face set automasking
  on.

* Various fixes related to hard edges and smoothing.

* Started writing some code to defragment bmesh mempools.
  Need to figure out how to avoid triggering excessive
  PBVH node rebuilds.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenlib/BLI_mempool.h
M	source/blender/blenlib/intern/BLI_mempool.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_smooth.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 76adab9168b..afed28d8120 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -33,6 +33,9 @@
 extern "C" {
 #endif
 
+// experimental feature to detect quad diagonals and mark (but not dissolve) them
+//#define SCULPT_DIAGONAL_EDGE_MARKS
+
 typedef struct SculptVertRef {
   intptr_t i;
 } SculptVertRef;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index b0870e0558e..956b69d608f 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1789,6 +1789,8 @@ void BKE_brush_sculpt_reset(Brush *br)
       break;
     case SCULPT_TOOL_SMOOTH:
       br->flag &= ~BRUSH_SPACE_ATTEN;
+      br->flag2 |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT;
+
       br->spacing = 5;
       br->alpha = 0.7f;
       br->surface_smooth_shape_preservation = 0.5f;
@@ -1801,9 +1803,10 @@ void BKE_brush_sculpt_reset(Brush *br)
       br->alpha = 1.0f;
       br->rake_factor = 1.0f;
       br->dyntopo.inherit = DYNTOPO_INHERIT_BITMASK &
-                            ~(DYNTOPO_INHERIT_ALL | DYNTOPO_LOCAL_COLLAPSE | DYNTOPO_INHERIT_DETAIL_RANGE);
+                            ~(DYNTOPO_INHERIT_ALL | DYNTOPO_LOCAL_COLLAPSE |
+                              DYNTOPO_INHERIT_DETAIL_RANGE);
       br->dyntopo.flag |= DYNTOPO_LOCAL_COLLAPSE;
-      br->dyntopo.detail_range = 0.5f;
+      br->dyntopo.detail_range = 0.4f;
       break;
     case SCULPT_TOOL_THUMB:
       br->size = 75;
@@ -1980,13 +1983,14 @@ void BKE_brush_sculpt_reset(Brush *br)
       // don't use DYNTOPO_INHERIT_BITMASK, we want to include
       // future bits
 
-      br->flag |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT |
-                  BRUSH_CURVATURE_RAKE;
+      br->flag2 |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT |
+                   BRUSH_CURVATURE_RAKE;
       br->dyntopo.inherit = 0x7FFFFFFF &
                             ~(DYNTOPO_INHERIT_ALL | DYNTOPO_SUBDIVIDE | DYNTOPO_COLLAPSE);
       br->dyntopo.flag |= DYNTOPO_COLLAPSE | DYNTOPO_SUBDIVIDE;
       br->autosmooth_factor = 0.05;
       br->topology_rake_factor = 0.35;
+      br->topology_rake_projection = 0.975;
 
       break;
     case SCULPT_TOOL_VCOL_BOUNDARY:
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 766a1b95b21..d2324788561 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -61,16 +61,18 @@
  * (avoids performing subdivisions too far away). */
 #define EVEN_GENERATION_SCALE 1.1f
 
-// recursion depth to start applying front face test
+/* recursion depth to start applying front face test */
 #define DEPTH_START_LIMIT 5
 
-//#define FANCY_EDGE_WEIGHTS
-#define SKINNY_EDGE_FIX
+//#define FANCY_EDGE_WEIGHTS <= too slow
+//#define SKINNY_EDGE_FIX
 
-// slightly relax geometry by this factor along surface tangents
-// to improve convergence of remesher
+/* slightly relax geometry by this factor along surface tangents
+   to improve convergence of remesher */
 #define DYNTOPO_SAFE_SMOOTH_FAC 0.05f
 
+#define DYNTOPO_SAFE_SMOOTH_SUBD_ONLY_FAC 0.75f
+
 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
 #  include "BKE_global.h"
 #endif
@@ -157,8 +159,12 @@ struct EdgeQueueContext;
 
 static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
 static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
-static void pbvh_split_edges(
-    PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges);
+static void pbvh_split_edges(struct EdgeQueueContext *eq_ctx,
+                             PBVH *pbvh,
+                             BMesh *bm,
+                             BMEdge **edges,
+                             int totedge,
+                             bool ignore_isolated_edges);
 void bm_log_message(const char *fmt, ...);
 void pbvh_bmesh_check_nodes_simple(PBVH *pbvh);
 static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
@@ -458,7 +464,7 @@ static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge
   return e;
 }
 
-BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
+BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
 {
   float co[3];
   float tan[3];
@@ -516,9 +522,9 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
   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);
+  atomic_cas_float(&v->co[0], x, x + co[0] * fac);
+  atomic_cas_float(&v->co[1], y, y + co[1] * fac);
+  atomic_cas_float(&v->co[2], z, z + co[2] * fac);
 }
 
 static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
@@ -1229,6 +1235,7 @@ typedef struct EdgeQueueContext {
   int val34_verts_tot;
   int val34_verts_size;
   bool local_mode;
+  float surface_smooth_fac;
 } EdgeQueueContext;
 
 static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
@@ -1279,9 +1286,15 @@ BLI_INLINE float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1,
 {
 #ifdef FANCY_EDGE_WEIGHTS
   float l = len_squared_v3v3(v1->co, v2->co);
-  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);
+  // float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+  MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v1);
+  MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v2);
+  float val = (float)(mv1->valence + mv2->valence) * 0.5f;
+
+  val -= 6.0f;
+  val = MAX2(val, 1.0f);
+
+  // val = powf(val, 0.5);
   l *= val;
 
   return l;
@@ -1301,14 +1314,16 @@ BLI_INLINE float calc_weighted_edge_collapse(EdgeQueueContext *eq_ctx, BMVert *v
 {
 #ifdef FANCY_EDGE_WEIGHTS
   float l = len_squared_v3v3(v1->co, v2->co);
-  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;
+  // float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+  MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v1);
+  MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v2);
+  float val = (float)(mv1->valence + mv2->valence) * 0.5f;
+
+  val -= 6.0f;
+  val = MAX2(val, 1.0f);
 
-  // if (BM_vert_edge_count(v1) == 4 || BM_vert_edge_count(v2) == 4) {
-  //  l *= 0.25f;
-  //}
+  // val = powf(val, 0.5);
+  l *= val;
 
   return l;
 #else
@@ -1548,11 +1563,6 @@ static void long_edge_queue_edge_add_recursive(EdgeQueueContext *eq_ctx,
     edge_queue_insert(eq_ctx, l_edge->e, -len_sq, eq_ctx->q->limit_len);
   }
 
-  /* temp support previous behavior! */
-  if (UNLIKELY(G.debug_value == 1234)) {
-    return;
-  }
-
   if ((l_edge->radial_next != l_edge)) {
     const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
 
@@ -1678,11 +1688,6 @@ static void short_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
 
   edge_thread_data_insert(tdata, l_edge->e);
 
-  /* temp support previous behavior! */
-  if (UNLIKELY(G.debug_value == 1234)) {
-    return;
-  }
-
   if ((l_edge->radial_next != l_edge)) {
     const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
 
@@ -1716,7 +1721,8 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
                                                  BMLoop *l_end,
                                                  const float len_sq,
                                                  float limit_len,
-                                                 int depth)
+                                                 int depth,
+                                                 bool insert)
 {
   BLI_assert(len_sq > square_f(limit_len));
 
@@ -1732,11 +1738,8 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
   }
 #endif
 
-  edge_thread_data_insert(tdata, l_edge->e);
-
-  /* temp support previous behavior! */
-  if (UNLIKELY(G.debug_value == 1234)) {
-    return;
+  if (insert) {
+    edge_thread_data_insert(tdata, l_edge->e);
   }
 
   if ((l_edge->radial_next != l_edge)) {
@@ -1758,14 +1761,24 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
 
         len_sq_other *= w * w;
 
-        if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
-          long_edge_queue_edge_add_recursive_2(tdata,
-                                               l_adjacent[i]->radial_next,
-                                               l_adjacent[i],
-                                               len_sq_other,
-                                               limit_len,
-                                               depth + 1);
+        bool insert_ok = len_sq_other > max_ff(len_sq_cmp, limit_len_sq);
+#ifdef EVEN_NO_TEST_DEPTH_LIMIT
+        if (!insert_ok && depth >= EVEN_NO_TEST_DEPTH_LIMIT) {
+          continue;
+        }
+#else
+        if (!insert_ok) {
+          continue;
         }
+#endif
+
+        long_edge_queue_edge_add_recursive_2(tdata,
+                                             l_adjacent[i]->radial_next,
+                                             l_adjacent[i],
+                                             len_sq_other,
+                                             limit_len,
+                                             depth + 1,
+                                             insert_ok);
       }
     } while ((l_iter = l_iter->radial_next) != l_end);
   }
@@ -1825,8 +1838,8 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
 
         // try to improve convergence by applying a small amount of smoothing to topology,
         // but tangentially to surface.
-        if (BLI_rng_get_float(rng) > 0.75) {
-          surface_smooth_v_safe(tdata->pbvh, l_iter->v);
+        if (BLI_rng_get_float(rng) > 0.5) {
+          surface_smooth_v_safe(tdata->pbvh, l_iter->v, eq_ctx->surface_sm

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list