diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_paint_common.py | 38 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 48 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_intern.h | 9 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_paint_color.c | 17 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_types.h | 16 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 78 |
6 files changed, 189 insertions, 17 deletions
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 application. */ char gradient_fill_mode; - char _pad0[1]; + char _pad0[5]; /** Projection shape (sphere, circle). */ char falloff_shape; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index b4703ab9aa2..43f31922292 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2283,6 +2283,84 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Tip Scale X", "Scale of the brush tip in the X axis"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_hardness_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_HARDNESS_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure for Hardness", "Use pressure to modulate hardness"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "invert_hardness_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_HARDNESS_PRESSURE_INVERT); + RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0); + RNA_def_property_ui_text( + prop, "Invert Pressure for Hardness", "Invert the modulation of pressure in hardness"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "use_flow_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_FLOW_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure for Flow", "Use pressure to modulate flow"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "invert_flow_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_FLOW_PRESSURE_INVERT); + RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0); + RNA_def_property_ui_text( + prop, "Invert Pressure for Flow", "Invert the modulation of pressure in flow"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "use_wet_mix_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_MIX_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure for Wet Mix", "Use pressure to modulate wet mix"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "invert_wet_mix_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_MIX_PRESSURE_INVERT); + RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0); + RNA_def_property_ui_text( + prop, "Invert Pressure for Wet Mix", "Invert the modulation of pressure in wet mix"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "use_wet_persistence_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_PERSISTENCE_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text( + prop, "Use Pressure for Wet Persistence", "Use pressure to modulate wet persistence"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "invert_wet_persistence_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna( + prop, NULL, "paint_flags", BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT); + RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0); + RNA_def_property_ui_text(prop, + "Invert Pressure for Wet Persistence", + "Invert the modulation of pressure in wet persistence"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "use_density_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_DENSITY_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure for Density", "Use pressure to modulate density"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "invert_density_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_DENSITY_PRESSURE_INVERT); + RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0); + RNA_def_property_ui_text( + prop, "Invert Pressure for Density", "Invert the modulation of pressure in density"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "dash_ratio", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "dash_ratio"); RNA_def_property_range(prop, 0.0f, 1.0f); |