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:
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py8
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py3
-rw-r--r--source/blender/blenkernel/intern/brush.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c258
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h9
-rw-r--r--source/blender/makesdna/DNA_brush_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_brush.c42
7 files changed, 326 insertions, 8 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 34afcc09407..3d2474d006a 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -665,6 +665,14 @@ def brush_settings(layout, context, brush, popover=False):
col.prop(brush, "use_multiplane_scrape_dynamic")
col.prop(brush, "show_multiplane_scrape_planes_preview")
+ if brush.sculpt_tool == 'SMOOTH':
+ col = layout.column()
+ col.prop(brush, "smooth_deform_type")
+ if brush.smooth_deform_type == 'SURFACE':
+ col.prop(brush, "surface_smooth_shape_preservation")
+ col.prop(brush, "surface_smooth_current_vertex")
+ col.prop(brush, "surface_smooth_iterations")
+
if brush.sculpt_tool == 'MASK':
layout.row().prop(brush, "mask_tool", expand=True)
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index c501c4f66a1..9a7e42bdbce 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1031,6 +1031,9 @@ class _defs_sculpt:
layout.prop(props, "strength")
layout.prop(props, "deform_axis")
layout.prop(props, "use_face_sets")
+ if (props.type == "SURFACE_SMOOTH"):
+ layout.prop(props, "surface_smooth_shape_preservation", expand=False)
+ layout.prop(props, "surface_smooth_current_vertex", expand=False)
return dict(
idname="builtin.mesh_filter",
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e6045c45dc8..2306b046026 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1348,6 +1348,9 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_SPACE_ATTEN;
br->spacing = 5;
br->alpha = 0.7f;
+ br->surface_smooth_shape_preservation = 0.5f;
+ br->surface_smooth_current_vertex = 0.5f;
+ br->surface_smooth_iterations = 4;
break;
case SCULPT_TOOL_SNAKE_HOOK:
br->alpha = 1.0f;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index ea3fb5624dd..a99b6e44d18 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -914,6 +914,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool)
SCULPT_TOOL_LAYER,
SCULPT_TOOL_DRAW_SHARP,
SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_SMOOTH,
SCULPT_TOOL_POSE);
}
@@ -2859,7 +2860,7 @@ static float bmesh_neighbor_average_mask(BMVert *v, const int cd_vert_mask_offse
}
}
-static void grids_neighbor_average(SculptSession *ss, float result[3], int index)
+static void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index)
{
float avg[3] = {0.0f, 0.0f, 0.0f};
int total = 0;
@@ -3155,7 +3156,7 @@ static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata,
}
else {
float avg[3], val[3];
- grids_neighbor_average(ss, avg, vd.index);
+ SCULPT_neighbor_coords_average(ss, avg, vd.index);
sub_v3_v3v3(val, avg, vd.co);
madd_v3_v3v3fl(val, vd.co, val, fade);
sculpt_clip(sd, ss, vd.co, val);
@@ -3254,6 +3255,153 @@ static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptSession *ss = ob->sculpt;
smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
}
+/* HC Smooth Algorithm. */
+/* From: Improved Laplacian Smoothing of Noisy Surface Meshes */
+
+static void surface_smooth_laplacian_step(SculptSession *ss,
+ float *disp,
+ const float co[3],
+ float (*laplacian_disp)[3],
+ const int v_index,
+ const float origco[3],
+ const float alpha)
+{
+ float laplacian_smooth_co[3];
+ float weigthed_o[3], weigthed_q[3], d[3];
+ SCULPT_neighbor_coords_average(ss, laplacian_smooth_co, v_index);
+
+ mul_v3_v3fl(weigthed_o, origco, alpha);
+ mul_v3_v3fl(weigthed_q, co, 1.0f - alpha);
+ add_v3_v3v3(d, weigthed_o, weigthed_q);
+ sub_v3_v3v3(laplacian_disp[v_index], laplacian_smooth_co, d);
+
+ sub_v3_v3v3(disp, laplacian_smooth_co, co);
+}
+
+static void surface_smooth_displace_step(SculptSession *ss,
+ float *co,
+ float (*laplacian_disp)[3],
+ const int v_index,
+ const float beta,
+ const float fade)
+{
+ float b_avg[3] = {0.0f, 0.0f, 0.0f};
+ float b_current_vertex[3];
+ int total = 0;
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, v_index, ni)
+ {
+ add_v3_v3(b_avg, laplacian_disp[ni.index]);
+ total++;
+ }
+ sculpt_vertex_neighbors_iter_end(ni);
+ if (total > 0) {
+ mul_v3_v3fl(b_current_vertex, b_avg, (1.0f - beta) / (float)total);
+ madd_v3_v3fl(b_current_vertex, laplacian_disp[v_index], beta);
+ mul_v3_fl(b_current_vertex, clamp_f(fade, 0.0f, 1.0f));
+ sub_v3_v3(co, b_current_vertex);
+ }
+}
+
+static void do_surface_smooth_brush_laplacian_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+ float alpha = brush->surface_smooth_shape_preservation;
+
+ PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ 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, 0.0f, vd.index, tls->thread_id);
+
+ float disp[3];
+ surface_smooth_laplacian_step(ss,
+ disp,
+ vd.co,
+ ss->cache->surface_smooth_laplacian_disp,
+ vd.index,
+ orig_data.co,
+ alpha);
+ madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+}
+
+static void do_surface_smooth_brush_displace_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+ const float beta = brush->surface_smooth_current_vertex;
+
+ PBVHVertexIter vd;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ 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, 0.0f, vd.index, tls->thread_id);
+ surface_smooth_displace_step(
+ ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->cache->mirror_symmetry_pass == 0 && ss->cache->radial_symmetry_pass == 0) {
+ ss->cache->surface_smooth_laplacian_disp = MEM_callocN(
+ SCULPT_vertex_count_get(ss) * 3 * sizeof(float), "HC smooth laplacian b");
+ }
+
+ /* Threaded loop over nodes. */
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ PBVHParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ for (int i = 0; i < brush->surface_smooth_iterations; i++) {
+ BKE_pbvh_parallel_range(
+ 0, totnode, &data, do_surface_smooth_brush_laplacian_task_cb_ex, &settings);
+ BKE_pbvh_parallel_range(
+ 0, totnode, &data, do_surface_smooth_brush_displace_task_cb_ex, &settings);
+ }
+}
static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
@@ -6010,7 +6158,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
do_draw_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_SMOOTH:
- do_smooth_brush(sd, ob, nodes, totnode);
+ if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
+ do_smooth_brush(sd, ob, nodes, totnode);
+ }
+ else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
+ do_surface_smooth_brush(sd, ob, nodes, totnode);
+ }
break;
case SCULPT_TOOL_CREASE:
do_crease_brush(sd, ob, nodes, totnode);
@@ -9178,7 +9331,9 @@ static void sculpt_filter_cache_free(SculptSession *ss)
if (ss->filter_cache->automask) {
MEM_freeN(ss->filter_cache->automask);
}
-
+ if (ss->filter_cache->surface_smooth_laplacian_disp) {
+ MEM_freeN(ss->filter_cache->surface_smooth_laplacian_disp);
+ }
MEM_freeN(ss->filter_cache);
ss->filter_cache = NULL;
}
@@ -9191,6 +9346,7 @@ typedef enum eSculptMeshFilterTypes {
MESH_FILTER_RANDOM = 4,
MESH_FILTER_RELAX = 5,
MESH_FILTER_RELAX_FACE_SETS = 6,
+ MESH_FILTER_SURFACE_SMOOTH = 7,
} eSculptMeshFilterTypes;
static EnumPropertyItem prop_mesh_filter_types[] = {
@@ -9205,6 +9361,11 @@ static EnumPropertyItem prop_mesh_filter_types[] = {
0,
"Relax Face Sets",
"Smooth the edges of all the Face Sets"},
+ {MESH_FILTER_SURFACE_SMOOTH,
+ "SURFACE_SMOOTH",
+ 0,
+ "Surface Smooth",
+ "Smooth the surface of the mesh, preserving the volume"},
{0, NULL, 0, NULL, NULL},
};
@@ -9223,8 +9384,11 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = {
static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets)
{
- return use_face_sets ||
- ELEM(filter_type, MESH_FILTER_SMOOTH, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS);
+ return use_face_sets || ELEM(filter_type,
+ MESH_FILTER_SMOOTH,
+ MESH_FILTER_RELAX,
+ MESH_FILTER_RELAX_FACE_SETS,
+ MESH_FILTER_SURFACE_SMOOTH);
}
static void mesh_filter_task_cb(void *__restrict userdata,
@@ -9296,7 +9460,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
bmesh_neighbor_average(avg, vd.bm_vert);
break;
case PBVH_GRIDS:
- grids_neighbor_average(ss, avg, vd.index);
+ SCULPT_neighbor_coords_average(ss, avg, vd.index);
break;
}
sub_v3_v3v3(val, avg, orig_co);
@@ -9357,6 +9521,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
sub_v3_v3v3(disp, val, vd.co);
break;
}
+ case MESH_FILTER_SURFACE_SMOOTH: {
+ surface_smooth_laplacian_step(ss,
+ disp,
+ vd.co,
+ ss->filter_cache->surface_smooth_laplacian_disp,
+ vd.index,
+ orig_data.co,
+ ss->filter_cache->surface_smooth_shape_preservation);
+ break;
+ }
}
for (int it = 0; it < 3; it++) {
@@ -9365,7 +9539,12 @@ static void mesh_filter_task_cb(void *__restrict userdata,
}
}
- add_v3_v3v3(final_pos, orig_co, disp);
+ if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
+ madd_v3_v3v3fl(final_pos, vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ }
+ else {
+ add_v3_v3v3(final_pos, orig_co, disp);
+ }
copy_v3_v3(vd.co, final_pos);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -9376,6 +9555,32 @@ static void mesh_filter_task_cb(void *__restrict userdata,
BKE_pbvh_node_mark_update(node);
}
+static void mesh_filter_surface_smooth_displace_task_cb(
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ PBVHNode *node = data->nodes[i];
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ float fade = vd.mask ? *vd.mask : 0.0f;
+ fade = 1.0f - fade;
+ fade *= data->filter_strength;
+ if (fade == 0.0f) {
+ continue;
+ }
+ surface_smooth_displace_step(ss,
+ vd.co,
+ ss->filter_cache->surface_smooth_laplacian_disp,
+ vd.index,
+ ss->filter_cache->surface_smooth_current_vertex,
+ clamp_f(fade, 0.0f, 1.0f));
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
@@ -9418,6 +9623,14 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
&settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
BKE_pbvh_parallel_range(0, ss->filter_cache->totnode, &data, mesh_filter_task_cb, &settings);
+ if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
+ BKE_pbvh_parallel_range(0,
+ ss->filter_cache->totnode,
+ &data,
+ mesh_filter_surface_smooth_displace_task_cb,
+ &settings);
+ }
+
ss->filter_cache->iteration_count++;
if (ss->deform_modifiers_active || ss->shapekey_active) {
@@ -9480,6 +9693,15 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
}
+ if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SURFACE_SMOOTH) {
+ ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(
+ 3 * sizeof(float) * SCULPT_vertex_count_get(ss), "surface smooth disp");
+ ss->filter_cache->surface_smooth_shape_preservation = RNA_float_get(
+ op->ptr, "surface_smooth_shape_preservation");
+ ss->filter_cache->surface_smooth_current_vertex = RNA_float_get(
+ op->ptr, "surface_smooth_current_vertex");
+ }
+
ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X;
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
@@ -9532,6 +9754,26 @@ static void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
false,
"Use Face Sets",
"Apply the filter only to the Face Mask under the cursor");
+
+ /* Surface Smooth Mesh Filter properties. */
+ RNA_def_float(ot->srna,
+ "surface_smooth_shape_preservation",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Shape Preservation",
+ "How much of the original shape is preserved when smoothing",
+ 0.0f,
+ 1.0f);
+ RNA_def_float(ot->srna,
+ "surface_smooth_current_vertex",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Per Vertex Displacement",
+ "How much the position of each individual vertex influences the final result",
+ 0.0f,
+ 1.0f);
}
typedef enum eSculptMaskFilterTypes {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index b8235dc5c95..d8e29d0e773 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -618,6 +618,10 @@ typedef struct StrokeCache {
float initial_normal[3];
float true_initial_normal[3];
+ /* Surface Smooth Brush */
+ /* Stores the displacement produced by the laplacian step of HC smooth. */
+ float (*surface_smooth_laplacian_disp)[3];
+
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
struct Dial *dial;
@@ -650,6 +654,11 @@ typedef struct FilterCache {
* achieve certain effects. */
int iteration_count;
+ /* Stores the displacement produced by the laplacian step of HC smooth. */
+ float (*surface_smooth_laplacian_disp)[3];
+ float surface_smooth_shape_preservation;
+ float surface_smooth_current_vertex;
+
/* unmasked nodes */
PBVHNode **nodes;
int totnode;
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 1fad828e887..59e9d3be58d 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -281,6 +281,11 @@ typedef enum eBrushClothDeformType {
BRUSH_CLOTH_DEFORM_EXPAND = 6,
} eBrushClothDeformType;
+typedef enum eBrushSmoothDeformType {
+ BRUSH_SMOOTH_DEFORM_LAPLACIAN = 0,
+ BRUSH_SMOOTH_DEFORM_SURFACE = 1,
+} eBrushSmoothDeformType;
+
typedef enum eBrushClothForceFalloffType {
BRUSH_CLOTH_FORCE_FALLOFF_RADIAL = 0,
BRUSH_CLOTH_FORCE_FALLOFF_PLANE = 1,
@@ -473,6 +478,12 @@ typedef struct Brush {
float cloth_sim_limit;
float cloth_sim_falloff;
+ /* smooth */
+ int smooth_deform_type;
+ float surface_smooth_shape_preservation;
+ float surface_smooth_current_vertex;
+ int surface_smooth_iterations;
+
/* multiplane scrape */
float multiplane_scrape_angle;
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index a4091718487..1a163c9e2eb 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1794,6 +1794,20 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_smooth_deform_type_items[] = {
+ {BRUSH_SMOOTH_DEFORM_LAPLACIAN,
+ "LAPLACIAN",
+ 0,
+ "Laplacian",
+ "Smooths the surface and the volume"},
+ {BRUSH_SMOOTH_DEFORM_SURFACE,
+ "SURFACE",
+ 0,
+ "Surface",
+ "Smooths the surface of the mesh, preserving the volue"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "Brush", "ID");
RNA_def_struct_ui_text(
srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting");
@@ -1909,6 +1923,11 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Force Falloff", "Shape used in the brush to apply force to the cloth");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "smooth_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_smooth_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "jitter_unit", PROP_ENUM, PROP_NONE); /* as an enum */
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, brush_jitter_unit_items);
@@ -2101,6 +2120,29 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Pose Origin Offset", "Offset of the pose origin in relation to the brush radius");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "surface_smooth_shape_preservation", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "surface_smooth_shape_preservation");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop, "Shape Preservation", "How much of the original shape is preserved when smoothing");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "surface_smooth_current_vertex", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "surface_smooth_current_vertex");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop,
+ "Per Vertex Displacement",
+ "How much the position of each individual vertex influences the final result");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "surface_smooth_iterations", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "surface_smooth_iterations");
+ RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_ui_range(prop, 1, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Iterations", "Number of smoothing iterations per brush step");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "multiplane_scrape_angle", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "multiplane_scrape_angle");
RNA_def_property_range(prop, 0.0f, 160.0f);