Fix #129085: Face set from Masked operator doesnt work with Multires

When the operator was ported away from the old PBVHVertRef
implementation, the corresponding Multires mask elements were never
accessed correctly.

Pull Request: https://projects.blender.org/blender/blender/pulls/129137
This commit is contained in:
Sean Kim
2024-10-18 21:46:36 +02:00
committed by Sean Kim
parent c2073095c9
commit ffa4f6eaba

View File

@@ -432,31 +432,64 @@ static int create_op_exec(bContext *C, wmOperator *op)
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
switch (mode) {
case CreateMode::Masked: {
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
bke::AttrDomain::Face);
const VArraySpan<float> mask = *attributes.lookup<float>(".sculpt_mask",
bke::AttrDomain::Point);
if (!mask.is_empty()) {
face_sets_update(depsgraph,
object,
node_mask,
[&](const Span<int> indices, MutableSpan<int> face_sets) {
for (const int i : indices.index_range()) {
if (!hide_poly.is_empty() && hide_poly[indices[i]]) {
continue;
if (pbvh.type() == bke::pbvh::Type::Mesh) {
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
bke::AttrDomain::Face);
const VArraySpan<float> mask = *attributes.lookup<float>(".sculpt_mask",
bke::AttrDomain::Point);
if (!mask.is_empty()) {
face_sets_update(depsgraph,
object,
node_mask,
[&](const Span<int> indices, MutableSpan<int> face_sets) {
for (const int i : indices.index_range()) {
if (!hide_poly.is_empty() && hide_poly[indices[i]]) {
continue;
}
const Span<int> face_verts = corner_verts.slice(faces[indices[i]]);
if (!std::any_of(face_verts.begin(),
face_verts.end(),
[&](const int vert) { return mask[vert] > 0.5f; }))
{
continue;
}
face_sets[i] = next_face_set;
}
const Span<int> face_verts = corner_verts.slice(faces[indices[i]]);
if (!std::any_of(face_verts.begin(),
face_verts.end(),
[&](const int vert) { return mask[vert] > 0.5f; }))
{
continue;
});
}
}
else if (pbvh.type() == bke::pbvh::Type::Grids) {
const OffsetIndices<int> faces = mesh.faces();
const SculptSession &ss = *object.sculpt;
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const int grid_area = subdiv_ccg.grid_area;
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
bke::AttrDomain::Face);
const Span<float> masks = subdiv_ccg.masks;
if (!masks.is_empty()) {
face_sets_update(depsgraph,
object,
node_mask,
[&](const Span<int> indices, MutableSpan<int> face_sets) {
for (const int i : indices.index_range()) {
if (!hide_poly.is_empty() && hide_poly[indices[i]]) {
continue;
}
const Span<float> face_masks = masks.slice(
bke::ccg::face_range(faces, grid_area, indices[i]));
if (!std::any_of(face_masks.begin(),
face_masks.end(),
[&](const float mask) { return mask > 0.5f; }))
{
continue;
}
face_sets[i] = next_face_set;
}
face_sets[i] = next_face_set;
}
});
});
}
}
break;
}