Fix: Plane brush sculpt normal can be invalid with symmetry enabled

Instead of skipping `update_sculpt_normal` entirely, we should avoid
doing the extra sampled calculation when we know we have a valid plane
normal.

This better aligns with future refactors to avoid both caclulating and
setting values inside `calc_brush_plane`.

Pull Request: https://projects.blender.org/blender/blender/pulls/137689
This commit is contained in:
Sean Kim
2025-04-18 06:54:05 +02:00
committed by Sean Kim
parent 18e5efd21a
commit fa2514aeab

View File

@@ -807,14 +807,6 @@ static bool brush_uses_topology_rake(const SculptSession &ss, const Brush &brush
*/
static int sculpt_brush_needs_normal(const SculptSession &ss, const Brush &brush)
{
if (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_PLANE) {
/* The normal for the Plane brush is expected to have already been calculated in
* #calc_brush_plane. */
BLI_assert_msg(!math::is_zero(ss.cache->sculpt_normal),
"Normal should have been previously calculated.");
return false;
}
using namespace blender::ed::sculpt_paint;
const MTex *mask_tex = BKE_brush_mask_texture_get(&brush, OB_MODE_SCULPT);
return ((bke::brush::supports_normal_weight(brush) && (ss.cache->normal_weight > 0.0f)) ||
@@ -2586,7 +2578,7 @@ static float3 calc_sculpt_normal(const Depsgraph &depsgraph,
static void update_sculpt_normal(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &ob,
const IndexMask &node_mask)
const brushes::NodeMaskResult &node_mask_result)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
StrokeCache &cache = *ob.sculpt->cache;
@@ -2602,10 +2594,15 @@ static void update_sculpt_normal(const Depsgraph &depsgraph,
if (cache.mirror_symmetry_pass == 0 && cache.radial_symmetry_pass == 0 &&
(SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal))
{
cache.sculpt_normal = calc_sculpt_normal(depsgraph, sd, ob, node_mask);
if (brush.falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
project_plane_v3_v3v3(cache.sculpt_normal, cache.sculpt_normal, cache.view_normal_symm);
normalize_v3(cache.sculpt_normal);
if (node_mask_result.plane_normal) {
cache.sculpt_normal = *node_mask_result.plane_normal;
}
else {
cache.sculpt_normal = calc_sculpt_normal(depsgraph, sd, ob, node_mask_result.node_mask);
if (brush.falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
project_plane_v3_v3v3(cache.sculpt_normal, cache.sculpt_normal, cache.view_normal_symm);
normalize_v3(cache.sculpt_normal);
}
}
copy_v3_v3(cache.sculpt_normal_symm, cache.sculpt_normal);
}
@@ -3294,7 +3291,7 @@ static void do_brush_action(const Depsgraph &depsgraph,
}
if (sculpt_brush_needs_normal(ss, brush)) {
update_sculpt_normal(depsgraph, sd, ob, node_mask);
update_sculpt_normal(depsgraph, sd, ob, node_mask_result);
}
update_brush_local_mat(sd, ob);