Cleanup: Sculpt: Simplify threaded node iteration

347ec1acd7 switched to iterating over nodes with index
masks but introduced nested lambdas with the inner one slicing
the index mask with a range provided by `parallel_for`. That was
done to avoid calling `.local()` more than necessary but in practice
that doesn't have an effect, especially with a grain size of 1.

That nested iteration is cumbersome and error-prone. For the
simple parallel loops with thread local data, switch to just using the
`GrainSize` argument to `mask.foreach_index` instead.

Pull Request: https://projects.blender.org/blender/blender/pulls/128221
This commit is contained in:
Hans Goudey
2024-09-27 04:31:39 +02:00
committed by Hans Goudey
parent d832bf3ae4
commit f241c15042
42 changed files with 2525 additions and 2958 deletions

View File

@@ -123,13 +123,11 @@ void do_bmesh_topology_rake_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
for ([[maybe_unused]] const int i : IndexRange(count)) {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(
depsgraph, sd, object, brush, direction, factor * ss.cache->pressure, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(
depsgraph, sd, object, brush, direction, factor * ss.cache->pressure, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
}
pbvh.tag_positions_changed(node_mask);

View File

@@ -232,21 +232,19 @@ void do_clay_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
test_plane,
bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
test_plane,
bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -254,23 +252,19 @@ void do_clay_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -282,23 +282,21 @@ void do_clay_strips_brush(const Depsgraph &depsgraph,
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
mat,
plane,
strength,
flip,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
mat,
plane,
strength,
flip,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -306,23 +304,19 @@ void do_clay_strips_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -262,21 +262,19 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph,
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
plane_tilt,
clay_strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
plane_tilt,
clay_strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -284,23 +282,19 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, brush, plane_tilt, clay_strength, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, brush, plane_tilt, clay_strength, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, brush, plane_tilt, clay_strength, object, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, brush, plane_tilt, clay_strength, object, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -265,21 +265,19 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
offset,
strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
offset,
strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -287,23 +285,19 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -181,13 +181,11 @@ static void offset_positions(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -195,23 +193,19 @@ static void offset_positions(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -182,21 +182,19 @@ static void do_draw_face_sets_brush_mesh(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<MeshLocalData> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
MeshLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> face_indices = nodes[i].faces();
calc_faces(depsgraph,
object,
brush,
ss.cache->bstrength,
ss.cache->paint_face_set,
positions_eval,
nodes[i],
face_indices,
tls,
face_sets.span);
});
const Span<int> face_indices = nodes[i].faces();
calc_faces(depsgraph,
object,
brush,
ss.cache->bstrength,
ss.cache->paint_face_set,
positions_eval,
nodes[i],
face_indices,
tls,
face_sets.span);
});
pbvh.tag_face_sets_changed(node_mask);
face_sets.finish();
@@ -282,18 +280,16 @@ static void do_draw_face_sets_brush_grids(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<GridLocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
GridLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph,
object,
brush,
ss.cache->bstrength,
ss.cache->paint_face_set,
nodes[i],
tls,
face_sets.span);
});
calc_grids(depsgraph,
object,
brush,
ss.cache->bstrength,
ss.cache->paint_face_set,
nodes[i],
tls,
face_sets.span);
});
pbvh.tag_face_sets_changed(node_mask);
face_sets.finish();
@@ -415,12 +411,10 @@ static void do_draw_face_sets_brush_bmesh(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<BMeshLocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
BMeshLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(
object, brush, ss.cache->bstrength, ss.cache->paint_face_set, nodes[i], tls, cd_offset);
});
calc_bmesh(
object, brush, ss.cache->bstrength, ss.cache->paint_face_set, nodes[i], tls, cd_offset);
});
pbvh.tag_face_sets_changed(node_mask);
}

View File

@@ -185,12 +185,10 @@ static void offset_positions(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph, sd, brush, offset, nodes[i], object, tls, position_data);
bke::pbvh::update_node_bounds_mesh(position_data.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;
}
@@ -198,23 +196,19 @@ static void offset_positions(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -231,12 +231,10 @@ void do_draw_vector_displacement_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -244,23 +242,19 @@ void do_draw_vector_displacement_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -244,13 +244,10 @@ void do_elastic_deform_brush(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -258,23 +255,19 @@ void do_elastic_deform_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
} break;
}

View File

@@ -257,23 +257,19 @@ void calc_smooth_translations(const Depsgraph &depsgraph,
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const Span<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_translations_faces(
positions_eval, faces, corner_verts, vert_to_face_map, nodes[i], tls, translations);
});
calc_translations_faces(
positions_eval, faces, corner_verts, vert_to_face_map, nodes[i], tls, translations);
});
break;
}
case bke::pbvh::Type::Grids: {
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_translations_grids(subdiv_ccg, nodes[i], tls, translations);
});
calc_translations_grids(subdiv_ccg, nodes[i], tls, translations);
});
break;
}
@@ -281,10 +277,9 @@ void calc_smooth_translations(const Depsgraph &depsgraph,
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);
const Span<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index(
[&](const int i) { calc_translations_bmesh(nodes[i], tls, translations); });
calc_translations_bmesh(nodes[i], tls, translations);
});
break;
}
@@ -318,21 +313,19 @@ void do_enhance_details_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
vert_normals,
translations,
strength,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
vert_normals,
translations,
strength,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -340,23 +333,19 @@ void do_enhance_details_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -219,12 +219,10 @@ void do_grab_brush(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -232,23 +230,19 @@ void do_grab_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -194,13 +194,11 @@ void do_inflate_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -208,23 +206,19 @@ void do_inflate_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, scale, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, scale, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, scale, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, scale, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -394,24 +394,22 @@ void do_layer_brush(const Depsgraph &depsgraph,
}
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
vert_normals,
masks,
use_persistent_base,
persistent_position,
persistent_normal,
object,
nodes[i],
tls,
displacement,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
vert_normals,
masks,
use_persistent_base,
persistent_position,
persistent_normal,
object,
nodes[i],
tls,
displacement,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
persistent_disp_attr.finish();
break;
@@ -424,12 +422,10 @@ void do_layer_brush(const Depsgraph &depsgraph,
}
const MutableSpan<float> displacement = ss.cache->layer_displacement_factor;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, brush, object, nodes[i], tls, displacement);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, brush, object, nodes[i], tls, displacement);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
@@ -439,12 +435,10 @@ void do_layer_brush(const Depsgraph &depsgraph,
}
const MutableSpan<float> displacement = ss.cache->layer_displacement_factor;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, brush, object, nodes[i], tls, displacement);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, brush, object, nodes[i], tls, displacement);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -225,21 +225,19 @@ void do_mask_brush(const Depsgraph &depsgraph,
bke::SpanAttributeWriter<float> mask = attributes.lookup_or_add_for_write_span<float>(
".sculpt_mask", bke::AttrDomain::Point);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
brush,
bstrength,
positions,
vert_normals,
nodes[i],
object,
mesh,
tls,
mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
calc_faces(depsgraph,
brush,
bstrength,
positions,
vert_normals,
nodes[i],
object,
mesh,
tls,
mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
mask.finish();
break;
@@ -249,12 +247,10 @@ void do_mask_brush(const Depsgraph &depsgraph,
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
MutableSpan<float> masks = subdiv_ccg.masks;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, object, brush, bstrength, nodes[i], tls);
bke::pbvh::node_update_mask_grids(key, masks, nodes[i]);
});
calc_grids(depsgraph, object, brush, bstrength, nodes[i], tls);
bke::pbvh::node_update_mask_grids(key, masks, nodes[i]);
});
break;
}
@@ -262,12 +258,10 @@ void do_mask_brush(const Depsgraph &depsgraph,
const int mask_offset = CustomData_get_offset_named(
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, object, brush, bstrength, nodes[i], tls);
bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]);
});
calc_bmesh(depsgraph, object, brush, bstrength, nodes[i], tls);
bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]);
});
break;
}

View File

@@ -645,23 +645,21 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph,
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -669,41 +667,37 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph,
sd,
brush,
mat,
multiplane_scrape_planes,
ss.cache->multiplane_scrape_angle,
strength,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -109,12 +109,10 @@ void do_displacement_eraser_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_node(depsgraph, sd, object, brush, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_node(depsgraph, sd, object, brush, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
pbvh.tag_positions_changed(node_mask);
bke::pbvh::flush_bounds_to_parents(pbvh);

View File

@@ -185,25 +185,21 @@ void do_displacement_smear_brush(const Depsgraph &depsgraph,
eval_all_limit_positions(subdiv_ccg, ss.cache->displacement_smear.limit_surface_co);
}
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.slice(range).foreach_index([&](const int i) {
store_node_prev_displacement(ss.cache->displacement_smear.limit_surface_co,
subdiv_ccg.positions,
key,
nodes[i],
ss.cache->displacement_smear.prev_displacement);
});
node_mask.foreach_index(GrainSize(1), [&](const int i) {
store_node_prev_displacement(ss.cache->displacement_smear.limit_surface_co,
subdiv_ccg.positions,
key,
nodes[i],
ss.cache->displacement_smear.prev_displacement);
});
const float strength = std::clamp(ss.cache->bstrength, 0.0f, 1.0f);
threading::EnumerableThreadSpecific<LocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_node(depsgraph, ob, brush, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_node(depsgraph, ob, brush, strength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
pbvh.tag_positions_changed(node_mask);
bke::pbvh::flush_bounds_to_parents(pbvh);

View File

@@ -254,21 +254,19 @@ void do_pinch_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
stroke_xz,
ss.cache->bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
stroke_xz,
ss.cache->bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -276,23 +274,19 @@ void do_pinch_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -229,22 +229,20 @@ static void do_plane_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
plane,
ss.cache->bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data,
indexed_filter);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
plane,
ss.cache->bstrength,
vert_normals,
nodes[i],
object,
tls,
position_data,
indexed_filter);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -252,39 +250,35 @@ static void do_plane_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph,
sd,
object,
brush,
plane,
ss.cache->bstrength,
nodes[i],
tls,
generic_filter);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph,
sd,
object,
brush,
plane,
ss.cache->bstrength,
nodes[i],
tls,
generic_filter);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph,
sd,
object,
brush,
plane,
ss.cache->bstrength,
nodes[i],
tls,
generic_filter);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph,
sd,
object,
brush,
plane,
ss.cache->bstrength,
nodes[i],
tls,
generic_filter);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -216,12 +216,10 @@ void do_rotate_brush(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph, sd, brush, angle, nodes[i], object, tls, position_data);
bke::pbvh::update_node_bounds_mesh(position_data.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;
}
@@ -229,23 +227,19 @@ void do_rotate_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, angle, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, angle, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, angle, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, angle, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -295,20 +295,18 @@ void do_smooth_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
for (const float strength : iteration_strengths(brush_strength)) {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph,
sd,
faces,
corner_verts,
ss.vertex_info.boundary,
object,
brush,
strength,
nodes[i],
tls);
});
calc_grids(depsgraph,
sd,
faces,
corner_verts,
ss.vertex_info.boundary,
object,
brush,
strength,
nodes[i],
tls);
});
}
break;
@@ -319,11 +317,9 @@ void do_smooth_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
for (const float strength : iteration_strengths(brush_strength)) {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, strength, nodes[i], tls);
});
calc_bmesh(depsgraph, sd, object, brush, strength, nodes[i], tls);
});
}
break;

View File

@@ -305,10 +305,9 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
for (const float strength : iteration_strengths(brush_strength)) {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index(
[&](const int i) { calc_grids(depsgraph, object, brush, strength, nodes[i], tls); });
calc_grids(depsgraph, object, brush, strength, nodes[i], tls);
});
}
bke::pbvh::update_mask_grids(*ss.subdiv_ccg, node_mask, pbvh);
@@ -323,11 +322,9 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph,
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
for (const float strength : iteration_strengths(brush_strength)) {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, object, mask_offset, brush, strength, nodes[i], tls);
});
calc_bmesh(depsgraph, object, mask_offset, brush, strength, nodes[i], tls);
});
}
bke::pbvh::update_mask_bmesh(*ss.bm, node_mask, pbvh);

View File

@@ -380,21 +380,19 @@ void do_snake_hook_brush(const Depsgraph &depsgraph,
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
object,
brush,
&spvc,
grab_delta,
vert_normals,
nodes[i],
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
object,
brush,
&spvc,
grab_delta,
vert_normals,
nodes[i],
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -402,23 +400,19 @@ void do_snake_hook_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -192,12 +192,10 @@ void do_thumb_brush(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph, sd, brush, offset, nodes[i], object, tls, position_data);
bke::pbvh::update_node_bounds_mesh(position_data.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;
}
@@ -205,23 +203,19 @@ void do_thumb_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -327,22 +327,20 @@ void do_topology_slide_brush(const Depsgraph &depsgraph,
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_faces(depsgraph,
sd,
brush,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_faces(depsgraph,
sd,
brush,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
nodes[i],
object,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -350,23 +348,19 @@ void do_topology_slide_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -230,24 +230,22 @@ static void flush_face_changes_node(Mesh &mesh,
Vector<bool> new_hide;
};
threading::EnumerableThreadSpecific<TLS> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> node_faces = nodes[i].faces();
const Span<int> node_faces = nodes[i].faces();
tls.new_hide.resize(node_faces.size());
gather_data_mesh(hide_poly.span.as_span(), node_faces, tls.new_hide.as_mutable_span());
tls.new_hide.resize(node_faces.size());
gather_data_mesh(hide_poly.span.as_span(), node_faces, tls.new_hide.as_mutable_span());
calc_face_hide(node_faces, faces, corner_verts, hide_vert, tls.new_hide.as_mutable_span());
calc_face_hide(node_faces, faces, corner_verts, hide_vert, tls.new_hide.as_mutable_span());
if (array_utils::indexed_data_equal<bool>(hide_poly.span, node_faces, tls.new_hide)) {
return;
}
if (array_utils::indexed_data_equal<bool>(hide_poly.span, node_faces, tls.new_hide)) {
return;
}
scatter_data_mesh(tls.new_hide.as_span(), node_faces, hide_poly.span);
node_changed[i] = true;
bke::pbvh::node_update_visibility_mesh(hide_vert, nodes[i]);
});
scatter_data_mesh(tls.new_hide.as_span(), node_faces, hide_poly.span);
node_changed[i] = true;
bke::pbvh::node_update_visibility_mesh(hide_vert, nodes[i]);
});
hide_poly.finish();
@@ -297,22 +295,20 @@ static void vert_hide_update(const Depsgraph &depsgraph,
bool any_changed = false;
threading::EnumerableThreadSpecific<Vector<bool>> all_new_hide;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
Vector<bool> &new_hide = all_new_hide.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
new_hide.resize(verts.size());
gather_data_mesh(hide_vert.span.as_span(), verts, new_hide.as_mutable_span());
calc_hide(verts, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_vert.span, verts, new_hide)) {
return;
}
new_hide.resize(verts.size());
gather_data_mesh(hide_vert.span.as_span(), verts, new_hide.as_mutable_span());
calc_hide(verts, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_vert.span, verts, new_hide)) {
return;
}
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideVert);
scatter_data_mesh(new_hide.as_span(), verts, hide_vert.span);
});
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideVert);
scatter_data_mesh(new_hide.as_span(), verts, hide_vert.span);
});
hide_vert.finish();
@@ -339,35 +335,33 @@ static void grid_hide_update(Depsgraph &depsgraph,
Array<bool> node_changed(node_mask.min_array_size(), false);
bool any_changed = false;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
BitGroupVector<> new_hide(grids.size(), grid_hidden.group_size());
for (const int i : grids.index_range()) {
new_hide[i].copy_from(grid_hidden[grids[i]].as_span());
}
node_mask.foreach_index(GrainSize(1), [&](const int i) {
const Span<int> grids = nodes[i].grids();
BitGroupVector<> new_hide(grids.size(), grid_hidden.group_size());
for (const int i : grids.index_range()) {
new_hide[i].copy_from(grid_hidden[grids[i]].as_span());
}
for (const int i : grids.index_range()) {
calc_hide(grids[i], new_hide[i]);
}
for (const int i : grids.index_range()) {
calc_hide(grids[i], new_hide[i]);
}
if (std::all_of(grids.index_range().begin(), grids.index_range().end(), [&](const int i) {
return bits::spans_equal(grid_hidden[grids[i]], new_hide[i]);
}))
{
return;
}
if (std::all_of(grids.index_range().begin(), grids.index_range().end(), [&](const int i) {
return bits::spans_equal(grid_hidden[grids[i]], new_hide[i]);
}))
{
return;
}
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideVert);
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideVert);
for (const int i : grids.index_range()) {
grid_hidden[grids[i]].copy_from(new_hide[i].as_span());
}
for (const int i : grids.index_range()) {
grid_hidden[grids[i]].copy_from(new_hide[i].as_span());
}
node_changed[i] = true;
bke::pbvh::node_update_visibility_grids(grid_hidden, nodes[i]);
});
node_changed[i] = true;
bke::pbvh::node_update_visibility_grids(grid_hidden, nodes[i]);
});
IndexMaskMemory memory;

View File

@@ -212,21 +212,19 @@ void update_mask_mesh(const Depsgraph &depsgraph,
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::EnumerableThreadSpecific<LocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = hide::node_visible_verts(nodes[i], hide_vert, tls.visible_verts);
tls.mask.resize(verts.size());
gather_data_mesh(mask.span.as_span(), verts, tls.mask.as_mutable_span());
update_fn(tls.mask, verts);
if (array_utils::indexed_data_equal<float>(mask.span, verts, tls.mask)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
scatter_data_mesh(tls.mask.as_span(), verts, mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
node_changed[i] = true;
});
const Span<int> verts = hide::node_visible_verts(nodes[i], hide_vert, tls.visible_verts);
tls.mask.resize(verts.size());
gather_data_mesh(mask.span.as_span(), verts, tls.mask.as_mutable_span());
update_fn(tls.mask, verts);
if (array_utils::indexed_data_equal<float>(mask.span, verts, tls.mask)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
scatter_data_mesh(tls.mask.as_span(), verts, mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
node_changed[i] = true;
});
IndexMaskMemory memory;
@@ -404,17 +402,15 @@ static void fill_mask_mesh(const Depsgraph &depsgraph,
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::EnumerableThreadSpecific<Vector<int>> all_index_data;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
Vector<int> &index_data = all_index_data.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = hide::node_visible_verts(nodes[i], hide_vert, index_data);
if (std::all_of(verts.begin(), verts.end(), [&](int i) { return mask.span[i] == value; })) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
mask.span.fill_indices(verts, value);
node_changed[i] = true;
});
const Span<int> verts = hide::node_visible_verts(nodes[i], hide_vert, index_data);
if (std::all_of(verts.begin(), verts.end(), [&](int i) { return mask.span[i] == value; })) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
mask.span.fill_indices(verts, value);
node_changed[i] = true;
});
IndexMaskMemory memory;
@@ -783,29 +779,27 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.slice(range).foreach_index([&](const int node_index) {
bke::pbvh::GridsNode &node = nodes[node_index];
bool any_changed = false;
for (const int grid : node.grids()) {
const int vert_start = grid * key.grid_area;
BKE_subdiv_ccg_foreach_visible_grid_vert(key, grid_hidden, grid, [&](const int i) {
const int vert = vert_start + i;
if (gesture::is_affected(gesture_data, positions[vert], normals[vert])) {
float &mask = masks[vert];
if (!any_changed) {
any_changed = true;
undo::push_node(depsgraph, object, &node, undo::Type::Mask);
}
mask = mask_gesture_get_new_value(mask, op.mode, op.value);
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
bke::pbvh::GridsNode &node = nodes[node_index];
bool any_changed = false;
for (const int grid : node.grids()) {
const int vert_start = grid * key.grid_area;
BKE_subdiv_ccg_foreach_visible_grid_vert(key, grid_hidden, grid, [&](const int i) {
const int vert = vert_start + i;
if (gesture::is_affected(gesture_data, positions[vert], normals[vert])) {
float &mask = masks[vert];
if (!any_changed) {
any_changed = true;
undo::push_node(depsgraph, object, &node, undo::Type::Mask);
}
});
if (any_changed) {
bke::pbvh::node_update_mask_grids(key, masks, node);
node_changed[node_index] = true;
mask = mask_gesture_get_new_value(mask, op.mode, op.value);
}
});
if (any_changed) {
bke::pbvh::node_update_mask_grids(key, masks, node);
node_changed[node_index] = true;
}
});
}
});
IndexMaskMemory memory;
@@ -820,25 +814,23 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.slice(range).foreach_index([&](const int i) {
bool any_changed = false;
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&nodes[i])) {
if (gesture::is_affected(gesture_data, vert->co, vert->no)) {
const float old_mask = BM_ELEM_CD_GET_FLOAT(vert, offset);
if (!any_changed) {
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
}
const float new_mask = mask_gesture_get_new_value(old_mask, op.mode, op.value);
BM_ELEM_CD_SET_FLOAT(vert, offset, new_mask);
node_mask.foreach_index(GrainSize(1), [&](const int i) {
bool any_changed = false;
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&nodes[i])) {
if (gesture::is_affected(gesture_data, vert->co, vert->no)) {
const float old_mask = BM_ELEM_CD_GET_FLOAT(vert, offset);
if (!any_changed) {
any_changed = true;
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);
}
const float new_mask = mask_gesture_get_new_value(old_mask, op.mode, op.value);
BM_ELEM_CD_SET_FLOAT(vert, offset, new_mask);
}
if (any_changed) {
bke::pbvh::node_update_mask_bmesh(offset, nodes[i]);
node_changed[i] = true;
}
});
}
if (any_changed) {
bke::pbvh::node_update_mask_bmesh(offset, nodes[i]);
node_changed[i] = true;
}
});
IndexMaskMemory memory;

View File

@@ -1089,111 +1089,108 @@ static void do_vpaint_brush_blur_loops(const bContext *C,
Vector<float> distances;
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
blender::threading::parallel_for(node_mask.index_range(), 1LL, [&](IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ? dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
const float brush_fade = factors[i];
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
using Blend = typename Traits::BlendType;
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
/* Get the average face color */
Color color_final(0, 0, 0, 0);
const float brush_fade = factors[i];
int total_hit_loops = 0;
Blend blend[4] = {0};
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
using Blend = typename Traits::BlendType;
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
/* Get the average face color */
Color color_final(0, 0, 0, 0);
int total_hit_loops = 0;
Blend blend[4] = {0};
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
return;
}
total_hit_loops += faces[face].size();
for (const int corner : faces[face]) {
const Color &col = colors[corner];
/* Color is squared to compensate the `sqrt` color encoding. */
blend[0] += (Blend)col.r * (Blend)col.r;
blend[1] += (Blend)col.g * (Blend)col.g;
blend[2] += (Blend)col.b * (Blend)col.b;
blend[3] += (Blend)col.a * (Blend)col.a;
}
}
if (total_hit_loops == 0) {
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
return;
}
total_hit_loops += faces[face].size();
for (const int corner : faces[face]) {
const Color &col = colors[corner];
/* Use rgb^2 color averaging. */
Color *col = &color_final;
color_final.r = Traits::round(sqrtf(Traits::divide_round(blend[0], total_hit_loops)));
color_final.g = Traits::round(sqrtf(Traits::divide_round(blend[1], total_hit_loops)));
color_final.b = Traits::round(sqrtf(Traits::divide_round(blend[2], total_hit_loops)));
color_final.a = Traits::round(sqrtf(Traits::divide_round(blend[3], total_hit_loops)));
/* For each face owning this vert,
* paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
const int corner = bke::mesh::face_find_corner_from_vert(
faces[face], corner_verts, vert);
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!previous_color.is_empty()) {
/* Get the previous loop color */
if (isZero(previous_color[corner])) {
previous_color[corner] = colors[corner];
}
color_orig = previous_color[corner];
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[corner] = vpaint_blend<Color, Traits>(
vp, colors[corner], color_orig, *col, final_alpha, Traits::range * brush_strength);
/* Color is squared to compensate the `sqrt` color encoding. */
blend[0] += (Blend)col.r * (Blend)col.r;
blend[1] += (Blend)col.g * (Blend)col.g;
blend[2] += (Blend)col.b * (Blend)col.b;
blend[3] += (Blend)col.a * (Blend)col.a;
}
});
}
});
}
if (total_hit_loops == 0) {
return;
}
/* Use rgb^2 color averaging. */
Color *col = &color_final;
color_final.r = Traits::round(sqrtf(Traits::divide_round(blend[0], total_hit_loops)));
color_final.g = Traits::round(sqrtf(Traits::divide_round(blend[1], total_hit_loops)));
color_final.b = Traits::round(sqrtf(Traits::divide_round(blend[2], total_hit_loops)));
color_final.a = Traits::round(sqrtf(Traits::divide_round(blend[3], total_hit_loops)));
/* For each face owning this vert,
* paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
const int corner = bke::mesh::face_find_corner_from_vert(
faces[face], corner_verts, vert);
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!previous_color.is_empty()) {
/* Get the previous loop color */
if (isZero(previous_color[corner])) {
previous_color[corner] = colors[corner];
}
color_orig = previous_color[corner];
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[corner] = vpaint_blend<Color, Traits>(
vp, colors[corner], color_orig, *col, final_alpha, Traits::range * brush_strength);
}
});
}
});
}
@@ -1247,102 +1244,99 @@ static void do_vpaint_brush_blur_verts(const bContext *C,
Vector<float> distances;
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
blender::threading::parallel_for(node_mask.index_range(), 1LL, [&](IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
const float brush_fade = factors[i];
/* Get the average face color */
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
using Blend = typename Traits::BlendType;
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
Color color_final(0, 0, 0, 0);
int total_hit_loops = 0;
Blend blend[4] = {0};
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
total_hit_loops += faces[face].size();
for (const int vert : corner_verts.slice(faces[face])) {
const Color &col = colors[vert];
/* Color is squared to compensate the `sqrt` color encoding. */
blend[0] += (Blend)col.r * (Blend)col.r;
blend[1] += (Blend)col.g * (Blend)col.g;
blend[2] += (Blend)col.b * (Blend)col.b;
blend[3] += (Blend)col.a * (Blend)col.a;
}
}
if (total_hit_loops == 0) {
return;
}
/* Use rgb^2 color averaging. */
color_final.r = Traits::round(sqrtf(Traits::divide_round(blend[0], total_hit_loops)));
color_final.g = Traits::round(sqrtf(Traits::divide_round(blend[1], total_hit_loops)));
color_final.b = Traits::round(sqrtf(Traits::divide_round(blend[2], total_hit_loops)));
color_final.a = Traits::round(sqrtf(Traits::divide_round(blend[3], total_hit_loops)));
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!previous_color.is_empty()) {
/* Get the previous loop color */
if (isZero(previous_color[vert])) {
previous_color[vert] = colors[vert];
}
color_orig = previous_color[vert];
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[vert] = vpaint_blend<Color, Traits>(vp,
colors[vert],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
});
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ? dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
});
const float brush_fade = factors[i];
/* Get the average face color */
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
using Blend = typename Traits::BlendType;
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
Color color_final(0, 0, 0, 0);
int total_hit_loops = 0;
Blend blend[4] = {0};
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
total_hit_loops += faces[face].size();
for (const int vert : corner_verts.slice(faces[face])) {
const Color &col = colors[vert];
/* Color is squared to compensate the `sqrt` color encoding. */
blend[0] += (Blend)col.r * (Blend)col.r;
blend[1] += (Blend)col.g * (Blend)col.g;
blend[2] += (Blend)col.b * (Blend)col.b;
blend[3] += (Blend)col.a * (Blend)col.a;
}
}
if (total_hit_loops == 0) {
return;
}
/* Use rgb^2 color averaging. */
color_final.r = Traits::round(sqrtf(Traits::divide_round(blend[0], total_hit_loops)));
color_final.g = Traits::round(sqrtf(Traits::divide_round(blend[1], total_hit_loops)));
color_final.b = Traits::round(sqrtf(Traits::divide_round(blend[2], total_hit_loops)));
color_final.a = Traits::round(sqrtf(Traits::divide_round(blend[3], total_hit_loops)));
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!previous_color.is_empty()) {
/* Get the previous loop color */
if (isZero(previous_color[vert])) {
previous_color[vert] = colors[vert];
}
color_orig = previous_color[vert];
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[vert] = vpaint_blend<Color, Traits>(vp,
colors[vert],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
});
}
});
}
@@ -1408,145 +1402,141 @@ static void do_vpaint_brush_smear(const bContext *C,
Vector<float> distances;
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
blender::threading::parallel_for(node_mask.index_range(), 1LL, [&](IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
/* Calculate the dot prod. between ray norm on surf and current vert
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ? dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
const float brush_fade = factors[i];
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
bool do_color = false;
/* Minimum dot product between brush direction and current
* to neighbor direction is 0.0, meaning orthogonal. */
float stroke_dot_max = 0.0f;
/* Calculate the dot prod. between ray norm on surf and current vert
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
const float brush_fade = factors[i];
/* Get the color of the loop in the opposite
* direction of the brush movement */
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
MutableSpan<Color> color_curr = g_color_curr.typed<T>().template cast<Color>();
MutableSpan<Color> color_prev_smear = g_color_prev_smear.typed<T>().template cast<Color>();
MutableSpan<Color> color_prev = g_color_prev.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
bool do_color = false;
/* Minimum dot product between brush direction and current
* to neighbor direction is 0.0, meaning orthogonal. */
float stroke_dot_max = 0.0f;
Color color_final(0, 0, 0, 0);
/* Get the color of the loop in the opposite
* direction of the brush movement */
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
MutableSpan<Color> color_curr = g_color_curr.typed<T>().template cast<Color>();
MutableSpan<Color> color_prev_smear =
g_color_prev_smear.typed<T>().template cast<Color>();
MutableSpan<Color> color_prev = g_color_prev.typed<T>().template cast<Color>();
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
Color color_final(0, 0, 0, 0);
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
for (const int face : vert_to_face[vert]) {
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
for (const int corner : faces[face]) {
const int v_other_index = corner_verts[corner];
if (v_other_index == vert) {
continue;
}
for (const int corner : faces[face]) {
const int v_other_index = corner_verts[corner];
if (v_other_index == vert) {
continue;
}
/* Get the direction from the
* selected vert to the neighbor. */
float other_dir[3];
sub_v3_v3v3(other_dir, vert_positions[vert], vert_positions[v_other_index]);
project_plane_v3_v3v3(other_dir, other_dir, cache.view_normal_symm);
/* Get the direction from the
* selected vert to the neighbor. */
float other_dir[3];
sub_v3_v3v3(other_dir, vert_positions[vert], vert_positions[v_other_index]);
project_plane_v3_v3v3(other_dir, other_dir, cache.view_normal_symm);
normalize_v3(other_dir);
const float stroke_dot = dot_v3v3(other_dir, brush_dir);
int elem_index;
if (vpd.domain == AttrDomain::Point) {
elem_index = v_other_index;
}
else {
elem_index = corner;
}
if (stroke_dot > stroke_dot_max) {
stroke_dot_max = stroke_dot;
color_final = color_prev_smear[elem_index];
do_color = true;
}
}
}
if (!do_color) {
return;
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* For each face owning this vert,
* paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
normalize_v3(other_dir);
const float stroke_dot = dot_v3v3(other_dir, brush_dir);
int elem_index;
if (vpd.domain == AttrDomain::Point) {
elem_index = vert;
elem_index = v_other_index;
}
else {
elem_index = bke::mesh::face_find_corner_from_vert(faces[face], corner_verts, vert);
}
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
elem_index = corner;
}
/* Get the previous element color */
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!color_prev.is_empty()) {
/* Get the previous element color */
if (isZero(color_prev[elem_index])) {
color_prev[elem_index] = colors[elem_index];
}
color_orig = color_prev[elem_index];
if (stroke_dot > stroke_dot_max) {
stroke_dot_max = stroke_dot;
color_final = color_prev_smear[elem_index];
do_color = true;
}
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[elem_index] = vpaint_blend<Color, Traits>(vp,
colors[elem_index],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
color_curr[elem_index] = colors[elem_index];
}
});
}
});
}
if (!do_color) {
return;
}
const float final_alpha = Traits::range * brush_fade * brush_strength *
brush_alpha_pressure;
/* For each face owning this vert,
* paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
int elem_index;
if (vpd.domain == AttrDomain::Point) {
elem_index = vert;
}
else {
elem_index = bke::mesh::face_find_corner_from_vert(faces[face], corner_verts, vert);
}
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
/* Get the previous element color */
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
if (!color_prev.is_empty()) {
/* Get the previous element color */
if (isZero(color_prev[elem_index])) {
color_prev[elem_index] = colors[elem_index];
}
color_orig = color_prev[elem_index];
}
/* Mix the new color with the original
* based on the brush strength and the curve. */
colors[elem_index] = vpaint_blend<Color, Traits>(vp,
colors[elem_index],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
color_curr[elem_index] = colors[elem_index];
}
});
}
});
}
@@ -1590,53 +1580,51 @@ static void calculate_average_color(VPaintData &vpd,
const Span<Color> colors = attribute.typed<T>().template cast<Color>();
Array<VPaintAverageAccum<Blend>> accum(nodes.size());
blender::threading::parallel_for(node_mask.index_range(), 1LL, [&](IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
VPaintAverageAccum<Blend> &accum2 = accum[i];
accum2.len = 0;
memset(accum2.value, 0, sizeof(accum2.value));
VPaintAverageAccum<Blend> &accum2 = accum[i];
accum2.len = 0;
memset(accum2.value, 0, sizeof(accum2.value));
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
accum2.len += vert_to_face[vert].size();
/* if a vertex is within the brush region, then add its color to the blend. */
for (const int face : vert_to_face[vert]) {
int elem_index;
if (vpd.domain == AttrDomain::Corner) {
elem_index = bke::mesh::face_find_corner_from_vert(faces[face], corner_verts, vert);
}
else {
elem_index = vert;
}
accum2.len += vert_to_face[vert].size();
/* if a vertex is within the brush region, then add its color to the blend. */
for (const int face : vert_to_face[vert]) {
int elem_index;
if (vpd.domain == AttrDomain::Corner) {
elem_index = bke::mesh::face_find_corner_from_vert(faces[face], corner_verts, vert);
}
else {
elem_index = vert;
}
/* Color is squared to compensate the `sqrt` color encoding. */
const Color &col = colors[elem_index];
accum2.value[0] += col.r * col.r;
accum2.value[1] += col.g * col.g;
accum2.value[2] += col.b * col.b;
}
/* Color is squared to compensate the `sqrt` color encoding. */
const Color &col = colors[elem_index];
accum2.value[0] += col.r * col.r;
accum2.value[1] += col.g * col.g;
accum2.value[2] += col.b * col.b;
}
});
}
});
Blend accum_len = 0;
@@ -1725,121 +1713,118 @@ static void vpaint_do_draw(const bContext *C,
Vector<float> distances;
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
blender::threading::parallel_for(node_mask.index_range(), 1LL, [&](IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide(mesh, verts, factors);
if (!select_vert.is_empty()) {
filter_factors_with_selection(select_vert, verts, factors);
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
tls.distances.resize(verts.size());
const MutableSpan<float> distances = tls.distances;
calc_brush_distances(
ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
filter_distances_with_radius(cache.radius, distances, factors);
calc_brush_strength_factors(cache, brush, distances, factors);
/* Calculate the dot product between ray normal on surface and current vertex
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ? dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
const float brush_fade = factors[i];
for (const int i : verts.index_range()) {
const int vert = verts[i];
if (factors[i] == 0.0f) {
continue;
}
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
Color color_final = fromFloat<Color>(vpd.paintcol);
/* Calculate the dot product between ray normal on surface and current vertex
* (ie splash prevention factor), and only paint front facing verts. */
float brush_strength = cache.bstrength;
const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1.0f;
if (!vwpaint::test_brush_angle_falloff(
brush, vpd.normal_angle_precalc, angle_cos, &brush_strength))
{
continue;
}
const float brush_fade = factors[i];
/* If we're painting with a texture, sample the texture color and alpha. */
float tex_alpha = 1.0;
if (vpd.is_texbrush) {
/* NOTE: we may want to paint alpha as vertex color alpha. */
to_static_color_type(vpd.type, [&](auto dummy) {
using T = decltype(dummy);
using Color =
std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
using Traits = blender::color::Traits<Color>;
MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
Color color_final = fromFloat<Color>(vpd.paintcol);
/* If we're painting with a texture, sample the texture color and alpha. */
float tex_alpha = 1.0;
if (vpd.is_texbrush) {
/* NOTE: we may want to paint alpha as vertex color alpha. */
/* If the active area is being applied for symmetry, flip it
* across the symmetry axis and rotate it back to the original
* position in order to project it. This ensures that the
* brush texture will be oriented correctly.
* This is the method also used in #sculpt_apply_texture(). */
float3 position = vpd.vert_positions[vert];
if (cache.radial_symmetry_pass) {
position = blender::math::transform_point(cache.symm_rot_mat_inv, position);
}
const float3 symm_point = blender::ed::sculpt_paint::symmetry_flip(
position, cache.mirror_symmetry_pass);
tex_alpha = paint_and_tex_color_alpha<Color>(vp, vpd, symm_point, &color_final);
/* If the active area is being applied for symmetry, flip it
* across the symmetry axis and rotate it back to the original
* position in order to project it. This ensures that the
* brush texture will be oriented correctly.
* This is the method also used in #sculpt_apply_texture(). */
float3 position = vpd.vert_positions[vert];
if (cache.radial_symmetry_pass) {
position = blender::math::transform_point(cache.symm_rot_mat_inv, position);
}
const float3 symm_point = blender::ed::sculpt_paint::symmetry_flip(
position, cache.mirror_symmetry_pass);
Color color_orig(0, 0, 0, 0);
tex_alpha = paint_and_tex_color_alpha<Color>(vp, vpd, symm_point, &color_final);
}
Color color_orig(0, 0, 0, 0);
if (vpd.domain == AttrDomain::Point) {
if (!previous_color.is_empty()) {
if (isZero(previous_color[vert])) {
previous_color[vert] = colors[vert];
}
color_orig = previous_color[vert];
}
const float final_alpha = Traits::frange * brush_fade * brush_strength * tex_alpha *
brush_alpha_pressure;
colors[vert] = vpaint_blend<Color, Traits>(vp,
colors[vert],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
}
else {
/* For each face owning this vert, paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
const int corner = bke::mesh::face_find_corner_from_vert(
faces[face], corner_verts, vert);
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */
if (vpd.domain == AttrDomain::Point) {
if (!previous_color.is_empty()) {
if (isZero(previous_color[vert])) {
previous_color[vert] = colors[vert];
if (isZero(previous_color[corner])) {
previous_color[corner] = colors[corner];
}
color_orig = previous_color[vert];
color_orig = previous_color[corner];
}
const float final_alpha = Traits::frange * brush_fade * brush_strength * tex_alpha *
brush_alpha_pressure;
colors[vert] = vpaint_blend<Color, Traits>(vp,
colors[vert],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
colors[corner] = vpaint_blend<Color, Traits>(vp,
colors[corner],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
}
else {
/* For each face owning this vert, paint each loop belonging to this vert. */
for (const int face : vert_to_face[vert]) {
const int corner = bke::mesh::face_find_corner_from_vert(
faces[face], corner_verts, vert);
if (!select_poly.is_empty() && !select_poly[face]) {
continue;
}
Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */
if (!previous_color.is_empty()) {
if (isZero(previous_color[corner])) {
previous_color[corner] = colors[corner];
}
color_orig = previous_color[corner];
}
const float final_alpha = Traits::frange * brush_fade * brush_strength * tex_alpha *
brush_alpha_pressure;
colors[corner] = vpaint_blend<Color, Traits>(vp,
colors[corner],
color_orig,
color_final,
final_alpha,
Traits::range * brush_strength);
}
}
});
}
});
}
});
}
});
}

View File

@@ -1290,24 +1290,22 @@ static void do_bend_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bend_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_bend_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -1316,47 +1314,43 @@ static void do_bend_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bend_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_bend_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bend_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bend_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.bend.pivot_positions,
boundary.bend.pivot_rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -1581,23 +1575,21 @@ static void do_slide_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_slide_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_slide_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -1606,45 +1598,41 @@ static void do_slide_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_slide_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_slide_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_slide_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_slide_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.slide.directions,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -1855,22 +1843,20 @@ static void do_inflate_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_inflate_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_inflate_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -1879,43 +1865,39 @@ static void do_inflate_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_inflate_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_inflate_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_inflate_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_inflate_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -2129,23 +2111,21 @@ static void do_grab_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grab_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_grab_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -2154,45 +2134,41 @@ static void do_grab_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grab_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grab_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grab_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_grab_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
ss.cache->grab_delta_symm,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -2411,24 +2387,22 @@ static void do_twist_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_twist_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_twist_mesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -2437,47 +2411,43 @@ static void do_twist_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_twist_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_twist_grids(depsgraph,
sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_twist_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_twist_bmesh(depsgraph,
sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
boundary.twist.pivot_position,
boundary.twist.rotation_axis,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -2813,25 +2783,23 @@ static void do_smooth_brush(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalDataMesh> all_tls;
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_smooth_mesh(sd,
object,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
calc_smooth_mesh(sd,
object,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -2840,41 +2808,37 @@ static void do_smooth_brush(const Depsgraph &depsgraph,
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::EnumerableThreadSpecific<LocalDataGrids> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataGrids &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_smooth_grids(sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_smooth_grids(sd,
object,
subdiv_ccg,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalDataBMesh> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalDataBMesh &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_smooth_bmesh(sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_smooth_bmesh(sd,
object,
boundary.edit_info.propagation_steps_num,
boundary.edit_info.strength_factor,
nodes[i],
tls,
boundary.initial_vert_position,
strength,
deform_target);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -1242,21 +1242,19 @@ static void calc_constraint_factors(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
if (ss.cache) {
const MutableSpan positions = gather_data_mesh(init_positions, verts, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_mesh(factors.as_span(), verts, cloth_factors);
});
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
if (ss.cache) {
const MutableSpan positions = gather_data_mesh(init_positions, verts, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_mesh(factors.as_span(), verts, cloth_factors);
});
break;
}
@@ -1264,45 +1262,41 @@ static void calc_constraint_factors(const Depsgraph &depsgraph,
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
tls.factors.resize(grid_verts_num);
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(depsgraph, object, automasking, nodes[i], grids, factors);
if (ss.cache) {
const Span<float3> positions = gather_data_grids(
subdiv_ccg, init_positions, grids, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_grids(subdiv_ccg, factors.as_span(), grids, cloth_factors);
});
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
tls.factors.resize(grid_verts_num);
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(depsgraph, object, automasking, nodes[i], grids, factors);
if (ss.cache) {
const Span<float3> positions = gather_data_grids(
subdiv_ccg, init_positions, grids, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_grids(subdiv_ccg, factors.as_span(), grids, cloth_factors);
});
break;
}
case bke::pbvh::Type::BMesh: {
const BMesh &bm = *ss.bm;
const Span<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
const_cast<bke::pbvh::BMeshNode *>(&nodes[i]));
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
if (ss.cache) {
const MutableSpan positions = gather_data_bmesh(init_positions, verts, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_bmesh(factors.as_span(), verts, cloth_factors);
});
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
const_cast<bke::pbvh::BMeshNode *>(&nodes[i]));
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
if (ss.cache) {
const MutableSpan positions = gather_data_bmesh(init_positions, verts, tls.positions);
calc_brush_simulation_falloff(
*brush, ss.cache->radius, sim_location, positions, factors);
}
scatter_data_bmesh(factors.as_span(), verts, cloth_factors);
});
break;
}
@@ -1407,32 +1401,30 @@ void do_simulation_step(const Depsgraph &depsgraph,
});
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PositionDeformData position_data(depsgraph, object);
threading::parallel_for(active_nodes.index_range(), 1, [&](const IndexRange range) {
active_nodes.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
active_nodes.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
solve_verts_simulation(object, brush, sim_location, verts, factors, tls, cloth_sim);
solve_verts_simulation(object, brush, sim_location, verts, factors, tls, cloth_sim);
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]] - position_data.eval[verts[i]];
}
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]] - position_data.eval[verts[i]];
}
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
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(position_data.eval, nodes[i]);
});
cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] =
SCULPT_CLOTH_NODE_INACTIVE;
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -1447,30 +1439,28 @@ void do_simulation_step(const Depsgraph &depsgraph,
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<float3> cloth_positions = cloth_sim.pos;
MutableSpan<float3> positions = subdiv_ccg.positions;
threading::parallel_for(active_nodes.index_range(), 1, [&](const IndexRange range) {
active_nodes.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
active_nodes.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
tls.factors.resize(grid_verts_num);
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_grids_factors(depsgraph, object, automasking, nodes[i], grids, factors);
tls.factors.resize(grid_verts_num);
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_grids_factors(depsgraph, object, automasking, nodes[i], grids, factors);
const Span<int> verts = calc_vert_indices_grids(key, grids, tls.vert_indices);
solve_verts_simulation(object, brush, sim_location, verts, factors, tls, cloth_sim);
const Span<int> verts = calc_vert_indices_grids(key, grids, tls.vert_indices);
solve_verts_simulation(object, brush, sim_location, verts, factors, tls, cloth_sim);
for (const int grid : grids) {
const IndexRange grid_range = bke::ccg::grid_range(key, grid);
positions.slice(grid_range).copy_from(cloth_positions.slice(grid_range));
}
for (const int grid : grids) {
const IndexRange grid_range = bke::ccg::grid_range(key, grid);
positions.slice(grid_range).copy_from(cloth_positions.slice(grid_range));
}
cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] =
SCULPT_CLOTH_NODE_INACTIVE;
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] =
SCULPT_CLOTH_NODE_INACTIVE;
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
@@ -1482,29 +1472,26 @@ void do_simulation_step(const Depsgraph &depsgraph,
return cloth_sim.node_state[node_index] == SCULPT_CLOTH_NODE_ACTIVE;
});
BMesh &bm = *ss.bm;
threading::parallel_for(active_nodes.index_range(), 1, [&](const IndexRange range) {
active_nodes.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
active_nodes.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
const auto_mask::Cache *automasking = auto_mask::active_cache_get(ss);
auto_mask::calc_vert_factors(depsgraph, object, automasking, nodes[i], verts, factors);
const Span<int> vert_indices = calc_vert_indices_bmesh(verts, tls.vert_indices);
solve_verts_simulation(
object, brush, sim_location, vert_indices, factors, tls, cloth_sim);
const Span<int> vert_indices = calc_vert_indices_bmesh(verts, tls.vert_indices);
solve_verts_simulation(object, brush, sim_location, vert_indices, factors, tls, cloth_sim);
for (BMVert *vert : verts) {
copy_v3_v3(vert->co, cloth_sim.pos[BM_elem_index_get(vert)]);
}
for (BMVert *vert : verts) {
copy_v3_v3(vert->co, cloth_sim.pos[BM_elem_index_get(vert)]);
}
cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] =
SCULPT_CLOTH_NODE_INACTIVE;
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] =
SCULPT_CLOTH_NODE_INACTIVE;
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -1585,60 +1572,54 @@ static void cloth_brush_apply_brush_foces(const Depsgraph &depsgraph,
const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, ob);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, ob);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_forces_mesh(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
positions_eval,
vert_normals,
nodes[i],
tls);
});
calc_forces_mesh(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
positions_eval,
vert_normals,
nodes[i],
tls);
});
break;
}
case bke::pbvh::Type::Grids: {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_forces_grids(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
nodes[i],
tls);
});
calc_forces_grids(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
nodes[i],
tls);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_forces_bmesh(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
nodes[i],
tls);
});
calc_forces_bmesh(depsgraph,
ob,
brush,
offset,
mat,
sim_location,
gravity,
falloff_plane,
nodes[i],
tls);
});
break;
}
@@ -1684,18 +1665,8 @@ static void copy_positions_to_array(const Depsgraph &depsgraph,
positions.copy_from(bke::pbvh::vert_positions_eval(depsgraph, object));
break;
case bke::pbvh::Type::Grids: {
const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
IndexMaskMemory memory;
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
threading::parallel_for(node_mask.index_range(), 8, [&](const IndexRange range) {
Vector<float3> node_positions;
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
gather_grids_positions(subdiv_ccg, grids, node_positions);
scatter_data_grids(subdiv_ccg, node_positions.as_span(), grids, positions);
});
});
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
positions.copy_from(subdiv_ccg.positions);
break;
}
case bke::pbvh::Type::BMesh:
@@ -1715,22 +1686,8 @@ static void copy_normals_to_array(const Depsgraph &depsgraph,
normals.copy_from(bke::pbvh::vert_normals_eval(depsgraph, object));
break;
case bke::pbvh::Type::Grids: {
const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
IndexMaskMemory memory;
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
threading::parallel_for(node_mask.index_range(), 8, [&](const IndexRange range) {
Vector<float3> node_normals;
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
node_normals.resize(grid_verts_num);
gather_grids_normals(subdiv_ccg, grids, node_normals);
scatter_data_grids(subdiv_ccg, node_normals.as_span(), grids, normals);
});
});
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
normals.copy_from(subdiv_ccg.normals);
break;
}
case bke::pbvh::Type::BMesh:
@@ -2338,22 +2295,20 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set",
bke::AttrDomain::Face);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_filter_forces_mesh(*depsgraph,
filter_type,
filter_strength,
gravity,
positions_eval,
vert_normals,
vert_to_face_map,
face_sets,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]);
});
apply_filter_forces_mesh(*depsgraph,
filter_type,
filter_strength,
gravity,
positions_eval,
vert_normals,
vert_to_face_map,
face_sets,
nodes[i],
object,
tls);
bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]);
});
break;
}
@@ -2365,25 +2320,21 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_filter_forces_grids(
*depsgraph, face_sets, filter_type, filter_strength, gravity, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
apply_filter_forces_grids(
*depsgraph, face_sets, filter_type, filter_strength, gravity, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_filter_forces_bmesh(
*depsgraph, filter_type, filter_strength, gravity, nodes[i], object, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
apply_filter_forces_bmesh(
*depsgraph, filter_type, filter_strength, gravity, nodes[i], object, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -301,45 +301,41 @@ static void face_sets_update(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<TLS> all_tls;
if (pbvh.type() == bke::pbvh::Type::Mesh) {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> faces = nodes[i].faces();
const Span<int> faces = nodes[i].faces();
tls.new_face_sets.resize(faces.size());
MutableSpan<int> new_face_sets = tls.new_face_sets;
array_utils::gather(face_sets.span.as_span(), faces, new_face_sets);
calc_face_sets(faces, new_face_sets);
if (array_utils::indexed_data_equal<int>(face_sets.span, faces, new_face_sets)) {
return;
}
tls.new_face_sets.resize(faces.size());
MutableSpan<int> new_face_sets = tls.new_face_sets;
array_utils::gather(face_sets.span.as_span(), faces, new_face_sets);
calc_face_sets(faces, new_face_sets);
if (array_utils::indexed_data_equal<int>(face_sets.span, faces, new_face_sets)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
node_changed[i] = true;
});
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
node_changed[i] = true;
});
}
else if (pbvh.type() == bke::pbvh::Type::Grids) {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
tls.new_face_sets.resize(faces.size());
MutableSpan<int> new_face_sets = tls.new_face_sets;
array_utils::gather(face_sets.span.as_span(), faces, new_face_sets);
calc_face_sets(faces, new_face_sets);
if (array_utils::indexed_data_equal<int>(face_sets.span, faces, new_face_sets)) {
return;
}
tls.new_face_sets.resize(faces.size());
MutableSpan<int> new_face_sets = tls.new_face_sets;
array_utils::gather(face_sets.span.as_span(), faces, new_face_sets);
calc_face_sets(faces, new_face_sets);
if (array_utils::indexed_data_equal<int>(face_sets.span, faces, new_face_sets)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
node_changed[i] = true;
});
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
node_changed[i] = true;
});
}
@@ -385,19 +381,17 @@ static void clear_face_sets(const Depsgraph &depsgraph, Object &object, const In
else if (pbvh.type() == bke::pbvh::Type::Grids) {
threading::EnumerableThreadSpecific<Vector<int>> all_face_indices;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
Vector<int> &face_indices = all_face_indices.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], face_indices);
if (std::any_of(faces.begin(), faces.end(), [&](const int face) {
return face_sets[face] != default_face_set;
}))
{
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
node_changed[i] = true;
}
});
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], face_indices);
if (std::any_of(faces.begin(), faces.end(), [&](const int face) {
return face_sets[face] != default_face_set;
}))
{
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
node_changed[i] = true;
}
});
}
IndexMaskMemory memory;
@@ -889,45 +883,41 @@ static void face_hide_update(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<TLS> all_tls;
if (pbvh.type() == bke::pbvh::Type::Mesh) {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> faces = nodes[i].faces();
const Span<int> faces = nodes[i].faces();
tls.new_hide.resize(faces.size());
MutableSpan<bool> new_hide = tls.new_hide;
array_utils::gather(hide_poly.span.as_span(), faces, new_hide);
calc_hide(faces, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_poly.span, faces, new_hide)) {
return;
}
tls.new_hide.resize(faces.size());
MutableSpan<bool> new_hide = tls.new_hide;
array_utils::gather(hide_poly.span.as_span(), faces, new_hide);
calc_hide(faces, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_poly.span, faces, new_hide)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideFace);
array_utils::scatter(new_hide.as_span(), faces, hide_poly.span);
node_changed[i] = true;
});
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideFace);
array_utils::scatter(new_hide.as_span(), faces, hide_poly.span);
node_changed[i] = true;
});
}
else if (pbvh.type() == bke::pbvh::Type::Grids) {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
tls.new_hide.resize(faces.size());
MutableSpan<bool> new_hide = tls.new_hide;
array_utils::gather(hide_poly.span.as_span(), faces, new_hide);
calc_hide(faces, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_poly.span, faces, new_hide)) {
return;
}
tls.new_hide.resize(faces.size());
MutableSpan<bool> new_hide = tls.new_hide;
array_utils::gather(hide_poly.span.as_span(), faces, new_hide);
calc_hide(faces, new_hide);
if (array_utils::indexed_data_equal<bool>(hide_poly.span, faces, new_hide)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideFace);
array_utils::scatter(new_hide.as_span(), faces, hide_poly.span);
node_changed[i] = true;
});
undo::push_node(depsgraph, object, &nodes[i], undo::Type::HideFace);
array_utils::scatter(new_hide.as_span(), faces, hide_poly.span);
node_changed[i] = true;
});
}
@@ -1363,19 +1353,17 @@ static void edit_fairing(const Depsgraph &depsgraph,
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::EnumerableThreadSpecific<LocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : verts.index_range()) {
translations[i] = new_positions[verts[i]] - positions[verts[i]];
}
scale_translations(translations, strength);
clip_and_lock_translations(sd, ss, positions, verts, translations);
position_data.deform(translations, verts);
});
const Span<int> verts = nodes[i].verts();
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : verts.index_range()) {
translations[i] = new_positions[verts[i]] - positions[verts[i]];
}
scale_translations(translations, strength);
clip_and_lock_translations(sd, ss, positions, verts, translations);
position_data.deform(translations, verts);
});
}
@@ -1677,31 +1665,29 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const IndexMa
}
else if (pbvh.type() == bke::pbvh::Type::Grids) {
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TLS &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
undo::push_node(depsgraph, *gesture_data.vc.obact, &nodes[i], undo::Type::FaceSet);
const Span<int> node_faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
undo::push_node(depsgraph, *gesture_data.vc.obact, &nodes[i], undo::Type::FaceSet);
const Span<int> node_faces = bke::pbvh::node_face_indices_calc_grids(
*ss.subdiv_ccg, nodes[i], tls.face_indices);
bool any_updated = false;
for (const int face : node_faces) {
if (!hide_poly.is_empty() && hide_poly[face]) {
continue;
}
const Span<int> face_verts = corner_verts.slice(faces[face]);
const float3 face_center = bke::mesh::face_center_calc(positions, face_verts);
const float3 face_normal = bke::mesh::face_normal_calc(positions, face_verts);
if (!gesture::is_affected(gesture_data, face_center, face_normal)) {
continue;
}
face_sets.span[face] = new_face_set;
any_updated = true;
bool any_updated = false;
for (const int face : node_faces) {
if (!hide_poly.is_empty() && hide_poly[face]) {
continue;
}
if (any_updated) {
node_changed[i] = true;
const Span<int> face_verts = corner_verts.slice(faces[face]);
const float3 face_center = bke::mesh::face_center_calc(positions, face_verts);
const float3 face_normal = bke::mesh::face_normal_calc(positions, face_verts);
if (!gesture::is_affected(gesture_data, face_center, face_normal)) {
continue;
}
});
face_sets.span[face] = new_face_set;
any_updated = true;
}
if (any_updated) {
node_changed[i] = true;
}
});
}
@@ -1723,28 +1709,26 @@ static void gesture_apply_bmesh(gesture::GestureData &gesture_data, const IndexM
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.slice(range).foreach_index([&](const int i) {
undo::push_node(depsgraph, *gesture_data.vc.obact, &nodes[i], undo::Type::FaceSet);
node_mask.foreach_index(GrainSize(1), [&](const int i) {
undo::push_node(depsgraph, *gesture_data.vc.obact, &nodes[i], undo::Type::FaceSet);
bool any_updated = false;
for (BMFace *face : BKE_pbvh_bmesh_node_faces(&nodes[i])) {
if (BM_elem_flag_test(face, BM_ELEM_HIDDEN)) {
continue;
}
float3 center;
BM_face_calc_center_median(face, center);
if (!gesture::is_affected(gesture_data, center, face->no)) {
continue;
}
BM_ELEM_CD_SET_INT(face, offset, new_face_set);
any_updated = true;
bool any_updated = false;
for (BMFace *face : BKE_pbvh_bmesh_node_faces(&nodes[i])) {
if (BM_elem_flag_test(face, BM_ELEM_HIDDEN)) {
continue;
}
float3 center;
BM_face_calc_center_median(face, center);
if (!gesture::is_affected(gesture_data, center, face->no)) {
continue;
}
BM_ELEM_CD_SET_INT(face, offset, new_face_set);
any_updated = true;
}
if (any_updated) {
node_changed[i] = true;
}
});
if (any_updated) {
node_changed[i] = true;
}
});
IndexMaskMemory memory;

View File

@@ -339,25 +339,23 @@ static void sculpt_color_presmooth_init(const Mesh &mesh, Object &object)
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
for ([[maybe_unused]] const int iteration : IndexRange(2)) {
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.vert_neighbors.resize(verts.size());
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
const Span<Vector<int>> vert_neighbors = tls.vert_neighbors;
tls.vert_neighbors.resize(verts.size());
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
const Span<Vector<int>> vert_neighbors = tls.vert_neighbors;
tls.averaged_colors.resize(verts.size());
const MutableSpan<float4> averaged_colors = tls.averaged_colors;
smooth::neighbor_data_average_mesh(
pre_smoothed_color.as_span(), vert_neighbors, averaged_colors);
tls.averaged_colors.resize(verts.size());
const MutableSpan<float4> averaged_colors = tls.averaged_colors;
smooth::neighbor_data_average_mesh(
pre_smoothed_color.as_span(), vert_neighbors, averaged_colors);
for (const int i : verts.index_range()) {
pre_smoothed_color[verts[i]] = math::interpolate(
pre_smoothed_color[verts[i]], averaged_colors[i], 0.5f);
}
});
for (const int i : verts.index_range()) {
pre_smoothed_color[verts[i]] = math::interpolate(
pre_smoothed_color[verts[i]], averaged_colors[i], 0.5f);
}
});
}
}
@@ -389,21 +387,19 @@ static void sculpt_color_filter_apply(bContext *C, wmOperator *op, Object &ob)
bke::GSpanAttributeWriter color_attribute = active_color_attribute_for_write(mesh);
threading::EnumerableThreadSpecific<LocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
color_filter_task(depsgraph,
ob,
faces,
corner_verts,
vert_to_face_map,
mode,
filter_strength,
fill_color,
nodes[i],
tls,
color_attribute);
});
color_filter_task(depsgraph,
ob,
faces,
corner_verts,
vert_to_face_map,
mode,
filter_strength,
fill_color,
nodes[i],
tls,
color_attribute);
});
pbvh.tag_attribute_changed(node_mask, mesh.active_color_attribute);
color_attribute.finish();

View File

@@ -780,12 +780,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastIncrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = increase_contrast_mask_mesh(
*depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
});
node_changed[i] = increase_contrast_mask_mesh(
*depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));
@@ -793,12 +791,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastDecrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = decrease_contrast_mask_mesh(
*depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
});
node_changed[i] = decrease_contrast_mask_mesh(
*depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));
@@ -855,11 +851,9 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastIncrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = increase_contrast_mask_grids(*depsgraph, ob, nodes[i], tls);
});
node_changed[i] = increase_contrast_mask_grids(*depsgraph, ob, nodes[i], tls);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));
@@ -867,11 +861,9 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastDecrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = decrease_contrast_mask_grids(*depsgraph, ob, nodes[i], tls);
});
node_changed[i] = decrease_contrast_mask_grids(*depsgraph, ob, nodes[i], tls);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));
@@ -933,12 +925,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastIncrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = increase_contrast_mask_bmesh(
*depsgraph, ob, mask_offset, nodes[i], tls);
});
node_changed[i] = increase_contrast_mask_bmesh(
*depsgraph, ob, mask_offset, nodes[i], tls);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));
@@ -946,12 +936,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
case FilterType::ContrastDecrease: {
Array<bool> node_changed(node_mask.min_array_size(), false);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
FilterLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
node_changed[i] = decrease_contrast_mask_bmesh(
*depsgraph, ob, mask_offset, nodes[i], tls);
});
node_changed[i] = decrease_contrast_mask_bmesh(
*depsgraph, ob, mask_offset, nodes[i], tls);
});
IndexMaskMemory memory;
pbvh.tag_masks_changed(IndexMask::from_bools(node_changed, memory));

