diff options
-rw-r--r-- | source/blender/blenkernel/intern/mesh_boolean_convert.cc | 12 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_boolean.cc | 40 |
2 files changed, 41 insertions, 11 deletions
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({}); } } @@ -90,6 +97,25 @@ static void node_geo_exec(GeoNodeExecParams params) } 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) { meshes.append_n_times(mesh_in, set_group.transforms.size()); @@ -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)); } |