[Bf-blender-cvs] [3b37538975f] master: Fix T103663: Set material node can fail for single material
Iliya Katueshenock
noreply at git.blender.org
Fri Jan 6 15:42:15 CET 2023
Commit: 3b37538975f3298c9ce5369d114f27fd5f84781a
Author: Iliya Katueshenock
Date: Fri Jan 6 09:34:03 2023 -0500
Branches: master
https://developer.blender.org/rB3b37538975f3298c9ce5369d114f27fd5f84781a
Fix T103663: Set material node can fail for single material
Caused by f1c0249f34c4171ec311, which filled the wrong value.
I have noticed several problems:
- Using a full array as single result.
- Checking single material index for 0. If we have a list of all slots,
then we must check this in the list.
- The result was filled false. Simple fix.
- Fixed problem with incorrect recording by mask indices, not polygons.
- Added domain specifics to names to avoid confusion.
Differential Revision: https://developer.blender.org/D16926
===================================================================
M source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
===================================================================
diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
index dfb4181926e..bd1408c0f31 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -20,35 +20,40 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Selection")).field_source();
}
-static void select_mesh_by_material(const Mesh &mesh,
- const Material *material,
- const IndexMask mask,
- MutableSpan<bool> r_selection)
+static VArray<bool> select_mesh_faces_by_material(const Mesh &mesh,
+ const Material *material,
+ const IndexMask face_mask)
{
- BLI_assert(mesh.totpoly >= r_selection.size());
Vector<int> slots;
- for (const int i : IndexRange(mesh.totcol)) {
- if (mesh.mat[i] == material) {
- slots.append(i);
+ for (const int slot_i : IndexRange(mesh.totcol)) {
+ if (mesh.mat[slot_i] == material) {
+ slots.append(slot_i);
}
}
+ if (slots.is_empty()) {
+ return VArray<bool>::ForSingle(false, mesh.totpoly);
+ }
+
const AttributeAccessor attributes = mesh.attributes();
const VArray<int> material_indices = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
- if (material != nullptr && material_indices.is_single() &&
- material_indices.get_internal_single() == 0) {
- r_selection.fill_indices(mask, false);
- return;
+ if (material_indices.is_single()) {
+ const int slot_i = material_indices.get_internal_single();
+ return VArray<bool>::ForSingle(slots.contains(slot_i), mesh.totpoly);
}
const VArraySpan<int> material_indices_span(material_indices);
- threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) {
+ Array<bool> face_selection(face_mask.min_array_size());
+ threading::parallel_for(face_mask.index_range(), 1024, [&](IndexRange range) {
for (const int i : range) {
- const int face_index = mask[i];
- r_selection[i] = slots.contains(material_indices_span[face_index]);
+ const int face_index = face_mask[i];
+ const int slot_i = material_indices_span[face_index];
+ face_selection[face_index] = slots.contains(slot_i);
}
});
+
+ return VArray<bool>::ForContainer(std::move(face_selection));
}
class MaterialSelectionFieldInput final : public bke::GeometryFieldInput {
@@ -72,19 +77,12 @@ class MaterialSelectionFieldInput final : public bke::GeometryFieldInput {
if (mesh == nullptr) {
return {};
}
- const eAttrDomain domain = context.domain();
- if (domain == ATTR_DOMAIN_FACE) {
- Array<bool> selection(mask.min_array_size());
- select_mesh_by_material(*mesh, material_, mask, selection);
- return VArray<bool>::ForContainer(std::move(selection));
- }
- Array<bool> selection(mesh->totpoly);
- select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
- return mesh->attributes().adapt_domain<bool>(
- VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
+ const eAttrDomain domain = context.domain();
+ const IndexMask domain_mask = (domain == ATTR_DOMAIN_FACE) ? mask : IndexMask(mesh->totpoly);
- return nullptr;
+ VArray<bool> selection = select_mesh_faces_by_material(*mesh, material_, domain_mask);
+ return mesh->attributes().adapt_domain<bool>(std::move(selection), ATTR_DOMAIN_FACE, domain);
}
uint64_t hash() const override
More information about the Bf-blender-cvs
mailing list