[Bf-blender-cvs] [72ff64590d1] sculpt-dev: Sculpt: Fairing Brush

Pablo Dobarro noreply at git.blender.org
Wed Dec 16 21:36:52 CET 2020


Commit: 72ff64590d18b5f9b2620802fc79bb82ca92fd7a
Author: Pablo Dobarro
Date:   Tue Dec 15 20:39:53 2020 +0100
Branches: sculpt-dev
https://developer.blender.org/rB72ff64590d18b5f9b2620802fc79bb82ca92fd7a

Sculpt: Fairing Brush

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

M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenlib/BLI_utildefines.h
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/makesdna/DNA_brush_enums.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 33686cea4fc..02ec0ba85a3 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1698,6 +1698,12 @@ void BKE_brush_sculpt_reset(Brush *br)
       br->spacing = 10;
       br->alpha = 1.0f;
       break;
+    case SCULPT_TOOL_FAIRING:
+      br->curve_preset = BRUSH_CURVE_SMOOTHER;
+      br->flag &= ~BRUSH_SPACE_ATTEN;
+      br->spacing = 10;
+      br->alpha = 1.0f;
+      break;
     case SCULPT_TOOL_SLIDE_RELAX:
       br->spacing = 10;
       br->alpha = 1.0f;
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 40d24f07c25..d0a090108a6 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -298,6 +298,8 @@ extern "C" {
   (_VA_ELEM15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) || _VA_ELEM2(v, o))
 #define _VA_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
   (_VA_ELEM16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) || _VA_ELEM2(v, p))
+#define _VA_ELEM18(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \
+  (_VA_ELEM17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) || _VA_ELEM2(v, q))
 /* clang-format on */
 
 /* reusable ELEM macro */
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f89a5be27de..20b6b9767e6 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -738,6 +738,14 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
       brush->sculpt_tool = SCULPT_TOOL_DISPLACEMENT_ERASER;
     }
 
+    brush_name = "Fairing";
+    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_FAIRING;
+    }
+
     /* Use the same tool icon color in the brush cursor */
     for (brush = bmain->brushes.first; brush; brush = brush->id.next) {
       if (brush->ob_mode & OB_MODE_SCULPT) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 80a32682325..cd990dcfa14 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -50,6 +50,7 @@
 #include "BKE_ccg.h"
 #include "BKE_colortools.h"
 #include "BKE_context.h"
+#include "BKE_mesh_fair.h"
 #include "BKE_image.h"
 #include "BKE_kelvinlet.h"
 #include "BKE_key.h"
@@ -1218,6 +1219,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool)
               SCULPT_TOOL_ELASTIC_DEFORM,
               SCULPT_TOOL_SMOOTH,
               SCULPT_TOOL_BOUNDARY,
+              SCULPT_TOOL_FAIRING,
               SCULPT_TOOL_POSE);
 }
 
