From cfd857233c0a60d5908b6e3044b5e7142c8b8349 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 19 Mar 2023 18:46:34 +1100 Subject: [PATCH] Fix #2864. Fix bug where element containment was invalidly prioritised over voids and fills in relative placement. --- .../api/geometry/edit_object_placement.py | 7 ++++--- .../api/geometry/test_edit_object_placement.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py index 0830bbfbbb..e12885e1c2 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py @@ -76,9 +76,7 @@ class Usecase: matrix[2][3] *= self.unit_scale def get_placement_rel_to(self): - if getattr(self.settings["product"], "ContainedInStructure", None): - return self.settings["product"].ContainedInStructure[0].RelatingStructure.ObjectPlacement - elif getattr(self.settings["product"], "Decomposes", None): + if getattr(self.settings["product"], "Decomposes", None): relating_object = self.settings["product"].Decomposes[0].RelatingObject return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None elif getattr(self.settings["product"], "Nests", None): @@ -96,6 +94,9 @@ class Usecase: elif getattr(self.settings["product"], "ProjectsElements", None): relating_object = self.settings["product"].ProjectsElements[0].RelatingElement return relating_object.ObjectPlacement if hasattr(relating_object, "ObjectPlacement") else None + elif getattr(self.settings["product"], "ContainedInStructure", None): + return self.settings["product"].ContainedInStructure[0].RelatingStructure.ObjectPlacement + def get_children_settings(self, placement): if not placement: diff --git a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py index a63bb2446b..cb8d9412f2 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py +++ b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py @@ -266,8 +266,10 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): def test_changing_placements_relative_to_a_voided_element(self): ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") ifcopenshell.api.run("unit.assign_unit", self.file) + site = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSite") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcOpeningElement") + ifcopenshell.api.run("spatial.assign_container", self.file, product=element, relating_structure=site) matrix = numpy.array( ( (1.0, 0.0, 0.0, 1.0), @@ -298,8 +300,12 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): def test_changing_placements_relative_to_an_opening(self): ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") ifcopenshell.api.run("unit.assign_unit", self.file) + site = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSite") + wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcOpeningElement") subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcDoor") + ifcopenshell.api.run("spatial.assign_container", self.file, product=wall, relating_structure=site) + ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=site) matrix = numpy.array( ( (1.0, 0.0, 0.0, 1.0), @@ -316,7 +322,14 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): (0.0, 0.0, 0.0, 1.0), ) ) + ifcopenshell.api.run("void.add_opening", self.file, opening=element, element=wall) ifcopenshell.api.run("void.add_filling", self.file, element=subelement, opening=element) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=site, matrix=numpy.eye(4), is_si=False + ) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=wall, matrix=numpy.eye(4), is_si=False + ) ifcopenshell.api.run( "geometry.edit_object_placement", self.file, product=element, matrix=matrix.copy(), is_si=False ) @@ -325,6 +338,9 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): ) assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement), matrix) assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(subelement.ObjectPlacement), submatrix) + assert not site.ObjectPlacement.PlacementRelTo + assert wall.ObjectPlacement.PlacementRelTo == site.ObjectPlacement + assert element.ObjectPlacement.PlacementRelTo == wall.ObjectPlacement assert subelement.ObjectPlacement.PlacementRelTo == element.ObjectPlacement def test_changing_placements_relative_to_a_projected_element(self):