Sculpt: Initial support for custom pressure input curves

This commit is contained in:
Pablo Dobarro 2020-12-31 19:48:25 +01:00
parent 0663576d19
commit ef9eb626a8
6 changed files with 92 additions and 9 deletions

View File

@ -771,6 +771,10 @@ def brush_settings(layout, context, brush, popover=False):
elif sculpt_tool == 'MASK':
layout.row().prop(brush, "mask_tool", expand=True)
layout.template_curve_mapping(brush, "pressure_size_curve")
layout.template_curve_mapping(brush, "pressure_strength_curve", brush=True)
# End sculpt_tool interface.
# 3D and 2D Texture Paint Mode.

View File

@ -85,6 +85,8 @@ static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
}
brush_dst->curve = BKE_curvemapping_copy(brush_src->curve);
brush_dst->pressure_size_curve = BKE_curvemapping_copy(brush_src->pressure_size_curve);
brush_dst->pressure_strength_curve = BKE_curvemapping_copy(brush_src->pressure_strength_curve);
if (brush_src->gpencil_settings != NULL) {
brush_dst->gpencil_settings = MEM_dupallocN(brush_src->gpencil_settings);
brush_dst->gpencil_settings->curve_sensitivity = BKE_curvemapping_copy(
@ -119,6 +121,8 @@ static void brush_free_data(ID *id)
IMB_freeImBuf(brush->icon_imbuf);
}
BKE_curvemapping_free(brush->curve);
BKE_curvemapping_free(brush->pressure_size_curve);
BKE_curvemapping_free(brush->pressure_strength_curve);
if (brush->gpencil_settings != NULL) {
BKE_curvemapping_free(brush->gpencil_settings->curve_sensitivity);
@ -209,6 +213,12 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres
if (brush->curve) {
BKE_curvemapping_blend_write(writer, brush->curve);
}
if (brush->pressure_size_curve) {
BKE_curvemapping_blend_write(writer, brush->pressure_size_curve);
}
if (brush->pressure_strength_curve) {
BKE_curvemapping_blend_write(writer, brush->pressure_strength_curve);
}
if (brush->gpencil_settings) {
BLO_write_struct(writer, BrushGpencilSettings, brush->gpencil_settings);
@ -247,6 +257,29 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres
}
}
static void brush_reset_input_curve(CurveMapping *cumap)
{
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
cumap->preset = CURVE_PRESET_LINE;
CurveMap *cuma = cumap->cm;
BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
BKE_curvemapping_changed(cumap, false);
}
static void BKE_brush_default_input_curves_set(Brush *brush)
{
if (!brush->pressure_size_curve) {
brush->pressure_size_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
brush_reset_input_curve(brush->pressure_size_curve);
}
if (!brush->pressure_strength_curve) {
brush->pressure_strength_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
brush_reset_input_curve(brush->pressure_strength_curve);
}
}
static void brush_blend_read_data(BlendDataReader *reader, ID *id)
{
Brush *brush = (Brush *)id;
@ -254,6 +287,10 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
/* Falloff curve. */
BLO_read_data_address(reader, &brush->curve);
/* Input Curves. */
BLO_read_data_address(reader, &brush->pressure_size_curve);
BLO_read_data_address(reader, &brush->pressure_strength_curve);
BLO_read_data_address(reader, &brush->gradient);
if (brush->curve) {
@ -263,6 +300,20 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
}
if (brush->pressure_size_curve) {
BKE_curvemapping_blend_read(reader, brush->pressure_size_curve);
}
else {
BKE_brush_default_input_curves_set(brush);
}
if (brush->pressure_strength_curve) {
BKE_curvemapping_blend_read(reader, brush->pressure_strength_curve);
}
else {
BKE_brush_default_input_curves_set(brush);
}
/* grease pencil */
BLO_read_data_address(reader, &brush->gpencil_settings);
if (brush->gpencil_settings != NULL) {
@ -1678,6 +1729,7 @@ void BKE_brush_sculpt_reset(Brush *br)
brush_defaults(br);
BKE_brush_curve_preset(br, CURVE_PRESET_SMOOTH);
BKE_brush_default_input_curves_set(br);
/* Use the curve presets by default */
br->curve_preset = BRUSH_CURVE_SMOOTH;

View File

@ -679,7 +679,11 @@ static float paint_space_stroke_spacing(bContext *C,
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
float size_clamp = 0.0f;
float size = BKE_brush_size_get(scene, stroke->brush) * size_pressure;
float final_size_pressure = size_pressure;
if (brush->pressure_size_curve) {
final_size_pressure = BKE_curvemapping_evaluateF(brush->pressure_size_curve, 0, size_pressure);
}
float size = BKE_brush_size_get(scene, stroke->brush) * final_size_pressure;
if (paint_stroke_use_scene_spacing(brush, mode)) {
if (!BKE_brush_use_locked_size(scene, brush)) {
float last_object_space_position[3];
@ -688,7 +692,7 @@ static float paint_space_stroke_spacing(bContext *C,
size_clamp = paint_calc_object_space_radius(&stroke->vc, last_object_space_position, size);
}
else {
size_clamp = BKE_brush_unprojected_radius_get(scene, brush) * size_pressure;
size_clamp = BKE_brush_unprojected_radius_get(scene, brush) * final_size_pressure;
}
}
else {
@ -788,6 +792,7 @@ static float paint_space_stroke_spacing_variable(bContext *C,
/* average spacing */
float last_spacing = paint_space_stroke_spacing(
C, scene, stroke, last_size_pressure, pressure);
float new_spacing = paint_space_stroke_spacing(C, scene, stroke, new_size_pressure, pressure);
return 0.5f * (last_spacing + new_spacing);

View File

@ -2297,7 +2297,6 @@ static float brush_strength(const Sculpt *sd,
const float root_alpha = BKE_brush_alpha_get(scene, brush);
const float alpha = root_alpha * root_alpha;
const float dir = (brush->flag & BRUSH_DIR_IN) ? -1.0f : 1.0f;
const float pressure = BKE_brush_use_alpha_pressure(brush) ? cache->pressure : 1.0f;
const float pen_flip = cache->pen_flip ? -1.0f : 1.0f;
const float invert = cache->invert ? -1.0f : 1.0f;
float overlap = ups->overlap_factor;
@ -2309,14 +2308,18 @@ static float brush_strength(const Sculpt *sd,
flip = 1.0f;
}
float pressure = BKE_brush_use_alpha_pressure(brush) ? cache->pressure : 1.0f;
pressure = BKE_brush_use_alpha_pressure(brush) && brush->pressure_strength_curve ?
BKE_curvemapping_evaluateF(brush->pressure_strength_curve, 0, cache->pressure) :
pressure;
/* Pressure final value after being tweaked depending on the brush. */
float final_pressure;
switch (brush->sculpt_tool) {
case SCULPT_TOOL_CLAY:
final_pressure = pow4f(pressure);
// final_pressure = pow4f(pressure);
overlap = (1.0f + overlap) / 2.0f;
return 0.25f * alpha * flip * final_pressure * overlap * feather;
return 0.25f * alpha * flip * pressure * overlap * feather;
case SCULPT_TOOL_DRAW:
case SCULPT_TOOL_DRAW_SHARP:
case SCULPT_TOOL_LAYER:
@ -2356,11 +2359,11 @@ static float brush_strength(const Sculpt *sd,
return alpha * pressure * overlap * feather;
case SCULPT_TOOL_CLAY_STRIPS:
/* Clay Strips needs less strength to compensate the curve. */
final_pressure = powf(pressure, 1.5f);
return alpha * flip * final_pressure * overlap * feather * 0.3f;
// final_pressure = powf(pressure, 1.5f);
return alpha * flip * pressure * overlap * feather * 0.3f;
case SCULPT_TOOL_CLAY_THUMB:
final_pressure = pressure * pressure;
return alpha * flip * final_pressure * overlap * feather * 1.3f;
// final_pressure = pressure * pressure;
return alpha * flip * pressure * overlap * feather * 1.3f;
case SCULPT_TOOL_MASK:
overlap = (1.0f + overlap) / 2.0f;
@ -7196,6 +7199,11 @@ static void sculpt_update_cache_invariants(
static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, float initial_size)
{
if (brush->pressure_size_curve) {
return initial_size *
BKE_curvemapping_evaluateF(brush->pressure_size_curve, 0, cache->pressure);
}
switch (brush->sculpt_tool) {
case SCULPT_TOOL_CLAY:
return max_ff(initial_size * 0.20f, initial_size * pow3f(cache->pressure));

View File

@ -154,6 +154,10 @@ typedef struct Brush {
struct MTex mtex;
struct MTex mask_mtex;
/** Pen Input curves */
struct CurveMapping *pressure_size_curve;
struct CurveMapping *pressure_strength_curve;
struct Brush *toggle_brush;
struct ImBuf *icon_imbuf;

View File

@ -3249,6 +3249,16 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Curve", "Editable falloff curve");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "pressure_size_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Pressure/Size Curve", "Pressure/Size input curve");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "pressure_strength_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Pressure/Strength Curve", "Pressure/Strength input curve");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "paint_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Paint Curve", "Active paint curve");