@@ -1226,6 +1228,7 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool)
   return ELEM(sculpt_tool,
               SCULPT_TOOL_SMOOTH,
               SCULPT_TOOL_LAYER,
+              SCULPT_TOOL_FAIRING,
               SCULPT_TOOL_POSE,
               SCULPT_TOOL_BOUNDARY,
               SCULPT_TOOL_CLOTH,
@@ -2336,6 +2339,8 @@ static float brush_strength(const Sculpt *sd,
       return alpha * flip * pressure * overlap * feather;
     case SCULPT_TOOL_DISPLACEMENT_ERASER:
       return alpha * pressure * overlap * feather;
+    case SCULPT_TOOL_FAIRING:
+      return alpha * pressure * overlap * feather;
     case SCULPT_TOOL_CLOTH:
       if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
         /* Grab deform uses the same falloff as a regular grab brush. */
@@ -3103,6 +3108,165 @@ static void do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Sculpt Multires Displacement Eraser Brush
+ * \{ */
+
+static void do_fairing_brush_tag_store_task_cb_ex(void *__restrict userdata,
+                                                    const int n,
+                                                    const TaskParallelTLS *__restrict tls)
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  SculptBrushTest test;
+  SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+      ss, &test, data->brush->falloff_shape);
+  PBVHVertexIter vd;
+
+  const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
+  const Brush *brush = data->brush;
+
+  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;
+    }
+
+    if (SCULPT_vertex_is_boundary(ss, vd.index)) {
+        continue;
+    }
+
+    const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+                                                                  brush,
+                                                                  ss->cache->prefairing_co[vd.index],
+                                                                  sqrtf(test.dist),
+                                                                  vd.no,
+                                                                  vd.fno,
+                                                                  vd.mask ? *vd.mask : 0.0f,
+                                                                  vd.index,
+                                                                  thread_id);
+
+    if (fade == 0.0f) {
+        continue;
+    }
+
+    ss->cache->fairing_fade[vd.index] = max_ff(fade, ss->cache->fairing_fade[vd.index]);
+    ss->cache->fairing_mask[vd.index] = true;
+
+  }
+  BKE_pbvh_vertex_iter_end;
+}
+
+static void do_fairing_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+  SculptSession *ss = ob->sculpt;
+  Brush *brush = BKE_paint_brush(&sd->paint);
+  const int totvert = SCULPT_vertex_count_get(ss);
+
+  if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+      return;
+  }
+
+  if (!ss->cache->fairing_mask) {
+      ss->cache->fairing_mask = MEM_malloc_arrayN(totvert, sizeof(bool), "fairing_mask");
+      ss->cache->fairing_fade = MEM_malloc_arrayN(totvert, sizeof(float), "fairing_fade");
+      ss->cache->prefairing_co = MEM_malloc_arrayN(totvert, sizeof(float) * 3, "prefairing_co");
+  }
+
+  if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+    for (int i = 0; i < totvert; i++) {
+      ss->cache->fairing_mask[i] = false;
+      ss->cache->fairing_fade[i] = 0.0f;
+      copy_v3_v3(ss->cache->prefairing_co[i], SCULPT_vertex_co_get(ss, i));
+    }
+  }
+
+  SCULPT_boundary_info_ensure(ob);
+
+  /* Threaded loop over nodes. */
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .brush = brush,
+      .nodes = nodes,
+  };
+
+  TaskParallelSettings settings;
+  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+  BLI_task_parallel_range(0, totnode, &data, do_fairing_brush_tag_store_task_cb_ex, &settings);
+}
+
+static void do_fairing_brush_displace_task_cb_ex(void *__restrict userdata,
+                                                    const int n,
+                                                    const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  PBVHVertexIter vd;
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+  {
+      if (!ss->cache->fairing_mask[vd.index]) {
+          continue;
+      }
+      float disp[3];
+      sub_v3_v3v3(disp, vd.co, ss->cache->prefairing_co[vd.index]);
+      mul_v3_fl(disp, ss->cache->fairing_fade[vd.index]);
+      copy_v3_v3(vd.co, ss->cache->prefairing_co[vd.index]);
+      add_v3_v3(vd.co, disp);
+      if (vd.mvert) {
+        vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+      }
+  }
+  BKE_pbvh_vertex_iter_end;
+}
+
+static void sculpt_fairing_brush_exec_fairing_for_cache(Sculpt *sd, Object *ob) {
+  BLI_assert(BKE_pbvh_type(ss->pbvh) != PBVH_GRIDS);
+  BLI_assert(ss->cache);
+
+  SculptSession *ss = ob->sculpt;
+  Brush *brush = BKE_paint_brush(&sd->paint);
+  Mesh *mesh = ob->data;
+
+  if (!ss->cache->fairing_mask) {
+      return;
+  }
+
+  switch (BKE_pbvh_type(ss->pbvh)) {
+  case PBVH_FACES: {
+        MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+        BKE_mesh_prefair_and_fair_vertices(mesh, mvert, ss->cache->fairing_mask, MESH_FAIRING_DEPTH_TANGENCY);
+      }
+      break;
+  case PBVH_BMESH: {
+      BKE_bmesh_prefair_and_fair_vertices(ss->bm, ss->cache->fairing_mask, MESH_FAIRING_DEPTH_TANGENCY);
+       }
+      break;
+   case PBVH_GRIDS:
+      BLI_assert(false);
+  }
+
+  PBVHNode **nodes;
+  int totnode;
+  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .brush = brush,
+      .nodes = nodes,
+  };
+
+  TaskParallelSettings settings;
+  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+  BLI_task_parallel_range(0, totnode, &data, do_fairing_brush_displace_task_cb_ex, &settings);
+  MEM_freeN(nodes);
+}
+
+/** \} */
+
 static void do_draw_brush_task_cb_ex(void *__restrict userdata,
                                      const int n,
                                      const TaskParallelTLS *__restrict tls)
@@ -5933,6 +6097,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       case SCULPT_TOOL_SMEAR:
         SCULPT_do_smear_brush(sd, ob, nodes, totnode);
         break;
+      case SCULPT_TOOL_FAIRING:
+        do_fairing_brush(sd, ob, nodes, totnode);
+        break;
     }
 
     if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
@@ -6494,6 +6661,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
       return "Paint Brush";
     case SCULPT_TOOL_SMEAR:
       return "Smear Brush";
+    case SCULPT_TOOL_FAIRING:
+      return "Fairing Brush";
   }
 
   return "Sculpting";
@@ -6510,6 +6679,9 @@ void SCULPT_cache_free(StrokeCache *cache)
   MEM_SAFE_FREE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list