From 776842a0646345affca67d0f346e477449e26fb1 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 15 Oct 2021 17:07:23 +1100 Subject: [PATCH] Spatial containers are now shown sorted by Z index order for convenience. --- .../blenderbim/bim/module/geometry/operator.py | 10 ++++++---- src/blenderbim/blenderbim/tool/container.py | 11 +++++++++++ src/blenderbim/test/bim/feature/geometry.feature | 5 +++++ src/blenderbim/test/bim/test_feature.py | 6 ++++++ src/blenderbim/test/tool/test_container.py | 15 +++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index a757abc555..8719e880db 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -498,7 +498,8 @@ class OverrideDuplicateMove(bpy.types.Operator): new_active_obj = None for obj in context.selected_objects: new_obj = obj.copy() - new_obj.data = obj.data.copy() + if obj.data: + new_obj.data = obj.data.copy() if obj == context.active_object: new_active_obj = new_obj for collection in obj.users_collection: @@ -514,14 +515,15 @@ class OverrideDuplicateMove(bpy.types.Operator): self.new_active_obj = None for obj in context.selected_objects: new_obj = obj.copy() - new_obj.data = obj.data.copy() + if obj.data: + new_obj.data = obj.data.copy() if obj == context.active_object: self.new_active_obj = new_obj - # This is the only difference - bpy.ops.bim.copy_class(obj=new_obj.name) for collection in obj.users_collection: collection.objects.link(new_obj) obj.select_set(False) new_obj.select_set(True) + # This is the only difference + bpy.ops.bim.copy_class(obj=new_obj.name) bpy.ops.transform.translate("INVOKE_DEFAULT") return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/tool/container.py b/src/blenderbim/blenderbim/tool/container.py index 78f67791c4..8e964554bf 100644 --- a/src/blenderbim/blenderbim/tool/container.py +++ b/src/blenderbim/blenderbim/tool/container.py @@ -17,6 +17,7 @@ # along with BlenderBIM Add-on. If not, see . import bpy +import ifcopenshell import blenderbim.core.tool import blenderbim.tool as tool @@ -57,7 +58,17 @@ class Container(blenderbim.core.tool.Container): props.active_container_id = parent.id() for rel in parent.IsDecomposedBy or []: + related_objects = [] for element in rel.RelatedObjects: + if element.ObjectPlacement: + related_objects.append( + (element, ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)[2][3]) + ) + else: + related_objects.append((element, float("-inf"))) + related_objects = sorted(related_objects, key=lambda e: e[1]) + for element in related_objects: + element = element[0] new = props.containers.add() new.name = element.Name or "Unnamed" new.long_name = element.LongName or "" diff --git a/src/blenderbim/test/bim/feature/geometry.feature b/src/blenderbim/test/bim/feature/geometry.feature index cbd79e4713..282ae30212 100644 --- a/src/blenderbim/test/bim/feature/geometry.feature +++ b/src/blenderbim/test/bim/feature/geometry.feature @@ -45,7 +45,9 @@ Scenario: Override delete - with active IFC data Scenario: Override duplicate move - without active IFC data Given an empty Blender session And I add a cube + And I add an empty And the object "Cube" is selected + And additionally the object "Empty" is selected When I press "object.duplicate_move" Then the object "Cube" exists And the object "Cube.001" exists @@ -57,8 +59,11 @@ Scenario: Override duplicate move - with active IFC data And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" And I press "bim.assign_class" And the object "IfcWall/Cube" is selected + And additionally the object "IfcBuildingStorey/My Storey" is selected When I press "object.duplicate_move" Then the object "IfcWall/Cube" exists And the object "IfcWall/Cube" is an "IfcWall" And the object "IfcWall/Cube.001" exists And the object "IfcWall/Cube.001" is an "IfcWall" + And the object "IfcBuildingStorey/My Storey.001" exists + And the object "IfcBuildingStorey/My Storey.001" is an "IfcBuildingStorey" diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index f76d396138..a763d4e0fc 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -72,6 +72,12 @@ def i_add_a_cube(): bpy.ops.mesh.primitive_cube_add() +@given("I add an empty") +@when("I add an empty") +def i_add_an_empty(): + bpy.ops.object.empty_add() + + @given("I add a material") def i_add_a_material(): bpy.context.active_object.active_material = bpy.data.materials.new("Material") diff --git a/src/blenderbim/test/tool/test_container.py b/src/blenderbim/test/tool/test_container.py index 0e2e6736a0..e642b0d068 100644 --- a/src/blenderbim/test/tool/test_container.py +++ b/src/blenderbim/test/tool/test_container.py @@ -118,3 +118,18 @@ class TestImportContainers(NewFile): assert props.containers[0].has_decomposition is True assert props.containers[0].ifc_definition_id == tool.Ifc.get().by_type("IfcBuilding")[0].id() assert props.active_container_id == site.id() + + def test_importing_sorted_by_z_placement(self): + bpy.ops.bim.create_project() + building = tool.Ifc.get().by_type("IfcBuilding")[0] + storey1 = tool.Ifc.get().by_type("IfcBuildingStorey")[0] + storey1.Name = "Higher" + bpy.ops.bim.copy_class(obj=tool.Ifc.get_object(storey1).name) + storey2 = tool.Ifc.get().by_type("IfcBuildingStorey")[1] + storey2.Name = "Lower" + storey2.ObjectPlacement.RelativePlacement.Location.Coordinates = (0., 0., -100.) + subject.import_containers(building) + props = bpy.context.scene.BIMSpatialProperties + assert len(props.containers) == 2 + assert props.containers[0].name == "Lower" + assert props.containers[1].name == "Higher"