Sculpt: Initial support for custom pressure input curves
This commit is contained in:
parent
0663576d19
commit
ef9eb626a8
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue