[Bf-blender-cvs] [901654dcbf3] temp_bmesh_multires: * Added a "color boundary" tool that tries to smooth out vcol boundaries

Joseph Eagar noreply at git.blender.org
Wed Nov 4 04:08:59 CET 2020


Commit: 901654dcbf3498d2f0bb317d58556f9e0ede7602
Author: Joseph Eagar
Date:   Tue Nov 3 19:08:37 2020 -0800
Branches: temp_bmesh_multires
https://developer.blender.org/rB901654dcbf3498d2f0bb317d58556f9e0ede7602

* Added a "color boundary" tool that tries to smooth out vcol boundaries

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

M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenloader/intern/versioning_defaults.c
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_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 17243b328e8..330d4619605 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1799,6 +1799,14 @@ void BKE_brush_sculpt_reset(Brush *br)
       br->flag &= ~BRUSH_SPACE_ATTEN;
       br->curve_preset = BRUSH_CURVE_SPHERE;
       break;
+    case SCULPT_TOOL_VCOL_BOUNDARY:
+      br->flag &= ~BRUSH_SPACE_ATTEN;
+      br->spacing = 5;
+      br->alpha = 0.7f;
+      br->surface_smooth_shape_preservation = 0.5f;
+      br->surface_smooth_current_vertex = 0.5f;
+      br->surface_smooth_iterations = 4;
+      break;
     default:
       break;
   }
@@ -1858,6 +1866,7 @@ void BKE_brush_sculpt_reset(Brush *br)
       br->sub_col[2] = 0.005f;
       break;
 
+    case SCULPT_TOOL_VCOL_BOUNDARY:
     case SCULPT_TOOL_SIMPLIFY:
     case SCULPT_TOOL_PAINT:
     case SCULPT_TOOL_MASK:
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 48a24755250..3af3c42fa5d 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -697,6 +697,14 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
       brush->sculpt_tool = SCULPT_TOOL_PAINT;
     }
 
+    brush_name = "Color Boundary";
+    brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+    if (!brush) {
+      brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
+      id_us_min(&brush->id);
+      brush->sculpt_tool = SCULPT_TOOL_VCOL_BOUNDARY;
+    }
+
     brush_name = "Smear";
     brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
     if (!brush) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 028c534b8fc..e7e6ae8c9ca 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1512,6 +1512,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool)
               SCULPT_TOOL_DRAW_SHARP,
               SCULPT_TOOL_ELASTIC_DEFORM,
               SCULPT_TOOL_SMOOTH,
+              SCULPT_TOOL_VCOL_BOUNDARY,
               SCULPT_TOOL_BOUNDARY,
               SCULPT_TOOL_POSE);
 }
