[Bf-blender-cvs] [a00bfa89769] temp_bmesh_multires: Sculpt dyntopo: more smooth stuff

Joseph Eagar noreply at git.blender.org
Tue Aug 24 07:55:29 CEST 2021


Commit: a00bfa89769616db309c180fdaefa83ff0ba5386
Author: Joseph Eagar
Date:   Mon Aug 23 22:55:17 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBa00bfa89769616db309c180fdaefa83ff0ba5386

Sculpt dyntopo: more smooth stuff

* All of the smooth brushes now use the SculptCustomLayer
  system for temporary data, so all work with dyntopo now.
* You can now use a flat array in SculptCustomLayer with
  PBVH_BMESH (though you have to build the structure manually).
  The mesh filter code uses this.
* Smooth (and autosmooth) now have an option to preserve face
  set boundaries.  Corners are currently not handled.
* Simplify brush has preserve face set boundaries autosmooth
  flag set by default.
* SCULPT_vertex_is_boundary now takes an addition argument
  for whether to check for face set boundaries.

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.c
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_expand.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mesh.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/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 1043e8af1dc..8025caa8bf9 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -568,6 +568,7 @@ def brush_settings(layout, context, brush, popover=False):
             )
 
             box.prop(brush, "use_weighted_smooth")
+            box.prop(brush, "preserve_faceset_boundary")
 
             box.prop(brush, "use_custom_auto_smooth_spacing", text="Custom Spacing")
             if brush.use_custom_auto_smooth_spacing:
@@ -815,6 +816,8 @@ def brush_settings(layout, context, brush, popover=False):
         elif sculpt_tool == 'SMOOTH':
             col = layout.column()
             col.prop(brush, "use_weighted_smooth")
+            col.prop(brush, "preserve_faceset_boundary")
+
             col.prop(brush, "smooth_deform_type")
 
             if brush.smooth_deform_type == 'SURFACE':
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index c4571ded635..4b75109be3e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1975,12 +1975,16 @@ void BKE_brush_sculpt_reset(Brush *br)
       break;
 
     case SCULPT_TOOL_SIMPLIFY:
-      //don't use DYNTOPO_INHERIT_BITMASK, we want to include
-      //future bits
+      // don't use DYNTOPO_INHERIT_BITMASK, we want to include
+      // future bits
+
+      br->flag |= BRUSH_SMOOTH_PRESERVE_FACE_SETS;
       br->dyntopo.inherit = 0x7FFFFFFF &
                             ~(DYNTOPO_INHERIT_ALL | DYNTOPO_SUBDIVIDE | DYNTOPO_COLLAPSE);
       br->dyntopo.flag |= DYNTOPO_COLLAPSE | DYNTOPO_SUBDIVIDE;
       br->autosmooth_factor = 0.02;
+
+      break;
     case SCULPT_TOOL_VCOL_BOUNDARY:
     case SCULPT_TOOL_PAINT:
     case SCULPT_TOOL_MASK:
@@ -2639,7 +2643,8 @@ void BKE_brush_get_dyntopo(Brush *brush, Sculpt *sd, DynTopoSettings *out)
     brush->dyntopo = *out = brush2.dyntopo;
 
     brush_free_data((ID *)&brush2);
-  } else if (!out->detail_size) {
+  }
+  else if (!out->detail_size) {
     brush->dyntopo.inherit |= DYNTOPO_INHERIT_DETAIL_SIZE;
     brush->dyntopo.detail_size = 12.0;
   }
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 4f477324dda..fcd87b81335 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1595,7 +1595,7 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
     }
   }
 
-  double start = PIL_check_seconds_timer();
+  // double start = PIL_check_seconds_timer();
 
   modified = modified || BKE_pbvh_bmesh_update_topology(pbvh,
                                                         mode,
@@ -1609,9 +1609,9 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
                                                         mask_cb,
                                                         mask_cb_data);
 
-  double end = PIL_check_seconds_timer();
+  // double end = PIL_check_seconds_timer();
 
