Sculpt: Extract deformation position data and logic to a class

In an effort to improve code documentation, reduce the number of
commonly needed arguments, and avoid repeating work for each
BVH node, combine position data and shape key data arrays to a
temporary struct used during brush deformation.

I'm generally wary of adding such object-oriented abstractions to
the code, but I think this one will hold up, and I find things easier to
understand after the change. It reduces overhead too, since the
evaluated position attribute and shape key data aren't retrieved
potentially thousands of times.

Pull Request: https://projects.blender.org/blender/blender/pulls/127725
This commit is contained in:
Hans Goudey
2024-09-17 19:55:25 +02:00
committed by Hans Goudey
parent b2ce5393ad
commit d15681a459
34 changed files with 479 additions and 572 deletions

View File

@@ -59,12 +59,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float4 &test_plane,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -45,12 +45,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const float4 &plane,
const float strength,
const bool flip,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> 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;

View File

@@ -45,19 +45,18 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float4 &plane_tilt,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> 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<float> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> 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;

View File

@@ -71,12 +71,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float3 &offset,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -40,12 +40,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -39,11 +39,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -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<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
MutableSpan<float3> 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<float> 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<float> 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<float4> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -89,11 +89,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const KelvinletParams &kelvinet_params,
const float3 &offset,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -38,14 +38,13 @@ struct LocalData {
static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const Span<float3> all_translations,
const float strength,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -42,12 +42,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float4 &plane,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -41,12 +41,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float4 &plane,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -53,11 +53,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -47,12 +47,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float3 &scale,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -117,7 +117,6 @@ BLI_NOINLINE static void calc_translations(const Span<float3> base_positions,
static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const Span<float> 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<float> layer_displacement_factor,
MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
const SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
const Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> 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<float> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
const MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
const VArraySpan masks = *attributes.lookup<float>(".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();

View File

@@ -340,19 +340,18 @@ static void calc_faces(const Depsgraph &depsgraph,
const std::array<float4, 2> &scrape_planes,
const float angle,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> 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<float> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> 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;

View File

@@ -65,19 +65,18 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const std::array<float3, 2> &stroke_xz,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> 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<float> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -45,15 +45,15 @@ struct BMeshLocalData {
Vector<Vector<BMVert *>> vert_neighbors;
};
static void apply_positions_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Span<float3> positions_eval,
static void apply_positions_faces(const Sculpt &sd,
const Span<int> verts,
Object &object,
const MutableSpan<float3> translations,
const MutableSpan<float3> 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<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
Array<int> node_offset_data;
const OffsetIndices<int> 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<bool>(".hide_poly", bke::AttrDomain::Face);
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
Array<int> node_offset_data;
const OffsetIndices<int> 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);

View File

@@ -57,11 +57,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float angle,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -42,12 +42,11 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const float4 &plane,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float> 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<float> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -57,14 +57,13 @@ struct LocalData {
BLI_NOINLINE static void apply_positions_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
const float strength,
Object &object,
LocalData &tls,
const Span<float3> new_positions,
MutableSpan<float3> 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<float> 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<float> 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<float3> 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<bool>(".hide_poly", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
Array<int> node_offset_data;
const OffsetIndices<int> 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);
});
}
}

View File

@@ -161,11 +161,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Brush &brush,
const SculptProjectVector *spvc,
const float3 &grab_delta,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
bke::pbvh::MeshNode &node,
LocalData &tls,
const MutableSpan<float3> 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<Mesh *>(object.data);
const Span<int> 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<float> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -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<bool>(".hide_poly", bke::AttrDomain::Face);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
Array<int> 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<float> 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<float> 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<int> 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<float> 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<float3> 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<float3> 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);
});
}
}

View File

@@ -39,11 +39,10 @@ static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> 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<float3> 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<LocalData> all_tls;
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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;

View File

@@ -152,7 +152,6 @@ BLI_NOINLINE static void calc_neighbor_influence(const Span<float3> positions,
static void calc_faces(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const GroupedSpan<int> 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<float3> 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<int> 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<float> factors = tls.factors;
@@ -199,10 +198,11 @@ static void calc_faces(const Depsgraph &depsgraph,
tls.translations.resize(verts.size());
const MutableSpan<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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;

View File

@@ -127,15 +127,6 @@ void scatter_data_grids(const SubdivCCG &subdiv_ccg,
template<typename T>
void scatter_data_bmesh(Span<T> node_data, const Set<BMVert *, 0> &verts, MutableSpan<T> 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<float3> gather_grids_positions(const SubdivCCG &subdiv_ccg,
const Span<int> grids,
@@ -423,19 +414,6 @@ void update_shape_keys(Object &object,
Span<float3> translations,
Span<float3> 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<float3> positions_eval,
Span<int> verts,
MutableSpan<float3> translations,
MutableSpan<float3> positions_orig);
/**
* Creates OffsetIndices based on each node's unique vertex count, allowing for easy slicing of a
* new array.

View File

@@ -7226,6 +7226,83 @@ void clip_and_lock_translations(const Sculpt &sd,
}
}
PositionDeformData::PositionDeformData(const Depsgraph &depsgraph, Object &object_orig)
{
Mesh &mesh = *static_cast<Mesh *>(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<float3> src, const Span<int> indices, MutableSpan<float3> dst)
{
for (const int i : indices) {
dst[i] = src[i];
}
}
void PositionDeformData::deform(MutableSpan<float3> translations, const Span<int> 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<float3 *>(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<float3 *>(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<float3> positions_eval,
const Span<int> verts,
const MutableSpan<float3> translations,
const MutableSpan<float3> positions_orig)
{
SculptSession &ss = *object.sculpt;
clip_and_lock_translations(sd, ss, positions_eval, verts, translations);
MutableSpan<float3> 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<Mesh *>(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<float3> translations, const Span<float> factors)
{
for (const int i : translations.index_range()) {

View File

@@ -1091,7 +1091,6 @@ BLI_NOINLINE static void calc_bend_position(const Span<float3> positions,
static void calc_bend_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &object,
const Span<float3> positions_eval,
const Span<int> vert_propagation_steps,
const Span<float> vert_factors,
const Span<float3> 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<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -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<float3> positions,
static void calc_slide_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &object,
const Span<float3> positions_eval,
const Span<int> vert_propagation_steps,
const Span<float> vert_factors,
const Span<float3> 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<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -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<float3> positions,
static void calc_inflate_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &object,
const Span<float3> positions_eval,
const Span<int> vert_propagation_steps,
const Span<float> 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<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -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<float3> positions,
static void calc_grab_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &object,
const Span<float3> positions_eval,
const Span<int> vert_propagation_steps,
const Span<float> 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<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -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<float3> positions,
static void calc_twist_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
Object &object,
const Span<float3> positions_eval,
const Span<int> vert_propagation_steps,
const Span<float> 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<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
@@ -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<int> 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<float3> positions_eval,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const GroupedSpan<int> 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<float3> 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<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> positions = gather_data_mesh(position_data.eval, verts, tls.positions);
const MutableSpan<float3> 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<float3> 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<Mesh *>(object.data);
Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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;

View File

@@ -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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> 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<float3> 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;

View File

@@ -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<float3> positions = bke::pbvh::vert_positions_eval(depsgraph, ob);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, ob);
const Span<float3> positions = position_data.eval;
const GroupedSpan<int> 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);
});
});
}

View File

@@ -351,8 +351,7 @@ static void calc_smooth_filter(const Depsgraph &depsgraph,
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<float3> 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<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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<float3> 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<float3> translations;
};
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> 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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<float3> 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<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
const OffsetIndices faces = mesh.faces();
const Span<int> 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<int> verts = nodes[node_index].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> positions = gather_data_mesh(
position_data.eval, verts, tls.positions);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
@@ -1651,7 +1649,7 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph,
tls.smooth_positions.resize(verts.size());
const MutableSpan<float3> 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<float> 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<float3> 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<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const PositionDeformData position_data(depsgraph, object);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
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<int> verts = nodes[i].verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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;

View File

@@ -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<float3> 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<MutableSpan<float3>> eval_mut_;
/**
* Transforms from deforming modifiers, used to convert translations of evaluated positions to
* "original" translations.
*/
std::optional<Span<float3x3>> deform_imats_;
/**
* Positions from the original mesh. Not the same as #eval if there are deform modifiers.
*/
MutableSpan<float3> orig_;
Key *keys_;
KeyBlock *active_key_;
bool basis_active_;
std::optional<Array<bool>> dependent_keys_;
public:
PositionDeformData(const Depsgraph &depsgraph, Object &object_orig);
void deform(MutableSpan<float3> translations, Span<int> verts) const;
};
enum class UpdateType {
Position,
Mask,

View File

@@ -157,18 +157,17 @@ BLI_NOINLINE static void add_arrays(const MutableSpan<float3> a, const Span<floa
static void calc_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
BrushLocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
const Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> verts = node.verts();
const Span<float3> positions = gather_data_mesh(positions_eval, verts, tls.positions);
const Span<float3> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob);
MutableSpan<float3> 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;

View File

@@ -43,20 +43,19 @@ struct LocalData {
Vector<float3> 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<float3> positions_eval,
const Span<float3> vert_normals,
const bke::pbvh::MeshNode &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<float3> 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;

View File

@@ -188,15 +188,14 @@ BLI_NOINLINE static void filter_translations_with_symmetry(const Span<float3> po
}
}
static void transform_node_mesh(const Depsgraph &depsgraph,
const Sculpt &sd,
static void transform_node_mesh(const Sculpt &sd,
const std::array<float4x4, 8> &transform_mats,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
TransformLocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
SculptSession &ss = *object.sculpt;
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<int> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob);
MutableSpan<float3> 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 &params,
const float4x4 &elastic_transform_mat,
const float3 &elastic_transform_pivot,
const Span<float3> positions_eval,
const bke::pbvh::MeshNode &node,
Object &object,
TransformLocalData &tls,
const MutableSpan<float3> positions_orig)
const PositionDeformData &position_data)
{
const SculptSession &ss = *object.sculpt;
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<int> 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<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob);
MutableSpan<float3> 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;