[Bf-blender-cvs] [d2c1357fc5f] sculpt-dev: Sculpt: Initial implementation of uniform smoothing

Pablo Dobarro noreply at git.blender.org
Sat Mar 27 21:52:50 CET 2021


Commit: d2c1357fc5f0b5e5bfb929811f15d8f634d1687a
Author: Pablo Dobarro
Date:   Sat Mar 27 21:52:24 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rBd2c1357fc5f0b5e5bfb929811f15d8f634d1687a

Sculpt: Initial implementation of uniform smoothing

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

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/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 971c3a9fdcd..16e7813b1db 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -6519,6 +6519,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_DIRECTIONAL) {
         SCULPT_do_directional_smooth_brush(sd, ob, nodes, totnode);
       }
+      else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_UNIFORM_WEIGHTS) {
+        SCULPT_do_uniform_weights_smooth_brush(sd, ob, nodes, totnode);
+      }
       break;
     case SCULPT_TOOL_CREASE:
       do_crease_brush(sd, ob, nodes, totnode);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 4e4da9f0adf..c4235b13f96 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -589,6 +589,9 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
 /* Directional Smooth Brush. */
 void SCULPT_do_directional_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
 
+/* Uniform Weights Smooth Brush. */
+void SCULPT_do_uniform_weights_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+
 /* Slide/Relax */
 void SCULPT_relax_vertex(struct SculptSession *ss,
                          struct PBVHVertexIter *vd,
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index e3a158b91c0..fb34f93c427 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -649,3 +649,103 @@ void SCULPT_do_directional_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes
     BLI_task_parallel_range(0, totnode, &data, SCULPT_do_directional_smooth_task_cb_ex, &settings);
   }
 }
+
+static void SCULPT_do_uniform_weigths_smooth_task_cb_ex(void *__restrict userdata,
+                                                    const int n,
+                                                    const TaskParallelTLS *__restrict tls)
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  const Brush *brush = data->brush;
+  const float bstrength = ss->cache->bstrength;
+
+  PBVHVertexIter vd;
+
+  SculptBrushTest test;
+  SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+      ss, &test, data->brush->falloff_shape);
+  const int thread_id = BLI_task_parallel_thread_id(tls);
+
+  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
+    if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
+      continue;
+    }
+    const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+                                                                brush,
+                                                                vd.co,
+                                                                sqrtf(test.dist),
+                                                                vd.no,
+                                                                vd.fno,
+                                                                vd.mask ? *vd.mask : 0.0f,
+                                                                vd.index,
+                                                                thread_id);
+
+
+
+
+    float len_accum = 0;
+    int tot_neighbors = 0;
+
+    SculptVertexNeighborIter ni;
+    SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+      len_accum += len_v3v3(SCULPT_vertex_co_get(ss, vd.index), SCULPT_vertex_co_get(ss, ni.index));
+      tot_neighbors++;
+    }
+    SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+    /* Avoid division by 0 when there are no neighbors. */
+    if (tot_neighbors == 0) {
+      continue;
+    }
+
+    const float len_avg = bstrength * len_accum / tot_neighbors;
+
+
+    float co_accum[3] = {0.0f};
+
+    SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+      const float neighbor_co[3];
+      const float neighbor_disp[3];
+      sub_v3_v3v3(neighbor_disp, SCULPT_vertex_co_get(ss, ni.index), SCULPT_vertex_co_get(ss, vd.index));
+      normalize_v3(neighbor_disp);
+      mul_v3_fl(neighbor_disp, len_avg);
+      add_v3_v3v3(neighbor_co, SCULPT_vertex_co_get(ss, vd.index), neighbor_disp);
+      add_v3_v3(co_accum, neighbor_co);
+    }
+    SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+    float smooth_co[3];
+    mul_v3_v3fl(smooth_co, co_accum, 1.0f / tot_neighbors);
+
+    float final_disp[3];
+    sub_v3_v3v3(final_disp, smooth_co, vd.co);
+    madd_v3_v3v3fl(final_disp, vd.co, final_disp, fade);
+    SCULPT_clip(data->sd, ss, vd.co, final_disp);
+
+    if (vd.mvert) {
+      vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+    }
+    BKE_pbvh_vertex_iter_end;
+  }
+}
+
+
+
+void SCULPT_do_uniform_weights_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+  Brush *brush = BKE_paint_brush(&sd->paint);
+
+  /* Threaded loop over nodes. */
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .brush = brush,
+      .nodes = nodes,
+  };
+
+  TaskParallelSettings settings;
+  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+  for (int i = 0; i < brush->surface_smooth_iterations; i++) {
+    BLI_task_parallel_range(0, totnode, &data, SCULPT_do_uniform_weigths_smooth_task_cb_ex, &settings);
+  }
+}
\ No newline at end of file
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index 9db37306af2..05952b0b954 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -235,6 +235,7 @@ typedef enum eBrushSmoothDeformType {
   BRUSH_SMOOTH_DEFORM_LAPLACIAN = 0,
   BRUSH_SMOOTH_DEFORM_SURFACE = 1,
   BRUSH_SMOOTH_DEFORM_DIRECTIONAL = 2,
+  BRUSH_SMOOTH_DEFORM_UNIFORM_WEIGHTS = 3,
 } eBrushSmoothDeformType;
 
 typedef enum eBrushClothForceFalloffType {
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index f773443fc6a..f94af82feb6 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2191,6 +2191,11 @@ static void rna_def_brush(BlenderRNA *brna)
        0,
        "Directional",
        "Smooths the surface taking into account the direction of the stroke"},
+      {BRUSH_SMOOTH_DEFORM_UNIFORM_WEIGHTS,
+       "UNIFORM_WEIGHTS",
+       0,
+       "Uniform Weights",
+       "Smooths the surface considering that all edges have the same length"},
       {0, NULL, 0, NULL, NULL},
   };



More information about the Bf-blender-cvs mailing list