There are a lot of nested objects to go through to get to the colours of objects in IFC, and there are two paths to follow:
print("Colour in material:")
print(rebars[1].HasAssociations[0].RelatingMaterial.HasRepresentation[0].Representations[0].Items[0].Styles[0].Styles[0].Styles[0].SurfaceColour)
print("Colour in representation:")
print(rebars[1].Representation.Representations[0].Items[0].StyledByItem[0].Styles[0].Styles[0].Styles[0].SurfaceColour)
Here is a script I made to set colors to rebars based on different values of an attribute. I need one IfcStyledItem
per Rebar instance, but do I need one new of the three styles (IfcSurfaceStyleRendering, IfcSurfaceStyle, IfcPresentationStyleAssignment
) for each color, or could I reuse them?
import ifcopenshell
f = ifcopenshell.open(r"Rebar-diameter.ifc")
rebars = f.by_type('IfcReinforcingBar')
colours = (
("darkslategray", "#2f4f4f"),
("darkolivegreen", "#556b2f"),
("saddlebrown", "#8b4513"),
("olivedrab", "#6b8e23"),
("seagreen", "#2e8b57"),
("maroon", "#800000"),
("midnightblue", "#191970"),
("slategray", "#708090"),
("green", "#008000"),
("peru", "#cd853f"),
("steelblue", "#4682b4"),
("navy", "#000080"),
("yellowgreen", "#9acd32"),
("lightseagreen", "#20b2aa"),
("indianred", "#cd5c5c"),
("limegreen", "#32cd32"),
("goldenrod", "#daa520"),
("darkseagreen", "#8fbc8f"),
("purple", "#800080"),
("darkorchid", "#9932cc"),
("red", "#ff0000"),
("darkorange", "#ff8c00"),
("gold", "#ffd700"),
("yellow", "#ffff00"),
("mediumblue", "#0000cd"),
("burlywood", "#deb887"),
("lime", "#00ff00"),
("springgreen", "#00ff7f"),
("royalblue", "#4169e1"),
("darksalmon", "#e9967a"),
("crimson", "#dc143c"),
("aqua", "#00ffff"),
("deepskyblue", "#00bfff"),
("blue", "#0000ff"),
("purple3", "#a020f0"),
("greenyellow", "#adff2f"),
("tomato", "#ff6347"),
("fuchsia", "#ff00ff"),
("palevioletred", "#db7093"),
("khaki", "#f0e68c"),
("cornflower", "#6495ed"),
("plum", "#dda0dd"),
("skyblue", "#87ceeb"),
("deeppink", "#ff1493"),
("violet", "#ee82ee"),
("palegreen", "#98fb98"),
("aquamarine", "#7fffd4"),
("hotpink", "#ff69b4"),
("pink", "#ffc0cb")
)
import itertools, math
rebar_groups = []
for k,g in itertools.groupby(rebars, lambda x: x.NominalDiameter):
rebar_groups.append(list(g))
num_groups = len(rebar_groups)
colours = colours*math.ceil(len(rebar_groups)/len(colours))
colours = colours[:len(rebar_groups)]
rgb_colours = list()
for hex in colours:
h = hex[1].lstrip('#')
rgb = tuple(int(h[i:i+2], 16)/255 for i in (0, 2, 4))
rgb_colours.append(f.createIfcColourRgb(hex[0], rgb[0], rgb[1], rgb[2]))
i = 0
for i, group in enumerate(rebar_groups):
colour = rgb_colours[i]
surfaceStyleRendering = f.createIfcSurfaceStyleRendering()
surfaceStyleRendering.SurfaceColour = colour
surfaceStyle = f.createIfcSurfaceStyle(colour.Name, "BOTH",(surfaceStyleRendering,))
presStyleAssign = f.createIfcPresentationStyleAssignment((surfaceStyle,))
i=i+1
for rebar in group:
item = rebar.Representation.Representations[0].Items[0]
f.createIfcStyledItem(item, (presStyleAssign,), colour.Name)
f.write(r"Rebar-diameter-modiefied.ifc")