[Bf-blender-cvs] [f80e4f0046e] master: Fix T93272: Material index mapping missing for mesh boolean node

Hans Goudey noreply at git.blender.org
Tue May 3 09:47:42 CEST 2022


Commit: f80e4f0046ed93714c1c71a60264e9d012237654
Author: Hans Goudey
Date:   Tue May 3 09:28:35 2022 +0200
Branches: master
https://developer.blender.org/rBf80e4f0046ed93714c1c71a60264e9d012237654

Fix T93272: Material index mapping missing for mesh boolean node

This commit implements copying of materials and material indices from
all of the boolean node's input meshes. The materials are added to the
final mesh in the order that they appear when looking through the
materials of the input meshes in the same order of the multi-socket
input node.

All material remapping is done with mesh-level materials. Object-level
materials are not considered, since the meshes don't come from objects.

Merging all materials rather than just the materials on the first mesh
requires a change to the boolean-mesh conversion. This subtly changes
the behavior for object linked materials, but in a good way I think;
now the material remap arrays are respected no matter the number
of materials on the first mesh input.

Differential Revision: https://developer.blender.org/D14788

===================================================================

M	source/blender/blenkernel/intern/mesh_boolean_convert.cc
M	source/blender/nodes/geometry/nodes/node_geo_boolean.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index 9e77b138359..14bd6aa5b2f 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -407,17 +407,11 @@ static void copy_poly_attributes(Mesh *dest_mesh,
                                  int index_in_orig_me,
                                  Span<short> material_remap)
 {
-  mp->mat_nr = orig_mp->mat_nr;
-  if (mp->mat_nr >= dest_mesh->totcol) {
-    mp->mat_nr = 0;
+  if (material_remap.size() > 0 && material_remap.index_range().contains(orig_mp->mat_nr)) {
+    mp->mat_nr = material_remap[orig_mp->mat_nr];
   }
   else {
-    if (material_remap.size() > 0) {
-      short mat_nr = material_remap[orig_mp->mat_nr];
-      if (mat_nr >= 0 && mat_nr < dest_mesh->totcol) {
-        mp->mat_nr = mat_nr;
-      }
-    }
+    mp->mat_nr = orig_mp->mat_nr;
   }
 
   mp->flag = orig_mp->flag;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index 34256f23175..df2be8e7d37 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -68,6 +68,9 @@ static void node_geo_exec(GeoNodeExecParams params)
   Vector<const Mesh *> meshes;
   Vector<const float4x4 *> transforms;
 
+  VectorSet<Material *> materials;
+  Vector<Array<short>> material_remaps;
+
   GeometrySet set_a;
   if (operation == GEO_NODE_BOOLEAN_DIFFERENCE) {
     set_a = params.extract_input<GeometrySet>("Mesh 1");
@@ -78,6 +81,10 @@ static void node_geo_exec(GeoNodeExecParams params)
     if (mesh_in_a != nullptr) {
       meshes.append(mesh_in_a);
       transforms.append(nullptr);
+      for (Material *material : Span(mesh_in_a->mat, mesh_in_a->totcol)) {
+        materials.add(material);
+      }
+      material_remaps.append({});
     }
   }
 
@@ -89,6 +96,25 @@ static void node_geo_exec(GeoNodeExecParams params)
     bke::geometry_set_gather_instances(geometry_set, set_groups);
   }
 
+  for (const bke::GeometryInstanceGroup &set_group : set_groups) {
+    const Mesh *mesh = set_group.geometry_set.get_mesh_for_read();
+    if (mesh != nullptr) {
+      for (Material *material : Span(mesh->mat, mesh->totcol)) {
+        materials.add(material);
+      }
+    }
+  }
+  for (const bke::GeometryInstanceGroup &set_group : set_groups) {
+    const Mesh *mesh = set_group.geometry_set.get_mesh_for_read();
+    if (mesh != nullptr) {
+      Array<short> map(mesh->totcol);
+      for (const int i : IndexRange(mesh->totcol)) {
+        map[i] = materials.index_of(mesh->mat[i]);
+      }
+      material_remaps.append(std::move(map));
+    }
+  }
+
   for (const bke::GeometryInstanceGroup &set_group : set_groups) {
     const Mesh *mesh_in = set_group.geometry_set.get_mesh_for_read();
     if (mesh_in != nullptr) {
@@ -99,8 +125,18 @@ static void node_geo_exec(GeoNodeExecParams params)
     }
   }
 
-  Mesh *result = blender::meshintersect::direct_mesh_boolean(
-      meshes, transforms, float4x4::identity(), {}, use_self, hole_tolerant, operation);
+  Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes,
+                                                             transforms,
+                                                             float4x4::identity(),
+                                                             material_remaps,
+                                                             use_self,
+                                                             hole_tolerant,
+                                                             operation);
+
+  MEM_SAFE_FREE(result->mat);
+  result->mat = (Material **)MEM_malloc_arrayN(materials.size(), sizeof(Material *), __func__);
+  result->totcol = materials.size();
+  MutableSpan(result->mat, result->totcol).copy_from(materials);
 
   params.set_output("Mesh", GeometrySet::create_with_mesh(result));
 }



More information about the Bf-blender-cvs mailing list