@@ -2733,6 +2734,8 @@ static float brush_strength(const Sculpt *sd,
 
     case SCULPT_TOOL_SMOOTH:
       return flip * alpha * pressure * feather;
+    case SCULPT_TOOL_VCOL_BOUNDARY:
+      return flip * alpha * pressure * feather;
 
     case SCULPT_TOOL_PINCH:
       if (flip > 0.0f) {
@@ -6308,6 +6311,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       case SCULPT_TOOL_PAINT:
         SCULPT_do_paint_brush(sd, ob, nodes, totnode);
         break;
+      case SCULPT_TOOL_VCOL_BOUNDARY:
+        SCULPT_smooth_vcol_boundary(sd, ob, nodes, totnode);
+        break;
       case SCULPT_TOOL_SMEAR:
         SCULPT_do_smear_brush(sd, ob, nodes, totnode);
         break;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index c751e26633b..0779eae4588 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -519,6 +519,11 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
                                              float result[3],
                                              SculptVertRef index);
 
+void SCULPT_smooth_vcol_boundary(Sculpt *sd,
+                                 Object *ob,
+                                 PBVHNode **nodes,
+                                 const int totnode);
+
 void SCULPT_smooth(Sculpt *sd,
                    Object *ob,
                    PBVHNode **nodes,
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 18ba44844ca..c92611e7481 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -299,8 +299,7 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
 }
 
 #ifdef PROXY_ADVANCED
-static void do_smooth_brush_task_cb_ex(
-    void *__restrict userdata,
+static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
                                        const int n,
                                        const TaskParallelTLS *__restrict tls)
 {
@@ -348,7 +347,7 @@ static void do_smooth_brush_task_cb_ex(
       while (ni < MAX_PROXY_NEIGHBORS && p->neighbors[i][ni].node >= 0) {
         ProxyKey *key = p->neighbors[i] + ni;
         PBVHNode *n2 = ss->pbvh->nodes + key->node;
-        
+
         // printf("%d %d %d %p\n", key->node, key->pindex, ss->pbvh->totnode, n2);
 
         if (key->pindex < 0 || key->pindex >= n2->proxyverts.size) {
@@ -675,3 +674,179 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
         0, totnode, &data, SCULPT_do_surface_smooth_brush_displace_task_cb_ex, &settings);
   }
 }
+
+static void do_smooth_vcol_boundary_brush_task_cb_ex(void *__restrict userdata,
+                                                     const int n,
+                                                     const TaskParallelTLS *__restrict tls)
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  Sculpt *sd = data->sd;
+  const Brush *brush = data->brush;
+  const bool smooth_mask = data->smooth_mask;
+  float bstrength = data->strength;
+
+  PBVHVertexIter vd;
+
+  CLAMP(bstrength, 0.0f, 1.0f);
+
+  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);
+
+  float avg[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+  float tot = 0.0f;
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+  {
+    if (!vd.col) {
+      continue;
+    }
+
+    if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+      const float fade = bstrength * SCULPT_brush_strength_factor(
+                                         ss,
+                                         brush,
+                                         vd.co,
+                                         sqrtf(test.dist),
+                                         vd.no,
+                                         vd.fno,
+                                         smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+                                         vd.vertex,
+                                         thread_id);
+
+      madd_v3_v3fl(avg, vd.col, fade);
+      tot += fade;
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+
+  if (tot == 0.0f) {
+    return;
+  }
+  tot = 1.0f / tot;
+
+  mul_v3_fl(avg, tot);
+
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+  {
+    if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+      const float fade = bstrength * SCULPT_brush_strength_factor(
+                                         ss,
+                                         brush,
+                                         vd.co,
+                                         sqrtf(test.dist),
+                                         vd.no,
+                                         vd.fno,
+                                         smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
+                                         vd.vertex,
+                                         thread_id);
+      if (!vd.col) {
+        continue;
+      }
+
+      float avg2[3], val[3];
+      float tot2 = 0.0f;
+
+      zero_v3(avg2);
+
+      copy_v4_v4(avg, vd.col);
+
+      madd_v3_v3fl(avg2, vd.co, 0.5f);
+      tot2 += 0.5f;
+
+      SculptVertexNeighborIter ni;
+      SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) {
+        const float *col = SCULPT_vertex_color_get(ss, ni.vertex);
+        const float *co = SCULPT_vertex_co_get(ss, ni.vertex);
+
+        //simple color metric
+        float dv[4];
+        sub_v4_v4v4(dv, col, avg);
+        float w = (fabs(dv[0]) + fabs(dv[1]) + fabs(dv[2]) + fabs(dv[3])) / 4.0;
+
+        //w = 1.0f - w;
+        //w = fabs(0.5 - w);
+        w *= w * w;
+
+        madd_v3_v3fl(avg2, co, w);
+        tot2 += w;
+      }
+      SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+      if (tot2 == 0.0) {
+        continue;
+      }
+
+      mul_v3_fl(avg2, 1.0 / tot2);
+
+      sub_v3_v3v3(val, avg2, vd.co);
+      madd_v3_v3v3fl(val, vd.co, val, fade);
+      SCULPT_clip(sd, ss, vd.co, val);
+
+      if (vd.mvert) {
+        vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+      }
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+}
+
+void SCULPT_smooth_vcol_boundary(Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode)
+{
+  SculptSession *ss = ob->sculpt;
+
+  Brush *brush = BKE_paint_brush(&sd->paint);
+  float bstrength = ss->cache->bstrength;
+
+  const int max_iterations = 4;
+  const float fract = 1.0f / max_iterations;
+  PBVHType type = BKE_pbvh_type(ss->pbvh);
+  int iteration, count;
+  float last;
+
+  CLAMP(bstrength, 0.0f, 1.0f);
+
+  count = (int)(bstrength * max_iterations);
+  last = max_iterations * (bstrength - count * fract);
+
+  if (type == PBVH_FACES && !ss->pmap) {
+    BLI_assert(!"sculpt smooth: pmap missing");
+    return;
+  }
+
+  if (type != PBVH_BMESH) {
+    SCULPT_vertex_random_access_ensure(ss);
+  }
+
+  SCULPT_boundary_info_ensure(ob);
+
+#ifdef PROXY_ADVANCED
+  int datamask = PV_CO | PV_NEIGHBORS | PV_NO | PV_INDEX | PV_MASK;
+  BKE_pbvh_ensure_proxyarrays(ss, ss->pbvh, nodes, totnode, datamask);
+
+  BKE_pbvh_load_proxyarrays(ss->pbvh, nodes, totnode, PV_CO | PV_NO | PV_MASK);
+#endif
+  for (iteration = 0; iteration <= count; iteration++) {
+    const float strength = (iteration != count) ? 1.0f : last;
+
+    SculptThreadedTaskData data = {
+        .sd = sd,
+        .ob = ob,
+        .brush = brush,
+        .nodes = nodes,
+        .smooth_mask = false,
+        .strength = strength,
+    };
+
+    TaskParallelSettings settings;
+    BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+    BLI_task_paral

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list