From ea530858bd20bf7ddf9c78d6429bf7fa150efe1d Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 21 Mar 2022 12:03:15 +1100 Subject: [PATCH] You can now remove material sets independent of elements --- .../api/material/remove_material_set.py | 48 +++++++++++++++++ .../api/material/test_remove_material_set.py | 53 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/ifcopenshell-python/ifcopenshell/api/material/remove_material_set.py create mode 100644 src/ifcopenshell-python/test/api/material/test_remove_material_set.py diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/remove_material_set.py b/src/ifcopenshell-python/ifcopenshell/api/material/remove_material_set.py new file mode 100644 index 0000000000..f002b3a9fd --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/material/remove_material_set.py @@ -0,0 +1,48 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2022 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import ifcopenshell + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + inverse_elements = self.file.get_inverse(self.settings["material"]) + if self.settings["material"].is_a("IfcMaterialLayerSet"): + set_items = self.settings["material"].MaterialLayers or [] + elif self.settings["material"].is_a("IfcMaterialProfileSet"): + set_items = self.settings["material"].MaterialProfiles or [] + elif self.settings["material"].is_a("IfcMaterialConstituentSet"): + set_items = self.settings["material"].MaterialConstituents or [] + elif self.settings["material"].is_a("IfcMaterialList"): + set_items = [] + for set_item in set_items: + self.file.remove(set_item) + self.file.remove(self.settings["material"]) + for inverse in inverse_elements: + if inverse.is_a("IfcRelAssociatesMaterial"): + self.file.remove(inverse) + elif inverse.is_a("IfcMaterialProperties"): + for prop in inverse.Properties or []: + self.file.remove(prop) + self.file.remove(inverse) diff --git a/src/ifcopenshell-python/test/api/material/test_remove_material_set.py b/src/ifcopenshell-python/test/api/material/test_remove_material_set.py new file mode 100644 index 0000000000..fe78ce351c --- /dev/null +++ b/src/ifcopenshell-python/test/api/material/test_remove_material_set.py @@ -0,0 +1,53 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2022 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import test.bootstrap +import ifcopenshell.api + + +class TestRemoveMaterialSet(test.bootstrap.IFC4): + def test_removing_material_set(self): + material = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet") + ifcopenshell.api.run("material.remove_material_set", self.file, material=material) + assert len(self.file.by_type("IfcMaterialLayerSet")) == 0 + + def test_removing_material_set_with_associations(self): + wall = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + material = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet") + ifcopenshell.api.run("material.assign_material", self.file, product=wall, material=material) + ifcopenshell.api.run("material.remove_material_set", self.file, material=material) + assert len(self.file.by_type("IfcMaterialLayerSet")) == 0 + assert len(self.file.by_type("IfcRelAssociatesMaterial")) == 0 + + def test_removing_a_material_set_with_set_items_but_preserving_materials(self): + material = ifcopenshell.api.run("material.add_material", self.file) + material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet") + ifcopenshell.api.run("material.add_layer", self.file, layer_set=material_set, material=material) + ifcopenshell.api.run("material.remove_material_set", self.file, material=material_set) + assert len(self.file.by_type("IfcMaterialLayerSet")) == 0 + assert len(self.file.by_type("IfcMaterialLayer")) == 0 + assert len(self.file.by_type("IfcMaterial")) == 1 + + def test_removing_a_material_set_with_properties(self): + material = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialLayerSet") + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=material, name="Foo_Bar") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Foo": "Bar"}) + assert material.HasProperties + ifcopenshell.api.run("material.remove_material_set", self.file, material=material) + assert len(self.file.by_type("IfcMaterialProperties")) == 0 + assert len(self.file.by_type("IfcPropertySingleValue")) == 0