[Bf-blender-cvs] [69afdf69702] master: Sculpt: Support pen pressure modulation in Paint Brush properties

Pablo Dobarro noreply at git.blender.org
Tue Jul 21 22:43:57 CEST 2020


Commit: 69afdf69702c8f1d4d43f7369a94bb36a4a349f2
Author: Pablo Dobarro
Date:   Mon Jul 20 00:37:41 2020 +0200
Branches: master
https://developer.blender.org/rB69afdf69702c8f1d4d43f7369a94bb36a4a349f2

Sculpt: Support pen pressure modulation in Paint Brush properties

This allows to use pen pressure modulation in hardness, wet mix, wet
persistence, flow and density, as well as inverting the modulation (more
pressure, less density...). With this, it is possible to create brushes
that mix paint or apply a new color based on the pressure.

Reviewed By: sergey, campbellbarton

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

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_paint_color.c
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 004bcaf819b..5044d1be34c 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -544,7 +544,11 @@ def brush_settings(layout, context, brush, popover=False):
 
         # normal_radius_factor
         layout.prop(brush, "normal_radius_factor", slider=True)
-        layout.prop(brush, "hardness", slider=True)
+
+        row = layout.row(align=True)
+        row.prop(brush, "hardness", slider=True)
+        row.prop(brush, "invert_hardness_pressure", text = "")
+        row.prop(brush, "use_hardness_pressure", text = "")
 
         # auto_smooth_factor and use_inverse_smooth_pressure
         if capabilities.has_auto_smooth:
@@ -674,13 +678,31 @@ def brush_settings(layout, context, brush, popover=False):
             layout.prop(brush, "use_grab_active_vertex")
 
         if brush.sculpt_tool == 'PAINT':
-            col = layout.column()
-            col.prop(brush, "flow")
-            col.prop(brush, "wet_mix")
-            col.prop(brush, "wet_persistence")
-            col.prop(brush, "density")
-            col.prop(brush, "tip_roundness")
-            col.prop(brush, "tip_scale_x")
+            row = layout.row(align=True)
+            row.prop(brush, "flow")
+            row.prop(brush, "invert_flow_pressure", text = "")
+            row.prop(brush, "use_flow_pressure", text= "")
+
+            row = layout.row(align=True)
+            row.prop(brush, "wet_mix")
+            row.prop(brush, "invert_wet_mix_pressure", text = "")
+            row.prop(brush, "use_wet_mix_pressure", text = "")
+
+            row = layout.row(align=True)
+            row.prop(brush, "wet_persistence")
+            row.prop(brush, "invert_wet_persistence_pressure", text ="")
+            row.prop(brush, "use_wet_persistence_pressure", text= "")
+
+            row = layout.row(align=True)
+            row.prop(brush, "density")
+            row.prop(brush, "invert_density_pressure", text = "")
+            row.prop(brush, "use_density_pressure", text = "")
+
+            row = layout.row()
+            row.prop(brush, "tip_roundness")
+
+            row = layout.row()
+            row.prop(brush, "tip_scale_x")
 
         if brush.sculpt_tool == 'SMEAR':
             col = layout.column()
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 02b736c00c2..e679c62fdaa 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2418,7 +2418,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
 
   /* Hardness. */
   float final_len = len;
-  const float hardness = br->hardness;
+  const float hardness = cache->paint_brush.hardness;
   float p = len / cache->radius;
   if (p < hardness) {
     final_len = 0.0f;
@@ -6618,6 +6618,50 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
   }
 }
 
+static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
+{
+  cache->paint_brush.hardness = brush->hardness;
+  if (brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE) {
+    cache->paint_brush.hardness *= brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE_INVERT ?
+                                       1.0f - cache->pressure :
+                                       cache->pressure;
+  }
+
+  cache->paint_brush.flow = brush->flow;
+  if (brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE) {
+    cache->paint_brush.flow *= brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE_INVERT ?
+                                   1.0f - cache->pressure :
+                                   cache->pressure;
+  }
+
+  cache->paint_brush.wet_mix = brush->wet_mix;
+  if (brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE) {
+    cache->paint_brush.wet_mix *= brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE_INVERT ?
+                                      1.0f - cache->pressure :
+                                      cache->pressure;
+
+    /* This makes wet mix more sensible in higher values, which allows to create brushes that have
+     * a wider pressure range were they only blend colors without applying too much of the brush
+     * color. */
+    cache->paint_brush.wet_mix = 1.0f - pow2f(1.0f - cache->paint_brush.wet_mix);
+  }
+
+  cache->paint_brush.wet_persistence = brush->wet_persistence;
+  if (brush->paint_flags & BRUSH_PAINT_WET_PERSISTENCE_PRESSURE) {
+    cache->paint_brush.wet_persistence = brush->paint_flags &
+                                                 BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT ?
+                                             1.0f - cache->pressure :
+                                             cache->pressure;
+  }
+
+  cache->paint_brush.density = brush->density;
+  if (brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE) {
+    cache->paint_brush.density = brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE_INVERT ?
+                                     1.0f - cache->pressure :
+                                     cache->pressure;
+  }
+}
+
 /* Initialize the stroke cache variants from operator properties. */
 static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr)
 {
@@ -6684,6 +6728,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
     cache->dyntopo_pixel_radius = ups->initial_pixel_radius;
   }
 
+  sculpt_update_cache_paint_variants(cache, brush);
+
   cache->radius_squared = cache->radius * cache->radius;
 
   if (brush->flag & BRUSH_ANCHORED) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 17c7e9e86c0..f834ab7b179 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -827,6 +827,15 @@ typedef struct StrokeCache {
   bool original;
   float anchored_location[3];
 
+  /* Paint Brush. */
+  struct {
+    float hardness;
+    float flow;
+    float wet_mix;
+    float wet_persistence;
+    float density;
+  } paint_brush;
+
   /* Pose brush */
   struct SculptPoseIKChain *pose_ik_chain;
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 608ba1b934e..f01a914fdd3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -164,7 +164,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
 
       /* Density. */
       float noise = 1.0f;
-      const float density = brush->density;
+      const float density = ss->cache->paint_brush.density;
       if (density < 1.0f) {
         const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
         if (hash_noise > density) {
@@ -178,11 +178,12 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
       float wet_mix_color[4];
       float buffer_color[4];
 
-      mul_v4_v4fl(paint_color, brush_color, fade * brush->flow);
-      mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * brush->flow);
+      mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
+      mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
 
       /* Interpolate with the wet_mix color for wet paint mixing. */
-      blend_color_interpolate_float(paint_color, paint_color, wet_mix_color, brush->wet_mix);
+      blend_color_interpolate_float(
+          paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
       blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
 
       /* Final mix over the original color using brush alpha. */
@@ -305,7 +306,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
 
   /* Wet paint color sampling. */
   float wet_color[4] = {0.0f};
-  if (brush->wet_mix > 0.0f) {
+  if (ss->cache->paint_brush.wet_mix > 0.0f) {
     SculptThreadedTaskData task_data = {
         .sd = sd,
         .ob = ob,
@@ -332,8 +333,10 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
       if (ss->cache->first_time) {
         copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
       }
-      blend_color_interpolate_float(
-          wet_color, wet_color, ss->cache->wet_mix_prev_color, brush->wet_persistence);
+      blend_color_interpolate_float(wet_color,
+                                    wet_color,
+                                    ss->cache->wet_mix_prev_color,
+                                    ss->cache->paint_brush.wet_persistence);
       copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
       CLAMP4(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
     }
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 0ad249ef2cd..76a172d6fda 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -388,6 +388,19 @@ typedef enum eAutomasking_flag {
   BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS = (1 << 3),
 } eAutomasking_flag;
 
+typedef enum ePaintBrush_flag {
+  BRUSH_PAINT_HARDNESS_PRESSURE = (1 << 0),
+  BRUSH_PAINT_HARDNESS_PRESSURE_INVERT = (1 << 1),
+  BRUSH_PAINT_FLOW_PRESSURE = (1 << 2),
+  BRUSH_PAINT_FLOW_PRESSURE_INVERT = (1 << 3),
+  BRUSH_PAINT_WET_MIX_PRESSURE = (1 << 4),
+  BRUSH_PAINT_WET_MIX_PRESSURE_INVERT = (1 << 5),
+  BRUSH_PAINT_WET_PERSISTENCE_PRESSURE = (1 << 6),
+  BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT = (1 << 7),
+  BRUSH_PAINT_DENSITY_PRESSURE = (1 << 8),
+  BRUSH_PAINT_DENSITY_PRESSURE_INVERT = (1 << 9),
+} ePaintBrush_flag;
+
 typedef struct Brush {
   ID id;
 
@@ -454,6 +467,7 @@ typedef struct Brush {
   float wet_persistence;
   /** Density */
   float density;
+  int paint_flags;
 
   /** Tip Shape */
   /* Factor that controls the shape of the brush tip by rounding the corners of a square. */
@@ -480,7 +494,7 @@ typedef struct Brush {
   /** Source for fill tool color gradient 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list