[Bf-blender-cvs] [baa24243a53] temp_bmesh_multires: Sculpt dyntopo: Dynamic field-propegated topology rake

Joseph Eagar noreply at git.blender.org
Tue Aug 31 00:13:17 CEST 2021


Commit: baa24243a53b8935ce30fa120dcb72e67ad8fcb2
Author: Joseph Eagar
Date:   Mon Aug 30 15:04:43 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBbaa24243a53b8935ce30fa120dcb72e67ad8fcb2

Sculpt dyntopo: Dynamic field-propegated topology rake

I might write a paper on this.  Topology rake now locally
updates a vector field, which it uses to smooth the input
and constrain to mesh (including face set) boundaries.
This can make an enormous difference for things like
smoothing.

Note that this is different from the existing 'curvature rake'
mode, which also builds a field and which is fed into the input
of this new one.

The only oddity is that the field is stored in a CD_PROP_COLOR
since we don't have a CD_PROP_FLOAT4, and this shows up in the UI
(not sure if I'm messing up the CD_TEMPORARY flags or if the UI
doesn't check for them).

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
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/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 64d1c4c2caa..dd8873b84c5 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -567,10 +567,13 @@ def brush_settings(layout, context, brush, popover=False):
                 slider=True,
             )
 
-            box.prop(brush, "boundary_smooth_factor");
+            box.prop(brush, "boundary_smooth_factor")
             box.prop(brush, "use_weighted_smooth")
             box.prop(brush, "preserve_faceset_boundary")
 
+            if brush.preserve_faceset_boundary:
+                box.prop(brush, "autosmooth_fset_slide")
+
             box.prop(brush, "use_custom_auto_smooth_spacing", text="Custom Spacing")
             if brush.use_custom_auto_smooth_spacing:
                UnifiedPaintPanel.prop_unified(
@@ -619,7 +622,7 @@ def brush_settings(layout, context, brush, popover=False):
 
             if brush.use_custom_topology_rake_spacing:
                 box.prop(brush, "topology_rake_spacing", text="Spacing")
-            box.prop(brush, "topology_rake_projection");
+            box.prop(brush, "topology_rake_projection")
 
             box.prop(brush, "topology_rake_radius_factor", slider=True)
             box.prop(brush, "use_curvature_rake")
@@ -820,6 +823,8 @@ def brush_settings(layout, context, brush, popover=False):
 
             col.prop(brush, "use_weighted_smooth")
             col.prop(brush, "preserve_faceset_boundary")
+            if brush.preserve_faceset_boundary:
+                col.prop(brush, "autosmooth_fset_slide")
 
             col.prop(brush, "smooth_deform_type")
 
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 5cf797bd075..e362ae31247 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -790,7 +790,6 @@ class VIEW3D_PT_sculpt_dyntopo_advanced(Panel, View3DPaintPanel):
 
         col.prop_enum(brush.dyntopo, "inherit", value="ALL", text="Use All Defaults", icon="LOCKED" if inherit_all else "UNLOCKED")
 
-
         def do_prop(key):
             row = col.row()
             if key.upper() in brush.dyntopo.inherit:
@@ -814,6 +813,8 @@ class VIEW3D_PT_sculpt_dyntopo_advanced(Panel, View3DPaintPanel):
         do_prop("collapse")
         do_prop("cleanup")
         do_prop("spacing")
+        do_prop("local_subdivide")
+        do_prop("local_collapse")
         do_prop("detail_size")
         do_prop("detail_range")
         do_prop("detail_percent")
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 4cc4e0b1704..76adab9168b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -424,9 +424,11 @@ struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
 void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size, float detail_range);
 
 typedef enum {
-  PBVH_Subdivide = 1,
-  PBVH_Collapse = 2,
-  PBVH_Cleanup = 4,  // dissolve verts surrounded by either 3 or 4 triangles then triangulate
+  PBVH_Subdivide = 1 << 0,
+  PBVH_Collapse = 1 << 1,
+  PBVH_Cleanup = 1 << 2,  // dissolve verts surrounded by either 3 or 4 triangles then triangulate
+  PBVH_LocalSubdivide = 1 << 3,
+  PBVH_LocalCollapse = 1 << 4
 } PBVHTopologyUpdateMode;
 
 typedef float (*DyntopoMaskCB)(SculptVertRef vertex, void *userdata);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 15fba14257d..b0870e0558e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1800,8 +1800,10 @@ void BKE_brush_sculpt_reset(Brush *br)
     case SCULPT_TOOL_SNAKE_HOOK:
       br->alpha = 1.0f;
       br->rake_factor = 1.0f;
-      br->dyntopo.inherit = DYNTOPO_INHERIT_BITMASK & ~(DYNTOPO_INHERIT_ALL | DYNTOPO_COLLAPSE);
-      br->dyntopo.flag |= DYNTOPO_COLLAPSE;
+      br->dyntopo.inherit = DYNTOPO_INHERIT_BITMASK &
+                            ~(DYNTOPO_INHERIT_ALL | DYNTOPO_LOCAL_COLLAPSE | DYNTOPO_INHERIT_DETAIL_RANGE);
+      br->dyntopo.flag |= DYNTOPO_LOCAL_COLLAPSE;
+      br->dyntopo.detail_range = 0.5f;
       break;
     case SCULPT_TOOL_THUMB:
       br->size = 75;
@@ -2701,6 +2703,24 @@ void BKE_brush_get_dyntopo(Brush *brush, Sculpt *sd, DynTopoSettings *out)
     }
   }
 
