[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