From cea4c0c01dea1f01bb795eba2880b84946ede72d Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 7 Sep 2024 14:50:09 +1000 Subject: [PATCH] Fix #5345. Bug when adding a new representation using "full representation". No temp data is used, so deletion not required. --- .../bonsai/bim/module/geometry/operator.py | 37 ++++++++++--------- src/bonsai/test/bim/feature/geometry.feature | 14 ++++++- src/bonsai/test/bim/feature/root.feature | 9 ++++- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 04e549c175..452346e2fb 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -176,24 +176,23 @@ class AddRepresentation(bpy.types.Operator, tool.Ifc.Operator): ) return {"FINISH"} - # NOTE: `data` is temporary data generated to add a representation. - data: bpy.types.Mesh + new_rep_data: bpy.types.Mesh | None = None if conversion_method == "OUTLINE": if ifc_context.ContextType == "Plan": - data = tool.Geometry.generate_outline_mesh(obj, axis="+Z") + new_rep_data = tool.Geometry.generate_outline_mesh(obj, axis="+Z") elif ifc_context.ContextIdentifier == "Profile": - data = tool.Geometry.generate_outline_mesh(obj, axis="-Y") + new_rep_data = tool.Geometry.generate_outline_mesh(obj, axis="-Y") else: - data = tool.Geometry.generate_outline_mesh(obj, axis="+Z") - tool.Geometry.change_object_data(obj, data, is_global=True) + new_rep_data = tool.Geometry.generate_outline_mesh(obj, axis="+Z") + tool.Geometry.change_object_data(obj, new_rep_data, is_global=True) elif conversion_method == "BOX": if ifc_context.ContextType == "Plan": - data = tool.Geometry.generate_2d_box_mesh(obj, axis="Z") + new_rep_data = tool.Geometry.generate_2d_box_mesh(obj, axis="Z") elif ifc_context.ContextIdentifier == "Profile": - data = tool.Geometry.generate_2d_box_mesh(obj, axis="Y") + new_rep_data = tool.Geometry.generate_2d_box_mesh(obj, axis="Y") else: - data = tool.Geometry.generate_3d_box_mesh(obj) - tool.Geometry.change_object_data(obj, data, is_global=True) + new_rep_data = tool.Geometry.generate_3d_box_mesh(obj) + tool.Geometry.change_object_data(obj, new_rep_data, is_global=True) elif conversion_method in ("OBJECT", "CUBE"): if conversion_method == "OBJECT": if not (source_obj := props.representation_from_object): @@ -202,17 +201,17 @@ class AddRepresentation(bpy.types.Operator, tool.Ifc.Operator): depsgraph = context.evaluated_depsgraph_get() eval_obj = source_obj.evaluated_get(depsgraph) - data = bpy.data.meshes.new_from_object(eval_obj) + new_rep_data = bpy.data.meshes.new_from_object(eval_obj) else: # CUBE - data = bpy.data.meshes.new("Cube") - bm = tool.Blender.get_bmesh_for_mesh(data) + new_rep_data = bpy.data.meshes.new("Cube") + bm = tool.Blender.get_bmesh_for_mesh(new_rep_data) bmesh.ops.create_cube(bm, size=1) - tool.Blender.apply_bmesh(data, bm) + tool.Blender.apply_bmesh(new_rep_data, bm) if original_data: - tool.Geometry.change_object_data(obj, data, is_global=True) + tool.Geometry.change_object_data(obj, new_rep_data, is_global=True) else: - obj = tool.Geometry.recreate_object_with_data(obj, data, is_global=True) + obj = tool.Geometry.recreate_object_with_data(obj, new_rep_data, is_global=True) try: core.add_representation( @@ -228,11 +227,13 @@ class AddRepresentation(bpy.types.Operator, tool.Ifc.Operator): # Object might be recreated, need to set it as active again. if context.active_object != obj: tool.Blender.set_active_object(obj) - bpy.data.meshes.remove(data) + if new_rep_data: + bpy.data.meshes.remove(new_rep_data) except core.IncompatibleRepresentationError: if obj.data != original_data: tool.Geometry.change_object_data(obj, original_data, is_global=True) - bpy.data.meshes.remove(data) + if new_rep_data: + bpy.data.meshes.remove(new_rep_data) self.report({"ERROR"}, "No compatible representation for the context could be created.") return {"CANCELLED"} diff --git a/src/bonsai/test/bim/feature/geometry.feature b/src/bonsai/test/bim/feature/geometry.feature index efb5e81660..6e12aa0d84 100644 --- a/src/bonsai/test/bim/feature/geometry.feature +++ b/src/bonsai/test/bim/feature/geometry.feature @@ -326,7 +326,19 @@ Scenario: Override duplicate move - with active IFC data And the object "IfcWall/Cube.001" exists And the object "IfcWall/Cube.001" is an "IfcWall" And the object "IfcWall/Cube.001" has a "Tessellation" representation of "Model/Body/MODEL_VIEW" - And the object "IfcBuildingStorey/My Storey.001" exists + And the object "IfcBuildingStorey/My Storey.001" does not exist + +Scenario: Override duplicate move - with unlocked elements + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I set "scene.BIMRootProperties.ifc_product" to "IfcElement" + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcBuildingStorey/My Storey" is selected + And I set "scene.BIMSpatialDecompositionProperties.is_locked" to "False" + When I duplicate the selected objects + Then the object "IfcBuildingStorey/My Storey.001" exists And the object "IfcBuildingStorey/My Storey.001" is an "IfcBuildingStorey" Scenario: Override duplicate move - copying a coloured representation diff --git a/src/bonsai/test/bim/feature/root.feature b/src/bonsai/test/bim/feature/root.feature index ee26ac39ed..d9606b62a0 100644 --- a/src/bonsai/test/bim/feature/root.feature +++ b/src/bonsai/test/bim/feature/root.feature @@ -110,10 +110,17 @@ Scenario: Copy a wall And I duplicate the selected objects Then the object "IfcWall/Cube" and "IfcWall/Cube.001" are different elements -Scenario: Copy a storey +Scenario: Copy a storey - when locked Given an empty IFC project And the object "IfcBuildingStorey/My Storey" is selected When I duplicate the selected objects + Then the object "IfcBuildingStorey/My Storey.001" does not exist + +Scenario: Copy a storey - when unlocked + Given an empty IFC project + And the object "IfcBuildingStorey/My Storey" is selected + And I set "scene.BIMSpatialDecompositionProperties.is_locked" to "False" + When I duplicate the selected objects Then the object "IfcBuildingStorey/My Storey" and "IfcBuildingStorey/My Storey.001" are different elements And the object "IfcBuildingStorey/My Storey" is in the collection "IfcBuildingStorey/My Storey" And the object "IfcBuildingStorey/My Storey.001" is in the collection "IfcBuildingStorey/My Storey.001"