+  if (inherit & DYNTOPO_LOCAL_COLLAPSE) {
+    if (sd->flags & SCULPT_DYNTOPO_LOCAL_COLLAPSE) {
+      out->flag |= DYNTOPO_LOCAL_COLLAPSE;
+    }
+    else {
+      out->flag &= ~DYNTOPO_LOCAL_COLLAPSE;
+    }
+  }
+
+  if (inherit & DYNTOPO_LOCAL_SUBDIVIDE) {
+    if (sd->flags & SCULPT_DYNTOPO_LOCAL_SUBDIVIDE) {
+      out->flag |= DYNTOPO_LOCAL_SUBDIVIDE;
+    }
+    else {
+      out->flag &= ~DYNTOPO_LOCAL_SUBDIVIDE;
+    }
+  }
+
   if (inherit & DYNTOPO_COLLAPSE) {
     if (sd->flags & SCULPT_DYNTOPO_COLLAPSE) {
       out->flag |= DYNTOPO_COLLAPSE;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 51e1ef183c9..766a1b95b21 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -153,12 +153,22 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
   } \
   ((void)0)
 
+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);
 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,
+                                    PBVH *pbvh,
+                                    const float center[3],
+                                    const float view_normal[3],
+                                    float radius,
+                                    const bool use_frontface,
+                                    const bool use_projected,
+                                    bool is_collapse);
 
 //#define CHECKMESH
 //#define TEST_INVALID_NORMALS
@@ -1173,6 +1183,11 @@ static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
 
 struct EdgeQueue;
 
+typedef struct EdgePair {
+  BMVert *v1, *v2;
+  float limit_len_squared;
+} EdgePair;
+
 typedef struct EdgeQueue {
   HeapSimple *heap;
 
@@ -1196,7 +1211,7 @@ typedef struct EdgeQueue {
 #endif
 } EdgeQueue;
 
-typedef struct {
+typedef struct EdgeQueueContext {
   EdgeQueue *q;
   BLI_mempool *pool;
   BMesh *bm;
@@ -1213,6 +1228,7 @@ typedef struct {
   BMVert **val34_verts;
   int val34_verts_tot;
   int val34_verts_size;
+  bool local_mode;
 } EdgeQueueContext;
 
 static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
@@ -1420,6 +1436,7 @@ typedef struct EdgeQueueThreadData {
   EdgeQueueContext *eq_ctx;
   int totedge;
   int size;
+  bool is_collapse;
 } EdgeQueueThreadData;
 
 static void edge_thread_data_insert(EdgeQueueThreadData *tdata, BMEdge *e)
@@ -1434,7 +1451,14 @@ static void edge_thread_data_insert(EdgeQueueThreadData *tdata, BMEdge *e)
     }
   }
 
-  e->head.hflag |= BM_ELEM_TAG;
+  BMElem elem;
+  memcpy(&elem, (BMElem *)e, sizeof(BMElem));
+
+  elem.head.hflag = e->head.hflag | BM_ELEM_TAG;
+  int64_t iold = *((int64_t *)&e->head.index);
+  int64_t inew = *((int64_t *)&elem.head.index);
+
+  atomic_cas_int64((int64_t *)&e->head.index, iold, inew);
 
   tdata->edges[tdata->totedge] = e;
   tdata->totedge++;
@@ -1449,7 +1473,7 @@ static bool edge_queue_vert_in_circle(const EdgeQueue *q, BMVert *v)
   return len_squared_v3v3(q->center_proj, c) <= q->radius_squared;
 }
 
-static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, float priority)
+static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, float priority, float limit)
 {
   void **elems = eq_ctx->q->elems;
   BLI_array_declare(elems);
@@ -1463,9 +1487,12 @@ static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e, float priorit
     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;
+    EdgePair *pair = BLI_mempool_alloc(eq_ctx->pool);
+
+    pair->v1 = e->v1;
+    pair->v2 = e->v2;
+    pair->limit_len_squared = limit * limit;
+
 #ifdef DYNTOPO_USE_HEAP
     BLI_heapsimple_insert(eq_ctx->q->heap, priority, pair);
 #endif
@@ -1491,7 +1518,7 @@ static void long_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
     const float len_sq = BM_edge_calc_length_squared(e) * w * w;
 
     if (len_sq > eq_ctx->q->limit_len_squared) {
-      edge_queue_insert(eq_ctx, e, -len_sq);
+      edge_queue_insert(eq_ctx, e, -len_sq, eq_ctx->q->limit_len);
     }
   }
 }
@@ -1518,7 +1545,7 @@ static void long_edge_queue_edge_add_recursive(EdgeQueueContext *eq_ctx,
   if (EDGE_QUEUE_TEST(l_edge->e) == false)
 #  endif
   {
-    edge_queue_insert(eq_ctx, l_edge->e, -len_sq);
+    edge_queue_insert(eq_ctx, l_edge->e, -len_sq, eq_ctx->q->limit_len);
   }
 
   /* temp support previous behavior! */
@@ -1564,7 +1591,7 @@ static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx, BMEdge *e)
   {
     const float len_sq = calc_weighted_edge_collapse(eq_ctx, e->v1, e->v2);
     if (len_sq < eq_ctx->q->limit_len_squared) {
-      edge_queue_insert(eq_ctx, e, len_sq);
+      edge_queue_insert(eq_ctx, e, len_sq, eq_ctx->q->limit_len);
     }
   }
 }
@@ -1869,7 +1896,6 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
           continue;
         }
 
-#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
         float len_sq = calc_weighted_edge_collapse(eq_ctx, l_iter->e->v1, l_iter->e->v2);
         len_sq /= w * w;
 
@@ -1877,18 +1903,43 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
           short_edge_queue_edge_add_recursive_2(
               tdata, l_iter->radial_next, l_iter, len_sq, eq_ctx->q->limit_len, 0);
         }
-#else
-        const float len_sq = calc_weighted_edge_split(eq_ctx, l_iter->e->v1, l_iter->e->v

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list