From f8a29463559baaefc53b3f70204cc8678c19ff5f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 16 Oct 2023 15:05:40 +0500 Subject: [PATCH] Support other voiding IfcFeatureElementSubtraction elements #3889 Support other voiding IfcFeatureElementSubtraction besides IfcOpeningElement. --- src/blenderbim/blenderbim/bim/module/model/opening.py | 2 +- .../ifcopenshell/api/root/copy_class.py | 2 +- .../ifcopenshell/api/void/remove_opening.py | 5 +++-- .../test/api/root/test_copy_class.py | 11 +++++++++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/opening.py b/src/blenderbim/blenderbim/bim/module/model/opening.py index 9cb00d0169..adcf1f1079 100644 --- a/src/blenderbim/blenderbim/bim/module/model/opening.py +++ b/src/blenderbim/blenderbim/bim/module/model/opening.py @@ -801,7 +801,7 @@ class EditOpenings(Operator, tool.Ifc.Operator): return {"FINISHED"} def get_all_building_objects_of_similar_openings(self, opening): - if not opening.HasFillings: + if not opening.is_a("IfcOpeningElement") or not opening.HasFillings: return [] results = set() for rel in opening.HasFillings: diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py index 9b8f78bf70..7ffbdc38fa 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/copy_class.py @@ -130,7 +130,7 @@ class Usecase: elif inverse.is_a("IfcRelVoidsElement") and inverse.RelatingBuildingElement == from_element: opening = inverse.RelatedOpeningElement # We don't copy filled openings, since there is no guarantee the filling is also copied - if not opening.HasFillings: + if not opening.is_a("IfcOpeningElement") or not opening.HasFillings: new_opening = ifcopenshell.api.run("root.copy_class", self.file, product=opening) new_opening.VoidsElements[0].RelatingBuildingElement = to_element if new_opening.ObjectPlacement and new_opening.ObjectPlacement.is_a("IfcLocalPlacement"): diff --git a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py index 566416c8fd..9be088dc52 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py +++ b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py @@ -50,6 +50,7 @@ class Usecase: def execute(self): for rel in self.settings["opening"].VoidsElements: self.file.remove(rel) - for rel in self.settings["opening"].HasFillings: - self.file.remove(rel) + if self.settings["opening"].is_a("IfcOpeningElement"): + for rel in self.settings["opening"].HasFillings: + self.file.remove(rel) ifcopenshell.api.run("root.remove_product", self.file, product=self.settings["opening"]) diff --git a/src/ifcopenshell-python/test/api/root/test_copy_class.py b/src/ifcopenshell-python/test/api/root/test_copy_class.py index 520a074cde..36965258d4 100644 --- a/src/ifcopenshell-python/test/api/root/test_copy_class.py +++ b/src/ifcopenshell-python/test/api/root/test_copy_class.py @@ -120,6 +120,7 @@ class TestCopyClass(test.bootstrap.IFC4): assert new.RepresentationMaps is None def test_copying_an_element_with_an_opening(self): + # IfcOpeningElement opening wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") opening = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcOpeningElement") ifcopenshell.api.run("void.add_opening", self.file, opening=opening, element=wall) @@ -129,6 +130,16 @@ class TestCopyClass(test.bootstrap.IFC4): assert new.HasOpenings[0].RelatedOpeningElement != opening assert new.HasOpenings[0].RelatedOpeningElement.is_a("IfcOpeningElement") + # IfcVoidingFeature opening + plate = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcPlate") + opening = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcVoidingFeature") + ifcopenshell.api.run("void.add_opening", self.file, opening=opening, element=plate) + new = ifcopenshell.api.run("root.copy_class", self.file, product=plate) + assert plate.HasOpenings[0] != new.HasOpenings[0] + assert plate.HasOpenings[0].RelatedOpeningElement == opening + assert new.HasOpenings[0].RelatedOpeningElement != opening + assert new.HasOpenings[0].RelatedOpeningElement.is_a("IfcVoidingFeature") + def test_copying_an_element_with_a_filled_opening_should_not_copy_the_opening_nor_fill(self): wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") opening = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcOpeningElement")