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')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c88
-rw-r--r--source/blender/makesrna/intern/rna_brush.c14
4 files changed, 105 insertions, 3 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 03d079ba0e1..5d09109c506 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2331,7 +2331,7 @@ static float brush_strength(const Sculpt *sd,
}
case SCULPT_TOOL_SMOOTH:
- return alpha * pressure * feather;
+ return flip * alpha * pressure * feather;
case SCULPT_TOOL_PINCH:
if (flip > 0.0f) {
@@ -6365,6 +6365,7 @@ void SCULPT_cache_free(StrokeCache *cache)
MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(cache->layer_displacement_factor);
MEM_SAFE_FREE(cache->prev_colors);
+ MEM_SAFE_FREE(cache->detail_directions);
if (cache->pose_ik_chain) {
SCULPT_pose_ik_chain_free(cache->pose_ik_chain);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 65006031bb3..caa36a909fe 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -889,6 +889,9 @@ typedef struct StrokeCache {
/* Pose brush */
struct SculptPoseIKChain *pose_ik_chain;
+ /* Enhance Details. */
+ float (*detail_directions)[3];
+
/* Clay Thumb brush */
/* Angle of the front tilting plane of the brush to simulate clay accumulation. */
float clay_thumb_front_angle;
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 2b93298ac4a..63fe8643628 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -195,6 +195,85 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
}
}
+static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ Sculpt *sd = data->sd;
+ const Brush *brush = data->brush;
+
+ PBVHVertexIter vd;
+
+ float bstrength = ss->cache->bstrength;
+ CLAMP(bstrength, -1.0f, 1.0f);
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
+ SCULPT_clip(sd, ss, vd.co, disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void SCULPT_enhance_details_brush(Sculpt *sd,
+ Object *ob,
+ PBVHNode **nodes,
+ const int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ SCULPT_vertex_random_access_ensure(ss);
+ SCULPT_boundary_info_ensure(ob);
+
+ if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->cache->detail_directions = MEM_malloc_arrayN(
+ totvert, 3 * sizeof(float), "details directions");
+
+ for (int i = 0; i < totvert; i++) {
+ float avg[3];
+ SCULPT_neighbor_coords_average(ss, avg, i);
+ sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ }
+ }
+
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings);
+}
+
static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -300,7 +379,14 @@ void SCULPT_smooth(Sculpt *sd,
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
- SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
+ if (ss->cache->bstrength <= 0.0f) {
+ /* Invert mode, intensify details. */
+ SCULPT_enhance_details_brush(sd, ob, nodes, totnode);
+ }
+ else {
+ /* Regular mode, smooth. */
+ SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
+ }
}
/* HC Smooth Algorithm. */
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index a3fa4fed575..cc39a5dbe8d 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -45,6 +45,16 @@ static const EnumPropertyItem prop_direction_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static const EnumPropertyItem prop_smooth_direction_items[] = {
+ {0, "SMOOTH", ICON_ADD, "Smooth", "Smooth the surfae"},
+ {BRUSH_DIR_IN,
+ "ENHANCE_DETAILS",
+ ICON_REMOVE,
+ "Enhance Details",
+ "Enhance the surface detail"},
+ {0, NULL, 0, NULL, NULL},
+};
+
static const EnumPropertyItem sculpt_stroke_method_items[] = {
{0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
{BRUSH_DRAG_DOT, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"},
@@ -527,6 +537,7 @@ static bool rna_BrushCapabilitiesSculpt_has_direction_get(PointerRNA *ptr)
SCULPT_TOOL_DRAW_SHARP,
SCULPT_TOOL_CLAY,
SCULPT_TOOL_CLAY_STRIPS,
+ SCULPT_TOOL_SMOOTH,
SCULPT_TOOL_LAYER,
SCULPT_TOOL_INFLATE,
SCULPT_TOOL_BLOB,
@@ -795,7 +806,8 @@ static const EnumPropertyItem *rna_Brush_direction_itemf(bContext *C,
case SCULPT_TOOL_CLAY:
case SCULPT_TOOL_CLAY_STRIPS:
return prop_direction_items;
-
+ case SCULPT_TOOL_SMOOTH:
+ return prop_smooth_direction_items;
case SCULPT_TOOL_MASK:
switch ((BrushMaskTool)me->mask_tool) {
case BRUSH_MASK_DRAW: