From 25ec0ee36c29153c7537c0458025c75f193d40fb Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Tue, 1 Aug 2023 17:14:53 +0500 Subject: [PATCH] root.remove_product to remove IfcRelConnectsPorts too previously if you deleted some flow segment that was connected to another the connection would stay resulting in invalid ifc and other bugs --- .../ifcopenshell/api/root/remove_product.py | 6 +++++ .../test/api/root/test_remove_product.py | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py index eb61cea031..17752a6168 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py @@ -132,6 +132,12 @@ class Usecase: ): continue self.file.remove(inverse) + elif inverse.is_a("IfcRelConnectsPorts"): + if self.settings["product"] not in (inverse.RelatingPort, inverse.RelatedPort): + # if it's not RelatingPort/RelatedPort then it's optional RealizingElement + # so we keep the relationship + continue + self.file.remove(inverse) elif inverse.is_a("IfcRelAssignsToGroup"): if len(inverse.RelatedObjects) == 1: self.file.remove(inverse) 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 7431551d77..c37048874a 100644 --- a/src/ifcopenshell-python/test/api/root/test_remove_product.py +++ b/src/ifcopenshell-python/test/api/root/test_remove_product.py @@ -266,6 +266,29 @@ class TestRemoveProduct(test.bootstrap.IFC4): assert len(self.file.by_type("IfcSlab")) == 1 assert len(self.file.by_type("IfcWall")) == 1 + def test_removing_ports_connection_relationship(self): + port1 = ifcopenshell.api.run("system.add_port", self.file) + element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcFlowSegment") + ifcopenshell.api.run("system.assign_port", self.file, element=element1, port=port1) + + port2 = ifcopenshell.api.run("system.add_port", self.file) + element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcFlowSegment") + ifcopenshell.api.run("system.assign_port", self.file, element=element2, port=port2) + + ifcopenshell.api.run("system.connect_port", self.file, port1=port1, port2=port2, direction="SOURCE") + connection = self.file.by_type("IfcRelConnectsPorts")[0] + + # making sure removing realizing element won't remove the entire connection since it's optional + element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcFlowSegment") + connection.RealizingElement = element3 + ifcopenshell.api.run("root.remove_product", self.file, product=element3) + assert len(self.file.by_type("IfcRelConnectsPorts")) == 1 + + ifcopenshell.api.run("root.remove_product", self.file, product=element1) + assert len(self.file.by_type("IfcRelConnectsPorts")) == 0 + assert len(self.file.by_type("IfcFlowSegment")) == 1 + assert len(self.file.by_type("IfcDistributionPort")) == 1 + def test_removing_all_property_relationships_of_an_element(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="Foo_Bar")