-  printf("dyntopo time: %f\n", end - start);
+  // printf("dyntopo time: %f\n", end - start);
 
   return modified;
 }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index b3a98eb987c..11083dc7617 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -345,6 +345,7 @@ static bool sculpt_temp_customlayer_get(SculptSession *ss,
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_BMESH: {
       CustomData *cdata = NULL;
+      out->from_bmesh = true;
 
       if (!ss->bm) {
         return false;
@@ -386,6 +387,8 @@ static bool sculpt_temp_customlayer_get(SculptSession *ss,
       CustomData *cdata = NULL;
       int totelem = 0;
 
+      out->from_bmesh = false;
+
       switch (domain) {
         case ATTR_DOMAIN_POINT:
           totelem = ss->totvert;
@@ -424,6 +427,8 @@ static bool sculpt_temp_customlayer_get(SculptSession *ss,
       CustomData *cdata = NULL;
       int totelem = 0;
 
+      out->from_bmesh = false;
+
       switch (domain) {
         case ATTR_DOMAIN_POINT:
           totelem = BKE_pbvh_get_grid_num_vertices(ss->pbvh);
@@ -1113,7 +1118,8 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
   }
 }
 
-static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, SculptVertRef vertex)
+static bool sculpt_check_unique_face_set_in_base_mesh(const SculptSession *ss,
+                                                      SculptVertRef vertex)
 {
   int index = BKE_pbvh_vertex_index_to_table(ss->pbvh, vertex);
 
@@ -1136,7 +1142,9 @@ static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, SculptV
  * Checks if the face sets of the adjacent faces to the edge between \a v1 and \a v2
  * in the base mesh are equal.
  */
-static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss, int v1, int v2)
+static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(const SculptSession *ss,
+                                                               int v1,
+                                                               int v2)
 {
   MeshElemMap *vert_map = &ss->pmap[v1];
   int p1 = -1, p2 = -1;
@@ -1164,7 +1172,7 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss
   return true;
 }
 
-bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, SculptVertRef index)
+bool SCULPT_vertex_has_unique_face_set(const SculptSession *ss, SculptVertRef index)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_FACES: {
@@ -1174,9 +1182,17 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, SculptVertRef index)
       BMIter iter;
       BMLoop *l;
       BMVert *v = (BMVert *)index.i;
+      MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v);
+
+      if (mv->flag & DYNVERT_NEED_BOUNDARY) {
+        BKE_pbvh_update_vert_boundary(ss->cd_dyn_vert, ss->cd_faceset_offset, v);
+      }
+
+      return !(mv->flag & DYNVERT_FSET_BOUNDARY);
+
+#if 0
       int face_set = 0;
       bool first = true;
-
       if (ss->cd_faceset_offset == -1) {
         return false;
       }
@@ -1192,8 +1208,8 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, SculptVertRef index)
         first = false;
         face_set = face_set2;
       }
-
       return true;
+#endif
     }
     case PBVH_GRIDS: {
       const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
@@ -1521,7 +1537,9 @@ static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss,
                          BKE_pbvh_vertex_index_to_table(ss->pbvh, index));
 }
 
-bool SCULPT_vertex_is_boundary(const SculptSession *ss, const SculptVertRef vertex)
+bool SCULPT_vertex_is_boundary(const SculptSession *ss,
+                               const SculptVertRef vertex,
+                               bool check_facesets)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_BMESH: {
@@ -1531,13 +1549,30 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const SculptVertRef vert
         BKE_pbvh_update_vert_boundary(ss->cd_dyn_vert, ss->cd_faceset_offset, (BMVert *)vertex.i);
       }
 
-      return mv->flag & DYNVERT_BOUNDARY;
+      if (!check_facesets) {
+        return mv->flag & (DYNVERT_BOUNDARY);
+      }
+      else {
+        return mv->flag & (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY);
+      }
     }
     case PBVH_FACES: {
       if (!SCULPT_vertex_all_face_sets_visible_get(ss, vertex)) {
         return true;
       }
-      return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex);
+
+      if (check_facesets) {
+        bool ret = sculpt_check_boundary_vertex_in_base_mesh(ss, vertex);
+
+        if (ret) {
+          return ret;
+        }
+
+        return !SCULPT_vertex_has_unique_face_set(ss, vertex);
+      }
+      else {
+        return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex);
+      }
     }
 
     case PBVH_GRIDS: {
@@ -3657,6 +3692,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
   const int thread_id = BLI_task_parallel_thread_id(tls);
 
   const bool use_curvature = ss->cache->brush->flag2 & BRUSH_CURVATURE_RAKE;
+  bool check_fsets = ss->cache->brush->flag2 & BRUSH_SMOOTH_PRESERVE_FACE_SETS;
 
   if (use_curvature) {
     SCULPT_curvature_begin(ss, node, false);
@@ -3700,7 +3736,11 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
       copy_v3_v3(direction2, direction);
     }
 
-    SCULPT_bmesh_four_neighbor_average(avg, direction2, vd.bm_vert, data->rake_projection);
+    if (SCULPT_vertex_is_boundary(ss, vd.vertex, check_fsets)) {
+      continue;
+    }
+    SCULPT_bmesh_four_neighbor_average(
+        avg, direction2, vd.bm_vert, data->rake_projection, check_fsets);
 
     sub_v3_v3v3(val, avg, vd.co);
 
@@ -4288,7 +4328,7 @@ void SCULPT_relax_vertex(SculptSession *ss,
   int neighbor_count = 0;
   zero_v3(smooth_pos);
   zero_v3(boundary_normal);
-  const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->vertex);
+  const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->vertex, false);
 
   SculptVertexNeighborIter ni;
   SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->vertex, ni) {
@@ -4299,7 +4339,7 @@ void SCULPT_relax_vertex(SculptSession *ss,
       /* When the vertex to relax is boundary, use only connected boundary vertices for the average
        * position. */
       if (is_boundary) {
-        if (!SCULPT_vertex_is_boundary(ss, ni.vertex)) {
+        if (!SCULPT_vertex_is_boundary(ss, ni.vertex, false)) {
           continue;
         }
         add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.vertex));
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index c300a68cb67..567ad1f93b2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -188,7 +188,7 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
   }
 
   if (automasking->settings.flags & BRUSH_AUTOMASKING_BO

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list