From e96420335b7d046c834d3fd0dee11977c155bfe3 Mon Sep 17 00:00:00 2001 From: Robin Quint Date: Fri, 8 Aug 2025 14:54:02 +0200 Subject: [PATCH] Geometry for arbitrary objects is now synced for mirrored objects --- .../bonsai/bim/module/geometry/operator.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 9bc0566532..afa68b42e8 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +import json +import re from collections.abc import Sequence from time import time from typing import ( @@ -28,6 +30,7 @@ from typing import ( get_args, ) + import bmesh import bpy import ifcopenshell @@ -2713,6 +2716,29 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator): tool.Root.reload_item_decorator() tool.Geometry.reload_representation(props.representation_obj) + # apply changes to mirrored object, if it exists + if props.representation_obj and (representation_elem := tool.Ifc.get_entity(props.representation_obj)): + type_elem = ifcopenshell.util.element.get_type(representation_elem) + if type_elem and (mirrored_pset := ifcopenshell.util.element.get_pset(type_elem, "BBIM_InvertedSwingType", "Data")): + mirrored_data = json.loads(mirrored_pset) + if "inverted_swing_type" in mirrored_data and (inverted_type := tool.Ifc.get_entity_by_id(int(mirrored_data["inverted_swing_type"]))): + # object has mirror, update it as well + for map_index, repr_map in enumerate(type_elem.RepresentationMaps): + new_items = [] + for item in repr_map.MappedRepresentation.Items: + new_mirrored_repr = ifcopenshell.util.element.copy_deep(tool.Ifc.get(), item) + builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get()) + builder.mirror(new_mirrored_repr, (1, 0), create_copy=False) + new_items.append(new_mirrored_repr) + + old_items = inverted_type.RepresentationMaps[map_index].MappedRepresentation.Items + inverted_type.RepresentationMaps[map_index].MappedRepresentation.Items = new_items + for old_item in old_items: + ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_item) + + tool.Geometry.reload_representation(tool.Ifc.get_object(inverted_type)) + + def enable_edit_mode(self, context): if tool.Blender.toggle_edit_mode(context) == {"CANCELLED"}: return {"CANCELLED"}