mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Fix bug where editing styles didn't work if factors were stored instead of RGB colours
This commit is contained in:
@@ -1,67 +0,0 @@
|
||||
class Usecase:
|
||||
def __init__(self, file, **settings):
|
||||
self.file = file
|
||||
self.settings = {
|
||||
"style": None,
|
||||
"surface_colour": [], # RGB
|
||||
"diffuse_colour": [], # RGB
|
||||
"transparency": 0,
|
||||
"external_definition": {"location": None, "identification": None, "name": "Name"},
|
||||
}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
# has_external_definition = None
|
||||
for element in self.file.traverse(self.settings["style"]):
|
||||
if element.is_a("IfcSurfaceStyleShading"):
|
||||
if element.SurfaceColour:
|
||||
self.update_colour_rgb(element.SurfaceColour, self.settings["surface_colour"])
|
||||
else:
|
||||
element.SurfaceColour = self.create_colour_rgb(self.settings["surface_colour"])
|
||||
element.Transparency = self.settings["transparency"]
|
||||
if element.is_a("IfcSurfaceStyleRendering"):
|
||||
if element.DiffuseColour:
|
||||
self.update_colour_rgb(element.DiffuseColour, self.settings["diffuse_colour"])
|
||||
else:
|
||||
element.DiffuseColour = self.create_colour_rgb(self.settings["diffuse_colour"])
|
||||
# TODO: Move to separate usecase
|
||||
# if element.is_a("IfcExternallyDefinedSurfaceStyle"):
|
||||
# element.Location = self.settings["location"]
|
||||
# element.Identification = self.settings["identification"]
|
||||
# element.Name = self.settings["name"]
|
||||
# has_external_definition = True
|
||||
# if not has_external_definition:
|
||||
# styles = list(self.settings["style"].Styles)
|
||||
# styles.append(self.create_externally_defined_surface_style())
|
||||
# self.settings["style"].Styles = styles
|
||||
return self.settings["style"]
|
||||
|
||||
def create_surface_style_rendering(self):
|
||||
return self.file.create_entity(
|
||||
"IfcSurfaceStyleRendering",
|
||||
**{
|
||||
"SurfaceColour": self.create_colour_rgb(self.settings["surface_colour"]),
|
||||
"Transparency": self.settings["transparency"],
|
||||
"ReflectanceMethod": "NOTDEFINED",
|
||||
"DiffuseColour": self.create_colour_rgb(self.settings["diffuse_colour"]),
|
||||
}
|
||||
)
|
||||
|
||||
def create_externally_defined_surface_style(self):
|
||||
self.file.create_entity(
|
||||
"IfcExternallyDefinedSurfaceStyle",
|
||||
**{
|
||||
"Location": self.settings["location"],
|
||||
"Identification": self.settings["identification"],
|
||||
"Name": self.settings["name"],
|
||||
}
|
||||
)
|
||||
|
||||
def create_colour_rgb(self, colour):
|
||||
return self.file.createIfcColourRgb(None, colour[0], colour[1], colour[2])
|
||||
|
||||
def update_colour_rgb(self, element, colour):
|
||||
element[1] = colour[0]
|
||||
element[2] = colour[1]
|
||||
element[3] = colour[2]
|
||||
@@ -0,0 +1,45 @@
|
||||
class Usecase:
|
||||
def __init__(self, file, **settings):
|
||||
self.file = file
|
||||
self.settings = {"style": None, "attributes": {}}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
for key, value in self.settings["attributes"].items():
|
||||
if key == "SurfaceColour":
|
||||
self.edit_surface_colour(value)
|
||||
elif self.is_colour_or_factor(key):
|
||||
self.edit_colour_or_factor(key, value)
|
||||
else:
|
||||
setattr(self.settings["style"], key, value)
|
||||
|
||||
def edit_surface_colour(self, value):
|
||||
self.settings["style"].SurfaceColour[1] = value[0]
|
||||
self.settings["style"].SurfaceColour[2] = value[1]
|
||||
self.settings["style"].SurfaceColour[3] = value[2]
|
||||
|
||||
def is_colour_or_factor(self, name):
|
||||
return name in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]
|
||||
|
||||
def edit_colour_or_factor(self, name, value):
|
||||
if isinstance(value, (list, tuple)):
|
||||
attribute = getattr(self.settings["style"], name)
|
||||
if not attribute or not attribute.is_a("IfcColourRgb"):
|
||||
colour = self.file.createIfcColourRgb(None, 0, 0, 0)
|
||||
setattr(self.settings["style"], name, colour)
|
||||
attribute = getattr(self.settings["style"], name)
|
||||
attribute[1] = value[0]
|
||||
attribute[2] = value[1]
|
||||
attribute[3] = value[2]
|
||||
else:
|
||||
existing_value = getattr(self.settings["style"], name)
|
||||
if existing_value and existing_value.id():
|
||||
self.file.remove(existing_value)
|
||||
setattr(self.settings["style"], name, self.file.createIfcNormalisedRatioMeasure(value))
|
||||
@@ -0,0 +1,87 @@
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
class TestEditStyleColours(test.bootstrap.IFC4):
|
||||
def test_editing_a_shading_style(self):
|
||||
colour = self.file.createIfcColourRgb(None, 0, 0, 0)
|
||||
style = self.file.createIfcSurfaceStyleShading(colour)
|
||||
ifcopenshell.api.run(
|
||||
"style.edit_surface_style",
|
||||
self.file,
|
||||
style=style,
|
||||
attributes={"SurfaceColour": [1, 1, 1], "Transparency": 0.5},
|
||||
)
|
||||
assert style.SurfaceColour == colour
|
||||
assert list(colour) == [None, 1, 1, 1]
|
||||
assert style.Transparency == 0.5
|
||||
|
||||
def test_editing_an_empty_colour_or_factor(self):
|
||||
for attribute in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]:
|
||||
style = self.file.createIfcSurfaceStyleRendering(self.file.createIfcColourRgb(None, 0, 0, 0))
|
||||
ifcopenshell.api.run("style.edit_surface_style", self.file, style=style, attributes={attribute: [1, 1, 1]})
|
||||
assert list(getattr(style, attribute)) == [None, 1, 1, 1]
|
||||
|
||||
def test_editing_an_existing_colour_to_another_colour(self):
|
||||
for attribute in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]:
|
||||
colour = self.file.createIfcColourRgb(None, 0, 0, 0)
|
||||
style = self.file.createIfcSurfaceStyleRendering(self.file.createIfcColourRgb(None, 0, 0, 0))
|
||||
setattr(style, attribute, colour)
|
||||
ifcopenshell.api.run("style.edit_surface_style", self.file, style=style, attributes={attribute: [1, 1, 1]})
|
||||
assert list(colour) == [None, 1, 1, 1]
|
||||
|
||||
def test_editing_an_existing_colour_to_a_factor(self):
|
||||
for attribute in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]:
|
||||
colour = self.file.createIfcColourRgb(None, 0, 0, 0)
|
||||
colour_id = colour.id()
|
||||
style = self.file.createIfcSurfaceStyleRendering(self.file.createIfcColourRgb(None, 0, 0, 0))
|
||||
setattr(style, attribute, colour)
|
||||
ifcopenshell.api.run("style.edit_surface_style", self.file, style=style, attributes={attribute: 0.5})
|
||||
with pytest.raises(RuntimeError):
|
||||
self.file.by_id(colour_id)
|
||||
assert getattr(style, attribute).wrappedValue == 0.5
|
||||
|
||||
def test_editing_an_existing_factor_to_another_factor(self):
|
||||
for attribute in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]:
|
||||
style = self.file.createIfcSurfaceStyleRendering(self.file.createIfcColourRgb(None, 0, 0, 0))
|
||||
setattr(style, attribute, self.file.createIfcNormalisedRatioMeasure(0.5))
|
||||
ifcopenshell.api.run("style.edit_surface_style", self.file, style=style, attributes={attribute: 0.4})
|
||||
assert getattr(style, attribute).wrappedValue == 0.4
|
||||
|
||||
def test_editing_an_existing_factor_to_a_colour(self):
|
||||
for attribute in [
|
||||
"DiffuseColour",
|
||||
"TransmissionColour",
|
||||
"DiffuseTransmissionColour",
|
||||
"ReflectionColour",
|
||||
"SpecularColour",
|
||||
]:
|
||||
style = self.file.createIfcSurfaceStyleRendering(self.file.createIfcColourRgb(None, 0, 0, 0))
|
||||
setattr(style, attribute, self.file.createIfcNormalisedRatioMeasure(0.5))
|
||||
ifcopenshell.api.run("style.edit_surface_style", self.file, style=style, attributes={attribute: [1, 1, 1]})
|
||||
assert list(getattr(style, attribute)) == [None, 1, 1, 1]
|
||||
Reference in New Issue
Block a user