diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 8d075a9605..e7fa918d50 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -1183,7 +1183,7 @@ class OverrideDuplicateMove(bpy.types.Operator): operator: bpy.types.Operator, context: bpy.types.Context, linked: bool = False ) -> set["rna_enums.OperatorReturnItems"]: # Deep magick from the dawn of time - if tool.Ifc.get(): + if tool.Ifc.get() and tool.Model.has_selected_ifc_objects(include_active=False): IfcStore.execute_ifc_operator(operator, context) return {"FINISHED"} @@ -1287,6 +1287,11 @@ class OverrideDuplicateMove(bpy.types.Operator): if part_obj: all_objects_to_select.add(part_obj) + # Non-IFC duplicates aren't tracked in old_to_new but are left selected by duplicate_ifc_objects + all_objects_to_select.update( + obj for obj in context.selected_objects if not tool.Ifc.get_entity(obj) + ) + # Deselect everything first bpy.ops.object.select_all(action="DESELECT") diff --git a/src/bonsai/bonsai/tool/model.py b/src/bonsai/bonsai/tool/model.py index 60f79cc26e..281265cfcc 100644 --- a/src/bonsai/bonsai/tool/model.py +++ b/src/bonsai/bonsai/tool/model.py @@ -1305,8 +1305,8 @@ class Model(bonsai.core.tool.Model): return [obj for obj in tool.Blender.get_selected_objects() if tool.Ifc.get_entity(obj)] @classmethod - def has_selected_ifc_objects(cls) -> bool: - return any(tool.Ifc.get_entity(obj) for obj in tool.Blender.get_selected_objects()) + def has_selected_ifc_objects(cls, include_active: bool = True) -> bool: + return any(tool.Ifc.get_entity(obj) for obj in tool.Blender.get_selected_objects(include_active=include_active)) @classmethod def get_selected_mesh_objects(cls) -> list[bpy.types.Object]: diff --git a/src/bonsai/test/bim/feature/geometry.feature b/src/bonsai/test/bim/feature/geometry.feature index 3bbf22a5c2..1236f416c8 100644 --- a/src/bonsai/test/bim/feature/geometry.feature +++ b/src/bonsai/test/bim/feature/geometry.feature @@ -285,6 +285,32 @@ Scenario: Override duplicate move - without active IFC data Then the object "Cube" exists And the object "Cube.001" exists +Scenario: Override duplicate move - non-IFC objects inside an IFC project + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + When I duplicate the selected objects + Then the object "Cube" exists + And the object "Cube.001" exists + And the object "Cube.001" is selected + +Scenario: Override duplicate move - mixed IFC and non-IFC selection + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I look at the "Class" panel + And I set the "Products" property to "IfcElement" + And I set the "Class" property to "IfcWall" + And I click "Assign IFC Class" + And I add a cube + And the object "IfcWall/Cube" is selected + And additionally the object "Cube" is selected + When I duplicate the selected objects + Then the object "IfcWall/Cube.001" exists + And the object "IfcWall/Cube.001" is selected + And the object "Cube.001" exists + And the object "Cube.001" is selected + Scenario: Override duplicate move - with active IFC data Given an empty IFC project And I add a cube