diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_filter_mesh.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_filter_mesh.c | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index e9a98a17f8a..f9ae91fce7f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -82,7 +82,7 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) ss->filter_cache->random_seed = rand(); - float center[3] = {0.0f}; + const float center[3] = {0.0f}; SculptSearchSphereData search_data = { .original = true, .center = center, @@ -132,6 +132,7 @@ 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->sharpen_detail_directions); MEM_SAFE_FREE(ss->filter_cache); } @@ -260,7 +261,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, switch (filter_type) { case MESH_FILTER_SMOOTH: - CLAMP(fade, -1.0f, 1.0f); + fade = clamp_f(fade, -1.0f, 1.0f); SCULPT_neighbor_coords_average_interior(ss, avg, vd.index); sub_v3_v3v3(val, avg, orig_co); madd_v3_v3v3fl(val, orig_co, val, fade); @@ -305,7 +306,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, const uint *hash_co = (const uint *)orig_co; const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^ BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed); - mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f); + mul_v3_fl(normal, hash * (1.0f / 0xFFFFFFFF) - 0.5f); mul_v3_v3fl(disp, normal, fade); break; } @@ -356,6 +357,17 @@ static void mesh_filter_task_cb(void *__restrict userdata, mul_v3_v3fl( disp_avg, disp_avg, smooth_ratio * pow2f(ss->filter_cache->sharpen_factor[vd.index])); add_v3_v3v3(disp, disp_avg, disp_sharpen); + + /* Intensify details. */ + if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) { + float detail_strength[3]; + normal_short_to_float_v3(detail_strength, orig_data.no); + copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]); + madd_v3_v3fl(disp, + detail_strength, + -ss->filter_cache->sharpen_intensify_detail_strength * + ss->filter_cache->sharpen_factor[vd.index]); + } break; } } @@ -388,8 +400,10 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) for (int i = 0; i < totvert; i++) { float avg[3]; SCULPT_neighbor_coords_average(ss, avg, i); - ss->filter_cache->sharpen_factor[i] = len_v3v3(avg, SCULPT_vertex_co_get(ss, i)); + sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]); } + float max_factor = 0.0f; for (int i = 0; i < totvert; i++) { if (ss->filter_cache->sharpen_factor[i] > max_factor) { @@ -402,6 +416,30 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) ss->filter_cache->sharpen_factor[i] *= max_factor; ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]); } + + /* Smooth the calculated factors and directions to remove high frecuency detail. */ + for (int smooth_iterations = 0; + smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations; + smooth_iterations++) { + for (int i = 0; i < totvert; i++) { + float direction_avg[3] = {0.0f, 0.0f, 0.0f}; + float sharpen_avg = 0; + int total = 0; + + SculptVertexNeighborIter ni; + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]); + sharpen_avg += ss->filter_cache->sharpen_factor[ni.index]; + total++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + + if (total > 0) { + mul_v3_v3fl(ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / total); + ss->filter_cache->sharpen_factor[i] = sharpen_avg / total; + } + } + } } static void mesh_filter_surface_smooth_displace_task_cb( @@ -461,7 +499,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent * float len = event->prevclickx - event->mval[0]; filter_strength = filter_strength * -len * 0.001f * UI_DPI_FAC; - SCULPT_vertex_random_access_init(ss); + SCULPT_vertex_random_access_ensure(ss); bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets); BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false); @@ -527,7 +565,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); - SCULPT_vertex_random_access_init(ss); + SCULPT_vertex_random_access_ensure(ss); const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets); BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false); @@ -556,7 +594,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent } if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SURFACE_SMOOTH) { - ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(3 * sizeof(float) * totvert, + ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(sizeof(float[3]) * totvert, "surface smooth disp"); ss->filter_cache->surface_smooth_shape_preservation = RNA_float_get( op->ptr, "surface_smooth_shape_preservation"); @@ -566,7 +604,14 @@ 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_intensify_detail_strength = RNA_float_get( + op->ptr, "sharpen_intensify_detail_strength"); + ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get( + op->ptr, "sharpen_curvature_smooth_iterations"); + ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor"); + ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "sharpen detail direction"); mesh_filter_sharpen_init_factors(ss); } @@ -582,7 +627,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) { /* Identifiers. */ - ot->name = "Filter mesh"; + ot->name = "Filter Mesh"; ot->idname = "SCULPT_OT_mesh_filter"; ot->description = "Applies a filter to modify the current mesh"; @@ -642,4 +687,24 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) "How much smoothing is applied to polished surfaces", 0.0f, 1.0f); + + RNA_def_float(ot->srna, + "sharpen_intensify_detail_strength", + 0.0f, + 0.0f, + 10.0f, + "Intensify Details", + "How much creases and valleys are intensified", + 0.0f, + 1.0f); + + RNA_def_int(ot->srna, + "sharpen_curvature_smooth_iterations", + 0, + 0, + 10, + "Curvature Smooth Iterations", + "How much smooth the resulting shape is, ignoring high frequency details", + 0, + 10); } |