[Bf-blender-cvs] [df45257ec53] master: Sculpt: Split normal radius and area radius

Pablo Dobarro noreply at git.blender.org
Tue Feb 11 20:45:25 CET 2020


Commit: df45257ec53c795081e65a35784bd89ac8c3e83d
Author: Pablo Dobarro
Date:   Mon Dec 16 23:16:21 2019 +0100
Branches: master
https://developer.blender.org/rBdf45257ec53c795081e65a35784bd89ac8c3e83d

Sculpt: Split normal radius and area radius

This enables an extra layer of control in the sculpt brushes.
For now it is enabled only in Scrape, but it should work in all brushes (like normal radius). In the future it may also be enabled in other brushes.
You can tweak in this property in the scrape brush to achieve a much better behavior when working on curve surfaces and control how much volume you want to trim. In most cases, it also fixes the bug where the brush keeps trimming in the same area without disabling accumulate.
It should be possible to fix some other artifacts in other brushes by tweaking this default property.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D5993

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenlib/BLI_math_vector.h
M	source/blender/blenlib/intern/math_vector_inline.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/makesdna/DNA_brush_defaults.h
M	source/blender/makesdna/DNA_brush_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 2031546f4d0..e82caccdfe1 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -628,10 +628,14 @@ def brush_settings(layout, context, brush, popover=False):
             layout.separator()
         
         if brush.sculpt_tool == 'SCRAPE':
+            row = layout.row()
+            row.prop(brush, "area_radius_factor", slider=True)
             row = layout.row()
             row.prop(brush, "invert_to_scrape_fill", text="Invert to Fill")
 
         if brush.sculpt_tool == 'FILL':
+            row = layout.row()
+            row.prop(brush, "area_radius_factor", slider=True)
             row = layout.row()
             row.prop(brush, "invert_to_scrape_fill", text="Invert to Scrape")
 
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 69831f33ce5..6a40d126352 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -82,6 +82,7 @@ static void brush_defaults(Brush *brush)
   FROM_DEFAULT(topology_rake_factor);
   FROM_DEFAULT(crease_pinch_factor);
   FROM_DEFAULT(normal_radius_factor);
+  FROM_DEFAULT(area_radius_factor);
   FROM_DEFAULT(sculpt_plane);
   FROM_DEFAULT(plane_offset);
   FROM_DEFAULT(clone.alpha);
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index b39e979ec47..19a378269fe 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -105,6 +105,7 @@ MINLINE void add_v4_fl(float r[4], float f);
 MINLINE void add_v2_v2(float r[2], const float a[2]);
 MINLINE void add_v2_v2_db(double r[2], const double a[2]);
 MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]);
+MINLINE void add_v2_v2_int(int r[2], const int a[2]);
 MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]);
 MINLINE void add_v3_v3(float r[3], const float a[3]);
 MINLINE void add_v3_v3_db(double r[3], const double a[3]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index caa38c9cf08..a304042a605 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -373,6 +373,12 @@ MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
   r[1] = a[1] + b[1];
 }
 
+MINLINE void add_v2_v2_int(int r[2], const int a[2])
+{
+  r[0] = r[0] + a[0];
+  r[1] = r[1] + a[1];
+}
+
 MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
 {
   r[0] = a[0] + b[0];
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 6062d971629..dd67a4d72cb 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -4254,6 +4254,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
         }
       }
     }
+
+    for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
+      if (br->ob_mode & OB_MODE_SCULPT && br->area_radius_factor == 0.0f) {
+        br->area_radius_factor = 0.5f;
+      }
+    }
   }
 
   if (!MAIN_VERSION_ATLEAST(bmain, 282, 2)) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4fae136d133..92c74538fd1 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1439,7 +1439,8 @@ typedef struct AreaNormalCenterTLSData {
   /* 0 = towards view, 1 = flipped */
   float area_cos[2][3];
   float area_nos[2][3];
-  int area_count[2];
+  int count_no[2];
+  int count_co[2];
 } AreaNormalCenterTLSData;
 
 static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
@@ -1456,24 +1457,45 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
   SculptUndoNode *unode = NULL;
 
   bool use_original = false;
+  bool normal_test_r, area_test_r;
 
   if (ss->cache && ss->cache->original) {
     unode = sculpt_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
     use_original = (unode->co || unode->bm_entry);
   }
 
-  SculptBrushTest test;
-  SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(
-      ss, &test, data->brush->falloff_shape);
+  SculptBrushTest normal_test;
+  SculptBrushTestFn sculpt_brush_normal_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(
+      ss, &normal_test, data->brush->falloff_shape);
 
   /* Update the test radius to sample the normal using the normal radius of the brush. */
   if (data->brush->ob_mode == OB_MODE_SCULPT) {
-    float test_radius = sqrtf(test.radius_squared);
-    /* Layer brush produces artifacts with normal radius. */
+    float test_radius = sqrtf(normal_test.radius_squared);
+    /* Layer brush produces artifacts with normal and area radius. */
     if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) {
       test_radius *= data->brush->normal_radius_factor;
     }
-    test.radius_squared = test_radius * test_radius;
+    normal_test.radius_squared = test_radius * test_radius;
+  }
+
+  SculptBrushTest area_test;
+  SculptBrushTestFn sculpt_brush_area_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(
+      ss, &area_test, data->brush->falloff_shape);
+
+  if (data->brush->ob_mode == OB_MODE_SCULPT) {
+    float test_radius = sqrtf(area_test.radius_squared);
+    /* Layer brush produces artifacts with normal and area radius */
+    if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) {
+      /* Enable area radius control only on Scrape for now */
+      if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
+          data->brush->area_radius_factor > 0.0f) {
+        test_radius *= data->brush->area_radius_factor;
+      }
+      else {
+        test_radius *= data->brush->normal_radius_factor;
+      }
+    }
+    area_test.radius_squared = test_radius * test_radius;
   }
 
   /* When the mesh is edited we can't rely on original coords
@@ -1493,22 +1515,26 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
       };
       float co[3];
 
-      closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri));
+      closest_on_tri_to_point_v3(co, normal_test.location, UNPACK3(co_tri));
+
+      normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
+      area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
 
-      if (sculpt_brush_test_sq_fn(&test, co)) {
+      if (normal_test_r || area_test_r) {
         float no[3];
         int flip_index;
 
         normal_tri_v3(no, UNPACK3(co_tri));
 
         flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
-        if (use_area_cos) {
+        if (use_area_cos && area_test_r) {
           add_v3_v3(anctd->area_cos[flip_index], co);
+          anctd->count_co[flip_index] += 1;
         }
-        if (use_area_nos) {
+        if (use_area_nos && normal_test_r) {
           add_v3_v3(anctd->area_nos[flip_index], no);
+          anctd->count_no[flip_index] += 1;
         }
-        anctd->area_count[flip_index] += 1;
       }
     }
   }
@@ -1532,7 +1558,10 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
         co = vd.co;
       }
 
-      if (sculpt_brush_test_sq_fn(&test, co)) {
+      normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
+      area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
+
+      if (normal_test_r || area_test_r) {
         float no_buf[3];
         const float *no;
         int flip_index;
@@ -1555,13 +1584,14 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
 
         flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
                       0.0f);
-        if (use_area_cos) {
+        if (use_area_cos && area_test_r) {
           add_v3_v3(anctd->area_cos[flip_index], co);
+          anctd->count_co[flip_index] += 1;
         }
-        if (use_area_nos) {
+        if (use_area_nos && normal_test_r) {
           add_v3_v3(anctd->area_nos[flip_index], no);
+          anctd->count_no[flip_index] += 1;
         }
-        anctd->area_count[flip_index] += 1;
       }
     }
     BKE_pbvh_vertex_iter_end;
@@ -1584,8 +1614,8 @@ static void calc_area_normal_and_center_reduce(const void *__restrict UNUSED(use
   add_v3_v3(join->area_nos[1], anctd->area_nos[1]);
 
   /* Weights. */
-  join->area_count[0] += anctd->area_count[0];
-  join->area_count[1] += anctd->area_count[1];
+  add_v2_v2_int(join->count_no, anctd->count_no);
+  add_v2_v2_int(join->count_co, anctd->count_co);
 }
 
 static void calc_area_center(
@@ -1607,7 +1637,7 @@ static void calc_area_center(
       .use_area_cos = true,
   };
 
-  AreaNormalCenterTLSData anctd = {{{0}}};
+  AreaNormalCenterTLSData anctd = {0};
 
   PBVHParallelSettings settings;
   BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
@@ -1618,14 +1648,21 @@ static void calc_area_center(
 
   /* For flatten center. */
   for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
-    if (anctd.area_count[n] != 0) {
-      mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.area_count[n]);
+    if (anctd.count_co[n] != 0) {
+      mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
       break;
     }
   }
+
   if (n == 2) {
     zero_v3(r_area_co);
   }
+
+  if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
+    if (ss->cache) {
+      copy_v3_v3(r_area_co, ss->cache->location);
+    }
+  }
 }
 
 static void calc_area_normal(
@@ -1711,15 +1748,22 @@ static void calc_area_normal_and_center(
 
   /* For flatten center. */
   for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
-    if (anctd.area_count[n] != 0) {
-      mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.area_count[n]);
+    if (anctd.count_co[n] != 0) {
+      mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list