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.py17
-rw-r--r--source/blender/blenkernel/BKE_paint.h13
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h9
-rw-r--r--source/blender/blenkernel/intern/brush.c6
-rw-r--r--source/blender/blenkernel/intern/paint.c27
-rw-r--r--source/blender/blenkernel/intern/pbvh.c29
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c43
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c176
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c4
-rw-r--r--source/blender/makesdna/DNA_brush_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_brush.c1
12 files changed, 159 insertions, 170 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 32b386bf0ab..a13f39da4a9 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -600,19 +600,10 @@ def brush_settings(layout, context, brush, popover=False):
# use_persistent, set_persistent_base
if capabilities.has_persistence:
ob = context.sculpt_object
- do_persistent = True
-
- # not supported yet for this case
- for md in ob.modifiers:
- if md.type == 'MULTIRES':
- do_persistent = False
- break
-
- if do_persistent:
- layout.separator()
- layout.prop(brush, "use_persistent")
- layout.operator("sculpt.set_persistent_base")
- layout.separator()
+ layout.separator()
+ layout.prop(brush, "use_persistent")
+ layout.operator("sculpt.set_persistent_base")
+ layout.separator()
if brush.sculpt_tool == 'CLAY_STRIPS':
row = layout.row()
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 012188bed96..f78a142704b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -279,6 +279,12 @@ typedef struct SculptClothSimulation {
} SculptClothSimulation;
+typedef struct SculptLayerPersistentBase {
+ float co[3];
+ float no[3];
+ float disp;
+} SculptLayerPersistentBase;
+
/* Session data (mode-specific) */
typedef struct SculptSession {
@@ -329,9 +335,6 @@ typedef struct SculptSession {
unsigned int texcache_side, *texcache, texcache_actual;
struct ImagePool *tex_pool;
- /* Layer brush persistence between strokes */
- float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
-
struct StrokeCache *cache;
struct FilterCache *filter_cache;
@@ -359,6 +362,10 @@ typedef struct SculptSession {
float pose_origin[3];
SculptPoseIKChain *pose_ik_chain_preview;
+ /* Layer brush persistence between strokes */
+ /* This is freed with the PBVH, so it is always in sync with the mesh. */
+ SculptLayerPersistentBase *layer_base;
+
/* Transform operator */
float pivot_pos[3];
float pivot_rot[4];
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index a59ce816e26..94f0e544a6b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -122,7 +122,6 @@ void BKE_pbvh_build_bmesh(PBVH *bvh,
const int cd_vert_node_offset,
const int cd_face_node_offset);
void BKE_pbvh_free(PBVH *bvh);
-void BKE_pbvh_free_layer_disp(PBVH *bvh);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
@@ -310,14 +309,6 @@ void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets);
void BKE_pbvh_face_sets_color_set(PBVH *bvh, int seed, int color_default);
-/* Layer displacement */
-
-/* Get the node's displacement layer, creating it if necessary */
-float *BKE_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
-
-/* If the node has a displacement layer, free it and set to null */
-void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
-
/* vertex deformer */
float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3];
void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], const int totvert);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e1303b8d723..d775598f420 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1422,6 +1422,12 @@ void BKE_brush_sculpt_reset(Brush *br)
br->cloth_deform_type = BRUSH_CLOTH_DEFORM_DRAG;
br->flag &= ~(BRUSH_ALPHA_PRESSURE | BRUSH_SIZE_PRESSURE);
break;
+ case SCULPT_TOOL_LAYER:
+ br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->hardness = 0.35f;
+ br->alpha = 1.0f;
+ br->height = 0.05f;
+ break;
default:
break;
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index c5d60b29aca..420538061bb 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1306,9 +1306,10 @@ static void sculptsession_free_pbvh(Object *object)
}
MEM_SAFE_FREE(ss->pmap);
-
MEM_SAFE_FREE(ss->pmap_mem);
+ MEM_SAFE_FREE(ss->layer_base);
+
MEM_SAFE_FREE(ss->preview_vert_index_list);
ss->preview_vert_index_count = 0;
}
@@ -1353,31 +1354,17 @@ void BKE_sculptsession_free(Object *ob)
BM_log_free(ss->bm_log);
}
- if (ss->texcache) {
- MEM_freeN(ss->texcache);
- }
+ MEM_SAFE_FREE(ss->texcache);
if (ss->tex_pool) {
BKE_image_pool_free(ss->tex_pool);
}
- if (ss->layer_co) {
- MEM_freeN(ss->layer_co);
- }
+ MEM_SAFE_FREE(ss->orig_cos);
+ MEM_SAFE_FREE(ss->deform_cos);
+ MEM_SAFE_FREE(ss->deform_imats);
- if (ss->orig_cos) {
- MEM_freeN(ss->orig_cos);
- }
- if (ss->deform_cos) {
- MEM_freeN(ss->deform_cos);
- }
- if (ss->deform_imats) {
- MEM_freeN(ss->deform_imats);
- }
-
- if (ss->preview_vert_index_list) {
- MEM_freeN(ss->preview_vert_index_list);
- }
+ MEM_SAFE_FREE(ss->preview_vert_index_list);
if (ss->pose_ik_chain_preview) {
for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 06622f0d009..977e70745a3 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -685,8 +685,6 @@ void BKE_pbvh_free(PBVH *bvh)
if (node->face_vert_indices) {
MEM_freeN((void *)node->face_vert_indices);
}
- BKE_pbvh_node_layer_disp_free(node);
-
if (node->bm_faces) {
BLI_gset_free(node->bm_faces, NULL);
}
@@ -722,13 +720,6 @@ void BKE_pbvh_free(PBVH *bvh)
MEM_freeN(bvh);
}
-void BKE_pbvh_free_layer_disp(PBVH *bvh)
-{
- for (int i = 0; i < bvh->totnode; i++) {
- BKE_pbvh_node_layer_disp_free(&bvh->nodes[i]);
- }
-}
-
static void pbvh_iter_begin(PBVHIter *iter,
PBVH *bvh,
BKE_pbvh_SearchCallback scb,
@@ -2768,26 +2759,6 @@ void BKE_pbvh_grids_update(
}
}
-/* Get the node's displacement layer, creating it if necessary */
-float *BKE_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
-{
- if (!node->layer_disp) {
- int totvert = 0;
- BKE_pbvh_node_num_verts(bvh, node, &totvert, NULL);
- node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
- }
- return node->layer_disp;
-}
-
-/* If the node has a displacement layer, free it and set to null */
-void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
-{
- if (node->layer_disp) {
- MEM_freeN(node->layer_disp);
- node->layer_disp = NULL;
- }
-}
-
float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3]
{
float(*vertCos)[3] = NULL;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 04ca5770a97..33372a0d7cf 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1216,6 +1216,34 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession
}
}
+void SCULPT_layer_brush_height_preview_draw(const uint gpuattr,
+ const Brush *brush,
+ const float obmat[4][4],
+ const float location[3],
+ const float normal[3],
+ const float rds,
+ const float line_width,
+ const float outline_col[3],
+ const float alpha)
+{
+ float cursor_trans[4][4], cursor_rot[4][4];
+ float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float quat[4];
+ float height_preview_trans[3];
+ copy_m4_m4(cursor_trans, obmat);
+ madd_v3_v3v3fl(height_preview_trans, location, normal, brush->height);
+ translate_m4(
+ cursor_trans, height_preview_trans[0], height_preview_trans[1], height_preview_trans[2]);
+ rotation_between_vecs_to_quat(quat, z_axis, normal);
+ quat_to_mat4(cursor_rot, quat);
+ GPU_matrix_mul(cursor_trans);
+ GPU_matrix_mul(cursor_rot);
+
+ GPU_line_width(line_width);
+ immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
+ imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
+}
+
static bool paint_use_2d_cursor(ePaintMode mode)
{
if (mode >= PAINT_MODE_TEXTURE_3D) {
@@ -1476,6 +1504,21 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
GPU_matrix_pop();
}
+ /* Layer brush height. */
+ if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+ GPU_matrix_push();
+ SCULPT_layer_brush_height_preview_draw(pos,
+ brush,
+ vc.obact->obmat,
+ gi.location,
+ gi.normal,
+ rds,
+ 1.0f,
+ outline_col,
+ outline_alpha);
+ GPU_matrix_pop();
+ }
+
/* Update and draw dynamic mesh preview lines. */
GPU_matrix_push();
GPU_matrix_mul(vc.obact->obmat);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index b8c6e97fcc1..66f66bfceb8 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1709,10 +1709,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
/* Update the test radius to sample the normal using the normal radius of the brush. */
if (data->brush->ob_mode == OB_MODE_SCULPT) {
float test_radius = sqrtf(normal_test.radius_squared);
- /* Layer brush produces artifacts with normal and area radius. */
- if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) {
- test_radius *= data->brush->normal_radius_factor;
- }
+ test_radius *= data->brush->normal_radius_factor;
normal_test.radius = test_radius;
normal_test.radius_squared = test_radius * test_radius;
}
@@ -1724,15 +1721,13 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
if (data->brush->ob_mode == OB_MODE_SCULPT) {
float test_radius = sqrtf(area_test.radius_squared);
/* Layer brush produces artifacts with normal and area radius */
- if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) {
- /* Enable area radius control only on Scrape for now */
- if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
- data->brush->area_radius_factor > 0.0f) {
- test_radius *= data->brush->area_radius_factor;
- }
- else {
- test_radius *= data->brush->normal_radius_factor;
- }
+ /* Enable area radius control only on Scrape for now */
+ if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
+ data->brush->area_radius_factor > 0.0f) {
+ test_radius *= data->brush->area_radius_factor;
+ }
+ else {
+ test_radius *= data->brush->normal_radius_factor;
}
area_test.radius = test_radius;
area_test.radius_squared = test_radius * test_radius;
@@ -4072,23 +4067,14 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
SculptSession *ss = data->ob->sculpt;
Sculpt *sd = data->sd;
const Brush *brush = data->brush;
- const float *offset = data->offset;
+
+ const bool use_persistent_base = ss->layer_base && brush->flag & BRUSH_PERSISTENT;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
- float *layer_disp;
const float bstrength = ss->cache->bstrength;
- const float lim = (bstrength < 0.0f) ? -data->brush->height : data->brush->height;
- /* XXX: layer brush needs conversion to proxy but its more complicated */
- /* proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
-
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- /* Why does this have to be thread-protected? */
- BLI_mutex_lock(&data->mutex);
- layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, data->nodes[n]);
- BLI_mutex_unlock(&data->mutex);
-
SculptBrushTest test;
SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
ss, &test, data->brush->falloff_shape);
@@ -4098,38 +4084,65 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test_sq_fn(&test, orig_data.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,
- tls->thread_id);
- float *disp = &layer_disp[vd.i];
- float val[3];
-
- *disp += fade;
+ const float fade = SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ tls->thread_id);
- /* Don't let the displacement go past the limit. */
- if ((lim < 0.0f && *disp < lim) || (lim >= 0.0f && *disp > lim)) {
- *disp = lim;
+ const int vi = vd.index;
+ float *disp_factor;
+ if (use_persistent_base) {
+ disp_factor = &ss->layer_base[vi].disp;
+ }
+ else {
+ disp_factor = &ss->cache->layer_displacement_factor[vi];
}
- mul_v3_v3fl(val, offset, *disp);
+ /* When using persistent base, the layer brush Ctrl invert mode resets the height of the
+ * layer to 0. This makes possible to clean edges of previously added layers on top of the
+ * base. */
+ /* The main direction of the layers is inverted using the regular brush strength with the
+ * brush direction property. */
+ if (use_persistent_base && ss->cache->invert) {
+ (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
+ ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
+ }
+ else {
+ (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
+ }
+ if (vd.mask) {
+ const float clamp_mask = 1.0f - *vd.mask;
+ CLAMP(*disp_factor, -clamp_mask, clamp_mask);
+ }
+ else {
+ CLAMP(*disp_factor, -1.0f, 1.0f);
+ }
- if (!ss->multires.active && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
- int index = vd.vert_indices[vd.i];
+ float final_co[3];
+ float normal[3];
- /* Persistent base. */
- add_v3_v3(val, ss->layer_co[index]);
+ if (use_persistent_base) {
+ copy_v3_v3(normal, ss->layer_base[vi].no);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, ss->layer_base[vi].co, normal, *disp_factor);
}
else {
- add_v3_v3(val, orig_data.co);
+ normal_short_to_float_v3(normal, orig_data.no);
+ mul_v3_fl(normal, brush->height);
+ madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
}
- SCULPT_clip(sd, ss, vd.co, val);
+ float vdisp[3];
+ sub_v3_v3v3(vdisp, final_co, vd.co);
+ mul_v3_fl(vdisp, fabsf(fade));
+ add_v3_v3v3(final_co, vd.co, vdisp);
+
+ SCULPT_clip(sd, ss, vd.co, final_co);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -4143,24 +4156,23 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- float offset[3];
- mul_v3_v3v3(offset, ss->cache->scale, ss->cache->sculpt_normal_symm);
+ if (ss->cache->mirror_symmetry_pass == 0 && ss->cache->radial_symmetry_pass == 0 &&
+ ss->cache->first_time) {
+ ss->cache->layer_displacement_factor = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss),
+ "layer displacement factor");
+ }
SculptThreadedTaskData data = {
.sd = sd,
.ob = ob,
.brush = brush,
.nodes = nodes,
- .offset = offset,
};
- BLI_mutex_init(&data.mutex);
PBVHParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
BKE_pbvh_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
-
- BLI_mutex_end(&data.mutex);
}
static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
@@ -5948,6 +5960,7 @@ void SCULPT_cache_free(StrokeCache *cache)
{
MEM_SAFE_FREE(cache->dial);
MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
+ MEM_SAFE_FREE(cache->layer_displacement_factor);
if (cache->pose_ik_chain) {
SCULPT_pose_ik_chain_free(cache->pose_ik_chain);
@@ -6006,14 +6019,9 @@ static void sculpt_update_cache_invariants(
ss->cache = cache;
/* Set scaling adjustment. */
- if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- max_scale = 1.0f;
- }
- else {
- max_scale = 0.0f;
- for (int i = 0; i < 3; i++) {
- max_scale = max_ff(max_scale, fabsf(ob->scale[i]));
- }
+ max_scale = 0.0f;
+ for (int i = 0; i < 3; i++) {
+ max_scale = max_ff(max_scale, fabsf(ob->scale[i]));
}
cache->scale[0] = max_scale / ob->scale[0];
cache->scale[1] = max_scale / ob->scale[1];
@@ -6129,32 +6137,6 @@ static void sculpt_update_cache_invariants(
normalize_v3(cache->true_gravity_direction);
}
- /* Initialize layer brush displacements and persistent coords. */
- if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- /* Not supported yet for multires or dynamic topology. */
- if (!ss->multires.active && !ss->bm && !ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
- if (!ss->layer_co) {
- ss->layer_co = MEM_mallocN(sizeof(float) * 3 * ss->totvert, "sculpt mesh vertices copy");
- }
-
- if (ss->deform_cos) {
- memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
- }
- else {
- for (int i = 0; i < ss->totvert; i++) {
- copy_v3_v3(ss->layer_co[i], ss->mvert[i].co);
- }
- }
- }
-
- if (ss->bm) {
- /* Free any remaining layer displacements from nodes. If not and topology changes
- * from using another tool, then next layer toolstroke
- * can access past disp array bounds. */
- BKE_pbvh_free_layer_disp(ss->pbvh);
- }
- }
-
/* Make copies of the mesh vertex locations and normals for some tools. */
if (brush->flag & BRUSH_ANCHORED) {
cache->original = true;
@@ -7290,13 +7272,25 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
{
- SculptSession *ss = CTX_data_active_object(C)->sculpt;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
if (ss) {
- if (ss->layer_co) {
- MEM_freeN(ss->layer_co);
+ SCULPT_vertex_random_access_init(ss);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+
+ MEM_SAFE_FREE(ss->layer_base);
+
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->layer_base = MEM_mallocN(sizeof(SculptLayerPersistentBase) * totvert,
+ "layer persistent base");
+
+ for (int i = 0; i < totvert; i++) {
+ copy_v3_v3(ss->layer_base[i].co, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, i, ss->layer_base[i].no);
+ ss->layer_base[i].disp = 0.0f;
}
- ss->layer_co = NULL;
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 8189ca8c551..c1e7508f98b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -781,6 +781,9 @@ typedef struct StrokeCache {
/* Stores the displacement produced by the laplacian step of HC smooth. */
float (*surface_smooth_laplacian_disp)[3];
+ /* Layer brush */
+ float *layer_displacement_factor;
+
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
struct Dial *dial;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index c07ebf790d4..414a6101071 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1314,10 +1314,6 @@ void SCULPT_undo_push_end_ex(const bool use_nested_undo)
MEM_freeN(unode->no);
unode->no = NULL;
}
-
- if (unode->node) {
- BKE_pbvh_node_layer_disp_free(unode->node);
- }
}
/* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 87f0de6daa2..041943bc5e4 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -689,7 +689,6 @@ typedef enum eBrushUVSculptTool {
SCULPT_TOOL_SLIDE_RELAX, \
SCULPT_TOOL_CREASE, \
SCULPT_TOOL_BLOB, \
- SCULPT_TOOL_LAYER, \
SCULPT_TOOL_INFLATE, \
SCULPT_TOOL_CLAY, \
SCULPT_TOOL_CLAY_STRIPS, \
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index b5ed49b3476..1286d752b62 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2094,6 +2094,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "height");
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0, 1.0f);
+ RNA_def_property_ui_range(prop, 0, 0.2f, 1, 3);
RNA_def_property_ui_text(
prop, "Brush Height", "Affectable height of brush (layer height for layer tool, i.e.)");
RNA_def_property_update(prop, 0, "rna_Brush_update");