Sculpt: Clay Strips Tip Roundness property
This patch allow to change the brush tip shape between a square and a circle using a brush property. After this change we are no longer testing the distance against a cube (the Z axis is not used). I did not test this in depth, but if it does not produce any artifacts I think we can keep it this way instead of adding more complexity to the code. In this new distance test the brush falloff is only applied on the rounded parts of the square to avoid sharp artifacts in the diagonals. Because of this, the round version is much softer than the square one. The planned hardness property will fix this, but this can also be avoided by setting the fallof to a custom curve. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D6165
This commit is contained in:
parent
0ab7e32158
commit
6ee6a42d10
|
@ -609,6 +609,10 @@ def brush_settings(layout, context, brush, popover=False):
|
|||
layout.operator("sculpt.set_persistent_base")
|
||||
layout.separator()
|
||||
|
||||
if brush.sculpt_tool == 'CLAY_STRIPS':
|
||||
row = layout.row()
|
||||
row.prop(brush, "tip_roundness")
|
||||
|
||||
if brush.sculpt_tool == 'ELASTIC_DEFORM':
|
||||
layout.separator()
|
||||
layout.prop(brush, "elastic_deform_type")
|
||||
|
|
|
@ -949,9 +949,10 @@ void BKE_brush_sculpt_reset(Brush *br)
|
|||
br->flag |= BRUSH_ACCUMULATE | BRUSH_SIZE_PRESSURE;
|
||||
br->flag &= ~BRUSH_SPACE_ATTEN;
|
||||
br->alpha = 0.6f;
|
||||
br->spacing = 5;
|
||||
br->normal_radius_factor = 1.55f;
|
||||
br->curve_preset = BRUSH_CURVE_SPHERE;
|
||||
br->spacing = 6;
|
||||
br->tip_roundness = 0.18f;
|
||||
br->curve_preset = BRUSH_CURVE_SMOOTHER;
|
||||
break;
|
||||
case SCULPT_TOOL_MULTIPLANE_SCRAPE:
|
||||
br->flag2 |= BRUSH_MULTIPLANE_SCRAPE_DYNAMIC | BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW;
|
||||
|
|
|
@ -391,7 +391,7 @@ void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope
|
|||
cuma->curve[6].y = 0.025f;
|
||||
break;
|
||||
case CURVE_PRESET_BELL:
|
||||
cuma->curve[0].x = 0;
|
||||
cuma->curve[0].x = 0.0f;
|
||||
cuma->curve[0].y = 0.025f;
|
||||
|
||||
cuma->curve[1].x = 0.50f;
|
||||
|
|
|
@ -4428,7 +4428,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
/* Brush cursor alpha */
|
||||
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
|
||||
br->add_col[3] = 0.9f;
|
||||
br->sub_col[3] = 0.9f;
|
||||
|
@ -4447,5 +4446,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
br->flag2 |= BRUSH_POSE_IK_ANCHORED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tip Roundness. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "tip_roundness")) {
|
||||
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
|
||||
if (br->ob_mode & OB_MODE_SCULPT && br->sculpt_tool == SCULPT_TOOL_CLAY_STRIPS) {
|
||||
br->tip_roundness = 0.18f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1109,7 +1109,10 @@ bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
|
|||
}
|
||||
}
|
||||
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4])
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test,
|
||||
const float co[3],
|
||||
float local[4][4],
|
||||
const float roundness)
|
||||
{
|
||||
float side = M_SQRT1_2;
|
||||
float local_co[3];
|
||||
|
@ -1124,14 +1127,32 @@ bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float loca
|
|||
local_co[1] = fabsf(local_co[1]);
|
||||
local_co[2] = fabsf(local_co[2]);
|
||||
|
||||
const float p = 8.0f;
|
||||
if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
|
||||
test->dist = ((powf(local_co[0], p) + powf(local_co[1], p) + powf(local_co[2], p)) /
|
||||
powf(side, p));
|
||||
/* Keep the square and circular brush tips the same size. */
|
||||
side += (1.0f - side) * roundness;
|
||||
|
||||
const float hardness = 1.0f - roundness;
|
||||
const float constant_side = hardness * side;
|
||||
const float falloff_side = roundness * side;
|
||||
|
||||
if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
|
||||
/* Corner, distance to the center of the corner circle. */
|
||||
if (min_ff(local_co[0], local_co[1]) > constant_side) {
|
||||
float r_point[3];
|
||||
copy_v3_fl(r_point, constant_side);
|
||||
test->dist = len_v2v2(r_point, local_co) / falloff_side;
|
||||
return true;
|
||||
}
|
||||
/* Side, distance to the square XY axis. */
|
||||
if (max_ff(local_co[0], local_co[1]) > constant_side) {
|
||||
test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
|
||||
return true;
|
||||
}
|
||||
/* Inside the square, constant distance. */
|
||||
test->dist = 0.0f;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
/* Outside the square. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -5467,7 +5488,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
|
|||
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
|
||||
{
|
||||
if (sculpt_brush_test_cube(&test, vd.co, mat)) {
|
||||
if (sculpt_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
|
||||
if (plane_point_side_flip(vd.co, test.plane_tool, flip)) {
|
||||
float intr[3];
|
||||
float val[3];
|
||||
|
@ -7047,12 +7068,11 @@ static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, flo
|
|||
case SCULPT_TOOL_CLAY:
|
||||
return max_ff(initial_size * 0.20f, initial_size * pow3f(cache->pressure));
|
||||
case SCULPT_TOOL_CLAY_STRIPS:
|
||||
return max_ff(initial_size * 0.35f, initial_size * pow2f(cache->pressure));
|
||||
return max_ff(initial_size * 0.30f, initial_size * pow2f(cache->pressure));
|
||||
case SCULPT_TOOL_CLAY_THUMB: {
|
||||
float clay_stabilized_pressure = sculpt_clay_thumb_get_stabilized_pressure(cache);
|
||||
return initial_size * clay_stabilized_pressure;
|
||||
}
|
||||
|
||||
default:
|
||||
return initial_size * cache->pressure;
|
||||
}
|
||||
|
|
|
@ -280,7 +280,10 @@ void sculpt_brush_test_init(struct SculptSession *ss, SculptBrushTest *test);
|
|||
bool sculpt_brush_test_sphere(SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_sphere_sq(SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]);
|
||||
bool sculpt_brush_test_cube(SculptBrushTest *test,
|
||||
const float co[3],
|
||||
float local[4][4],
|
||||
const float roundness);
|
||||
bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3]);
|
||||
bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v);
|
||||
bool sculpt_search_circle_cb(PBVHNode *node, void *data_v);
|
||||
|
|
|
@ -311,7 +311,7 @@ typedef struct Brush {
|
|||
char mask_tool;
|
||||
/** Active grease pencil tool. */
|
||||
char gpencil_tool;
|
||||
char _pad1[5];
|
||||
char _pad1[1];
|
||||
|
||||
float autosmooth_factor;
|
||||
|
||||
|
@ -330,6 +330,10 @@ typedef struct Brush {
|
|||
int curve_preset;
|
||||
int automasking_flags;
|
||||
|
||||
/* Factor that controls the shape of the brush tip by rounding the corners of a square. */
|
||||
/* 0.0 value produces a square, 1.0 produces a circle. */
|
||||
float tip_roundness;
|
||||
|
||||
int elastic_deform_type;
|
||||
float elastic_deform_volume_preservation;
|
||||
|
||||
|
|
|
@ -1943,6 +1943,12 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
"Number of segments of the inverse kinematics chain that will deform the mesh");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "tip_roundness", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "tip_roundness");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Tip Roundness", "Roundness of the brush tip");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "auto_smooth_factor", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "autosmooth_factor");
|
||||
RNA_def_property_float_default(prop, 0);
|
||||
|
|
Loading…
Reference in New Issue