diff --git a/source/blender/editors/sculpt_paint/brushes/clay.cc b/source/blender/editors/sculpt_paint/brushes/clay.cc index 593bff3a2a7..09c9b6899d6 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay.cc @@ -59,12 +59,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float4 &test_plane, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -82,22 +81,23 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - calc_closest_to_plane(test_plane, positions_eval, verts, translations); + calc_closest_to_plane(test_plane, position_data.eval, verts, translations); scale_translations(translations, strength); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -225,10 +225,8 @@ void do_clay_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -238,13 +236,12 @@ void do_clay_brush(const Depsgraph &depsgraph, brush, test_plane, bstrength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/clay_strips.cc b/source/blender/editors/sculpt_paint/brushes/clay_strips.cc index 096e9392a4a..df97e7b7e9d 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay_strips.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay_strips.cc @@ -45,12 +45,11 @@ static void calc_faces(const Depsgraph &depsgraph, const float4 &plane, const float strength, const bool flip, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -61,38 +60,39 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; - calc_brush_cube_distances(brush, mat, positions_eval, verts, distances, factors); + calc_brush_cube_distances(brush, mat, position_data.eval, verts, distances, factors); scale_factors(distances, cache.radius); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, strength); if (flip) { - filter_below_plane_factors(positions_eval, verts, plane, factors); + filter_below_plane_factors(position_data.eval, verts, plane, factors); } else { - filter_above_plane_factors(positions_eval, verts, plane, factors); + filter_above_plane_factors(position_data.eval, verts, plane, factors); } tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - calc_translations_to_plane(positions_eval, verts, plane, translations); + calc_translations_to_plane(position_data.eval, verts, plane, translations); filter_plane_trim_limit_factors(brush, cache, translations, factors); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -278,10 +278,8 @@ void do_clay_strips_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { @@ -292,13 +290,12 @@ void do_clay_strips_brush(const Depsgraph &depsgraph, plane, strength, flip, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc b/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc index cf2b55aa98e..db492232fcc 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc @@ -45,19 +45,18 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float4 &plane_tilt, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -87,7 +86,8 @@ static void calc_faces(const Depsgraph &depsgraph, scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -259,10 +259,8 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { @@ -271,13 +269,12 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph, brush, plane_tilt, clay_strength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/crease.cc b/source/blender/editors/sculpt_paint/brushes/crease.cc index c8927824605..48d547119ca 100644 --- a/source/blender/editors/sculpt_paint/brushes/crease.cc +++ b/source/blender/editors/sculpt_paint/brushes/crease.cc @@ -71,12 +71,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float3 &offset, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -87,7 +86,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -95,18 +94,18 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_position(positions_eval, verts, cache.location_symm, translations); + translations_from_position(position_data.eval, verts, cache.location_symm, translations); if (brush.falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { project_translations(translations, cache.view_normal_symm); @@ -121,7 +120,8 @@ static void calc_faces(const Depsgraph &depsgraph, add_offset_to_translations(translations, factors, offset); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -261,10 +261,8 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -274,13 +272,12 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph, brush, offset, strength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/draw.cc b/source/blender/editors/sculpt_paint/brushes/draw.cc index 9f881529025..d0a2a046c46 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw.cc @@ -40,12 +40,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &offset, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { const SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -56,7 +55,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -64,20 +63,21 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; translations_from_offset_and_factors(offset, factors, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -177,25 +177,15 @@ static void offset_positions(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces(depsgraph, - sd, - brush, - offset, - positions_eval, - vert_normals, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces( + depsgraph, sd, brush, offset, vert_normals, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc b/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc index dbcba681cc1..9fa0f951e46 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc @@ -39,11 +39,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &offset, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -76,7 +75,8 @@ static void calc_faces(const Depsgraph &depsgraph, const MutableSpan translations = tls.translations; translations_from_offset_and_factors(offset, factors, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -182,16 +182,13 @@ static void offset_positions(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces( - depsgraph, sd, brush, offset, positions_eval, nodes[i], object, tls, positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces(depsgraph, sd, brush, offset, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc b/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc index bc174709de1..69c11744028 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc @@ -81,12 +81,11 @@ static void calc_brush_texture_colors(SculptSession &ss, static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -97,7 +96,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -105,7 +104,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); @@ -114,7 +113,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.colors.resize(verts.size()); const MutableSpan colors = tls.colors; - calc_brush_texture_colors(ss, brush, positions_eval, verts, factors, colors); + calc_brush_texture_colors(ss, brush, position_data.eval, verts, factors, colors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; @@ -122,7 +121,8 @@ static void calc_faces(const Depsgraph &depsgraph, SCULPT_calc_vertex_displacement(ss, brush, colors[i], translations[i]); } - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -227,24 +227,14 @@ void do_draw_vector_displacement_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces(depsgraph, - sd, - brush, - positions_eval, - vert_normals, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces(depsgraph, sd, brush, vert_normals, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc b/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc index 553b8645752..b9198d320fb 100644 --- a/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc +++ b/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc @@ -89,11 +89,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const KelvinletParams &kelvinet_params, const float3 &offset, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -121,7 +120,8 @@ static void calc_faces(const Depsgraph &depsgraph, scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -241,24 +241,14 @@ void do_elastic_deform_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces(depsgraph, - sd, - brush, - params, - grab_delta, - positions_eval, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces( + depsgraph, sd, brush, params, grab_delta, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/enhance_details.cc b/source/blender/editors/sculpt_paint/brushes/enhance_details.cc index 4de068f775b..5a8451dde55 100644 --- a/source/blender/editors/sculpt_paint/brushes/enhance_details.cc +++ b/source/blender/editors/sculpt_paint/brushes/enhance_details.cc @@ -38,14 +38,13 @@ struct LocalData { static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, - const Span positions_eval, const Span vert_normals, const Span all_translations, const float strength, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -56,7 +55,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -64,14 +63,14 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, strength); @@ -80,7 +79,8 @@ static void calc_faces(const Depsgraph &depsgraph, gather_data_mesh(all_translations, verts, translations); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -314,10 +314,8 @@ void do_enhance_details_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -325,15 +323,14 @@ void do_enhance_details_brush(const Depsgraph &depsgraph, calc_faces(depsgraph, sd, brush, - positions_eval, vert_normals, translations, strength, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/fill.cc b/source/blender/editors/sculpt_paint/brushes/fill.cc index 2bdfe7c1dfb..aa55831a0d5 100644 --- a/source/blender/editors/sculpt_paint/brushes/fill.cc +++ b/source/blender/editors/sculpt_paint/brushes/fill.cc @@ -42,12 +42,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float4 &plane, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -58,7 +57,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -66,26 +65,27 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, strength); - filter_above_plane_factors(positions_eval, verts, plane, factors); + filter_above_plane_factors(position_data.eval, verts, plane, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - calc_translations_to_plane(positions_eval, verts, plane, translations); + calc_translations_to_plane(position_data.eval, verts, plane, translations); filter_plane_trim_limit_factors(brush, cache, translations, factors); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -211,10 +211,8 @@ void do_fill_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -224,13 +222,12 @@ void do_fill_brush(const Depsgraph &depsgraph, brush, plane, ss.cache->bstrength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/flatten.cc b/source/blender/editors/sculpt_paint/brushes/flatten.cc index 48fc57b81c5..e24c25f1850 100644 --- a/source/blender/editors/sculpt_paint/brushes/flatten.cc +++ b/source/blender/editors/sculpt_paint/brushes/flatten.cc @@ -41,12 +41,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float4 &plane, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -57,7 +56,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -65,24 +64,25 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, strength); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - calc_translations_to_plane(positions_eval, verts, plane, translations); + calc_translations_to_plane(position_data.eval, verts, plane, translations); filter_plane_trim_limit_factors(brush, cache, translations, factors); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -204,10 +204,8 @@ void do_flatten_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -217,13 +215,12 @@ void do_flatten_brush(const Depsgraph &depsgraph, brush, plane, ss.cache->bstrength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/grab.cc b/source/blender/editors/sculpt_paint/brushes/grab.cc index 4ff711aa71c..939d05a5a90 100644 --- a/source/blender/editors/sculpt_paint/brushes/grab.cc +++ b/source/blender/editors/sculpt_paint/brushes/grab.cc @@ -53,11 +53,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &offset, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -94,7 +93,8 @@ static void calc_faces(const Depsgraph &depsgraph, const MutableSpan translations = tls.translations; translations_from_offset_and_factors(offset, factors, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -216,23 +216,13 @@ void do_grab_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces(depsgraph, - sd, - brush, - grab_delta, - positions_eval, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces(depsgraph, sd, brush, grab_delta, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/inflate.cc b/source/blender/editors/sculpt_paint/brushes/inflate.cc index 507b8960f88..afe78f30eea 100644 --- a/source/blender/editors/sculpt_paint/brushes/inflate.cc +++ b/source/blender/editors/sculpt_paint/brushes/inflate.cc @@ -47,12 +47,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &scale, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -63,7 +62,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -71,20 +70,21 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); const MutableSpan translations = gather_data_mesh(vert_normals, verts, tls.translations); apply_scale(translations, scale); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -190,25 +190,15 @@ void do_inflate_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces(depsgraph, - sd, - brush, - scale, - positions_eval, - vert_normals, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces( + depsgraph, sd, brush, scale, vert_normals, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/layer.cc b/source/blender/editors/sculpt_paint/brushes/layer.cc index c9961a0c35e..32602d485db 100644 --- a/source/blender/editors/sculpt_paint/brushes/layer.cc +++ b/source/blender/editors/sculpt_paint/brushes/layer.cc @@ -117,7 +117,6 @@ BLI_NOINLINE static void calc_translations(const Span base_positions, static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, - const Span positions_eval, const Span vert_normals, const Span mask_attribute, const bool use_persistent_base, @@ -127,14 +126,14 @@ static void calc_faces(const Depsgraph &depsgraph, bke::pbvh::MeshNode &node, LocalData &tls, MutableSpan layer_displacement_factor, - MutableSpan positions_orig) + const PositionDeformData &position_data) { const SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; const Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -190,7 +189,8 @@ static void calc_faces(const Depsgraph &depsgraph, brush.height, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } else { offset_displacement_factors(displacement_factors, factors, cache.bstrength); @@ -210,7 +210,8 @@ static void calc_faces(const Depsgraph &depsgraph, brush.height, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } } @@ -359,9 +360,8 @@ void do_layer_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - const MutableSpan positions_orig = mesh.vert_positions_for_write(); bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); const VArraySpan masks = *attributes.lookup(".sculpt_mask", bke::AttrDomain::Point); @@ -399,7 +399,6 @@ void do_layer_brush(const Depsgraph &depsgraph, calc_faces(depsgraph, sd, brush, - positions_eval, vert_normals, masks, use_persistent_base, @@ -409,8 +408,8 @@ void do_layer_brush(const Depsgraph &depsgraph, nodes[i], tls, displacement, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); persistent_disp_attr.finish(); diff --git a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc index 3d3dd097d89..c2bef4c4660 100644 --- a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc +++ b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc @@ -340,19 +340,18 @@ static void calc_faces(const Depsgraph &depsgraph, const std::array &scrape_planes, const float angle, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -391,7 +390,8 @@ static void calc_faces(const Depsgraph &depsgraph, scale_factors(factors, strength); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -642,10 +642,8 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); for (const int i : range) { @@ -656,13 +654,12 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph, multiplane_scrape_planes, ss.cache->multiplane_scrape_angle, strength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); } }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/pinch.cc b/source/blender/editors/sculpt_paint/brushes/pinch.cc index 11a5fe7b5e7..2d5bd38f681 100644 --- a/source/blender/editors/sculpt_paint/brushes/pinch.cc +++ b/source/blender/editors/sculpt_paint/brushes/pinch.cc @@ -65,19 +65,18 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const std::array &stroke_xz, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -109,7 +108,8 @@ static void calc_faces(const Depsgraph &depsgraph, scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -250,10 +250,8 @@ void do_pinch_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -263,13 +261,12 @@ void do_pinch_brush(const Depsgraph &depsgraph, brush, stroke_xz, ss.cache->bstrength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/relax.cc b/source/blender/editors/sculpt_paint/brushes/relax.cc index 5a942ac8c84..1771dc191a4 100644 --- a/source/blender/editors/sculpt_paint/brushes/relax.cc +++ b/source/blender/editors/sculpt_paint/brushes/relax.cc @@ -45,15 +45,15 @@ struct BMeshLocalData { Vector> vert_neighbors; }; -static void apply_positions_faces(const Depsgraph &depsgraph, - const Sculpt &sd, - const Span positions_eval, +static void apply_positions_faces(const Sculpt &sd, const Span verts, Object &object, const MutableSpan translations, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + SculptSession &ss = *object.sculpt; + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void apply_positions_grids(const Sculpt &sd, @@ -161,9 +161,8 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph, const VArraySpan hide_poly = *attributes.lookup(".hide_poly", bke::AttrDomain::Face); const VArraySpan face_sets = *attributes.lookup(".sculpt_face_set", bke::AttrDomain::Face); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); Array node_offset_data; const OffsetIndices node_vert_offsets = create_node_vert_offsets( @@ -177,7 +176,7 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph, MeshLocalData &tls = all_tls.local(); calc_factors_faces(depsgraph, brush, - positions_eval, + position_data.eval, vert_normals, vert_to_face_map, face_sets, @@ -192,7 +191,7 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph, node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { MeshLocalData &tls = all_tls.local(); smooth::calc_relaxed_translations_faces( - positions_eval, + position_data.eval, vert_normals, faces, corner_verts, @@ -208,13 +207,11 @@ static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph, }); node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { - apply_positions_faces(depsgraph, - sd, - positions_eval, + apply_positions_faces(sd, nodes[i].verts(), object, translations.as_mutable_span().slice(node_vert_offsets[pos]), - positions_orig); + position_data); }); } @@ -500,9 +497,8 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph, const VArraySpan hide_poly = *attributes.lookup(".hide_poly", bke::AttrDomain::Face); const VArraySpan face_sets = *attributes.lookup(".sculpt_face_set", bke::AttrDomain::Face); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); Array node_offset_data; const OffsetIndices node_vert_offsets = create_node_vert_offsets( @@ -526,7 +522,7 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph, node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { MeshLocalData &tls = all_tls.local(); smooth::calc_relaxed_translations_faces( - positions_eval, + position_data.eval, vert_normals, faces, corner_verts, @@ -542,14 +538,12 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph, }); node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { - apply_positions_faces(depsgraph, - sd, - positions_eval, + apply_positions_faces(sd, nodes[i].verts(), object, translations.as_mutable_span().slice(node_vert_offsets[pos]), - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); pbvh.tag_positions_changed(node_mask); bke::pbvh::flush_bounds_to_parents(pbvh); diff --git a/source/blender/editors/sculpt_paint/brushes/rotate.cc b/source/blender/editors/sculpt_paint/brushes/rotate.cc index 9e0b6d2de6f..9b052677891 100644 --- a/source/blender/editors/sculpt_paint/brushes/rotate.cc +++ b/source/blender/editors/sculpt_paint/brushes/rotate.cc @@ -57,11 +57,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float angle, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -97,7 +96,8 @@ static void calc_faces(const Depsgraph &depsgraph, calc_translations( orig_data.positions, cache.sculpt_normal_symm, factors, cache.location_symm, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -213,16 +213,13 @@ void do_rotate_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces( - depsgraph, sd, brush, angle, positions_eval, nodes[i], object, tls, positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces(depsgraph, sd, brush, angle, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/scrape.cc b/source/blender/editors/sculpt_paint/brushes/scrape.cc index f237fc94622..985d85e4e30 100644 --- a/source/blender/editors/sculpt_paint/brushes/scrape.cc +++ b/source/blender/editors/sculpt_paint/brushes/scrape.cc @@ -42,12 +42,11 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const float4 &plane, const float strength, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -58,7 +57,7 @@ static void calc_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -66,26 +65,27 @@ static void calc_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, strength); - filter_below_plane_factors(positions_eval, verts, plane, factors); + filter_below_plane_factors(position_data.eval, verts, plane, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - calc_translations_to_plane(positions_eval, verts, plane, translations); + calc_translations_to_plane(position_data.eval, verts, plane, translations); filter_plane_trim_limit_factors(brush, cache, translations, factors); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -212,10 +212,8 @@ void do_scrape_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -225,13 +223,12 @@ void do_scrape_brush(const Depsgraph &depsgraph, brush, plane, ss.cache->bstrength, - positions_eval, vert_normals, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/smooth.cc b/source/blender/editors/sculpt_paint/brushes/smooth.cc index c9f6d95451b..d5ea641ccef 100644 --- a/source/blender/editors/sculpt_paint/brushes/smooth.cc +++ b/source/blender/editors/sculpt_paint/brushes/smooth.cc @@ -57,14 +57,13 @@ struct LocalData { BLI_NOINLINE static void apply_positions_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, const float strength, Object &object, LocalData &tls, const Span new_positions, - MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -75,7 +74,7 @@ BLI_NOINLINE static void apply_positions_faces(const Depsgraph &depsgraph, tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -83,7 +82,7 @@ BLI_NOINLINE static void apply_positions_faces(const Depsgraph &depsgraph, tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); @@ -92,14 +91,15 @@ BLI_NOINLINE static void apply_positions_faces(const Depsgraph &depsgraph, scale_factors(factors, strength); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } BLI_NOINLINE static void do_smooth_brush_mesh(const Depsgraph &depsgraph, @@ -119,9 +119,8 @@ BLI_NOINLINE static void do_smooth_brush_mesh(const Depsgraph &depsgraph, const bke::AttributeAccessor attributes = mesh.attributes(); const VArraySpan hide_poly = *attributes.lookup(".hide_poly", bke::AttrDomain::Face); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); Array node_offset_data; const OffsetIndices node_vert_offsets = create_node_vert_offsets( @@ -146,7 +145,7 @@ BLI_NOINLINE static void do_smooth_brush_mesh(const Depsgraph &depsgraph, verts, tls.vert_neighbors); smooth::neighbor_data_average_mesh_check_loose( - positions_eval, + position_data.eval, verts, tls.vert_neighbors, new_positions.as_mutable_span().slice(node_vert_offsets[pos])); @@ -157,14 +156,13 @@ BLI_NOINLINE static void do_smooth_brush_mesh(const Depsgraph &depsgraph, apply_positions_faces(depsgraph, sd, brush, - positions_eval, vert_normals, nodes[i], strength, object, tls, new_positions.as_span().slice(node_vert_offsets[pos]), - positions_orig); + position_data); }); } } diff --git a/source/blender/editors/sculpt_paint/brushes/snake_hook.cc b/source/blender/editors/sculpt_paint/brushes/snake_hook.cc index 509767e4a10..8c2f1f7966f 100644 --- a/source/blender/editors/sculpt_paint/brushes/snake_hook.cc +++ b/source/blender/editors/sculpt_paint/brushes/snake_hook.cc @@ -161,11 +161,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Brush &brush, const SculptProjectVector *spvc, const float3 &grab_delta, - const Span positions_eval, const Span vert_normals, bke::pbvh::MeshNode &node, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -173,7 +172,7 @@ static void calc_faces(const Depsgraph &depsgraph, Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -216,7 +215,8 @@ static void calc_faces(const Depsgraph &depsgraph, calc_kelvinet_translation(cache, positions, factors, translations); } - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -376,10 +376,8 @@ void do_snake_hook_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -390,12 +388,11 @@ void do_snake_hook_brush(const Depsgraph &depsgraph, brush, &spvc, grab_delta, - positions_eval, vert_normals, nodes[i], tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc b/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc index 70bb409ff82..7dec5723141 100644 --- a/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc +++ b/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc @@ -66,9 +66,8 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph const bke::AttributeAccessor attributes = mesh.attributes(); const VArraySpan hide_poly = *attributes.lookup(".hide_poly", bke::AttrDomain::Face); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); Array node_offset_data; const OffsetIndices node_offsets = create_node_vert_offsets(nodes, node_mask, node_offset_data); @@ -81,7 +80,7 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph const MutableSpan factors = all_factors.as_mutable_span().slice(node_offsets[pos]); fill_factor_from_hide_and_mask(mesh, verts, factors); - filter_region_clip_factors(ss, positions_eval, verts, factors); + filter_region_clip_factors(ss, position_data.eval, verts, factors); if (brush.flag & BRUSH_FRONTFACE) { calc_front_face(cache.view_normal_symm, vert_normals, verts, factors); } @@ -89,7 +88,7 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph tls.distances.resize(verts.size()); const MutableSpan distances = tls.distances; calc_brush_distances( - ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); + ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances); filter_distances_with_radius(cache.radius, distances, factors); apply_hardness_to_distances(cache, distances); calc_brush_strength_factors(cache, brush, distances, factors); @@ -97,7 +96,7 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph auto_mask::calc_vert_factors( depsgraph, object, cache.automasking.get(), nodes[i], verts, factors); - calc_brush_texture_factors(ss, brush, positions_eval, verts, factors); + calc_brush_texture_factors(ss, brush, position_data.eval, verts, factors); scale_factors(factors, cache.bstrength); clamp_factors(factors); @@ -107,7 +106,7 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { LocalData &tls = all_tls.local(); const Span verts = nodes[i].verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); const Span factors = all_factors.as_span().slice(node_offsets[pos]); @@ -117,7 +116,8 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph tls.average_positions.resize(verts.size()); const MutableSpan average_positions = tls.average_positions; - smooth::neighbor_data_average_mesh(positions_eval, tls.vert_neighbors, average_positions); + smooth::neighbor_data_average_mesh( + position_data.eval, tls.vert_neighbors, average_positions); tls.laplacian_disp.resize(verts.size()); const MutableSpan laplacian_disp = tls.laplacian_disp; @@ -129,8 +129,8 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph scatter_data_mesh(laplacian_disp.as_span(), verts, all_laplacian_disp); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { @@ -156,8 +156,8 @@ BLI_NOINLINE static void do_surface_smooth_brush_mesh(const Depsgraph &depsgraph laplacian_disp, average_laplacian_disps, beta, translations); scale_translations(translations, factors); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); } } diff --git a/source/blender/editors/sculpt_paint/brushes/thumb.cc b/source/blender/editors/sculpt_paint/brushes/thumb.cc index ca28aa3936b..14fe118a738 100644 --- a/source/blender/editors/sculpt_paint/brushes/thumb.cc +++ b/source/blender/editors/sculpt_paint/brushes/thumb.cc @@ -39,11 +39,10 @@ static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &offset, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -77,7 +76,8 @@ static void calc_faces(const Depsgraph &depsgraph, const MutableSpan translations = tls.translations; translations_from_offset_and_factors(offset, factors, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -189,16 +189,13 @@ void do_thumb_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_faces( - depsgraph, sd, brush, offset, positions_eval, nodes[i], object, tls, positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_faces(depsgraph, sd, brush, offset, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/topology_slide.cc b/source/blender/editors/sculpt_paint/brushes/topology_slide.cc index eb55b51c24c..694d8d67417 100644 --- a/source/blender/editors/sculpt_paint/brushes/topology_slide.cc +++ b/source/blender/editors/sculpt_paint/brushes/topology_slide.cc @@ -152,7 +152,6 @@ BLI_NOINLINE static void calc_neighbor_influence(const Span positions, static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, - const Span positions_eval, const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face_map, @@ -160,7 +159,7 @@ static void calc_faces(const Depsgraph &depsgraph, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -168,7 +167,7 @@ static void calc_faces(const Depsgraph &depsgraph, const OrigPositionData orig_data = orig_position_data_get_mesh(object, node); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -199,10 +198,11 @@ static void calc_faces(const Depsgraph &depsgraph, tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; calc_translation_directions(brush, cache, positions, translations); - calc_neighbor_influence(positions_eval, positions, vert_neighbors, translations); + calc_neighbor_influence(position_data.eval, positions, vert_neighbors, translations); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void calc_grids(const Depsgraph &depsgraph, @@ -319,8 +319,7 @@ void do_topology_slide_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -333,7 +332,6 @@ void do_topology_slide_brush(const Depsgraph &depsgraph, calc_faces(depsgraph, sd, brush, - positions_eval, faces, corner_verts, vert_to_face_map, @@ -341,8 +339,8 @@ void do_topology_slide_brush(const Depsgraph &depsgraph, nodes[i], object, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/mesh_brush_common.hh b/source/blender/editors/sculpt_paint/mesh_brush_common.hh index 27ff1e588b5..efec8887e95 100644 --- a/source/blender/editors/sculpt_paint/mesh_brush_common.hh +++ b/source/blender/editors/sculpt_paint/mesh_brush_common.hh @@ -127,15 +127,6 @@ void scatter_data_grids(const SubdivCCG &subdiv_ccg, template void scatter_data_bmesh(Span node_data, const Set &verts, MutableSpan dst); -/** - * Note on the various positions arrays: - * - positions_orig: Positions owned by the original mesh. Not the same as `positions_eval` if - * there are deform modifiers. - * - positions_eval: Positions after procedural deformation, used to build the - * blender::bke::pbvh::Tree. Translations are built for these values, then applied to - * `positions_orig`. - */ - /** Fill the output array with all positions in the geometry referenced by the indices. */ inline MutableSpan gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span grids, @@ -423,19 +414,6 @@ void update_shape_keys(Object &object, Span translations, Span positions_orig); -/** - * Write the new translated positions to the original mesh, taking into account inverse - * deformation from modifiers, axis locking, and clipping. Flush the deformation to shape keys as - * well. - */ -void write_translations(const Depsgraph &depsgraph, - const Sculpt &sd, - Object &object, - Span positions_eval, - Span verts, - MutableSpan translations, - MutableSpan positions_orig); - /** * Creates OffsetIndices based on each node's unique vertex count, allowing for easy slicing of a * new array. diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 630ee45f03f..cbe4e8228a3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -7226,6 +7226,83 @@ void clip_and_lock_translations(const Sculpt &sd, } } +PositionDeformData::PositionDeformData(const Depsgraph &depsgraph, Object &object_orig) +{ + Mesh &mesh = *static_cast(object_orig.data); + this->eval = bke::pbvh::vert_positions_eval(depsgraph, object_orig); + + if (!object_orig.sculpt->deform_imats.is_empty()) { + deform_imats_ = object_orig.sculpt->deform_imats; + } + orig_ = mesh.vert_positions_for_write(); + + MutableSpan eval_mut = bke::pbvh::vert_positions_eval_for_write(depsgraph, object_orig); + if (eval_mut.data() != orig_.data()) { + eval_mut_ = eval_mut; + } + + if (Key *keys = mesh.key) { + keys_ = keys; + const int active_index = object_orig.shapenr - 1; + active_key_ = BKE_keyblock_find_by_index(keys, active_index); + basis_active_ = active_key_ == keys->refkey; + dependent_keys_ = BKE_keyblock_get_dependent_keys(keys_, active_index); + } + else { + keys_ = nullptr; + active_key_ = nullptr; + basis_active_ = false; + } +} + +static void copy_indices(const Span src, const Span indices, MutableSpan dst) +{ + for (const int i : indices) { + dst[i] = src[i]; + } +} + +void PositionDeformData::deform(MutableSpan translations, const Span verts) const +{ + if (eval_mut_) { + /* Apply translations to the evaluated mesh. This is necessary because multiple brush + * evaluations can happen in between object reevaluations (otherwise just deforming the + * original positions would be enough). */ + apply_translations(translations, verts, *eval_mut_); + } + + if (deform_imats_) { + /* Apply the reverse procedural deformation, since subsequent translation happens to the state + * from "before" deforming modifiers. */ + apply_crazyspace_to_translations(*deform_imats_, verts, translations); + } + + if (KeyBlock *key = active_key_) { + const MutableSpan active_key_data(static_cast(key->data), key->totelem); + if (basis_active_) { + /* The active shape key positions and the mesh positions are always kept in sync. */ + apply_translations(translations, verts, orig_); + copy_indices(orig_, verts, active_key_data); + } + else { + apply_translations(translations, verts, active_key_data); + } + + if (dependent_keys_) { + int i; + LISTBASE_FOREACH_INDEX (KeyBlock *, other_key, &keys_->block, i) { + if ((other_key != key) && (*dependent_keys_)[i]) { + MutableSpan data(static_cast(other_key->data), other_key->totelem); + apply_translations(translations, verts, data); + } + } + } + } + else { + apply_translations(translations, verts, orig_); + } +} + void update_shape_keys(Object &object, const Mesh &mesh, const KeyBlock &active_key, @@ -7256,43 +7333,6 @@ void update_shape_keys(Object &object, } } -void write_translations(const Depsgraph &depsgraph, - const Sculpt &sd, - Object &object, - const Span positions_eval, - const Span verts, - const MutableSpan translations, - const MutableSpan positions_orig) -{ - SculptSession &ss = *object.sculpt; - - clip_and_lock_translations(sd, ss, positions_eval, verts, translations); - - MutableSpan positions_eval_mut = bke::pbvh::vert_positions_eval_for_write(depsgraph, - object); - if (positions_eval_mut.data() != positions_orig.data()) { - apply_translations(translations, verts, positions_eval_mut); - } - - if (!ss.deform_imats.is_empty()) { - apply_crazyspace_to_translations(ss.deform_imats, verts, translations); - } - - const Mesh &mesh = *static_cast(object.data); - const KeyBlock *active_key = BKE_keyblock_from_object(&object); - if (!active_key) { - apply_translations(translations, verts, positions_orig); - return; - } - - const bool basis_shapekey_active = active_key == mesh.key->refkey; - if (basis_shapekey_active) { - apply_translations(translations, verts, positions_orig); - } - - update_shape_keys(object, mesh, *active_key, verts, translations, positions_orig); -} - void scale_translations(const MutableSpan translations, const Span factors) { for (const int i : translations.index_range()) { diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.cc b/source/blender/editors/sculpt_paint/sculpt_boundary.cc index 1a94db4b6d2..32adff4f7ca 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.cc +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -1091,7 +1091,6 @@ BLI_NOINLINE static void calc_bend_position(const Span positions, static void calc_bend_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, - const Span positions_eval, const Span vert_propagation_steps, const Span vert_factors, const Span vert_pivot_positions, @@ -1101,7 +1100,7 @@ static void calc_bend_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -1135,10 +1134,9 @@ static void calc_bend_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -1287,9 +1285,7 @@ static void do_bend_brush(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); @@ -1299,7 +1295,6 @@ static void do_bend_brush(const Depsgraph &depsgraph, calc_bend_mesh(depsgraph, sd, object, - positions_eval, boundary.edit_info.propagation_steps_num, boundary.edit_info.strength_factor, boundary.bend.pivot_positions, @@ -1309,8 +1304,8 @@ static void do_bend_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -1392,7 +1387,6 @@ BLI_NOINLINE static void calc_slide_position(const Span positions, static void calc_slide_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, - const Span positions_eval, const Span vert_propagation_steps, const Span vert_factors, const Span vert_slide_directions, @@ -1401,7 +1395,7 @@ static void calc_slide_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -1435,10 +1429,9 @@ static void calc_slide_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -1583,9 +1576,7 @@ static void do_slide_brush(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); @@ -1595,7 +1586,6 @@ static void do_slide_brush(const Depsgraph &depsgraph, calc_slide_mesh(depsgraph, sd, object, - positions_eval, boundary.edit_info.propagation_steps_num, boundary.edit_info.strength_factor, boundary.slide.directions, @@ -1604,8 +1594,8 @@ static void do_slide_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -1685,7 +1675,6 @@ BLI_NOINLINE static void calc_inflate_position(const Span positions, static void calc_inflate_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, - const Span positions_eval, const Span vert_propagation_steps, const Span vert_factors, const bke::pbvh::MeshNode &node, @@ -1693,7 +1682,7 @@ static void calc_inflate_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -1723,10 +1712,9 @@ static void calc_inflate_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -1862,9 +1850,7 @@ static void do_inflate_brush(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); @@ -1874,7 +1860,6 @@ static void do_inflate_brush(const Depsgraph &depsgraph, calc_inflate_mesh(depsgraph, sd, object, - positions_eval, boundary.edit_info.propagation_steps_num, boundary.edit_info.strength_factor, nodes[i], @@ -1882,8 +1867,8 @@ static void do_inflate_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -1960,7 +1945,6 @@ BLI_NOINLINE static void calc_grab_position(const Span positions, static void calc_grab_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, - const Span positions_eval, const Span vert_propagation_steps, const Span vert_factors, const bke::pbvh::MeshNode &node, @@ -1969,7 +1953,7 @@ static void calc_grab_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -1999,10 +1983,9 @@ static void calc_grab_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -2141,9 +2124,7 @@ static void do_grab_brush(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); @@ -2153,7 +2134,6 @@ static void do_grab_brush(const Depsgraph &depsgraph, calc_grab_mesh(depsgraph, sd, object, - positions_eval, boundary.edit_info.propagation_steps_num, boundary.edit_info.strength_factor, nodes[i], @@ -2162,8 +2142,8 @@ static void do_grab_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -2243,7 +2223,6 @@ BLI_NOINLINE static void calc_twist_position(const Span positions, static void calc_twist_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, - const Span positions_eval, const Span vert_propagation_steps, const Span vert_factors, const bke::pbvh::MeshNode &node, @@ -2253,7 +2232,7 @@ static void calc_twist_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -2284,10 +2263,9 @@ static void calc_twist_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -2428,9 +2406,7 @@ static void do_twist_brush(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { - Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); @@ -2440,7 +2416,6 @@ static void do_twist_brush(const Depsgraph &depsgraph, calc_twist_mesh(depsgraph, sd, object, - positions_eval, boundary.edit_info.propagation_steps_num, boundary.edit_info.strength_factor, nodes[i], @@ -2450,8 +2425,8 @@ static void do_twist_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -2616,10 +2591,8 @@ BLI_NOINLINE static void calc_average_position(const Span vert_propagation_ } } -static void calc_smooth_mesh(const Depsgraph &depsgraph, - const Sculpt &sd, +static void calc_smooth_mesh(const Sculpt &sd, Object &object, - const Span positions_eval, const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face, @@ -2631,7 +2604,7 @@ static void calc_smooth_mesh(const Depsgraph &depsgraph, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; @@ -2657,9 +2630,9 @@ static void calc_smooth_mesh(const Depsgraph &depsgraph, calc_vert_neighbors(faces, corner_verts, vert_to_face, hide_poly, verts, neighbors); tls.average_positions.resize(verts.size()); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh(position_data.eval, verts, tls.positions); const MutableSpan average_positions = tls.average_positions; - calc_average_position(positions_eval, + calc_average_position(position_data.eval, vert_propagation_steps, neighbors, propagation_steps, @@ -2674,10 +2647,9 @@ static void calc_smooth_mesh(const Depsgraph &depsgraph, case BRUSH_DEFORM_TARGET_GEOMETRY: { tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - translations_from_new_positions(new_positions, verts, positions_eval, translations); - - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + translations_from_new_positions(new_positions, verts, position_data.eval, translations); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; } case BRUSH_DEFORM_TARGET_CLOTH_SIM: @@ -2831,8 +2803,7 @@ static void do_smooth_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -2844,10 +2815,8 @@ static void do_smooth_brush(const Depsgraph &depsgraph, threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalDataMesh &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_smooth_mesh(depsgraph, - sd, + calc_smooth_mesh(sd, object, - positions_eval, faces, corner_verts, vert_to_face_map, @@ -2859,8 +2828,8 @@ static void do_smooth_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.cc b/source/blender/editors/sculpt_paint/sculpt_cloth.cc index 3854a432bf4..d2e84a6c194 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.cc @@ -1406,8 +1406,7 @@ void do_simulation_step(const Depsgraph &depsgraph, return cloth_sim.node_state[node_index] == SCULPT_CLOTH_NODE_ACTIVE; }); Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::parallel_for(active_nodes.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); active_nodes.slice(range).foreach_index([&](const int i) { @@ -1424,14 +1423,15 @@ void do_simulation_step(const Depsgraph &depsgraph, tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; for (const int i : verts.index_range()) { - translations[i] = cloth_sim.pos[verts[i]] - positions_eval[verts[i]]; + translations[i] = cloth_sim.pos[verts[i]] - position_data.eval[verts[i]]; } - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] = SCULPT_CLOTH_NODE_INACTIVE; - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index e3b3a53740b..926e1607673 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -1324,8 +1324,8 @@ static void edit_fairing(const Depsgraph &depsgraph, bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(ob); boundary::ensure_boundary_info(ob); - const Span positions = bke::pbvh::vert_positions_eval(depsgraph, ob); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, ob); + const Span positions = position_data.eval; const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); const BitSpan boundary_verts = ss.vertex_info.boundary; const bke::AttributeAccessor attributes = mesh.attributes(); @@ -1368,7 +1368,8 @@ static void edit_fairing(const Depsgraph &depsgraph, translations[i] = new_positions[verts[i]] - positions[verts[i]]; } scale_translations(translations, strength); - write_translations(depsgraph, sd, ob, positions, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, positions, verts, translations); + position_data.deform(translations, verts); }); }); } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc index 6bee4d1b940..12e3e70b6bf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc @@ -351,8 +351,7 @@ static void calc_smooth_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -362,7 +361,8 @@ static void calc_smooth_filter(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -385,7 +385,7 @@ static void calc_smooth_filter(const Depsgraph &depsgraph, tls.new_positions.resize(verts.size()); const MutableSpan new_positions = tls.new_positions; smooth::neighbor_data_average_mesh_check_loose( - positions_eval, verts, neighbors, new_positions); + position_data.eval, verts, neighbors, new_positions); tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; @@ -394,8 +394,8 @@ static void calc_smooth_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -497,15 +497,15 @@ static void calc_inflate_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -522,8 +522,8 @@ static void calc_inflate_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -611,15 +611,15 @@ static void calc_scale_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -636,8 +636,8 @@ static void calc_scale_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -741,15 +741,15 @@ static void calc_sphere_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -765,8 +765,8 @@ static void calc_sphere_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -863,15 +863,15 @@ static void calc_random_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -889,8 +889,8 @@ static void calc_random_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -981,9 +981,8 @@ static void calc_relax_filter(const Depsgraph &depsgraph, }; case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -1008,7 +1007,7 @@ static void calc_relax_filter(const Depsgraph &depsgraph, tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - smooth::calc_relaxed_translations_faces(positions_eval, + smooth::calc_relaxed_translations_faces(position_data.eval, vert_normals, faces, corner_verts, @@ -1023,8 +1022,8 @@ static void calc_relax_filter(const Depsgraph &depsgraph, translations); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -1147,9 +1146,8 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph, Vector translations; }; Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -1177,7 +1175,7 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph, tls.translations.resize(verts.size()); const MutableSpan translations = tls.translations; - smooth::calc_relaxed_translations_faces(positions_eval, + smooth::calc_relaxed_translations_faces(position_data.eval, vert_normals, faces, corner_verts, @@ -1192,8 +1190,8 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph, translations); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -1331,8 +1329,7 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); const GroupedSpan vert_to_face_map = mesh.vert_to_face_map(); @@ -1342,7 +1339,8 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -1360,7 +1358,7 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph, tls.average_positions.reinitialize(verts.size()); const MutableSpan average_positions = tls.average_positions; smooth::neighbor_data_average_mesh( - positions_eval, tls.vert_neighbors, average_positions); + position_data.eval, tls.vert_neighbors, average_positions); tls.laplacian_disp.reinitialize(verts.size()); const MutableSpan laplacian_disp = tls.laplacian_disp; @@ -1377,8 +1375,8 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph, scatter_data_mesh(laplacian_disp.as_span(), verts, all_laplacian_disp); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -1413,8 +1411,8 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph, scale_translations(translations, factors); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -1616,8 +1614,7 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); const OffsetIndices faces = mesh.faces(); const Span corner_verts = mesh.corner_verts(); @@ -1628,7 +1625,8 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int node_index) { const Span verts = nodes[node_index].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); tls.factors.resize(verts.size()); const MutableSpan factors = tls.factors; @@ -1651,7 +1649,7 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph, tls.smooth_positions.resize(verts.size()); const MutableSpan smooth_positions = tls.smooth_positions; - smooth::neighbor_data_average_mesh(positions_eval, neighbors, smooth_positions); + smooth::neighbor_data_average_mesh(position_data.eval, neighbors, smooth_positions); const Span sharpen_factors = gather_data_mesh( ss.filter_cache->sharpen_factor.as_span(), verts, tls.sharpen_factors); @@ -1660,11 +1658,11 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph, const MutableSpan translations = tls.translations; for (const int i : verts.index_range()) { const int vert = verts[i]; - const float3 &position = positions_eval[vert]; + const float3 &position = position_data.eval[vert]; float3 disp_sharpen(0.0f); for (const int neighbor : neighbors[i]) { - float3 disp_n = positions_eval[neighbor] - position; + float3 disp_n = position_data.eval[neighbor] - position; disp_n *= ss.filter_cache->sharpen_factor[neighbor]; disp_sharpen += disp_n; } @@ -1685,8 +1683,8 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph, scale_translations(translations, factors); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; @@ -1870,15 +1868,15 @@ static void calc_enhance_details_filter(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, object); threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span verts = nodes[i].verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh( + position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]); tls.factors.resize(verts.size()); @@ -1894,8 +1892,8 @@ static void calc_enhance_details_filter(const Depsgraph &depsgraph, reset_translations_to_original(translations, positions, orig_data.positions); zero_disabled_axis_components(*ss.filter_cache, translations); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); }); }); break; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index 27705266371..d26df3a1256 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -52,6 +52,7 @@ struct Dial; struct DistRayAABB_Precalc; struct Image; struct ImageUser; +struct Key; struct KeyBlock; struct Object; struct bContext; @@ -66,6 +67,48 @@ struct wmOperatorType; namespace blender::ed::sculpt_paint { +/** + * This class represents an API to deform original positions based on translations created from + * evaluated positions. It should be constructed once outside of a parallel context. + */ +class PositionDeformData { + public: + /** + * Positions from after procedural deformation from modifiers, used to build the + * pbvh::Tree. Translations are built for these values, then applied to the original positions. + * When there are no deforming modifiers, this will reference the same array as #orig. + */ + Span eval; + + private: + /** + * In some cases deformations must also apply to the evaluated positions (#eval) in case the + * changed values are needed elsewhere before the object is reevaluated (which would update the + * evaluated positions). + */ + std::optional> eval_mut_; + + /** + * Transforms from deforming modifiers, used to convert translations of evaluated positions to + * "original" translations. + */ + std::optional> deform_imats_; + + /** + * Positions from the original mesh. Not the same as #eval if there are deform modifiers. + */ + MutableSpan orig_; + + Key *keys_; + KeyBlock *active_key_; + bool basis_active_; + std::optional> dependent_keys_; + + public: + PositionDeformData(const Depsgraph &depsgraph, Object &object_orig); + void deform(MutableSpan translations, Span verts) const; +}; + enum class UpdateType { Position, Mask, diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.cc b/source/blender/editors/sculpt_paint/sculpt_pose.cc index 02efccf6dbf..8aa23d13055 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.cc +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -157,18 +157,17 @@ BLI_NOINLINE static void add_arrays(const MutableSpan a, const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, BrushLocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { SculptSession &ss = *object.sculpt; const StrokeCache &cache = *ss.cache; const Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const Span positions = gather_data_mesh(positions_eval, verts, tls.positions); + const Span positions = gather_data_mesh(position_data.eval, verts, tls.positions); const OrigPositionData orig_data = orig_position_data_get_mesh(object, node); tls.factors.resize(verts.size()); @@ -196,8 +195,8 @@ static void calc_mesh(const Depsgraph &depsgraph, switch (eBrushDeformTarget(brush.deform_target)) { case BRUSH_DEFORM_TARGET_GEOMETRY: reset_translations_to_original(translations, positions, orig_data.positions); - write_translations( - depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); break; case BRUSH_DEFORM_TARGET_CLOTH_SIM: add_arrays(translations, orig_data.positions); @@ -1783,14 +1782,12 @@ void do_pose_brush(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(ob.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, ob); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { BrushLocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - calc_mesh(depsgraph, sd, brush, positions_eval, nodes[i], ob, tls, positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + calc_mesh(depsgraph, sd, brush, nodes[i], ob, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/sculpt_project.cc b/source/blender/editors/sculpt_paint/sculpt_project.cc index b5aee7501e3..53a6a4ece0d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_project.cc +++ b/source/blender/editors/sculpt_paint/sculpt_project.cc @@ -43,20 +43,19 @@ struct LocalData { Vector translations; }; -static void apply_projection_mesh(const Depsgraph &depsgraph, - const Sculpt &sd, +static void apply_projection_mesh(const Sculpt &sd, const gesture::GestureData &gesture_data, - const Span positions_eval, const Span vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { + SculptSession &ss = *object.sculpt; Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); const MutableSpan normals = gather_data_mesh(vert_normals, verts, tls.normals); tls.factors.resize(verts.size()); @@ -70,7 +69,8 @@ static void apply_projection_mesh(const Depsgraph &depsgraph, calc_translations_to_plane(positions, gesture_data.line.plane, translations); scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void apply_projection_grids(const Sculpt &sd, @@ -149,24 +149,15 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(object.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object); + const PositionDeformData position_data(depsgraph, object); const Span vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object); - MutableSpan positions_orig = mesh.vert_positions_for_write(); undo::push_nodes(depsgraph, object, node_mask, undo::Type::Position); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - apply_projection_mesh(depsgraph, - sd, - gesture_data, - positions_eval, - vert_normals, - nodes[i], - object, - tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + apply_projection_mesh( + sd, gesture_data, vert_normals, nodes[i], object, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.cc b/source/blender/editors/sculpt_paint/sculpt_transform.cc index 795b8c75fa1..24ecbeb5663 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.cc +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -188,15 +188,14 @@ BLI_NOINLINE static void filter_translations_with_symmetry(const Span po } } -static void transform_node_mesh(const Depsgraph &depsgraph, - const Sculpt &sd, +static void transform_node_mesh(const Sculpt &sd, const std::array &transform_mats, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, TransformLocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { + SculptSession &ss = *object.sculpt; const Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); @@ -214,7 +213,8 @@ static void transform_node_mesh(const Depsgraph &depsgraph, const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(object); filter_translations_with_symmetry(orig_data.positions, symm, translations); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void transform_node_grids(const Sculpt &sd, @@ -299,15 +299,12 @@ static void sculpt_transform_all_vertices(const Depsgraph &depsgraph, const Scul switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(ob.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, ob); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { TransformLocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - transform_node_mesh( - depsgraph, sd, transform_mats, positions_eval, nodes[i], ob, tls, positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + transform_node_mesh(sd, transform_mats, nodes[i], ob, tls, position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break; @@ -362,21 +359,20 @@ BLI_NOINLINE static void apply_kelvinet_to_translations(const KelvinletParams &p } } -static void elastic_transform_node_mesh(const Depsgraph &depsgraph, - const Sculpt &sd, +static void elastic_transform_node_mesh(const Sculpt &sd, const KelvinletParams ¶ms, const float4x4 &elastic_transform_mat, const float3 &elastic_transform_pivot, - const Span positions_eval, const bke::pbvh::MeshNode &node, Object &object, TransformLocalData &tls, - const MutableSpan positions_orig) + const PositionDeformData &position_data) { + const SculptSession &ss = *object.sculpt; const Mesh &mesh = *static_cast(object.data); const Span verts = node.verts(); - const MutableSpan positions = gather_data_mesh(positions_eval, verts, tls.positions); + const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions); /* TODO: Using the factors array is unnecessary when there are no hidden vertices and no mask. */ tls.factors.resize(verts.size()); @@ -391,7 +387,8 @@ static void elastic_transform_node_mesh(const Depsgraph &depsgraph, scale_translations(translations, factors); - write_translations(depsgraph, sd, object, positions_eval, verts, translations, positions_orig); + clip_and_lock_translations(sd, ss, position_data.eval, verts, translations); + position_data.deform(translations, verts); } static void elastic_transform_node_grids(const Sculpt &sd, @@ -493,23 +490,19 @@ static void transform_radius_elastic(const Depsgraph &depsgraph, switch (pbvh.type()) { case bke::pbvh::Type::Mesh: { MutableSpan nodes = pbvh.nodes(); - Mesh &mesh = *static_cast(ob.data); - const Span positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob); - MutableSpan positions_orig = mesh.vert_positions_for_write(); + const PositionDeformData position_data(depsgraph, ob); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { TransformLocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - elastic_transform_node_mesh(depsgraph, - sd, + elastic_transform_node_mesh(sd, params, elastic_transform_mat, elastic_transform_pivot, - positions_eval, nodes[i], ob, tls, - positions_orig); - bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); + position_data); + bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]); }); }); break;