Cleanup: Sculpt: Split mask and position smooth brushes
Previously they shared the same implementation with a check per vertex for whether to smooth the mask or the positions. Though it adds a bit of duplication for now, everything else becomes simpler if the brush implementations are split.
This commit is contained in:
parent
97d0b52779
commit
ac15db443f
|
@ -3569,10 +3569,10 @@ static void do_brush_action(Sculpt *sd,
|
|||
{
|
||||
if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
|
||||
smooth::do_smooth_brush(
|
||||
sd, ob, nodes, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
|
||||
sd, ob, nodes, brush->autosmooth_factor * (1.0f - ss->cache->pressure));
|
||||
}
|
||||
else {
|
||||
smooth::do_smooth_brush(sd, ob, nodes, brush->autosmooth_factor, false);
|
||||
smooth::do_smooth_brush(sd, ob, nodes, brush->autosmooth_factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2715,7 +2715,7 @@ void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
|||
SCULPT_do_mask_brush_draw(sd, ob, nodes);
|
||||
break;
|
||||
case BRUSH_MASK_SMOOTH:
|
||||
smooth::do_smooth_brush(sd, ob, nodes, ss->cache->bstrength, true);
|
||||
smooth::do_smooth_mask_brush(sd, ob, nodes, ss->cache->bstrength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1523,9 +1523,10 @@ void neighbor_color_average(SculptSession *ss, float result[4], PBVHVertRef vert
|
|||
*/
|
||||
void neighbor_coords_average_interior(SculptSession *ss, float result[3], PBVHVertRef vertex);
|
||||
|
||||
void do_smooth_brush(
|
||||
Sculpt *sd, Object *ob, blender::Span<PBVHNode *> nodes, float bstrength, bool smooth_mask);
|
||||
void do_smooth_brush(Sculpt *sd, Object *ob, blender::Span<PBVHNode *> nodes);
|
||||
void do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength);
|
||||
void do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
void do_smooth_mask_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength);
|
||||
|
||||
/* Surface Smooth Brush. */
|
||||
|
||||
|
@ -1542,7 +1543,7 @@ void surface_smooth_displace_step(SculptSession *ss,
|
|||
PBVHVertRef vertex,
|
||||
float beta,
|
||||
float fade);
|
||||
void do_surface_smooth_brush(Sculpt *sd, Object *ob, blender::Span<PBVHNode *> nodes);
|
||||
void do_surface_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
/* Slide/Relax */
|
||||
void relax_vertex(SculptSession *ss,
|
||||
|
|
|
@ -253,13 +253,11 @@ static void enhance_details_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes
|
|||
});
|
||||
}
|
||||
|
||||
static void do_smooth_brush_task(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
const bool smooth_mask,
|
||||
const SculptMaskWriteInfo mask_write,
|
||||
float bstrength,
|
||||
PBVHNode *node)
|
||||
static void smooth_mask_node(Object *ob,
|
||||
const Brush *brush,
|
||||
const SculptMaskWriteInfo mask_write,
|
||||
float bstrength,
|
||||
PBVHNode *node)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
|
@ -287,61 +285,115 @@ static void do_smooth_brush_task(Object *ob,
|
|||
sqrtf(test.dist),
|
||||
vd.no,
|
||||
vd.fno,
|
||||
smooth_mask ? 0.0f : vd.mask,
|
||||
0.0f,
|
||||
vd.vertex,
|
||||
thread_id,
|
||||
&automask_data);
|
||||
if (smooth_mask) {
|
||||
float val = neighbor_mask_average(ss, vd.vertex) - vd.mask;
|
||||
val *= fade * bstrength;
|
||||
float new_mask = vd.mask + val;
|
||||
CLAMP(new_mask, 0.0f, 1.0f);
|
||||
float val = neighbor_mask_average(ss, vd.vertex) - vd.mask;
|
||||
val *= fade * bstrength;
|
||||
float new_mask = vd.mask + val;
|
||||
CLAMP(new_mask, 0.0f, 1.0f);
|
||||
|
||||
SCULPT_mask_vert_set(BKE_pbvh_type(ss->pbvh), mask_write, new_mask, vd);
|
||||
}
|
||||
else {
|
||||
float avg[3], val[3];
|
||||
neighbor_coords_average_interior(ss, avg, vd.vertex);
|
||||
sub_v3_v3v3(val, avg, vd.co);
|
||||
madd_v3_v3v3fl(val, vd.co, val, fade);
|
||||
SCULPT_clip(sd, ss, vd.co, val);
|
||||
if (vd.is_mesh) {
|
||||
BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
|
||||
SCULPT_mask_vert_set(BKE_pbvh_type(ss->pbvh), mask_write, new_mask, vd);
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void do_smooth_mask_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
const int max_iterations = 4;
|
||||
const float fract = 1.0f / max_iterations;
|
||||
|
||||
CLAMP(bstrength, 0.0f, 1.0f);
|
||||
|
||||
const int count = int(bstrength * max_iterations);
|
||||
const float last = max_iterations * (bstrength - count * fract);
|
||||
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
SCULPT_boundary_info_ensure(ob);
|
||||
|
||||
SculptMaskWriteInfo mask_write = SCULPT_mask_get_for_write(ss);
|
||||
|
||||
for (const int iteration : IndexRange(count)) {
|
||||
const float strength = (iteration != count) ? 1.0f : last;
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
smooth_mask_node(ob, brush, mask_write, strength, nodes[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void smooth_position_node(
|
||||
Object *ob, Sculpt *sd, const Brush *brush, float bstrength, PBVHNode *node)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
PBVHVertexIter vd;
|
||||
|
||||
CLAMP(bstrength, 0.0f, 1.0f);
|
||||
|
||||
SculptBrushTest test;
|
||||
SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
|
||||
ss, &test, brush->falloff_shape);
|
||||
|
||||
const int thread_id = BLI_task_parallel_thread_id(nullptr);
|
||||
auto_mask::NodeData automask_data = auto_mask::node_begin(*ob, ss->cache->automasking, *node);
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto_mask::node_update(automask_data, vd);
|
||||
|
||||
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
|
||||
brush,
|
||||
vd.co,
|
||||
sqrtf(test.dist),
|
||||
vd.no,
|
||||
vd.fno,
|
||||
vd.mask,
|
||||
vd.vertex,
|
||||
thread_id,
|
||||
&automask_data);
|
||||
|
||||
float avg[3], val[3];
|
||||
neighbor_coords_average_interior(ss, avg, vd.vertex);
|
||||
sub_v3_v3v3(val, avg, vd.co);
|
||||
madd_v3_v3v3fl(val, vd.co, val, fade);
|
||||
SCULPT_clip(sd, ss, vd.co, val);
|
||||
if (vd.is_mesh) {
|
||||
BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
|
||||
}
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void do_smooth_brush(
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength, const bool smooth_mask)
|
||||
void do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
const int max_iterations = 4;
|
||||
const float fract = 1.0f / max_iterations;
|
||||
int iteration, count;
|
||||
float last;
|
||||
|
||||
CLAMP(bstrength, 0.0f, 1.0f);
|
||||
|
||||
count = int(bstrength * max_iterations);
|
||||
last = max_iterations * (bstrength - count * fract);
|
||||
const int count = int(bstrength * max_iterations);
|
||||
const float last = max_iterations * (bstrength - count * fract);
|
||||
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
SCULPT_boundary_info_ensure(ob);
|
||||
|
||||
for (iteration = 0; iteration <= count; iteration++) {
|
||||
for (const int iteration : IndexRange(count)) {
|
||||
const float strength = (iteration != count) ? 1.0f : last;
|
||||
SculptMaskWriteInfo mask_write;
|
||||
if (smooth_mask) {
|
||||
mask_write = SCULPT_mask_get_for_write(ss);
|
||||
}
|
||||
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
do_smooth_brush_task(ob, sd, brush, smooth_mask, mask_write, strength, nodes[i]);
|
||||
smooth_position_node(ob, sd, brush, strength, nodes[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -361,7 +413,7 @@ void do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
|||
}
|
||||
else {
|
||||
/* Regular mode, smooth. */
|
||||
do_smooth_brush(sd, ob, nodes, ss->cache->bstrength, false);
|
||||
do_smooth_brush(sd, ob, nodes, ss->cache->bstrength);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue