diff --git a/src/bonsai/bonsai/bim/module/material/operator.py b/src/bonsai/bonsai/bim/module/material/operator.py index 4cf66d9177..c6b92145b5 100644 --- a/src/bonsai/bonsai/bim/module/material/operator.py +++ b/src/bonsai/bonsai/bim/module/material/operator.py @@ -314,7 +314,7 @@ class RemoveConstituent(bpy.types.Operator, tool.Ifc.Operator): if len(material_set.MaterialConstituents) == 1: self.report({"ERROR"}, "At least one constituent must exist") return {"CANCELLED"} - ifcopenshell.api.run("material.remove_constituent", tool.Ifc.get(), constituent=constituent) + ifcopenshell.api.material.remove_constituent(tool.Ifc.get(), constituent=constituent) class AddProfile(bpy.types.Operator, tool.Ifc.Operator): @@ -349,7 +349,7 @@ class RemoveProfile(bpy.types.Operator, tool.Ifc.Operator): if len(material_set.MaterialProfiles) == 1: self.report({"ERROR"}, "At least one profile must exist") return {"CANCELLED"} - ifcopenshell.api.run("material.remove_profile", tool.Ifc.get(), profile=profile) + ifcopenshell.api.material.remove_profile(tool.Ifc.get(), profile=profile) class AddLayer(bpy.types.Operator, tool.Ifc.Operator): @@ -410,7 +410,7 @@ class RemoveLayer(bpy.types.Operator, tool.Ifc.Operator): if len(material_set.MaterialLayers) == 1: self.report({"ERROR"}, "At least one layer must exist") return {"CANCELLED"} - ifcopenshell.api.run("material.remove_layer", tool.Ifc.get(), layer=layer) + ifcopenshell.api.material.remove_layer(tool.Ifc.get(), layer=layer) for material_set in material_sets: slab.DumbSlabPlaner().regenerate_from_layer_set(material_set) wall.DumbWallPlaner().regenerate_from_layer_set(material_set) diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/remove_constituent.py b/src/ifcopenshell-python/ifcopenshell/api/material/remove_constituent.py index 7f6bd4d6a9..7521c48a15 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/material/remove_constituent.py +++ b/src/ifcopenshell-python/ifcopenshell/api/material/remove_constituent.py @@ -18,16 +18,16 @@ import ifcopenshell -def remove_constituent(file: ifcopenshell.file, constituent: ifcopenshell.entity_instance) -> None: +def remove_constituent( + file: ifcopenshell.file, constituent: ifcopenshell.entity_instance, should_remove_material: bool = False +) -> None: """Removes a constituent from a constituent set Note that it is invalid to have zero items in a set, so you should leave at least one constituent to ensure a valid IFC dataset. :param constituent: The IfcMaterialConstituent entity you want to remove - :type constituent: ifcopenshell.entity_instance - :return: None - :rtype: None + :param should_remove_material: If true, materials with no users will be removed Example: @@ -51,6 +51,7 @@ def remove_constituent(file: ifcopenshell.file, constituent: ifcopenshell.entity # invalid. ifcopenshell.api.material.remove_constituent(model, constituent=glazing) """ - settings = {"constituent": constituent} - - file.remove(settings["constituent"]) + material = layer.Material + file.remove(constituent) + if material and should_remove_material: + ifcopenshell.util.element.remove_deep2(file, subelement) diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/remove_layer.py b/src/ifcopenshell-python/ifcopenshell/api/material/remove_layer.py index 8f3a0f9450..7055beaf26 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/material/remove_layer.py +++ b/src/ifcopenshell-python/ifcopenshell/api/material/remove_layer.py @@ -15,19 +15,19 @@ # # You should have received a copy of the GNU Lesser General Public License # along with IfcOpenShell. If not, see . -import ifcopenshell +import ifcopenshell.util.element -def remove_layer(file: ifcopenshell.file, layer: ifcopenshell.entity_instance) -> None: +def remove_layer( + file: ifcopenshell.file, layer: ifcopenshell.entity_instance, should_remove_material: bool = False +) -> None: """Removes a layer from a layer set Note that it is invalid to have zero items in a set, so you should leave at least one layer to ensure a valid IFC dataset. :param layer: The IfcMaterialLayer entity you want to remove - :type layer: ifcopenshell.entity_instance - :return: None - :rtype: None + :param should_remove_material: If true, materials with no users will be removed Example: @@ -54,6 +54,7 @@ def remove_layer(file: ifcopenshell.file, layer: ifcopenshell.entity_instance) - # one one side such as to line a services riser. ifcopenshell.api.material.remove_layer(model, layer=layer3) """ - settings = {"layer": layer} - - file.remove(settings["layer"]) + material = layer.Material + file.remove(layer) + if material and should_remove_material: + ifcopenshell.util.element.remove_deep2(file, subelement) diff --git a/src/ifcopenshell-python/ifcopenshell/api/material/remove_profile.py b/src/ifcopenshell-python/ifcopenshell/api/material/remove_profile.py index 61c696d465..2883f21e41 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/material/remove_profile.py +++ b/src/ifcopenshell-python/ifcopenshell/api/material/remove_profile.py @@ -17,20 +17,23 @@ # along with IfcOpenShell. If not, see . -import ifcopenshell import ifcopenshell.util.element -def remove_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instance) -> None: +def remove_profile( + file: ifcopenshell.file, + profile: ifcopenshell.entity_instance, + should_remove_profile_def: bool = False, + should_remove_material: bool = False, +) -> None: """Removes a profile item from a profile set Note that it is invalid to have zero items in a set, so you should leave at least one profile to ensure a valid IFC dataset. :param profile: The IfcMaterialProfile entity you want to remove - :type profile: ifcopenshell.entity_instance - :return: None - :rtype: None + :param should_remove_profile_def: If true, profile defs with no users will be removed + :param should_remove_material: If true, materials with no users will be removed Example: @@ -64,12 +67,14 @@ def remove_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instanc ifcopenshell.api.material.remove_profile(model, profile=weld_profile) """ - settings = {"profile": profile} - subelements = set() - for attribute in settings["profile"]: + for attribute in profile: if isinstance(attribute, ifcopenshell.entity_instance): subelements.add(attribute) - file.remove(settings["profile"]) + file.remove(profile) for subelement in subelements: + if subelement.is_a("IfcMaterial") and not should_remove_material: + continue + elif subelement.is_a("IfcProfileDef") and not should_remove_profile_def: + continue ifcopenshell.util.element.remove_deep2(file, subelement)