Fix Sharpen mesh filter in Multires

Instead of accumulating displacement for each vertex into the neighbors, accumulate the opposite displacement from each neighbor into the vertex. I think this is the same and it does not produce artifacts in Multires.

Reviewed By: sergey, brecht

Differential Revision: https://developer.blender.org/D7508
This commit is contained in:
Pablo Dobarro 2020-05-27 17:23:50 +02:00
parent caca3d9c97
commit 15ed2f841c
2 changed files with 11 additions and 27 deletions

View File

@ -132,7 +132,6 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache->automask);
MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(ss->filter_cache->sharpen_factor);
MEM_SAFE_FREE(ss->filter_cache->accum_disp);
MEM_SAFE_FREE(ss->filter_cache);
}
@ -347,9 +346,18 @@ static void mesh_filter_task_cb(void *__restrict userdata,
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
fade = clamp_f(fade, 0.0f, 0.5f);
float disp_sharpen[3] = {0.0f, 0.0f, 0.0f};
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float disp_n[3];
sub_v3_v3v3(
disp_n, SCULPT_vertex_co_get(ss, ni.index), SCULPT_vertex_co_get(ss, vd.index));
mul_v3_fl(disp_n, ss->filter_cache->sharpen_factor[ni.index]);
add_v3_v3(disp_sharpen, disp_n);
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
float disp_sharpen[3];
copy_v3_v3(disp_sharpen, ss->filter_cache->accum_disp[vd.index]);
mul_v3_fl(disp_sharpen, 1.0f - ss->filter_cache->sharpen_factor[vd.index]);
float disp_avg[3];
@ -407,24 +415,6 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
}
}
static void mesh_filter_sharpen_accumulate_displacement(SculptSession *ss)
{
const int totvert = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totvert; i++) {
zero_v3(ss->filter_cache->accum_disp[i]);
}
for (int i = 0; i < totvert; i++) {
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
float disp_n[3];
sub_v3_v3v3(disp_n, SCULPT_vertex_co_get(ss, i), SCULPT_vertex_co_get(ss, ni.index));
mul_v3_fl(disp_n, ss->filter_cache->sharpen_factor[i]);
add_v3_v3(ss->filter_cache->accum_disp[ni.index], disp_n);
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
static void mesh_filter_surface_smooth_displace_task_cb(
void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
{
@ -487,10 +477,6 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false);
if (filter_type == MESH_FILTER_SHARPEN) {
mesh_filter_sharpen_accumulate_displacement(ss);
}
SculptThreadedTaskData data = {
.sd = sd,
.ob = ob,
@ -586,7 +572,6 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) {
ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio");
ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor");
ss->filter_cache->accum_disp = MEM_mallocN(3 * sizeof(float) * totvert, "orco");
mesh_filter_sharpen_init_factors(ss);
}

View File

@ -834,7 +834,6 @@ typedef struct FilterCache {
/* Sharpen mesh filter. */
float sharpen_smooth_ratio;
float *sharpen_factor;
float (*accum_disp)[3];
/* unmasked nodes */
PBVHNode **nodes;