diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index a6e6ce29af6..9ae8c317630 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -455,15 +455,6 @@ static void version_movieclips_legacy_camera_object(Main *bmain) } } -static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree) -{ - LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) { - if (STREQ(node->idname, "GeometryNodeMeshBoolean")) { - add_realize_instances_before_socket(ntree, node, nodeFindSocket(node, SOCK_IN, "Mesh 2")); - } - } -} - /* Version VertexWeightEdit modifier to make existing weights exclusive of the threshold. */ static void version_vertex_weight_edit_preserve_threshold_exclusivity(Main *bmain) { @@ -1300,14 +1291,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } - if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 3)) { - LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { - if (ntree->type == NTREE_GEOMETRY) { - version_geometry_nodes_add_realize_instance_nodes(ntree); - } - } - } - /* 400 4 did not require any do_version here. */ if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 5)) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc index 441cd30466c..efa92f5a94f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "BKE_geometry_set_instances.hh" +#include "BKE_instances.hh" #include "BKE_mesh_boolean_convert.hh" #include "DNA_mesh_types.h" @@ -65,6 +66,16 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) node->custom1 = GEO_NODE_BOOLEAN_DIFFERENCE; } +static Array calc_mesh_material_map(const Mesh &mesh, VectorSet &all_materials) +{ + Array map(mesh.totcol); + for (const int i : IndexRange(mesh.totcol)) { + Material *material = mesh.mat[i]; + map[i] = material ? all_materials.index_of_or_add(material) : -1; + } + return map; +} + static void node_geo_exec(GeoNodeExecParams params) { #ifdef WITH_GMP @@ -73,6 +84,7 @@ static void node_geo_exec(GeoNodeExecParams params) const bool hole_tolerant = params.get_input("Hole Tolerant"); Vector meshes; + Vector transforms; VectorSet materials; Vector> material_remaps; @@ -84,6 +96,7 @@ static void node_geo_exec(GeoNodeExecParams params) * to be a single mesh. */ if (const Mesh *mesh_in_a = set_a.get_mesh()) { meshes.append(mesh_in_a); + transforms.append(float4x4::identity()); if (mesh_in_a->totcol == 0) { /* Necessary for faces using the default material when there are no material slots. */ materials.add(nullptr); @@ -100,12 +113,39 @@ static void node_geo_exec(GeoNodeExecParams params) for (const GeometrySet &geometry : geometry_sets) { if (const Mesh *mesh = geometry.get_mesh()) { meshes.append(mesh); - Array map(mesh->totcol); - for (const int i : IndexRange(mesh->totcol)) { - Material *material = mesh->mat[i]; - map[i] = material ? materials.index_of_or_add(material) : -1; + transforms.append(float4x4::identity()); + material_remaps.append(calc_mesh_material_map(*mesh, materials)); + } + if (const bke::Instances *instances = geometry.get_instances()) { + const Span references = instances->references(); + const Span handles = instances->reference_handles(); + const Span instance_transforms = instances->transforms(); + for (const int i : handles.index_range()) { + const bke::InstanceReference &reference = references[handles[i]]; + switch (reference.type()) { + case bke::InstanceReference::Type::Object: { + const GeometrySet object_geometry = bke::object_get_evaluated_geometry_set( + reference.object()); + if (const Mesh *mesh = object_geometry.get_mesh()) { + meshes.append(mesh); + transforms.append(instance_transforms[i]); + material_remaps.append(calc_mesh_material_map(*mesh, materials)); + } + break; + } + case bke::InstanceReference::Type::GeometrySet: { + if (const Mesh *mesh = reference.geometry_set().get_mesh()) { + meshes.append(mesh); + transforms.append(instance_transforms[i]); + material_remaps.append(calc_mesh_material_map(*mesh, materials)); + } + break; + } + case bke::InstanceReference::Type::None: + case bke::InstanceReference::Type::Collection: + break; + } } - material_remaps.append(std::move(map)); } } @@ -116,7 +156,7 @@ static void node_geo_exec(GeoNodeExecParams params) Vector intersecting_edges; Mesh *result = blender::meshintersect::direct_mesh_boolean( meshes, - {}, + transforms, float4x4::identity(), material_remaps, use_self,