From bd934d9b8ec30c8dccc2de0c74fcdd36273fac5d Mon Sep 17 00:00:00 2001 From: Ryan Schultz Date: Sat, 18 Apr 2026 12:43:00 -0500 Subject: [PATCH] Fix #7948: Fix duplicate not applying openings to geometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When duplicating an element with HasOpenings, copy_class (API) correctly copies the IfcRelVoidsElement into IFC, but the new object's Blender mesh was never regenerated — it was just a data-block copy of the original. Call reload_body_representation on any new element with unfilled HasOpenings so the opening boolean subtraction is computed for the duplicated geometry. Generated with the assistance of an AI coding tool. --- src/bonsai/bonsai/tool/geometry.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/bonsai/bonsai/tool/geometry.py b/src/bonsai/bonsai/tool/geometry.py index e0b719f065..aa75bbc471 100644 --- a/src/bonsai/bonsai/tool/geometry.py +++ b/src/bonsai/bonsai/tool/geometry.py @@ -2374,6 +2374,25 @@ class Geometry(bonsai.core.tool.Geometry): # Recreate decompositions tool.Duplicate.recreate_decompositions(decomposition_relationships, old_to_new) + + # Reload geometry for duplicated elements that have unfilled openings. + # copy_class (API) copies HasOpenings in IFC, but the mesh geometry is + # just a data-block copy of the original — switch_representation must be + # called so the opening boolean is actually computed for the new element. + for new_els in old_to_new.values(): + for new_el in new_els: + has_openings = getattr(new_el, "HasOpenings", None) + if not has_openings: + continue + # Only reload for openings that have no filling (filled openings + # are already handled by recreate_decompositions). + unfilled = [rel for rel in has_openings if not rel.RelatedOpeningElement.HasFillings] + if not unfilled: + continue + new_obj_final = tool.Ifc.get_object(new_el) + if new_obj_final: + tool.Model.reload_body_representation(new_obj_final) + cls.remove_linked_aggregate_data(old_to_new) bonsai.bim.handler.refresh_ui_data() tool.Root.reload_grid_decorator()