Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_filter_mesh.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c81
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);
}