-
Notifications
You must be signed in to change notification settings - Fork 116
/
color.scad
307 lines (284 loc) · 11.1 KB
/
color.scad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
//////////////////////////////////////////////////////////////////////
// LibFile: color.scad
// HSV and HSL conversion, rainbow() module for coloring multiple objects.
// The recolor() and color_this() modules allow you to change the color
// of previously colored attachable objects.
// Includes:
// include <BOSL2/std.scad>
// FileGroup: Basic Modeling
// FileSummary: HSV and HSL conversion, color multiple objects, change color of objects
// FileFootnotes: STD=Included in std.scad
//////////////////////////////////////////////////////////////////////
use <builtins.scad>
// Section: Coloring Objects
// Module: recolor()
// Synopsis: Sets the color for attachable children and their descendants.
// SynTags: Trans
// Topics: Attachments
// See Also: color_this(), hsl(), hsv()
// Usage:
// recolor([c]) CHILDREN;
// Description:
// Sets the color for attachable children and their descendants, down until another {{recolor()}}
// or {{color_this()}}. This only works with attachables and you cannot have any color() modules
// above it in any parents, only other {{recolor()}} or {{color_this()}} modules. This works by
// setting the special `$color` variable, which attachable objects make use of to set the color.
// Arguments:
// c = Color name or RGBA vector. Default: The default color in your color scheme.
// Side Effects:
// Changes the value of `$color`.
// Sets the color of child attachments.
// Example:
// cuboid([10,10,5])
// recolor("green")attach(TOP,BOT) cuboid([9,9,4.5])
// attach(TOP,BOT) cuboid([8,8,4])
// recolor("purple") attach(TOP,BOT) cuboid([7,7,3.5])
// attach(TOP,BOT) cuboid([6,6,3])
// recolor("cyan")attach(TOP,BOT) cuboid([5,5,2.5])
// attach(TOP,BOT) cuboid([4,4,2]);
module recolor(c="default")
{
req_children($children);
$color=c;
children();
}
// Module: color_this()
// Synopsis: Sets the color for children at the current level only.
// SynTags: Trans
// Topics: Attachments
// See Also: recolor(), hsl(), hsv()
// Usage:
// color_this([c]) CHILDREN;
// Description:
// Sets the color for children at one level, reverting to the previous color for further descendants.
// This works only with attachables and you cannot have any color() modules above it in any parents,
// only recolor() or other color_this() modules. This works using the `$color` and `$save_color` variables,
// which attachable objects make use of to set the color.
// Arguments:
// c = Color name or RGBA vector. Default: the default color in your color scheme
// Side Effects:
// Changes the value of `$color` and `$save_color`.
// Sets the color of child attachments.
// Example:
// cuboid([10,10,5])
// color_this("green")attach(TOP,BOT) cuboid([9,9,4.5])
// attach(TOP,BOT) cuboid([8,8,4])
// color_this("purple") attach(TOP,BOT) cuboid([7,7,3.5])
// attach(TOP,BOT) cuboid([6,6,3])
// color_this("cyan")attach(TOP,BOT) cuboid([5,5,2.5])
// attach(TOP,BOT) cuboid([4,4,2]);
module color_this(c="default")
{
req_children($children);
$save_color=default($color,"default");
$color=c;
children();
}
// Module: rainbow()
// Synopsis: Iterates through a list, displaying children in different colors.
// SynTags: Trans
// Topics: List Handling
// See Also: hsl(), hsv()
// Usage:
// rainbow(list,[stride],[maxhues],[shuffle],[seed]) CHILDREN;
// Description:
// Iterates the list, displaying children in different colors for each list item. The color
// is set using the color() module, so this module is not compatible with {{recolor()}} or
// {{color_this()}}. This is useful for debugging regions or lists of paths.
// Arguments:
// list = The list of items to iterate through.
// stride = Consecutive colors stride around the color wheel divided into this many parts.
// maxhues = max number of hues to use (to prevent lots of indistinguishable hues)
// shuffle = if true then shuffle the hues in a random order. Default: false
// seed = seed to use for shuffle
// Side Effects:
// Sets the color to progressive values along the ROYGBIV spectrum for each item.
// Sets `$idx` to the index of the current item in `list` that we want to show.
// Sets `$item` to the current item in `list` that we want to show.
// Example(2D):
// rainbow(["Foo","Bar","Baz"]) fwd($idx*10) text(text=$item,size=8,halign="center",valign="center");
// Example(2D):
// rgn = [circle(d=45,$fn=3), circle(d=75,$fn=4), circle(d=50)];
// rainbow(rgn) stroke($item, closed=true);
module rainbow(list, stride=1, maxhues, shuffle=false, seed)
{
req_children($children);
ll = len(list);
maxhues = first_defined([maxhues,ll]);
huestep = 360 / maxhues;
huelist = [for (i=[0:1:ll-1]) posmod(i*huestep+i*360/stride,360)];
hues = shuffle ? shuffle(huelist, seed=seed) : huelist;
for($idx=idx(list)) {
$item = list[$idx];
hsv(h=hues[$idx]) children();
}
}
// Module: color_overlaps()
// Synopsis: Shows ghostly children, with overlaps highlighted in color.
// SynTags: Trans
// Topics: Debugging
// See Also: rainbow(), debug_vnf()
// Usage:
// color_overlaps([color]) CHILDREN;
// Description:
// Displays the given children in ghostly transparent gray, while the places where the
// they overlap are highlighted with the given color.
// Arguments:
// color = The color to highlight overlaps with. Default: "red"
// Example(2D): 2D Overlaps
// color_overlaps() {
// circle(d=50);
// left(20) circle(d=50);
// right(20) circle(d=50);
// }
// Example(): 3D Overlaps
// color_overlaps() {
// cuboid(50);
// left(30) sphere(d=50);
// right(30) sphere(d=50);
// xcyl(d=10,l=120);
// }
module color_overlaps(color="red") {
pairs = [for (i=[0:1:$children-1], j=[i+1:1:$children-1]) [i,j]];
for (p = pairs) {
color(color) {
intersection() {
children(p.x);
children(p.y);
}
}
}
%children();
}
// Module: ghost()
// Synopsis: Sets transparency for attachable children and their descendents.
// SynTags: Trans
// Topics: Attachments
// See Also: ghost_this(), recolor(), color_this()
// Usage:
// ghost([ghost]) CHILDREN;
// Description:
// Sets the transparency for the attachable children and their descendents until another {{ghost()}} or {{ghost_this()}}.
// By default, turns transparency on. Give the `false` parameter to disable transparency.
// Do not mix this with user supplied `%` operators anywhere in the geometry tree.
// Arguments:
// ghost = If true set the descendents to be transparent; if false, disable transparency. Default: true
// Example(3D):
// ghost() cuboid(10)
// ghost(false) cuboid(5);
function ghost(ghost) = no_function("ghost");
module ghost(ghost=true)
{
$ghost=ghost;
children();
}
// Module: ghost_this()
// Synopsis: Makes the children at a single level transparent.
// SynTags: Trans
// Topics: Attachments
// See Also: ghost(), recolor(), color_this()
// Usage:
// ghost_this() CHILDREN;
// Description:
// Makes the children transparent for one level, reverting to the previous transparency state for further descendents.
// This works only with attachables and you cannot give the `%` operator anywhere in the geometry tree.
// Example(3D):
// ghost_this() cuboid(10)
// cuboid(5);
function ghost_this() = no_function("ghost_this");
module ghost_this()
{
$ghost_this=true;
children();
}
// Section: Colorspace Conversion
// Function&Module: hsl()
// Synopsis: Sets the color of children to a specified hue, saturation, lightness and optional alpha channel value.
// SynTags: Trans
// See Also: hsv(), recolor(), color_this()
// Topics: Colors, Colorspace
// Usage:
// hsl(h,[s],[l],[a]) CHILDREN;
// rgb = hsl(h,[s],[l],[a]);
// Description:
// When called as a function, returns the `[R,G,B]` color for the given hue `h`, saturation `s`, and
// lightness `l` from the HSL colorspace. If you supply the `a` value then you'll get a length 4
// list `[R,G,B,A]`. When called as a module, sets the color using the color() module to the given
// hue `h`, saturation `s`, and lightness `l` from the HSL colorspace.
// Arguments:
// h = The hue, given as a value between 0 and 360. 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
// s = The saturation, given as a value between 0 and 1. 0 = grayscale, 1 = vivid colors. Default: 1
// l = The lightness, between 0 and 1. 0 = black, 0.5 = bright colors, 1 = white. Default: 0.5
// a = Specifies the alpha channel as a value between 0 and 1. 0 = fully transparent, 1=opaque. Default: 1
// Side Effects:
// When called as a module, sets the color of all children.
// Example:
// hsl(h=120,s=1,l=0.5) sphere(d=60);
// Example:
// rgb = hsl(h=270,s=0.75,l=0.6);
// color(rgb) cube(60, center=true);
function hsl(h,s=1,l=0.5,a) =
let(
h=posmod(h,360)
) [
for (n=[0,8,4])
let(k=(n+h/30)%12)
l - s*min(l,1-l)*max(min(k-3,9-k,1),-1),
if (is_def(a)) a
];
module hsl(h,s=1,l=0.5,a=1)
{
req_children($children);
color(hsl(h,s,l),a) children();
}
// Function&Module: hsv()
// Synopsis: Sets the color of children to a hue, saturation, value and optional alpha channel value.
// SynTags: Trans
// See Also: hsl(), recolor(), color_this()
// Topics: Colors, Colorspace
// Usage:
// hsv(h,[s],[v],[a]) CHILDREN;
// rgb = hsv(h,[s],[v],[a]);
// Description:
// When called as a function, returns the `[R,G,B]` color for the given hue `h`, saturation `s`, and
// value `v` from the HSV colorspace. If you supply the `a` value then you'll get a length 4 list
// `[R,G,B,A]`. When called as a module, sets the color using the color() module to the given hue
// `h`, saturation `s`, and value `v` from the HSV colorspace.
// Arguments:
// h = The hue, given as a value between 0 and 360. 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
// s = The saturation, given as a value between 0 and 1. 0 = grayscale, 1 = vivid colors. Default: 1
// v = The value, between 0 and 1. 0 = darkest black, 1 = bright. Default: 1
// a = Specifies the alpha channel as a value between 0 and 1. 0 = fully transparent, 1=opaque. Default: 1
// Side Effects:
// When called as a module, sets the color of all children.
// Example:
// hsv(h=120,s=1,v=1) sphere(d=60);
// Example:
// rgb = hsv(h=270,s=0.75,v=0.9);
// color(rgb) cube(60, center=true);
function hsv(h,s=1,v=1,a) =
assert(s>=0 && s<=1)
assert(v>=0 && v<=1)
assert(is_undef(a) || a>=0 && a<=1)
let(
h = posmod(h,360),
c = v * s,
hprime = h/60,
x = c * (1- abs(hprime % 2 - 1)),
rgbprime = hprime <=1 ? [c,x,0]
: hprime <=2 ? [x,c,0]
: hprime <=3 ? [0,c,x]
: hprime <=4 ? [0,x,c]
: hprime <=5 ? [x,0,c]
: hprime <=6 ? [c,0,x]
: [0,0,0],
m=v-c
)
is_def(a) ? point4d(add_scalar(rgbprime,m),a)
: add_scalar(rgbprime,m);
module hsv(h,s=1,v=1,a=1)
{
req_children($children);
color(hsv(h,s,v),a) children();
}
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap