Paint: Disable pressure sensitivity for certain brushes
A subset of brushes behave as "anchored" brushes, in that they do not apply to the surface continually underneath the cursor, but have a starting point and then are influenced by the mouse movement. These brushes behave oddly with tablet pressure sensitivity, as they cannot modulate over the course of the stroke without causing odd behavior. Currently, the pressure is only sampled at the very beginning of the stroke, which makes it difficult to control intuitively. Further work can be done to improve this behavior (e.g. D6603). The full list of brush types affected is below: * Grab * Snake Hook * Elastic Deform * Pose * Boundary * Thumb * Rotate * Cloth with Grab deformation Resolves #83697 Pull Request: https://projects.blender.org/blender/blender/pulls/146825
This commit is contained in:
@@ -783,17 +783,19 @@ def brush_settings(layout, context, brush, popover=False):
|
||||
|
||||
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="")
|
||||
if capabilities.has_hardness_pressure:
|
||||
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:
|
||||
pressure_name = "use_inverse_smooth_pressure" if capabilities.has_auto_smooth_pressure else None
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
context,
|
||||
brush,
|
||||
"auto_smooth_factor",
|
||||
pressure_name="use_inverse_smooth_pressure",
|
||||
pressure_name=pressure_name,
|
||||
slider=True,
|
||||
)
|
||||
|
||||
@@ -1080,6 +1082,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
size_mode = False
|
||||
strength = False
|
||||
strength_pressure = False
|
||||
size_pressure = False
|
||||
weight = False
|
||||
direction = False
|
||||
|
||||
@@ -1089,6 +1092,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
blend_mode = brush.image_paint_capabilities.has_color
|
||||
size = brush.image_paint_capabilities.has_radius
|
||||
strength = strength_pressure = True
|
||||
size_pressure = True
|
||||
|
||||
# Sculpt #
|
||||
if mode == 'SCULPT':
|
||||
@@ -1098,6 +1102,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
strength = True
|
||||
strength_pressure = brush.sculpt_capabilities.has_strength_pressure
|
||||
direction = brush.sculpt_capabilities.has_direction
|
||||
size_pressure = brush.sculpt_capabilities.has_size_pressure
|
||||
|
||||
# Vertex Paint #
|
||||
if mode == 'PAINT_VERTEX':
|
||||
@@ -1106,6 +1111,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
size = True
|
||||
strength = True
|
||||
strength_pressure = True
|
||||
size_pressure = True
|
||||
|
||||
# Weight Paint #
|
||||
if mode == 'PAINT_WEIGHT':
|
||||
@@ -1113,6 +1119,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
size = True
|
||||
weight = brush.weight_paint_capabilities.has_weight
|
||||
strength = strength_pressure = True
|
||||
size_pressure = True
|
||||
# Only draw blend mode for the Draw tool, because for other tools it is pointless. D5928#137944
|
||||
if brush.weight_brush_type == 'DRAW':
|
||||
blend_mode = True
|
||||
@@ -1124,6 +1131,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
strength = tool not in {'ADD', 'DELETE'}
|
||||
direction = tool in {'GROW_SHRINK', 'SELECTION_PAINT'}
|
||||
strength_pressure = tool not in {'SLIDE', 'ADD', 'DELETE'}
|
||||
size_pressure = True
|
||||
|
||||
# Grease Pencil #
|
||||
if mode == 'PAINT_GREASE_PENCIL':
|
||||
@@ -1135,6 +1143,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
if mode == 'SCULPT_GREASE_PENCIL':
|
||||
size = True
|
||||
strength = True
|
||||
size_pressure = True
|
||||
|
||||
### Draw settings. ###
|
||||
ups = UnifiedPaintPanel.paint_settings(context).unified_paint_settings
|
||||
@@ -1159,14 +1168,16 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
size_prop = "unprojected_size"
|
||||
if size or size_mode:
|
||||
if size:
|
||||
pressure_name = "use_pressure_size" if size_pressure else None
|
||||
curve_visibility_name = "show_size_curve" if size_pressure else None
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
context,
|
||||
brush,
|
||||
size_prop,
|
||||
unified_name="use_unified_size",
|
||||
pressure_name="use_pressure_size",
|
||||
curve_visibility_name="show_size_curve",
|
||||
pressure_name=pressure_name,
|
||||
curve_visibility_name=curve_visibility_name,
|
||||
text="Size",
|
||||
slider=True,
|
||||
)
|
||||
|
||||
@@ -257,6 +257,9 @@ bool supports_secondary_cursor_color(const Brush &brush);
|
||||
bool supports_smooth_stroke(const Brush &brush);
|
||||
bool supports_space_attenuation(const Brush &brush);
|
||||
bool supports_strength_pressure(const Brush &brush);
|
||||
bool supports_size_pressure(const Brush &brush);
|
||||
bool supports_auto_smooth_pressure(const Brush &brush);
|
||||
bool supports_hardness_pressure(const Brush &brush);
|
||||
bool supports_inverted_direction(const Brush &brush);
|
||||
bool supports_gravity(const Brush &brush);
|
||||
bool supports_tilt(const Brush &brush);
|
||||
|
||||
@@ -1885,9 +1885,41 @@ bool supports_space_attenuation(const Brush &brush)
|
||||
SCULPT_BRUSH_TYPE_SMOOTH,
|
||||
SCULPT_BRUSH_TYPE_SNAKE_HOOK);
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper method for classifying a certain subset of brush types.
|
||||
*
|
||||
* Certain sculpt deformations are 'grab-like' in that they behave as if they have an anchored
|
||||
* start point.
|
||||
*/
|
||||
static bool is_grab_tool(const Brush &brush)
|
||||
{
|
||||
return (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_CLOTH &&
|
||||
brush.cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) ||
|
||||
ELEM(brush.sculpt_brush_type,
|
||||
SCULPT_BRUSH_TYPE_GRAB,
|
||||
SCULPT_BRUSH_TYPE_SNAKE_HOOK,
|
||||
SCULPT_BRUSH_TYPE_ELASTIC_DEFORM,
|
||||
SCULPT_BRUSH_TYPE_POSE,
|
||||
SCULPT_BRUSH_TYPE_BOUNDARY,
|
||||
SCULPT_BRUSH_TYPE_THUMB,
|
||||
SCULPT_BRUSH_TYPE_ROTATE);
|
||||
}
|
||||
bool supports_strength_pressure(const Brush &brush)
|
||||
{
|
||||
return !ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_GRAB, SCULPT_BRUSH_TYPE_SNAKE_HOOK);
|
||||
return !is_grab_tool(brush);
|
||||
}
|
||||
bool supports_size_pressure(const Brush &brush)
|
||||
{
|
||||
return !is_grab_tool(brush);
|
||||
}
|
||||
bool supports_auto_smooth_pressure(const Brush &brush)
|
||||
{
|
||||
return !is_grab_tool(brush);
|
||||
}
|
||||
bool supports_hardness_pressure(const Brush &brush)
|
||||
{
|
||||
return !is_grab_tool(brush);
|
||||
}
|
||||
bool supports_inverted_direction(const Brush &brush)
|
||||
{
|
||||
|
||||
@@ -1114,9 +1114,7 @@ bool paint_supports_dynamic_size(const Brush &br, const PaintMode mode)
|
||||
|
||||
switch (mode) {
|
||||
case PaintMode::Sculpt:
|
||||
if (sculpt_is_grab_tool(br)) {
|
||||
return false;
|
||||
}
|
||||
return bke::brush::supports_size_pressure(br);
|
||||
break;
|
||||
|
||||
case PaintMode::Texture2D: /* fall through */
|
||||
|
||||
@@ -3422,7 +3422,9 @@ static void do_brush_action(const Depsgraph &depsgraph,
|
||||
if (!ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_SMOOTH, SCULPT_BRUSH_TYPE_MASK) &&
|
||||
brush.autosmooth_factor > 0)
|
||||
{
|
||||
if (brush.flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
|
||||
if (bke::brush::supports_auto_smooth_pressure(brush) &&
|
||||
brush.flag & BRUSH_INVERSE_SMOOTH_PRESSURE)
|
||||
{
|
||||
brushes::do_smooth_brush(
|
||||
depsgraph, sd, ob, node_mask, brush.autosmooth_factor * (1.0f - ss.cache->pressure));
|
||||
}
|
||||
@@ -4290,7 +4292,9 @@ static void brush_delta_update(const Depsgraph &depsgraph,
|
||||
static void cache_paint_invariants_update(StrokeCache &cache, const Brush &brush)
|
||||
{
|
||||
cache.hardness = brush.hardness;
|
||||
if (brush.paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE) {
|
||||
if (bke::brush::supports_hardness_pressure(brush) &&
|
||||
brush.paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE)
|
||||
{
|
||||
cache.hardness *= brush.paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE_INVERT ?
|
||||
1.0f - cache.pressure :
|
||||
cache.pressure;
|
||||
|
||||
@@ -552,6 +552,24 @@ static bool rna_BrushCapabilitiesSculpt_has_strength_pressure_get(PointerRNA *pt
|
||||
return blender::bke::brush::supports_strength_pressure(*br);
|
||||
}
|
||||
|
||||
static bool rna_BrushCapabilitiesSculpt_has_size_pressure_get(PointerRNA *ptr)
|
||||
{
|
||||
const Brush *br = static_cast<const Brush *>(ptr->data);
|
||||
return blender::bke::brush::supports_size_pressure(*br);
|
||||
}
|
||||
|
||||
static bool rna_BrushCapabilitiesSculpt_has_auto_smooth_pressure_get(PointerRNA *ptr)
|
||||
{
|
||||
const Brush *br = static_cast<const Brush *>(ptr->data);
|
||||
return blender::bke::brush::supports_auto_smooth_pressure(*br);
|
||||
}
|
||||
|
||||
static bool rna_BrushCapabilitiesSculpt_has_hardness_pressure_get(PointerRNA *ptr)
|
||||
{
|
||||
const Brush *br = static_cast<const Brush *>(ptr->data);
|
||||
return blender::bke::brush::supports_hardness_pressure(*br);
|
||||
}
|
||||
|
||||
static bool rna_BrushCapabilitiesSculpt_has_direction_get(PointerRNA *ptr)
|
||||
{
|
||||
const Brush *br = static_cast<const Brush *>(ptr->data);
|
||||
@@ -1169,6 +1187,9 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna)
|
||||
SCULPT_BRUSH_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
|
||||
SCULPT_BRUSH_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
|
||||
SCULPT_BRUSH_CAPABILITY(has_strength_pressure, "Has Strength Pressure");
|
||||
SCULPT_BRUSH_CAPABILITY(has_size_pressure, "Has Size Pressure");
|
||||
SCULPT_BRUSH_CAPABILITY(has_auto_smooth_pressure, "Has Auto-Smooth Pressure");
|
||||
SCULPT_BRUSH_CAPABILITY(has_hardness_pressure, "Has Hardness Pressure");
|
||||
SCULPT_BRUSH_CAPABILITY(has_direction, "Has Direction");
|
||||
SCULPT_BRUSH_CAPABILITY(has_gravity, "Has Gravity");
|
||||
SCULPT_BRUSH_CAPABILITY(has_tilt, "Has Tilt");
|
||||
|
||||
Reference in New Issue
Block a user