From b7eaefee50e4feef1b1dd9ea7a8880e69707bdc5 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 23 Sep 2022 23:26:29 +1000 Subject: [PATCH] Fix bug when deleting elements may possibly create an invalid containment relationship --- .../ifcopenshell/api/root/remove_product.py | 5 +++-- .../test/api/root/test_remove_product.py | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py index 41de3aed29..705e8cbd73 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py @@ -65,8 +65,9 @@ class Usecase: if not inverse.RelatedObjects: self.file.remove(inverse) elif inverse.is_a("IfcRelAggregates"): - if inverse.RelatingObject == self.settings["product"]: + if inverse.RelatingObject == self.settings["product"] or len(inverse.RelatedObjects) == 1: self.file.remove(inverse) - elif len(inverse.RelatedObjects) == 1: + elif inverse.is_a("IfcRelContainedInSpatialStructure"): + if inverse.RelatingStructure == self.settings["product"] or len(inverse.RelatedElements) == 1: self.file.remove(inverse) self.file.remove(self.settings["product"]) diff --git a/src/ifcopenshell-python/test/api/root/test_remove_product.py b/src/ifcopenshell-python/test/api/root/test_remove_product.py index ce6aaf2fa1..b922e72936 100644 --- a/src/ifcopenshell-python/test/api/root/test_remove_product.py +++ b/src/ifcopenshell-python/test/api/root/test_remove_product.py @@ -162,3 +162,25 @@ class TestRemoveProduct(test.bootstrap.IFC4): assert len(self.file.by_type("IfcRelAggregates")) == 0 assert len(self.file.by_type("IfcElementAssembly")) == 1 assert len(self.file.by_type("IfcBeam")) == 0 + + def test_removing_all_containment_relationships_of_a_container(self): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSpace") + subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=element) + total_entities = len(list(self.file)) + ifcopenshell.api.run("root.remove_product", self.file, product=element) + assert len(list(self.file)) == total_entities - 2 + assert len(self.file.by_type("IfcRelContainedInSpatialStructure")) == 0 + assert len(self.file.by_type("IfcSpace")) == 0 + assert len(self.file.by_type("IfcWall")) == 1 + + def test_removing_all_containment_relationships_of_an_element(self): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcSpace") + subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + ifcopenshell.api.run("spatial.assign_container", self.file, product=subelement, relating_structure=element) + total_entities = len(list(self.file)) + ifcopenshell.api.run("root.remove_product", self.file, product=subelement) + assert len(list(self.file)) == total_entities - 2 + assert len(self.file.by_type("IfcRelContainedInSpatialStructure")) == 0 + assert len(self.file.by_type("IfcSpace")) == 1 + assert len(self.file.by_type("IfcWall")) == 0