Sculpt: Smooth deform type for Boundary Brush

This adds a smooth deformation type to the boundary brush, which smooths
the boundary and has a regular falloff towards the inside of the mesh.
For smoothing, only vertices parallel to the boundary are taken into
account, creating this effect.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D9204
This commit is contained in:
Pablo Dobarro 2020-10-18 00:16:54 +02:00
parent f780bfafcf
commit 2b2f3da721
3 changed files with 65 additions and 0 deletions

View File

@ -868,6 +868,66 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
}
static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symmetry_pass = ss->cache->mirror_symmetry_pass;
const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass];
const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
continue;
}
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
}
float coord_accum[3] = {0.0f, 0.0f, 0.0f};
int total_neighbors = 0;
const int current_propagation_steps = boundary->edit_info[vd.index].num_propagation_steps;
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
if (current_propagation_steps == boundary->edit_info[ni.index].num_propagation_steps) {
add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.index));
total_neighbors++;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total_neighbors == 0) {
continue;
}
float disp[3];
float avg[3];
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
mul_v3_v3fl(avg, coord_accum, 1.0f / total_neighbors);
sub_v3_v3v3(disp, avg, vd.co);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(
target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
}
/* Main Brush Function. */
void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
@ -945,6 +1005,9 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
case BRUSH_BOUNDARY_DEFORM_TWIST:
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_twist_task_cb_ex, &settings);
break;
case BRUSH_BOUNDARY_DEFORM_SMOOTH:
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_smooth_task_cb_ex, &settings);
break;
}
}

View File

@ -388,6 +388,7 @@ typedef enum eBrushBoundaryDeformType {
BRUSH_BOUNDARY_DEFORM_INFLATE = 2,
BRUSH_BOUNDARY_DEFORM_GRAB = 3,
BRUSH_BOUNDARY_DEFORM_TWIST = 4,
BRUSH_BOUNDARY_DEFORM_SMOOTH = 5,
} eBrushBushBoundaryDeformType;
typedef enum eBrushBoundaryFalloffType {

View File

@ -2181,6 +2181,7 @@ static void rna_def_brush(BlenderRNA *brna)
{BRUSH_BOUNDARY_DEFORM_INFLATE, "INFLATE", 0, "Inflate", ""},
{BRUSH_BOUNDARY_DEFORM_GRAB, "GRAB", 0, "Grab", ""},
{BRUSH_BOUNDARY_DEFORM_TWIST, "TWIST", 0, "Twist", ""},
{BRUSH_BOUNDARY_DEFORM_SMOOTH, "SMOOTH", 0, "Smooth", ""},
{0, NULL, 0, NULL, NULL},
};