diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py b/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py index f2ce64495f..9031db5dd5 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py +++ b/src/ifcopenshell-python/ifcopenshell/api/style/edit_surface_style.py @@ -73,34 +73,35 @@ class Usecase: self.settings = {"style": style, "attributes": attributes or {}} def execute(self): + attributes = {} + for attribute in self.settings["style"].wrapped_data.declaration().as_entity().all_attributes(): + attribute_type = attribute.type_of_attribute() + if attribute_type.as_aggregation_type() is None: + attribute_type = attribute_type.declared_type().name() + else: + # doesn't have .declared_type() + attribute_type = attribute_type.type_of_element() + attributes[attribute.name()] = attribute_type + for key, value in self.settings["attributes"].items(): - if key == "SurfaceColour": - self.edit_surface_colour(value) + attribute_class = attributes.get(key) + if attribute_class == "IfcColourRgb": + self.edit_colour_rgb(key, value) elif key == "SpecularHighlight": self.edit_specular_highlight(value) - elif self.is_colour_or_factor(key): + elif attribute_class == "IfcColourOrFactor": self.edit_colour_or_factor(key, value) else: setattr(self.settings["style"], key, value) - def edit_surface_colour(self, value): - if not self.settings["style"].SurfaceColour: - self.settings["style"].SurfaceColour = self.file.createIfcColourRgb( - value.get("Name", None), value["Red"], value["Green"], value["Blue"] - ) - self.settings["style"].SurfaceColour[0] = value.get("Name", None) - self.settings["style"].SurfaceColour[1] = value["Red"] - self.settings["style"].SurfaceColour[2] = value["Green"] - self.settings["style"].SurfaceColour[3] = value["Blue"] - - def is_colour_or_factor(self, name): - return name in [ - "DiffuseColour", - "TransmissionColour", - "DiffuseTransmissionColour", - "ReflectionColour", - "SpecularColour", - ] + def edit_colour_rgb(self, name, value: dict): + if (attribute := getattr(self.settings["style"], name)) is None: + attribute = self.file.createIfcColourRgb() + setattr(self.settings["style"], name, attribute) + attribute.Name = value.get("Name", None) + attribute.Red = value["Red"] + attribute.Green = value["Green"] + attribute.Blue = value["Blue"] def edit_colour_or_factor(self, name, value): if isinstance(value, dict): diff --git a/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py b/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py index 1e0ec65bbd..48282ece48 100644 --- a/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py +++ b/src/ifcopenshell-python/test/api/style/test_edit_surface_style.py @@ -140,3 +140,33 @@ class TestEditSurfaceStyle(test.bootstrap.IFC4): ) assert style.SpecularHighlight.is_a("IfcSpecularRoughness") assert style.SpecularHighlight.wrappedValue == 0.5 + + def test_editing_texture_style(self): + style = self.file.createIfcSurfaceStyleWithTextures() + textures = ({"Mode": "DIFFUSE", "RepeatS": True, "RepeatT": True, "URLReference": "diffuse.jpg"},) + textures = ifcopenshell.api.run("style.add_surface_textures", self.file, textures=textures) + ifcopenshell.api.run( + "style.edit_surface_style", + self.file, + style=style, + attributes={"Textures": textures}, + ) + assert set(style.Textures) == set(textures) + + def test_editing_lighting_style(self): + style = self.file.createIfcSurfaceStyleLighting() + attributes = ( + "DiffuseTransmissionColour", + "DiffuseReflectionColour", + "TransmissionColour", + "ReflectanceColour", + ) + attributes = {a: {"Red": 1, "Green": 1, "Blue": 1} for a in attributes} + ifcopenshell.api.run( + "style.edit_surface_style", + self.file, + style=style, + attributes=attributes, + ) + for attribute in attributes: + assert tuple(getattr(style, attribute)) == (None, 1, 1, 1)