material_shading.py
Python script, ASCII text executable
1
import inkex
2
import inkex.transforms
3
import inkex.colors
4
import io
5
import colorsys
6
7
def get_fill(elem):
8
if elem.get("fill"):
9
return elem.get("fill")
10
if elem.style.get("fill"):
11
return elem.style["fill"]
12
return "#000000"
13
14
15
def get_bottom_edge_colour(elem):
16
fill = inkex.colors.Color(get_fill(elem))
17
h, s, l = fill.to("hsl").hue / 255 * 360, fill.to("hsl").saturation / 255 * 100, fill.to("hsl").lightness / 255 * 100
18
if s < 10:
19
if l > 80:
20
return "#212121", 0.1
21
return "#212121", 0.2
22
if 203 < h <= 315:
23
return "#1A237E", 0.2
24
if 65 < h <= 203:
25
return "#263238", 0.2
26
if 25 < h <= 65:
27
return "#BF360C", 0.2
28
return "#3E2723", 0.2
29
30
31
def get_top_edge_colour(elem):
32
fill = inkex.colors.Color(get_fill(elem))
33
h, s, l = fill.to("hsl").hue / 255 * 360, fill.to("hsl").saturation / 255 * 100, fill.to("hsl").lightness / 255 * 100
34
if s < 10 and l > 80:
35
return "#ffffff", 0.4
36
return "#ffffff", 0.2
37
38
39
class MaterialShading(inkex.EffectExtension):
40
def effect(self):
41
selected = list(self.svg.selection)
42
43
dy = self.svg.unittouu("1px")
44
45
if not selected:
46
inkex.errormsg("Select one or more paths or path-convertible objects first!")
47
return
48
49
ids_to_difference = []
50
for elem in selected:
51
shifted_up = elem.copy()
52
parent = elem.getparent()
53
index = parent.index(elem)
54
55
shifted_up = elem.copy()
56
shifted_up.transform = elem.transform @ inkex.transforms.Transform(f"translate(0, {-dy})")
57
parent.insert(index + 1, shifted_up)
58
shifted_down = elem.copy()
59
shifted_down.transform = elem.transform @ inkex.transforms.Transform(f"translate(0, {dy})")
60
parent.insert(index + 1, shifted_down)
61
copy_1 = elem.copy()
62
copy_1.style["fill"], copy_1.style["fill-opacity"] = get_bottom_edge_colour(elem)
63
parent.insert(index + 1, copy_1)
64
copy_2 = elem.copy()
65
copy_2.style["fill"], copy_2.style["fill-opacity"] = get_top_edge_colour(elem)
66
parent.insert(index + 1, copy_2)
67
ids_to_difference.append(",".join((copy_1.get_id(), shifted_up.get_id())))
68
ids_to_difference.append(",".join((copy_2.get_id(), shifted_down.get_id())))
69
70
svg_bytes = inkex.command.inkscape_command(
71
self.document,
72
actions="".join(f"select-by-id:{ids}; path-difference; select-clear; " for ids in ids_to_difference).removesuffix("; ")
73
)
74
75
self.document = inkex.load_svg(svg_bytes)
76
77
78
if __name__ == "__main__":
79
MaterialShading().run()
80