1//////////////////////////////////////////////////////////////////////////
2// LibFile: cubetruss.scad
3// Parts for making modular open-frame cross-braced trusses and connectors.
4// Includes:
5// include <BOSL2/std.scad>
6// include <BOSL2/cubetruss.scad>
7// FileGroup: Parts
8// FileSummary: Modular open-framed trusses and joiners.
9//////////////////////////////////////////////////////////////////////////
10
11$cubetruss_size = 30;
12$cubetruss_strut_size = 3;
13$cubetruss_bracing = true;
14$cubetruss_clip_thickness = 1.6;
15
16
17// Section: Cube Trusses
18
19// Function: cubetruss_dist()
20// Usage:
21// cubetruss_dist(cubes, gaps, [size], [strut]);
22// Description:
23// Function to calculate the length of a cubetruss truss.
24// Arguments:
25// cubes = The number of cubes along the truss's length.
26// gaps = The number of extra strut widths to add in, corresponding to each time a truss butts up against another.
27// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
28// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
29// Topics: Trusses
30function cubetruss_dist(cubes=0, gaps=0, size, strut) =
31 let(
32 size = is_undef(size)? $cubetruss_size : size,
33 strut = is_undef(strut)? $cubetruss_strut_size : strut
34 ) cubes*(size-strut)+gaps*strut;
35
36
37// Module: cubetruss_segment()
38// Usage:
39// cubetruss_segment([size], [strut], [bracing]);
40// Description:
41// Creates a single cubetruss cube segment.
42// Arguments:
43// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
44// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
45// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
46// ---
47// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
48// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
49// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
50// Topics: Attachable, Trusses
51// Examples:
52// cubetruss_segment(bracing=false);
53// cubetruss_segment(bracing=true);
54// cubetruss_segment(strut=4);
55// cubetruss_segment(size=40);
56module cubetruss_segment(size, strut, bracing, anchor=CENTER, spin=0, orient=UP) {
57 size = is_undef(size)? $cubetruss_size : size;
58 strut = is_undef(strut)? $cubetruss_strut_size : strut;
59 bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
60 h = size;
61 crossthick = strut/sqrt(2);
62 voffset = 0.333;
63 attachable(anchor,spin,orient, size=[size,size,size]) {
64 render(convexity=10)
65 union() {
66 difference() {
67 // Start with a cube.
68 cube([size, size, h], center=true);
69
70 cube([size-strut*2, size-strut*2, h-strut*2], center=true);
71
72 // Hollow out octogons in X and Y axes.
73 zrot_copies([0,90]) {
74 xrot(90) zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8);
75 }
76
77 // Hollow out octogon vertically.
78 zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8);
79 }
80
81 // Interior cross-supports
82 if (bracing) {
83 for (i = [-1,1]) {
84 zrot(i*45) {
85 difference() {
86 cube([crossthick, (size-strut)*sqrt(2), h], center=true);
87 up(i*voffset) {
88 yscale(1.3) {
89 yrot(90) {
90 zrot(180/6) {
91 cylinder(h=crossthick+1, d=(min(h,size)-2*strut)/cos(180/6)-2*voffset, center=true, $fn=6);
92 }
93 }
94 }
95 }
96 }
97 }
98 }
99 }
100 }
101 children();
102 }
103}
104
105
106// Module: cubetruss_support()
107// Usage:
108// cubetruss_support([size], [strut], [extents], [anchor], [spin], [orient]) [ATTACHMENTS];
109// Description:
110// Creates a single cubetruss support.
111// Arguments:
112// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
113// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
114// extents = If given as an integer, specifies the number of vertical segments for the support. If given as a list of 3 integers, specifies the number of segments in the X, Y, and Z directions. Default: 1.
115// ---
116// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
117// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
118// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
119// Topics: Attachable, Trusses
120// Example(VPT=[0,0,0],VPD=150):
121// cubetruss_support();
122// Example(VPT=[0,0,0],VPD=200):
123// cubetruss_support(extents=2);
124// Example(VPT=[0,0,0],VPD=250):
125// cubetruss_support(extents=3);
126// Example(VPT=[0,0,0],VPD=350):
127// cubetruss_support(extents=[2,2,3]);
128// Example(VPT=[0,0,0],VPD=150):
129// cubetruss_support(strut=4);
130// Example(VPT=[0,0,0],VPD=260):
131// cubetruss_support(extents=2) show_anchors();
132module cubetruss_support(size, strut, extents=1, anchor=CENTER, spin=0, orient=UP) {
133 extents = is_num(extents)? [1,1,extents] : extents;
134 size = is_undef(size)? $cubetruss_size : size;
135 strut = is_undef(strut)? $cubetruss_strut_size : strut;
136 check =
137 assert(is_int(extents.x) && extents.x > 0)
138 assert(is_int(extents.y) && extents.y > 0)
139 assert(is_int(extents.z) && extents.z > 0);
140 w = (size-strut) * extents.x + strut;
141 l = (size-strut) * extents.y + strut;
142 h = (size-strut) * extents.z + strut;
143 attachable(anchor,spin,orient, size=[w,l,h], size2=[l,0], shift=[0,l/2], axis=DOWN) {
144 xcopies(size-strut, n=extents.x) {
145 difference() {
146 half_of(BACK/extents.y + UP/extents.z, s=size*(max(extents)+1))
147 cube([size,l,h], center=true);
148 half_of(BACK/extents.y + UP/extents.z, cp=strut, s=size*(max(extents)+1)) {
149 ycopies(size-strut, n=extents.y) {
150 zcopies(size-strut, n=extents.z) {
151 cyl(h=size+1, d=size-2*strut, circum=true, realign=true, orient=RIGHT, $fn=8);
152 cyl(h=size+1, d=size-2*strut, circum=true, realign=true, $fn=8);
153 cube(size-2*strut, center=true);
154 }
155 }
156 }
157 zcopies(size-strut, n=extents.z) {
158 cyl(h=extents.y*size+1, d=size-2*strut, circum=true, realign=true, orient=BACK, $fn=8);
159 }
160 }
161 }
162 children();
163 }
164}
165
166
167// Module: cubetruss_clip()
168// Usage:
169// cubetruss_clip(extents, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
170// Description:
171// Creates a pair of clips to add onto the end of a truss.
172// Arguments:
173// extents = How many cubes to separate the clips by.
174// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
175// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
176// clipthick = The thickness of the clip. Default: `$cubetruss_clip_thickness` (usually 1.6)
177// ---
178// $slop = allowance for printer overextrusion
179// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
180// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
181// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
182// Topics: Attachable, Trusses
183// Examples:
184// cubetruss_clip(extents=2);
185// cubetruss_clip(extents=1);
186// cubetruss_clip(clipthick=2.5);
187module cubetruss_clip(extents=1, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
188 size = is_undef(size)? $cubetruss_size : size;
189 strut = is_undef(strut)? $cubetruss_strut_size : strut;
190 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
191 cliplen = strut * 2.6;
192 clipheight = min(size+strut, size/3+2*strut*2.6);
193 clipsize = 0.5;
194 s = [extents*(size-strut)+strut+2*clipthick, strut*2, clipheight-2*strut];
195 attachable(anchor,spin,orient, size=s) {
196 xflip_copy(offset=(extents*(size-strut)+strut)/2) {
197 difference() {
198 union() {
199 difference() {
200 right(clipthick/2-0.01) {
201 back(strut) {
202 difference() {
203 xrot(90) prismoid([clipthick, clipheight], [clipthick, clipheight-cliplen*2], h=cliplen);
204 right(clipthick/2) chamfer_edge_mask(l=clipheight+0.1, chamfer=clipthick);
205 }
206 }
207 }
208 fwd(strut*3/2) {
209 cube([get_slop(), strut*3, size], center=true);
210 }
211 }
212 right(get_slop()/2+0.01) {
213 fwd(strut*1.25+get_slop()) {
214 yrot(-90) prismoid([clipheight-cliplen*2, strut/2], [clipheight-cliplen*2-2*clipsize, strut/2], h=clipsize+0.01);
215 }
216 }
217 }
218 fwd(strut*1.6) {
219 left(clipsize) {
220 yscale(1.5) chamfer_edge_mask(l=size+1, chamfer=clipsize+clipthick/3);
221 }
222 }
223 zcopies(clipheight-strut) cube([clipthick*3, cliplen*2, strut], center=true);
224 zcopies(clipheight-2*strut) right(clipthick) chamfer_edge_mask(l=cliplen*2, chamfer=clipthick, orient=BACK);
225 }
226 }
227 children();
228 }
229}
230
231
232// Module: cubetruss_foot()
233// Usage:
234// cubetruss_foot(w, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
235// Description:
236// Creates a foot that can be clipped onto the bottom of a truss for support.
237// Arguments:
238// w = The number of cube segments to span between the clips. Default: 1
239// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
240// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
241// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
242// ---
243// $slop = make fit looser to allow for printer overextrusion
244// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
245// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
246// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
247// Topics: Attachable, Trusses
248// Examples:
249// cubetruss_foot(w=1);
250// cubetruss_foot(w=3);
251module cubetruss_foot(w=1, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
252 size = is_undef(size)? $cubetruss_size : size;
253 strut = is_undef(strut)? $cubetruss_strut_size : strut;
254 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
255 clipsize = 0.5;
256 wall_h = strut+clipthick*1.5;
257 cyld = (size-2*strut)/cos(180/8);
258 s = [w*(size-strut)+strut+2*clipthick, size-2*strut, strut+clipthick];
259 attachable(anchor,spin,orient, size=s, offset=[0,0,(strut-clipthick)/2]) {
260 down(clipthick) {
261 // Base
262 up(clipthick/2) {
263 cuboid([w*(size-strut)+strut+2*clipthick, size-2*strut, clipthick], chamfer=strut, edges="Z");
264 }
265
266 // Walls
267 xcopies(w*(size-strut)+strut+clipthick) {
268 up(clipthick-0.01) {
269 prismoid([clipthick, (size-4*strut)], [clipthick, size/3.5], h=wall_h, anchor=BOT);
270 }
271 }
272
273 // Horiz Wall Clips
274 up(clipthick+strut+get_slop()*2) {
275 xcopies(w*(size-strut)+strut) {
276 prismoid([clipsize*2, size/3.5], [0.1, size/3.5], h=clipsize*3, anchor=BOT);
277 }
278 }
279
280 // Middle plugs
281 for (xcol = [0:w-1]) {
282 right((xcol-(w-1)/2)*(size-strut)) {
283 difference() {
284 // Start with octagon to fit sides.
285 up(clipthick-0.01) {
286 zrot(180/8) cylinder(h=strut, d1=cyld-4*get_slop(), d2=cyld-4*get_slop()-1, center=false, $fn=8);
287 }
288
289 // Bevel to fit.
290 up(clipthick+strut) {
291 ycopies(size-2*strut-4*get_slop()) {
292 chamfer_edge_mask(l=size-strut, chamfer=strut*2/3, orient=RIGHT);
293 }
294 }
295
296 // Cut out X for possible top mount.
297 zrot_copies([-45, 45]) {
298 cube([size*3, strut/sqrt(2)+2*get_slop(), size*3], center=true);
299 }
300 }
301 }
302 }
303 }
304 children();
305 }
306}
307
308
309// Module: cubetruss_joiner()
310// Usage:
311// cubetruss_joiner([w], [vert], [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
312// Description:
313// Creates a part to join two cubetruss trusses end-to-end.
314// Arguments:
315// w = The number of cube segments to span between the clips. Default: 1
316// vert = If true, add vertical risers to clip to the ends of the cubetruss trusses. Default: true
317// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
318// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
319// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
320// ---
321// $slop = Make fit looser by this amount to allow for printer overextrusion
322// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
323// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
324// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
325// Topics: Attachable, Trusses
326// Examples:
327// cubetruss_joiner(w=1, vert=false);
328// cubetruss_joiner(w=1, vert=true);
329// cubetruss_joiner(w=2, vert=true, anchor=BOT);
330module cubetruss_joiner(w=1, vert=true, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
331 size = is_undef(size)? $cubetruss_size : size;
332 strut = is_undef(strut)? $cubetruss_strut_size : strut;
333 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
334 clipsize = 0.5;
335 s = [cubetruss_dist(w,1)+2*clipthick, cubetruss_dist(2,0)-0.1, strut+clipthick];
336 attachable(anchor,spin,orient, size=s, offset=[0,0,-(clipthick-strut)/2]) {
337 down(clipthick) {
338 // Base
339 cube([w*(size-strut)+strut+2*clipthick, size, clipthick], anchor=BOT);
340
341 xcopies(w*(size-strut)+strut+clipthick) {
342 cube([clipthick, size, clipthick+strut*3/4], anchor=BOT);
343 }
344
345 // Use feet
346 ycopies(size) {
347 cubetruss_foot(w=w, size=size, strut=strut, clipthick=clipthick, anchor=BOT);
348 }
349
350 if (vert) {
351 // Vert Walls
352 xcopies(w*(size-strut)+strut+clipthick) {
353 up(clipthick-0.01) {
354 prismoid([clipthick, size], [clipthick, 2*strut+2*clipthick], h=size*0.6, anchor=BOT);
355 }
356 }
357
358 // Vert Wall Clips
359 up(size/2) {
360 xflip_copy(offset=(w*(size-strut)+strut+0.02)/2) {
361 yflip_copy(offset=strut+get_slop()/2) {
362 yrot(-90) {
363 back_half() {
364 prismoid([size/3.5, clipthick*2], [size/3.5-4*2*clipsize, 0.1], h=2*clipsize, anchor=BOT);
365 }
366 }
367 }
368 }
369 }
370 }
371 }
372 children();
373 }
374}
375
376
377// Module: cubetruss_uclip()
378// Usage:
379// cubetruss_uclip(dual, [size], [strut], [clipthick], [$slop=], [anchor=], [spin=], [orient=]) [ATTACHMENTS];
380// Description:
381// Creates a small clip that can snap around one or two adjacent struts.
382// Arguments:
383// dual = If true, create a clip to clip around two adjacent struts. If false, just fit around one strut. Default: true
384// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
385// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
386// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
387// ---
388// $slop = Make fit looser by this amount
389// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
390// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
391// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
392// Topics: Attachable, Trusses
393// Examples:
394// cubetruss_uclip(dual=false);
395// cubetruss_uclip(dual=true);
396module cubetruss_uclip(dual=true, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
397 size = is_undef(size)? $cubetruss_size : size;
398 strut = is_undef(strut)? $cubetruss_strut_size : strut;
399 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
400 clipsize = 0.5;
401 s = [(dual?2:1)*strut+2*clipthick+get_slop(), strut+2*clipthick, size/3.5];
402 attachable(anchor,spin,orient, size=s) {
403 union() {
404 difference() {
405 cube(s, center=true);
406 back(clipthick) cube([(dual?2:1)*strut+get_slop(), strut+2*clipthick, size+1], center=true);
407 }
408 back((strut+get_slop())/2) {
409 xflip_copy(offset=(dual?1:0.5)*strut+get_slop()/2) {
410 yrot(-90) {
411 back_half() {
412 prismoid([size/3.5, clipthick*1.87], [size/3.5, 0.1], h=clipsize, anchor=BOT);
413 }
414 }
415 }
416 }
417 }
418 children();
419 }
420}
421
422
423// Module: cubetruss()
424// Usage:
425// cubetruss(extents, [clips], [bracing], [size], [strut], [clipthick]);
426// Description:
427// Creates a cubetruss truss, assembled out of one or more cubical segments.
428// Arguments:
429// extents = The number of cubes in length to make the truss. If given as a [X,Y,Z] vector, specifies the number of cubes in each dimension.
430// clips = List of vectors pointing towards the sides to add clips to.
431// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
432// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
433// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
434// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
435// ---
436// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
437// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
438// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
439// Topics: Attachable, Trusses
440// Examples:
441// cubetruss(extents=3);
442// cubetruss(extents=3, clips=FRONT);
443// cubetruss(extents=3, clips=[FRONT,BACK]);
444// cubetruss(extents=[2,3]);
445// cubetruss(extents=[1,4,2]);
446// cubetruss(extents=[1,4,2], bracing=false);
447module cubetruss(extents=6, clips=[], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
448 clips = is_vector(clips)? [clips] : clips;
449 size = is_undef(size)? $cubetruss_size : size;
450 strut = is_undef(strut)? $cubetruss_strut_size : strut;
451 bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
452 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
453 extents = is_vector(extents)? point3d(extents,fill=1) : [1,extents,1];
454 w = extents[0];
455 l = extents[1];
456 h = extents[2];
457 s = [cubetruss_dist(w,1), cubetruss_dist(l,1), cubetruss_dist(h,1)];
458 attachable(anchor,spin,orient, size=s) {
459 union() {
460 for (zrow = [0:h-1]) {
461 up((zrow-(h-1)/2)*(size-strut)) {
462 for (xcol = [0:w-1]) {
463 right((xcol-(w-1)/2)*(size-strut)) {
464 for (ycol = [0:l-1]) {
465 back((ycol-(l-1)/2)*(size-strut)) {
466 cubetruss_segment(size=size, strut=strut, bracing=bracing);
467 }
468 }
469 }
470 }
471 }
472 }
473 if (clipthick > 0) {
474 for (vec = clips) {
475 exts = v_abs(rot(from=FWD, to=vec, p=extents));
476 rot(from=FWD,to=vec) {
477 for (zrow = [0:1:exts.z-1]) {
478 up((zrow-(exts.z-1)/2)*(size-strut)) {
479 fwd((exts.y*(size-strut)+strut)/2) {
480 cubetruss_clip(size=size, strut=strut, extents=exts.x, clipthick=clipthick);
481 }
482 }
483 }
484 }
485 }
486 }
487 }
488 children();
489 }
490}
491
492
493// Module: cubetruss_corner()
494// Usage:
495// cubetruss_corner(h, extents, [bracing], [size], [strut], [clipthick]);
496// Description:
497// Creates a corner cubetruss with extents jutting out in one or more directions.
498// Arguments:
499// h = The number of cubes high to make the base and horizontal extents.
500// extents = The number of cubes to extend beyond the corner. If given as a vector of cube counts, gives the number of cubes to extend right, back, left, front, and up in order. If the vector is shorter than length 5 the extra cube counts are taken to be zero.
501// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30)
502// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3)
503// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true)
504// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6)
505// ---
506// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
507// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
508// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
509// Topics: Attachable, Trusses
510// Examples:
511// cubetruss_corner(extents=2);
512// cubetruss_corner(extents=2, h=2);
513// cubetruss_corner(extents=[3,3,0,0,2]);
514// cubetruss_corner(extents=[3,0,3,0,2]);
515// cubetruss_corner(extents=[3,3,3,3,2]);
516module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing, size, strut, clipthick, anchor=CENTER, spin=0, orient=UP) {
517 size = is_undef(size)? $cubetruss_size : size;
518 strut = is_undef(strut)? $cubetruss_strut_size : strut;
519 bracing = is_undef(bracing)? $cubetruss_bracing : bracing;
520 clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick;
521 exts = is_vector(extents)? list_pad(extents,5,fill=0) : [extents, extents, 0, 0, extents];
522 dummy = assert(len(exts)==5, "Input extents must be a scalar or vector with length 5 or less.");
523 s = [cubetruss_dist(exts[0]+1+exts[2],1), cubetruss_dist(exts[1]+1+exts[3],1), cubetruss_dist(h+exts[4],1)];
524 offset = [cubetruss_dist(exts[0]-exts[2],0), cubetruss_dist(exts[1]-exts[3],0), cubetruss_dist(h+exts[4]-1,0)]/2;
525 attachable(anchor,spin,orient, size=s, offset=offset) {
526 union() {
527 for (zcol = [0:h-1]) {
528 up((size-strut)*zcol) {
529 cubetruss_segment(size=size, strut=strut, bracing=bracing);
530 }
531 }
532 for (dir = [0:3]) {
533 if (exts[dir] != undef && exts[dir] > 0) {
534 zrot(dir*90) {
535 for (zcol = [0:h-1]) {
536 up((size-strut+0.01)*zcol) {
537 for (i = [1:exts[dir]]) {
538 right((size-strut+0.01)*i) cubetruss_segment(size=size, strut=strut, bracing=bracing);
539 }
540 if (clipthick > 0) {
541 right(exts[dir]*(size-strut)+size/2) {
542 zrot(90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick);
543 }
544 }
545 }
546 }
547 }
548 }
549 }
550 if (exts[4] != undef && exts[4] > 0) {
551 for (i = [1:exts[4]]) {
552 up((size-strut+0.01)*(i+h-1)) cubetruss_segment(size=size, strut=strut, bracing=bracing);
553 }
554 if (clipthick > 0) {
555 up((exts[4]+h-1)*(size-strut)+size/2) {
556 xrot(-90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick);
557 }
558 }
559 }
560 }
561 children();
562 }
563}
564
565
566
567// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap