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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user