From 5885924bb7d3a2a9dfc25a33a5281271127eac4f Mon Sep 17 00:00:00 2001 From: Ryan Schultz Date: Sat, 18 Oct 2025 12:47:35 -0500 Subject: [PATCH] Fix #5709: The RCP will not be denied! :) --- src/bonsai/bonsai/bim/export_ifc.py | 11 ++++++++++- src/bonsai/bonsai/bim/module/drawing/operator.py | 13 +++++++++++-- src/bonsai/bonsai/bim/module/geometry/__init__.py | 6 ++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/bonsai/bonsai/bim/export_ifc.py b/src/bonsai/bonsai/bim/export_ifc.py index 5fe5a1df97..d920bda9a0 100644 --- a/src/bonsai/bonsai/bim/export_ifc.py +++ b/src/bonsai/bonsai/bim/export_ifc.py @@ -104,7 +104,16 @@ class IfcExporter: def sync_object_placement(self, obj: bpy.types.Object) -> Union[ifcopenshell.entity_instance, None]: element = self.file.by_id(tool.Blender.get_object_bim_props(obj).ifc_definition_id) - if tool.Geometry.is_scaled(obj): + # Handle camera scales specially + if obj.type == "CAMERA": + # Check if this is a reflected ceiling plan camera + camera = tool.Ifc.get_entity(obj) + if ifcopenshell.util.element.get_pset(camera, "EPset_Drawing", "TargetView") == "REFLECTED_PLAN_VIEW": + # Ensure reflected ceiling cameras have the correct scale + if obj.scale != (-1, -1, -1): + obj.scale = (-1, -1, -1) + # Skip all other scale handling for cameras + elif tool.Geometry.is_scaled(obj): bpy.ops.bim.update_representation(obj=obj.name) # update_representation might not apply scale if the object has openings # reset it, so let user know that the scale wasn't saved. diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py index cfb8253e82..52598ac6b1 100644 --- a/src/bonsai/bonsai/bim/module/drawing/operator.py +++ b/src/bonsai/bonsai/bim/module/drawing/operator.py @@ -2339,10 +2339,19 @@ class ActivateDrawingBase(tool.Ifc.Operator): camera = context.scene.camera assert camera camera_props = tool.Drawing.get_camera_props(camera) + # Check if this is a reflected ceiling camera and preserve its scale + camera_element = tool.Ifc.get_entity(camera) + is_reflected = False + if camera_element: + is_reflected = ifcopenshell.util.element.get_pset(camera_element, "EPset_Drawing", "TargetView") == "REFLECTED_PLAN_VIEW" + if is_reflected and camera.scale != (-1, -1, -1): + camera.scale = (-1, -1, -1) + if camera_props.update_representation(camera.matrix_world): bpy.ops.bim.update_representation(obj=camera.name, ifc_representation_class="") - # See 6452 and 6478. - # bpy.ops.bim.refresh_clipping_planes("INVOKE_DEFAULT") + # Restore the scale after update if needed + if is_reflected: + camera.scale = (-1, -1, -1) return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/geometry/__init__.py b/src/bonsai/bonsai/bim/module/geometry/__init__.py index bba979af30..385df0c749 100644 --- a/src/bonsai/bonsai/bim/module/geometry/__init__.py +++ b/src/bonsai/bonsai/bim/module/geometry/__init__.py @@ -109,8 +109,10 @@ def block_scale(scene: bpy.types.Scene) -> None: if obj.type == "CAMERA": camera = tool.Ifc.get_entity(obj) if ifcopenshell.util.element.get_pset(camera, "EPset_Drawing", "TargetView") == "REFLECTED_PLAN_VIEW": - obj.scale = (-1, -1, -1) - obj.rotation_euler = (0.0, 0.0, math.radians(180)) + # Only update if scale isn't already (-1, -1, -1) + if obj.scale != (-1, -1, -1): + obj.scale = (-1, -1, -1) + obj.rotation_euler = (0.0, 0.0, math.radians(180)) else: if obj.scale != (1, 1, 1): obj.scale = (1, 1, 1)