From 2e45d4a57eadbea2a4cfb0b1ac4af33514d7c207 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 21 Feb 2024 14:35:11 +0500 Subject: [PATCH] unassign_material_style to handle constituents --- .../api/style/unassign_material_style.py | 28 +++++++++++++++ .../api/style/test_unassign_material_style.py | 34 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/unassign_material_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/unassign_material_style.py index 51270a863d..674e5eb7f0 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/style/unassign_material_style.py +++ b/src/ifcopenshell-python/ifcopenshell/api/style/unassign_material_style.py @@ -17,6 +17,9 @@ # along with IfcOpenShell. If not, see . +import ifcopenshell + + class Usecase: def __init__(self, file, material=None, style=None, context=None): """Unassigns a style to a material @@ -67,3 +70,28 @@ class Usecase: self.file.remove(representation) if not definition.Representations: self.file.remove(definition) + + # handle material constituents and shape aspects + material_constituents_names = [] + for inverse in self.file.get_inverse(self.settings["material"]): + if inverse.is_a("IfcMaterialConstituent") and inverse.Name: + material_constituents_names.append(inverse.Name) + if not material_constituents_names: + return + + elements = ifcopenshell.util.element.get_elements_by_material(self.file, self.settings["material"]) + shape_aspects = [] + for element in elements: + shape_aspects += ifcopenshell.util.element.get_shape_aspects(element) + + for shape_aspect in shape_aspects: + if shape_aspect.Name not in material_constituents_names: + continue + + for rep in shape_aspect.ShapeRepresentations: + ifcopenshell.api.run( + "style.unassign_representation_styles", + self.file, + shape_representation=rep, + styles=[self.settings["style"]], + ) diff --git a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py index e2d2cc1964..936af3aa96 100644 --- a/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py +++ b/src/ifcopenshell-python/test/api/style/test_unassign_material_style.py @@ -45,3 +45,37 @@ class TestAssignMaterialStyle(test.bootstrap.IFC4): assert len(self.file.by_type("IfcMaterialDefinitionRepresentation")) == 0 assert len(self.file.by_type("IfcStyledRepresentation")) == 0 assert len(self.file.by_type("IfcStyledItem")) == 0 + + def test_update_shape_aspect_representaitons_items_styles_if_material_is_part_of_matching_material_constituents( + self, + ): + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + name = "Concrete" + product_shape = self.file.createIfcProductDefinitionShape() + element.Representation = product_shape + context = self.file.createIfcGeometricRepresentationContext() + + representation = self.file.createIfcShapeRepresentation() + item = self.file.createIfcExtrudedAreaSolid() + representation.Items = [item] + + shape_aspect = self.file.createIfcShapeAspect(ShapeRepresentations=(representation,), Name=name) + shape_aspect.PartOfProductDefinitionShape = product_shape + + style = self.file.createIfcSurfaceStyle() + material = ifcopenshell.api.run("material.add_material", self.file) + material_set = ifcopenshell.api.run( + "material.add_material_set", self.file, set_type="IfcMaterialConstituentSet" + ) + constituent = ifcopenshell.api.run( + "material.add_constituent", self.file, constituent_set=material_set, material=material + ) + constituent.Name = name + ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set) + + ifcopenshell.api.run("style.assign_material_style", self.file, material=material, style=style, context=context) + ifcopenshell.api.run( + "style.unassign_material_style", self.file, material=material, style=style, context=context + ) + + assert len(item.StyledByItem) == 0