View File

@@ -357,46 +357,38 @@ static void calc_smooth_filter(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.vert_neighbors.resize(verts.size());
MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors_interior(faces,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
{},
verts,
neighbors);
tls.new_positions.resize(verts.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_data_average_mesh_check_loose(
position_data.eval, verts, neighbors, new_positions);
tls.vert_neighbors.resize(verts.size());
MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors_interior(
faces, corner_verts, vert_to_face_map, ss.vertex_info.boundary, {}, verts, neighbors);
tls.new_positions.resize(verts.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_data_average_mesh_check_loose(
position_data.eval, verts, neighbors, new_positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -408,36 +400,34 @@ static void calc_smooth_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.new_positions.resize(positions.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_position_average_interior_grids(
faces, corner_verts, ss.vertex_info.boundary, subdiv_ccg, grids, new_positions);
tls.new_positions.resize(positions.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_position_average_interior_grids(
faces, corner_verts, ss.vertex_info.boundary, subdiv_ccg, grids, new_positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -445,36 +435,34 @@ static void calc_smooth_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.new_positions.resize(verts.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_position_average_interior_bmesh(verts, new_positions);
tls.new_positions.resize(verts.size());
const MutableSpan<float3> new_positions = tls.new_positions;
smooth::neighbor_position_average_interior_bmesh(verts, new_positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -500,31 +488,28 @@ static void calc_inflate_filter(const Depsgraph &depsgraph,
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -532,30 +517,28 @@ static void calc_inflate_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -563,32 +546,30 @@ static void calc_inflate_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -614,31 +595,28 @@ static void calc_scale_filter(const Depsgraph &depsgraph,
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -646,30 +624,28 @@ static void calc_scale_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -677,31 +653,29 @@ static void calc_scale_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_positions);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -744,30 +718,27 @@ static void calc_sphere_filter(const Depsgraph &depsgraph,
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_data.positions, factors, translations);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_data.positions, factors, translations);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -775,29 +746,27 @@ static void calc_sphere_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_data.positions, factors, translations);
reset_translations_to_original(translations, positions, orig_data.positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_data.positions, factors, translations);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -805,30 +774,28 @@ static void calc_sphere_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_positions, factors, translations);
reset_translations_to_original(translations, positions, orig_positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
calc_sphere_translations(orig_positions, factors, translations);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -866,32 +833,29 @@ static void calc_random_filter(const Depsgraph &depsgraph,
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
randomize_factors(orig_data.positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
randomize_factors(orig_data.positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -899,31 +863,29 @@ static void calc_random_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
randomize_factors(orig_data.positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
randomize_factors(orig_data.positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_data.normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -931,33 +893,31 @@ static void calc_random_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
randomize_factors(orig_positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
randomize_factors(orig_positions, ss.filter_cache->random_seed, factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations.copy_from(orig_normals);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -992,39 +952,37 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
bke::AttrDomain::Face);
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_faces(position_data.eval,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
face_sets,
hide_poly,
false,
verts,
factors,
tls.vert_neighbors,
translations);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_faces(position_data.eval,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
face_sets,
hide_poly,
false,
verts,
factors,
tls.vert_neighbors,
translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -1045,38 +1003,36 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,
false,
factors,
tls.vert_neighbors,
translations);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,
false,
factors,
tls.vert_neighbors,
translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -1093,29 +1049,27 @@ static void calc_relax_filter(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_bmesh(
verts, positions, face_set_offset, false, factors, tls.vert_neighbors, translations);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_bmesh(
verts, positions, face_set_offset, false, factors, tls.vert_neighbors, translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -1157,42 +1111,40 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
bke::AttrDomain::Face);
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
face_set::filter_verts_with_unique_face_sets_mesh(
vert_to_face_map, face_sets, relax_face_sets, verts, factors);
face_set::filter_verts_with_unique_face_sets_mesh(
vert_to_face_map, face_sets, relax_face_sets, verts, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_faces(position_data.eval,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
face_sets,
hide_poly,
relax_face_sets,
verts,
factors,
tls.vert_neighbors,
translations);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_faces(position_data.eval,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
ss.vertex_info.boundary,
face_sets,
hide_poly,
relax_face_sets,
verts,
factors,
tls.vert_neighbors,
translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -1214,47 +1166,45 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
face_set::filter_verts_with_unique_face_sets_grids(faces,
corner_verts,
vert_to_face_map,
face_sets,
subdiv_ccg,
relax_face_sets,
grids,
factors);
face_set::filter_verts_with_unique_face_sets_grids(faces,
corner_verts,
vert_to_face_map,
face_sets,
subdiv_ccg,
relax_face_sets,
grids,
factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,
relax_face_sets,
factors,
tls.vert_neighbors,
translations);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_grids(subdiv_ccg,
faces,
corner_verts,
face_sets,
vert_to_face_map,
ss.vertex_info.boundary,
grids,
relax_face_sets,
factors,
tls.vert_neighbors,
translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -1270,37 +1220,35 @@ static void calc_relax_face_sets_filter(const Depsgraph &depsgraph,
&bm.pdata, CD_PROP_INT32, ".sculpt_face_set");
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
face_set::filter_verts_with_unique_face_sets_bmesh(
face_set_offset, relax_face_sets, verts, factors);
face_set::filter_verts_with_unique_face_sets_bmesh(
face_set_offset, relax_face_sets, verts, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_bmesh(verts,
positions,
face_set_offset,
relax_face_sets,
factors,
tls.vert_neighbors,
translations);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::calc_relaxed_translations_bmesh(verts,
positions,
face_set_offset,
relax_face_sets,
factors,
tls.vert_neighbors,
translations);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -1335,85 +1283,78 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.vert_neighbors.reinitialize(verts.size());
calc_vert_neighbors(
faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
tls.vert_neighbors.reinitialize(verts.size());
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
tls.average_positions.reinitialize(verts.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::neighbor_data_average_mesh(
position_data.eval, tls.vert_neighbors, average_positions);
tls.average_positions.reinitialize(verts.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::neighbor_data_average_mesh(
position_data.eval, tls.vert_neighbors, average_positions);
tls.laplacian_disp.reinitialize(verts.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.reinitialize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(positions,
orig_data.positions,
average_positions,
alpha,
laplacian_disp,
translations);
scale_translations(translations, factors);
tls.laplacian_disp.reinitialize(verts.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.reinitialize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(positions,
orig_data.positions,
average_positions,
alpha,
laplacian_disp,
translations);
scale_translations(translations, factors);
scatter_data_mesh(laplacian_disp.as_span(), verts, all_laplacian_disp);
scatter_data_mesh(laplacian_disp.as_span(), verts, all_laplacian_disp);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
const MutableSpan<float3> laplacian_disp = gather_data_mesh(
all_laplacian_disp.as_span(), verts, tls.laplacian_disp);
const MutableSpan<float3> laplacian_disp = gather_data_mesh(
all_laplacian_disp.as_span(), verts, tls.laplacian_disp);
tls.vert_neighbors.resize(verts.size());
calc_vert_neighbors(
faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
tls.vert_neighbors.resize(verts.size());
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::neighbor_data_average_mesh(
all_laplacian_disp.as_span(), tls.vert_neighbors, average_laplacian_disps);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::neighbor_data_average_mesh(
all_laplacian_disp.as_span(), tls.vert_neighbors, average_laplacian_disps);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -1421,77 +1362,73 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.average_positions.resize(positions.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::average_data_grids(
subdiv_ccg, subdiv_ccg.positions.as_span(), grids, average_positions);
tls.average_positions.resize(positions.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::average_data_grids(
subdiv_ccg, subdiv_ccg.positions.as_span(), grids, average_positions);
tls.laplacian_disp.resize(positions.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(positions,
orig_data.positions,
average_positions,
alpha,
laplacian_disp,
translations);
scale_translations(translations, factors);
tls.laplacian_disp.resize(positions.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(positions,
orig_data.positions,
average_positions,
alpha,
laplacian_disp,
translations);
scale_translations(translations, factors);
scatter_data_grids(subdiv_ccg, laplacian_disp.as_span(), grids, all_laplacian_disp);
scatter_data_grids(subdiv_ccg, laplacian_disp.as_span(), grids, all_laplacian_disp);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(orig_data.positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(orig_data.positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
const MutableSpan<float3> laplacian_disp = gather_data_grids(
subdiv_ccg, all_laplacian_disp.as_span(), grids, tls.laplacian_disp);
const MutableSpan<float3> laplacian_disp = gather_data_grids(
subdiv_ccg, all_laplacian_disp.as_span(), grids, tls.laplacian_disp);
tls.average_positions.resize(orig_data.positions.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::average_data_grids(
subdiv_ccg, all_laplacian_disp.as_span(), grids, average_laplacian_disps);
tls.average_positions.resize(orig_data.positions.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::average_data_grids(
subdiv_ccg, all_laplacian_disp.as_span(), grids, average_laplacian_disps);
tls.translations.resize(orig_data.positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
tls.translations.resize(orig_data.positions.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -1499,75 +1436,71 @@ static void calc_surface_smooth_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::neighbor_position_average_bmesh(verts, average_positions);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_positions = tls.average_positions;
smooth::neighbor_position_average_bmesh(verts, average_positions);
tls.laplacian_disp.resize(verts.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(
positions, orig_positions, average_positions, alpha, laplacian_disp, translations);
scale_translations(translations, factors);
tls.laplacian_disp.resize(verts.size());
const MutableSpan<float3> laplacian_disp = tls.laplacian_disp;
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_laplacian_step(
positions, orig_positions, average_positions, alpha, laplacian_disp, translations);
scale_translations(translations, factors);
scatter_data_bmesh(laplacian_disp.as_span(), verts, all_laplacian_disp);
scatter_data_bmesh(laplacian_disp.as_span(), verts, all_laplacian_disp);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
Array<float3> orig_positions(verts.size());
Array<float3> orig_normals(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, strength);
clamp_factors(factors, 0.0f, 1.0f);
const MutableSpan<float3> laplacian_disp = gather_data_bmesh(
all_laplacian_disp.as_span(), verts, tls.laplacian_disp);
const MutableSpan<float3> laplacian_disp = gather_data_bmesh(
all_laplacian_disp.as_span(), verts, tls.laplacian_disp);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::average_data_bmesh(all_laplacian_disp.as_span(), verts, average_laplacian_disps);
tls.average_positions.resize(verts.size());
const MutableSpan<float3> average_laplacian_disps = tls.average_positions;
smooth::average_data_bmesh(all_laplacian_disp.as_span(), verts, average_laplacian_disps);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
smooth::surface_smooth_displace_step(
laplacian_disp, average_laplacian_disps, beta, translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -1621,71 +1554,68 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph,
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
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) {
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
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(
position_data.eval, verts, tls.positions);
const Span<int> verts = nodes[node_index].verts();
const Span<float3> positions = gather_data_mesh(position_data.eval, verts, tls.positions);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
verts,
factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
verts,
factors);
scale_factors(factors, strength);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, neighbors);
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, neighbors);
tls.smooth_positions.resize(verts.size());
const MutableSpan<float3> smooth_positions = tls.smooth_positions;
smooth::neighbor_data_average_mesh(position_data.eval, neighbors, smooth_positions);
tls.smooth_positions.resize(verts.size());
const MutableSpan<float3> smooth_positions = tls.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);
const Span<float> sharpen_factors = gather_data_mesh(
ss.filter_cache->sharpen_factor.as_span(), verts, tls.sharpen_factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : verts.index_range()) {
const int vert = verts[i];
const float3 &position = position_data.eval[vert];
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : verts.index_range()) {
const int vert = verts[i];
const float3 &position = position_data.eval[vert];
float3 disp_sharpen(0.0f);
for (const int neighbor : neighbors[i]) {
float3 disp_n = position_data.eval[neighbor] - position;
disp_n *= ss.filter_cache->sharpen_factor[neighbor];
disp_sharpen += disp_n;
}
disp_sharpen *= (1.0f - sharpen_factors[i]);
translations[i] = disp_sharpen;
float3 disp_sharpen(0.0f);
for (const int neighbor : neighbors[i]) {
float3 disp_n = position_data.eval[neighbor] - position;
disp_n *= ss.filter_cache->sharpen_factor[neighbor];
disp_sharpen += disp_n;
}
const Span<float3> detail_directions = gather_data_mesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.detail_directions);
disp_sharpen *= (1.0f - sharpen_factors[i]);
translations[i] = disp_sharpen;
}
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
const Span<float3> detail_directions = gather_data_mesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.detail_directions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -1696,83 +1626,81 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int node_index) {
const Span<int> grids = nodes[node_index].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const Span<int> grids = nodes[node_index].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
grids,
factors);
scale_factors(factors, strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
grids,
factors);
scale_factors(factors, strength);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
tls.vert_neighbors.resize(positions.size());
tls.vert_neighbors.resize(positions.size());
tls.smooth_positions.resize(positions.size());
const MutableSpan<float3> smooth_positions = tls.smooth_positions;
smooth::average_data_grids(
subdiv_ccg, subdiv_ccg.positions.as_span(), grids, smooth_positions);
tls.smooth_positions.resize(positions.size());
const MutableSpan<float3> smooth_positions = tls.smooth_positions;
smooth::average_data_grids(
subdiv_ccg, subdiv_ccg.positions.as_span(), grids, smooth_positions);
const Span<float> sharpen_factors = gather_data_grids(
subdiv_ccg, ss.filter_cache->sharpen_factor.as_span(), grids, tls.sharpen_factors);
const Span<float> sharpen_factors = gather_data_grids(
subdiv_ccg, ss.filter_cache->sharpen_factor.as_span(), grids, tls.sharpen_factors);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : grids.index_range()) {
const int node_verts_start = i * key.grid_area;
const int grid = grids[i];
for (const short y : IndexRange(key.grid_size)) {
for (const short x : IndexRange(key.grid_size)) {
const int offset = CCG_grid_xy_to_index(key.grid_size, x, y);
const int node_vert = node_verts_start + offset;
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
for (const int i : grids.index_range()) {
const int node_verts_start = i * key.grid_area;
const int grid = grids[i];
for (const short y : IndexRange(key.grid_size)) {
for (const short x : IndexRange(key.grid_size)) {
const int offset = CCG_grid_xy_to_index(key.grid_size, x, y);
const int node_vert = node_verts_start + offset;
const float3 &position = positions[node_vert];
const float3 &position = positions[node_vert];
float3 disp_sharpen(0.0f);
SubdivCCGNeighbors neighbors;
BKE_subdiv_ccg_neighbor_coords_get(
subdiv_ccg, SubdivCCGCoord{grid, x, y}, false, neighbors);
for (const SubdivCCGCoord neighbor : neighbors.coords) {
float3 disp_n = vert_positions[neighbor.to_index(key)] - position;
disp_n *= ss.filter_cache->sharpen_factor[neighbor.to_index(key)];
disp_sharpen += disp_n;
}
disp_sharpen *= (1.0f - sharpen_factors[node_vert]);
translations[node_vert] = disp_sharpen;
float3 disp_sharpen(0.0f);
SubdivCCGNeighbors neighbors;
BKE_subdiv_ccg_neighbor_coords_get(
subdiv_ccg, SubdivCCGCoord{grid, x, y}, false, neighbors);
for (const SubdivCCGCoord neighbor : neighbors.coords) {
float3 disp_n = vert_positions[neighbor.to_index(key)] - position;
disp_n *= ss.filter_cache->sharpen_factor[neighbor.to_index(key)];
disp_sharpen += disp_n;
}
disp_sharpen *= (1.0f - sharpen_factors[node_vert]);
translations[node_vert] = disp_sharpen;
}
}
}
const Span<float3> detail_directions = gather_data_grids(
subdiv_ccg,
ss.filter_cache->detail_directions.as_span(),
grids,
tls.detail_directions);
const Span<float3> detail_directions = gather_data_grids(
subdiv_ccg,
ss.filter_cache->detail_directions.as_span(),
grids,
tls.detail_directions);
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -1781,70 +1709,68 @@ static void calc_sharpen_filter(const Depsgraph &depsgraph,
BM_mesh_elem_index_ensure(&bm, BM_VERT);
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int node_index) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[node_index]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[node_index]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
verts,
factors);
scale_factors(factors, strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(depsgraph,
object,
ss.filter_cache->automasking.get(),
nodes[node_index],
verts,
factors);
scale_factors(factors, strength);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
/* This filter can't work at full strength as it needs multiple iterations to reach a
* stable state. */
clamp_factors(factors, 0.0f, 0.5f);
tls.smooth_positions.resize(verts.size());
const MutableSpan<float3> smooth_positions = tls.smooth_positions;
smooth::neighbor_position_average_bmesh(verts, smooth_positions);
tls.smooth_positions.resize(verts.size());
const MutableSpan<float3> smooth_positions = tls.smooth_positions;
smooth::neighbor_position_average_bmesh(verts, smooth_positions);
const Span<float> sharpen_factors = gather_data_bmesh(
ss.filter_cache->sharpen_factor.as_span(), verts, tls.sharpen_factors);
const Span<float> sharpen_factors = gather_data_bmesh(
ss.filter_cache->sharpen_factor.as_span(), verts, tls.sharpen_factors);
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
tls.translations.resize(verts.size());
const MutableSpan<float3> translations = tls.translations;
Vector<BMVert *, 64> neighbors;
Vector<BMVert *, 64> neighbors;
int i = 0;
for (BMVert *vert : verts) {
const float3 position = vert->co;
int i = 0;
for (BMVert *vert : verts) {
const float3 position = vert->co;
float3 disp_sharpen(0.0f);
for (const BMVert *neighbor : vert_neighbors_get_bmesh(*vert, neighbors)) {
float3 disp_n = float3(neighbor->co) - position;
disp_n *= ss.filter_cache->sharpen_factor[BM_elem_index_get(neighbor)];
disp_sharpen += disp_n;
}
disp_sharpen *= (1.0f - sharpen_factors[i]);
translations[i] = disp_sharpen;
i++;
float3 disp_sharpen(0.0f);
for (const BMVert *neighbor : vert_neighbors_get_bmesh(*vert, neighbors)) {
float3 disp_n = float3(neighbor->co) - position;
disp_n *= ss.filter_cache->sharpen_factor[BM_elem_index_get(neighbor)];
disp_sharpen += disp_n;
}
const Span<float3> detail_directions = gather_data_bmesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.detail_directions);
disp_sharpen *= (1.0f - sharpen_factors[i]);
translations[i] = disp_sharpen;
i++;
}
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
const Span<float3> detail_directions = gather_data_bmesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.detail_directions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
calc_sharpen_detail_translations(*ss.filter_cache,
positions,
smooth_positions,
sharpen_factors,
detail_directions,
translations);
scale_translations(translations, factors);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -1871,30 +1797,27 @@ static void calc_enhance_details_filter(const Depsgraph &depsgraph,
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) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
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(
position_data.eval, verts, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_mesh(object, nodes[i]);
const Span<int> verts = nodes[i].verts();
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());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, final_strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(mesh, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, final_strength);
const MutableSpan translations = gather_data_mesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
const MutableSpan translations = gather_data_mesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
position_data.deform(translations, verts);
});
break;
}
@@ -1902,29 +1825,27 @@ static void calc_enhance_details_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, final_strength);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, final_strength);
const MutableSpan translations = gather_data_grids(
subdiv_ccg, ss.filter_cache->detail_directions.as_span(), grids, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
const MutableSpan translations = gather_data_grids(
subdiv_ccg, ss.filter_cache->detail_directions.as_span(), grids, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
break;
}
@@ -1932,30 +1853,28 @@ static void calc_enhance_details_filter(const Depsgraph &depsgraph,
BMesh &bm = *ss.bm;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(&nodes[i]);
const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
Array<float3> orig_positions(verts.size());
orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, {});
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, final_strength);
tls.factors.resize(verts.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(bm, verts, factors);
auto_mask::calc_vert_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], verts, factors);
scale_factors(factors, final_strength);
const MutableSpan<float3> translations = gather_data_bmesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
const MutableSpan<float3> translations = gather_data_bmesh(
ss.filter_cache->detail_directions.as_span(), verts, tls.translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_positions, translations);
apply_translations(translations, verts);
});
break;
}
@@ -1979,33 +1898,31 @@ static void calc_erase_displacement_filter(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::EnumerableThreadSpecific<LocalData> all_tls;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
const Span<int> grids = nodes[i].grids();
const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
const OrigPositionData orig_data = orig_position_data_get_grids(object, nodes[i]);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
tls.factors.resize(positions.size());
const MutableSpan<float> factors = tls.factors;
fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
auto_mask::calc_grids_factors(
depsgraph, object, ss.filter_cache->automasking.get(), nodes[i], grids, factors);
scale_factors(factors, strength);
clamp_factors(factors, -1.0f, 1.0f);
const MutableSpan<float3> new_positions = gather_data_grids(
subdiv_ccg, ss.filter_cache->limit_surface_co.as_span(), grids, tls.new_positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
const MutableSpan<float3> new_positions = gather_data_grids(
subdiv_ccg, ss.filter_cache->limit_surface_co.as_span(), grids, tls.new_positions);
tls.translations.resize(positions.size());
const MutableSpan<float3> translations = tls.translations;
translations_from_new_positions(new_positions, orig_data.positions, translations);
scale_translations(translations, factors);
reset_translations_to_original(translations, positions, orig_data.positions);
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
zero_disabled_axis_components(*ss.filter_cache, translations);
clip_and_lock_translations(sd, ss, orig_data.positions, translations);
apply_translations(translations, grids, subdiv_ccg);
});
}
@@ -2091,25 +2008,23 @@ static void mesh_filter_sharpen_init(const Depsgraph &depsgraph,
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
const Span<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = nodes[i].verts();
const Span<int> verts = nodes[i].verts();
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, neighbors);
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, neighbors);
tls.smooth_directions.resize(verts.size());
smooth::neighbor_data_average_mesh(
detail_directions.as_span(), neighbors, tls.smooth_directions.as_mutable_span());
scatter_data_mesh(tls.smooth_directions.as_span(), verts, detail_directions);
tls.smooth_directions.resize(verts.size());
smooth::neighbor_data_average_mesh(
detail_directions.as_span(), neighbors, tls.smooth_directions.as_mutable_span());
scatter_data_mesh(tls.smooth_directions.as_span(), verts, detail_directions);
tls.smooth_factors.resize(verts.size());
smooth::neighbor_data_average_mesh(
sharpen_factors.as_span(), neighbors, tls.smooth_factors.as_mutable_span());
scatter_data_mesh(tls.smooth_factors.as_span(), verts, sharpen_factors);
});
tls.smooth_factors.resize(verts.size());
smooth::neighbor_data_average_mesh(
sharpen_factors.as_span(), neighbors, tls.smooth_factors.as_mutable_span());
scatter_data_mesh(tls.smooth_factors.as_span(), verts, sharpen_factors);
});
break;
}
@@ -2117,48 +2032,42 @@ static void mesh_filter_sharpen_init(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
const Span<int> grids = nodes[i].grids();
const int grid_verts_num = grids.size() * key.grid_area;
tls.smooth_directions.resize(grid_verts_num);
smooth::average_data_grids(subdiv_ccg,
detail_directions.as_span(),
grids,
tls.smooth_directions.as_mutable_span());
scatter_data_grids(
subdiv_ccg, tls.smooth_directions.as_span(), grids, detail_directions);
tls.smooth_directions.resize(grid_verts_num);
smooth::average_data_grids(subdiv_ccg,
detail_directions.as_span(),
grids,
tls.smooth_directions.as_mutable_span());
scatter_data_grids(
subdiv_ccg, tls.smooth_directions.as_span(), grids, detail_directions);
tls.smooth_factors.resize(grid_verts_num);
smooth::average_data_grids(subdiv_ccg,
sharpen_factors.as_span(),
grids,
tls.smooth_factors.as_mutable_span());
scatter_data_grids(subdiv_ccg, tls.smooth_factors.as_span(), grids, sharpen_factors);
});
tls.smooth_factors.resize(grid_verts_num);
smooth::average_data_grids(
subdiv_ccg, sharpen_factors.as_span(), grids, tls.smooth_factors.as_mutable_span());
scatter_data_grids(subdiv_ccg, tls.smooth_factors.as_span(), grids, sharpen_factors);
});
break;
}
case bke::pbvh::Type::BMesh:
const Span<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
&const_cast<bke::pbvh::BMeshNode &>(nodes[i]));
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
&const_cast<bke::pbvh::BMeshNode &>(nodes[i]));
tls.smooth_directions.resize(verts.size());
smooth::average_data_bmesh(
detail_directions.as_span(), verts, tls.smooth_directions.as_mutable_span());
scatter_data_bmesh(tls.smooth_directions.as_span(), verts, detail_directions);
tls.smooth_directions.resize(verts.size());
smooth::average_data_bmesh(
detail_directions.as_span(), verts, tls.smooth_directions.as_mutable_span());
scatter_data_bmesh(tls.smooth_directions.as_span(), verts, detail_directions);
tls.smooth_factors.resize(verts.size());
smooth::average_data_bmesh(
sharpen_factors.as_span(), verts, tls.smooth_factors.as_mutable_span());
scatter_data_bmesh(tls.smooth_factors.as_span(), verts, sharpen_factors);
});
tls.smooth_factors.resize(verts.size());
smooth::average_data_bmesh(
sharpen_factors.as_span(), verts, tls.smooth_factors.as_mutable_span());
scatter_data_bmesh(tls.smooth_factors.as_span(), verts, sharpen_factors);
});
break;
}
@@ -2312,7 +2221,6 @@ static int sculpt_mesh_filter_confirm(SculptSession &ss,
wmOperator *op,
const MeshFilterType filter_type)
{
float initial_strength = ss.filter_cache->start_filter_strength;
/* Don't update strength property if we're storing an event history. */
if (sculpt_mesh_filter_is_continuous(filter_type)) {
@@ -2485,8 +2393,8 @@ static int sculpt_mesh_filter_start(bContext *C, wmOperator *op)
float2 mval_fl{float(mval[0]), float(mval[1])};
if (use_automasking) {
/* Update the active face set manually as the paint cursor is not enabled when using the Mesh
* Filter Tool. */
/* Update the active face set manually as the paint cursor is not enabled when using the
* Mesh Filter Tool. */
SculptCursorGeometryInfo sgi;
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
}
@@ -2558,16 +2466,16 @@ void register_operator_props(wmOperatorType *ot)
RNA_def_int_array(
ot->srna, "start_mouse", 2, nullptr, 0, 1 << 14, "Starting Mouse", "", 0, 1 << 14);
RNA_def_float(
ot->srna,
"area_normal_radius",
0.25,
0.001,
5.0,
"Normal Radius",
"Radius used for calculating area normal on initial click,\nin percentage of brush radius",
0.01,
1.0);
RNA_def_float(ot->srna,
"area_normal_radius",
0.25,
0.001,
5.0,
"Normal Radius",
"Radius used for calculating area normal on initial click,\nin percentage "
"of brush radius",
0.01,
1.0);
RNA_def_float(
ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
RNA_def_int(ot->srna,

View File

@@ -67,12 +67,10 @@ void write_mask_mesh(const Depsgraph &depsgraph,
threading::EnumerableThreadSpecific<Vector<int>> all_index_data;
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
Vector<int> &index_data = all_index_data.local();
node_mask.slice(range).foreach_index(GrainSize(1), [&](const int i) {
write_fn(mask.span, hide::node_visible_verts(nodes[i], hide_vert, index_data));
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
write_fn(mask.span, hide::node_visible_verts(nodes[i], hide_vert, index_data));
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
pbvh.tag_masks_changed(node_mask);
mask.finish();

View File

@@ -1086,20 +1086,18 @@ static void apply_mask_from_settings(const Depsgraph &depsgraph,
bke::SpanAttributeWriter mask = attributes.lookup_or_add_for_write_span<float>(
".sculpt_mask", bke::AttrDomain::Point);
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_mask_mesh(depsgraph,
object,
automasking,
mode,
factor,
invert_automask,
nodes[i],
tls,
mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
apply_mask_mesh(depsgraph,
object,
automasking,
mode,
factor,
invert_automask,
nodes[i],
tls,
mask.span);
bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]);
});
mask.finish();
break;
@@ -1109,13 +1107,11 @@ static void apply_mask_from_settings(const Depsgraph &depsgraph,
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
MutableSpan<float> masks = subdiv_ccg.masks;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_mask_grids(
depsgraph, object, automasking, mode, factor, invert_automask, nodes[i], tls);
bke::pbvh::node_update_mask_grids(key, masks, nodes[i]);
});
apply_mask_grids(
depsgraph, object, automasking, mode, factor, invert_automask, nodes[i], tls);
bke::pbvh::node_update_mask_grids(key, masks, nodes[i]);
});
break;
}
@@ -1123,13 +1119,11 @@ static void apply_mask_from_settings(const Depsgraph &depsgraph,
const int mask_offset = CustomData_get_offset_named(
&object.sculpt->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_mask_bmesh(
depsgraph, object, automasking, mode, factor, invert_automask, nodes[i], tls);
bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]);
});
apply_mask_bmesh(
depsgraph, object, automasking, mode, factor, invert_automask, nodes[i], tls);
bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]);
});
break;
}

View File

@@ -578,22 +578,20 @@ void do_paint_brush(const Scene &scene,
if (ss.cache->alt_smooth) {
threading::EnumerableThreadSpecific<ColorPaintLocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
ColorPaintLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
do_color_smooth_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
do_color_smooth_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
pbvh.tag_attribute_changed(node_mask, mesh.active_color_attribute);
color_attribute.finish();
@@ -653,25 +651,23 @@ void do_paint_brush(const Scene &scene,
}
threading::EnumerableThreadSpecific<ColorPaintLocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
ColorPaintLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
do_paint_brush_task(scene,
depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
brush,
mat,
wet_color,
nodes[i],
tls,
ss.cache->paint_brush.mix_colors,
color_attribute);
});
do_paint_brush_task(scene,
depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
brush,
mat,
wet_color,
nodes[i],
tls,
ss.cache->paint_brush.mix_colors,
color_attribute);
});
pbvh.tag_attribute_changed(node_mask, mesh.active_color_attribute);
color_attribute.finish();
@@ -880,22 +876,20 @@ void do_smear_brush(const Depsgraph &depsgraph,
/* Smooth colors mode. */
if (ss.cache->alt_smooth) {
threading::EnumerableThreadSpecific<ColorPaintLocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
ColorPaintLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
do_color_smooth_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
do_color_smooth_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
}
else {
@@ -911,22 +905,20 @@ void do_smear_brush(const Depsgraph &depsgraph,
}
});
threading::EnumerableThreadSpecific<ColorPaintLocalData> all_tls;
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
ColorPaintLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
do_smear_brush_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
do_smear_brush_task(depsgraph,
ob,
vert_positions,
vert_normals,
faces,
corner_verts,
vert_to_face_map,
hide_poly,
brush,
nodes[i],
tls,
color_attribute);
});
}
pbvh.tag_attribute_changed(node_mask, mesh.active_color_attribute);

View File

@@ -2124,12 +2124,10 @@ void do_pose_brush(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, ob);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
BrushLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_mesh(depsgraph, sd, brush, nodes[i], ob, tls, position_data);
bke::pbvh::update_node_bounds_mesh(position_data.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;
}
@@ -2137,23 +2135,19 @@ void do_pose_brush(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
BrushLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_grids(depsgraph, sd, brush, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
calc_grids(depsgraph, sd, brush, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
BrushLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
calc_bmesh(depsgraph, sd, brush, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
calc_bmesh(depsgraph, sd, brush, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -154,13 +154,11 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g
const PositionDeformData position_data(depsgraph, object);
const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
undo::push_nodes(depsgraph, object, node_mask, undo::Type::Position);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int 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]);
});
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;
}
@@ -169,24 +167,20 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
undo::push_nodes(depsgraph, object, node_mask, undo::Type::Position);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_projection_grids(sd, gesture_data, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
apply_projection_grids(sd, gesture_data, nodes[i], object, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
undo::push_nodes(depsgraph, object, node_mask, undo::Type::Position);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
apply_projection_bmesh(sd, gesture_data, nodes[i], object, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
apply_projection_bmesh(sd, gesture_data, nodes[i], object, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}

View File

@@ -701,23 +701,19 @@ void blur_geometry_data_array(const Object &object,
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
bke::AttrDomain::Face);
for ([[maybe_unused]] const int _ : IndexRange(iterations)) {
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
const Span<int> verts = hide::node_visible_verts(
nodes[i], hide_vert, tls.vert_indices);
const Span<int> verts = hide::node_visible_verts(nodes[i], hide_vert, tls.vert_indices);
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(
faces, corner_verts, vert_to_face_map, hide_poly, verts, neighbors);
tls.vert_neighbors.resize(verts.size());
const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
calc_vert_neighbors(faces, corner_verts, vert_to_face_map, hide_poly, verts, neighbors);
tls.new_factors.resize(verts.size());
const MutableSpan<float> new_factors = tls.new_factors;
smooth::neighbor_data_average_mesh(data.as_span(), neighbors, new_factors);
tls.new_factors.resize(verts.size());
const MutableSpan<float> new_factors = tls.new_factors;
smooth::neighbor_data_average_mesh(data.as_span(), neighbors, new_factors);
scatter_data_mesh(new_factors.as_span(), verts, data);
});
scatter_data_mesh(new_factors.as_span(), verts, data);
});
}
break;
@@ -728,29 +724,27 @@ void blur_geometry_data_array(const Object &object,
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
for ([[maybe_unused]] const int _ : IndexRange(iterations)) {
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int node_index) {
const Span<int> grids = nodes[node_index].grids();
const int grid_verts_num = key.grid_area * grids.size();
const Span<int> grids = nodes[node_index].grids();
const int grid_verts_num = key.grid_area * grids.size();
tls.new_factors.resize(grid_verts_num);
const MutableSpan<float> new_factors = tls.new_factors;
smooth::average_data_grids(subdiv_ccg, data.as_span(), grids, new_factors);
tls.new_factors.resize(grid_verts_num);
const MutableSpan<float> new_factors = tls.new_factors;
smooth::average_data_grids(subdiv_ccg, data.as_span(), grids, new_factors);
if (grid_hidden.is_empty()) {
scatter_data_grids(subdiv_ccg, new_factors.as_span(), grids, data);
if (grid_hidden.is_empty()) {
scatter_data_grids(subdiv_ccg, new_factors.as_span(), grids, data);
}
else {
for (const int i : grids.index_range()) {
const int node_start = i * key.grid_area;
BKE_subdiv_ccg_foreach_visible_grid_vert(
key, grid_hidden, grids[i], [&](const int offset) {
data[i] = new_factors[node_start + offset];
});
}
else {
for (const int i : grids.index_range()) {
const int node_start = i * key.grid_area;
BKE_subdiv_ccg_foreach_visible_grid_vert(
key, grid_hidden, grids[i], [&](const int offset) {
data[i] = new_factors[node_start + offset];
});
}
}
});
}
});
}
break;
@@ -758,26 +752,24 @@ void blur_geometry_data_array(const Object &object,
case bke::pbvh::Type::BMesh: {
const Span<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
for ([[maybe_unused]] const int _ : IndexRange(iterations)) {
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int node_index) {
LocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int node_index) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
const_cast<bke::pbvh::BMeshNode *>(&nodes[node_index]));
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(
const_cast<bke::pbvh::BMeshNode *>(&nodes[node_index]));
tls.new_factors.resize(verts.size());
const MutableSpan<float> new_factors = tls.new_factors;
smooth::average_data_bmesh(data.as_span(), verts, new_factors);
tls.new_factors.resize(verts.size());
const MutableSpan<float> new_factors = tls.new_factors;
smooth::average_data_bmesh(data.as_span(), verts, new_factors);
int i = 0;
for (const BMVert *vert : verts) {
if (BM_elem_flag_test(vert, BM_ELEM_HIDDEN)) {
i++;
continue;
}
data[BM_elem_index_get(vert)] = new_factors[i];
int i = 0;
for (const BMVert *vert : verts) {
if (BM_elem_flag_test(vert, BM_ELEM_HIDDEN)) {
i++;
continue;
}
});
data[BM_elem_index_get(vert)] = new_factors[i];
i++;
}
});
}
break;

View File

@@ -302,12 +302,10 @@ static void sculpt_transform_all_vertices(const Depsgraph &depsgraph, const Scul
case bke::pbvh::Type::Mesh: {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, ob);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
transform_node_mesh(sd, transform_mats, nodes[i], ob, tls, position_data);
bke::pbvh::update_node_bounds_mesh(position_data.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;
}
@@ -315,23 +313,19 @@ static void sculpt_transform_all_vertices(const Depsgraph &depsgraph, const Scul
SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
transform_node_grids(sd, transform_mats, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
transform_node_grids(sd, transform_mats, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
transform_node_bmesh(sd, transform_mats, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
transform_node_bmesh(sd, transform_mats, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}
@@ -493,19 +487,17 @@ static void transform_radius_elastic(const Depsgraph &depsgraph,
case bke::pbvh::Type::Mesh: {
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
const PositionDeformData position_data(depsgraph, ob);
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
elastic_transform_node_mesh(sd,
params,
elastic_transform_mat,
elastic_transform_pivot,
nodes[i],
ob,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
elastic_transform_node_mesh(sd,
params,
elastic_transform_mat,
elastic_transform_pivot,
nodes[i],
ob,
tls,
position_data);
bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
});
break;
}
@@ -513,25 +505,21 @@ static void transform_radius_elastic(const Depsgraph &depsgraph,
SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg;
MutableSpan<float3> positions = subdiv_ccg.positions;
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
elastic_transform_node_grids(
sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
elastic_transform_node_grids(
sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
});
break;
}
case bke::pbvh::Type::BMesh: {
MutableSpan<bke::pbvh::BMeshNode> nodes = pbvh.nodes<bke::pbvh::BMeshNode>();
threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) {
node_mask.foreach_index(GrainSize(1), [&](const int i) {
TransformLocalData &tls = all_tls.local();
node_mask.slice(range).foreach_index([&](const int i) {
elastic_transform_node_bmesh(
sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
elastic_transform_node_bmesh(
sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls);
bke::pbvh::update_node_bounds_bmesh(nodes[i]);
});
break;
}