diff --git a/attachments.scad b/attachments.scad index 3b3607f..a5b1eb9 100644 --- a/attachments.scad +++ b/attachments.scad @@ -116,10 +116,11 @@ function anchorpt(name, pos=[0,0,0], orient=UP, spin=0) = [name, pos, orient, sp // size = The [X,Y] size of the bottom of the cubical region. // size2 = The [X,Y] size of the top of the cubical region. // shift = The [X,Y] amount to shift the center of the top with respect to the center of the bottom. +// offset = The offset of the center of the object from the CENTER anchor. // geometry = One of "cube", "cylinder", or "sphere" to denote the overall geometry of the shape. Cones are "cylinder", and prismoids are "cube" for this purpose. Default: "cube" // anchors = A list of extra non-standard named anchors. // two_d = If true, object will be treated as 2D. -function find_anchor(anchor, h, size, size2=undef, shift=[0,0], anchors=[], geometry="cube", two_d=false) = +function find_anchor(anchor, h, size, size2=undef, shift=[0,0], offset=[0,0,0], anchors=[], geometry="cube", two_d=false) = is_string(anchor)? ( let(found = search([anchor], anchors, num_returns_per_match=1)[0]) assert(found!=[], str("Unknown anchor: ",anchor)) @@ -142,7 +143,8 @@ function find_anchor(anchor, h, size, size2=undef, shift=[0,0], anchors=[], geom phi = (anchor==UP||anchor==CENTER)? 0 : anchor==DOWN? 180 : 90 + (45 * anchor.z), theta = anchor==CENTER? 90 : atan2(anchor.y, anchor.x), vec = spherical_to_xyz(1, theta, phi), - pos = anchor==CENTER? CENTER : vmul(vec, (point3d(size)+h*UP)/2) + offset = vmul(offset,vabs(anchor)), + pos = anchor==CENTER? CENTER : vmul(vec, (point3d(size)+h*UP)/2) + offset ) [anchor, pos, vec, oang] : let ( xyal = ( geometry=="cylinder"? ( @@ -152,7 +154,8 @@ function find_anchor(anchor, h, size, size2=undef, shift=[0,0], anchors=[], geom ), botpt = point3d(vmul(size/2,xyal))+DOWN*h/2, toppt = point3d(vmul(size2/2,xyal)+shift)+UP*h/2, - pos = lerp(botpt, toppt, (anchor.z+1)/2), + offset = vmul(offset,vabs(anchor)), + pos = lerp(botpt, toppt, (anchor.z+1)/2) + offset, sidevec = two_d? point3d(xyal) : approx(norm(xyal),0)? [0,0,0] : rotate_points3d([point3d(xyal)], from=UP, to=toppt-botpt)[0], @@ -216,6 +219,7 @@ function _str_char_split(s,delim,n=0,acc=[],word="") = // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` // center = If given, overrides `anchor`. If true, centers vertically. If false, `anchor` will be set to the value in `noncentered`. // noncentered = The value to set `anchor` to if `center` == `false`. Default: `BOTTOM`. +// offset = The offset of the center of the object from the CENTER anchor. // geometry = One of "cube", "cylinder", or "sphere" to denote the overall geometry of the shape. Cones are "cylinder", and prismoids are "cube" for this purpose. Default: "cube" // anchors = A list of extra, non-standard optional anchors. // chain = If true, allow attachable children. @@ -244,6 +248,7 @@ module orient_and_anchor( spin=0, size2=undef, shift=[0,0], + offset=[0,0,0], geometry="cube", anchors=[], chain=false, @@ -252,13 +257,14 @@ module orient_and_anchor( size2 = point2d(default(size2, size)); shift = point2d(shift); anchr = is_undef(center)? anchor : (center? CENTER : noncentered); - pos = find_anchor(anchr, size.z, size, size2=size2, shift=shift, anchors=anchors, geometry=geometry, two_d=two_d)[1]; + pos = find_anchor(anchr, size.z, size, size2=size2, shift=shift, offset=offset, anchors=anchors, geometry=geometry, two_d=two_d)[1]; $parent_size = size; $parent_size2 = size2; $parent_shift = shift; $parent_geom = geometry; $parent_orient = orient; + $parent_offset = offset; $parent_2d = two_d; $parent_anchor = anchr; $parent_anchors = anchors; @@ -269,7 +275,7 @@ module orient_and_anchor( shown = !s_tags || any([for (tag=tags) in_list(tag, s_tags)]); hidden = any([for (tag=tags) in_list(tag, h_tags)]); if ($attach_to != undef) { - anch = find_anchor($attach_to, size.z, size, size2=size2, shift=shift, anchors=anchors, geometry=geometry, two_d=two_d); + anch = find_anchor($attach_to, size.z, size, size2=size2, shift=shift, offset=offset, anchors=anchors, geometry=geometry, two_d=two_d); ang = vector_angle(anch[2], DOWN); axis = vector_axis(anch[2], DOWN); ang2 = (anch[2]==UP || anch[2]==DOWN)? 0 : 180-anch[3]; @@ -326,7 +332,7 @@ module position(from, overlap=undef, norot=false) assert($parent_size != undef, "No object to attach to!"); anchors = (is_vector(from)||is_string(from))? [from] : from; for (anchr = anchors) { - anch = find_anchor(anchr, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, anchors=$parent_anchors, geometry=$parent_geom, two_d=$parent_2d); + anch = find_anchor(anchr, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, offset=$parent_offset, anchors=$parent_anchors, geometry=$parent_geom, two_d=$parent_2d); $attach_to = undef; $attach_anchor = anch; $attach_norot = true; @@ -358,7 +364,7 @@ module attach(from, to=undef, overlap=undef, norot=false) overlap = (overlap!=undef)? overlap : $overlap; anchors = (is_vector(from)||is_string(from))? [from] : from; for (anchr = anchors) { - anch = find_anchor(anchr, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, anchors=$parent_anchors, geometry=$parent_geom, two_d=$parent_2d); + anch = find_anchor(anchr, $parent_size.z, point2d($parent_size), size2=$parent_size2, shift=$parent_shift, offset=$parent_offset, anchors=$parent_anchors, geometry=$parent_geom, two_d=$parent_2d); $attach_to = to; $attach_anchor = anch; $attach_norot = norot; diff --git a/cubetruss.scad b/cubetruss.scad new file mode 100644 index 0000000..e50d5c1 --- /dev/null +++ b/cubetruss.scad @@ -0,0 +1,482 @@ +////////////////////////////////////////////////////////////////////////// +// Libfile: cubetruss.scad +// Parts for making modular open-frame cross-braced trusses and connectors. +// To use, add the following lines to the beginning of your file: +// ``` +// include +// include +// ``` +////////////////////////////////////////////////////////////////////////// + +$cubetruss_size = 30; +$cubetruss_strut_size = 3; +$cubetruss_bracing = true; +$cubetruss_clip_thickness = 1.6; + + +// Function: cubetruss_dist() +// Usage: +// cubetruss_dist(cubes, gaps, [size], [strut]); +// Description: +// Function to calculate the length of a cubetruss truss. +// Arguments: +// cubes = The number of cubes along the truss's length. +// gaps = The number of extra strut widths to add in, corresponding to each time a truss butts up against another. +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +function cubetruss_dist(cubes=0, gaps=0, size=undef, strut=undef) = + let( + size = is_undef(size)? $cubetruss_size : size, + strut = is_undef(strut)? $cubetruss_strut_size : strut + ) cubes*(size-strut)+gaps*strut; + + +// Module: cubetruss_segment() +// Usage: +// cubetruss_segment([size], [strut], [bracing]); +// Description: +// Creates a single cubetruss cube segment. +// Arguments: +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples: +// cubetruss_segment(bracing=false); +// cubetruss_segment(bracing=true); +// cubetruss_segment(strut=4); +// cubetruss_segment(size=40); +module cubetruss_segment(size=undef, strut=undef, bracing=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + bracing = is_undef(bracing)? $cubetruss_bracing : bracing; + h = size; + crossthick = strut/sqrt(2); + voffset = 0.333; + orient_and_anchor(size=[size, size, size], anchor=anchor, spin=spin, orient=orient, chain=true) { + render(convexity=10) + union() { + difference() { + // Start with a cube. + cube([size, size, h], center=true); + + cube([size-strut*2, size-strut*2, h-strut*2], center=true); + + // Hollow out octogons in X and Y axes. + zrot_copies([0,90]) { + xrot(90) zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8); + } + + // Hollow out octogon vertically. + zrot(180/8) cylinder(h=max(h,size)+1, d=(min(h,size)-2*strut)/cos(180/8), center=true, $fn=8); + } + + // Interior cross-supports + if (bracing) { + for (i = [-1,1]) { + zrot(i*45) { + difference() { + cube([crossthick, (size-strut)*sqrt(2), h], center=true); + up(i*voffset) { + yscale(1.3) { + yrot(90) { + zrot(180/6) { + cylinder(h=crossthick+1, d=(min(h,size)-2*strut)/cos(180/6)-2*voffset, center=true, $fn=6); + } + } + } + } + } + } + } + } + } + children(); + } +} + + +// Module: cubetruss_clip() +// Usage: +// cubetruss_clip(extents, [size], [strut], [clipthick]); +// Description: +// Creates a pair of clips to add onto the end of a truss. +// Arguments: +// extents = How many cubes to separate the clips by. +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// clipthick = The thickness of the clip. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples: +// cubetruss_clip(extents=2); +// cubetruss_clip(extents=1); +// cubetruss_clip(clipthick=2.5); +module cubetruss_clip(extents=1, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + cliplen = strut * 2.6; + clipheight = min(size+strut, size/3+2*strut*2.6); + clipsize = 0.5; + s = [extents*(size-strut)+strut+2*clipthick, strut*2, clipheight-2*strut]; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, chain=true) { + xflip_copy(offset=(extents*(size-strut)+strut)/2) { + difference() { + union() { + difference() { + right(clipthick/2-0.01) { + back(strut) { + difference() { + xrot(90) prismoid([clipthick, clipheight], [clipthick, clipheight-cliplen*2], h=cliplen); + right(clipthick/2) chamfer_mask_z(l=clipheight+0.1, chamfer=clipthick); + } + } + } + fwd(strut*3/2) { + cube([$slop, strut*3, size], center=true); + } + } + right($slop/2+0.01) { + fwd(strut*1.25+$slop) { + yrot(-90) prismoid([clipheight-cliplen*2, strut/2], [clipheight-cliplen*2-2*clipsize, strut/2], h=clipsize+0.01); + } + } + } + fwd(strut*1.6) { + left(clipsize) { + yscale(1.5) chamfer_mask_z(l=size+1, chamfer=clipsize+clipthick/3); + } + } + zspread(clipheight-strut) cube([clipthick*3, cliplen*2, strut], center=true); + zspread(clipheight-2*strut) right(clipthick) chamfer_mask_y(l=cliplen*2, chamfer=clipthick); + } + } + children(); + } +} + + +// Module: cubetruss_foot() +// Usage: +// cubetruss_foot(w, [size], [strut], [clipthick]); +// Description: +// Creates a foot that can be clipped onto the bottom of a truss for support. +// Arguments: +// w = The number of cube segments to span between the clips. Default: 1 +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples: +// cubetruss_foot(w=1); +// cubetruss_foot(w=3); +module cubetruss_foot(w=1, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + clipsize = 0.5; + wall_h = strut+clipthick*1.5; + cyld = (size-2*strut)/cos(180/8); + s = [w*(size-strut)+strut+2*clipthick, size-2*strut, strut+clipthick]; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, offset=[0,0,(strut-clipthick)/2], chain=true) { + down(clipthick) { + // Base + up(clipthick/2) { + cuboid([w*(size-strut)+strut+2*clipthick, size-2*strut, clipthick], chamfer=strut, edges=edges("Z")); + } + + // Walls + xspread(w*(size-strut)+strut+clipthick) { + up(clipthick-0.01) { + prismoid([clipthick, (size-4*strut)], [clipthick, size/3.5], h=wall_h, anchor=BOT); + } + } + + // Horiz Wall Clips + up(clipthick+strut+$slop*2) { + xspread(w*(size-strut)+strut) { + prismoid([clipsize*2, size/3.5], [0.1, size/3.5], h=clipsize*3, anchor=BOT); + } + } + + // Middle plugs + for (xcol = [0:w-1]) { + right((xcol-(w-1)/2)*(size-strut)) { + difference() { + // Start with octagon to fit sides. + up(clipthick-0.01) { + zrot(180/8) cylinder(h=strut, d1=cyld-4*$slop, d2=cyld-4*$slop-1, center=false, $fn=8); + } + + // Bevel to fit. + up(clipthick+strut) { + yspread(size-2*strut-4*$slop) { + chamfer_mask_x(l=size-strut, chamfer=strut*2/3); + } + } + + // Cut out X for possible top mount. + zrot_copies([-45, 45]) { + cube([size*3, strut/sqrt(2)+2*$slop, size*3], center=true); + } + } + } + } + } + children(); + } +} + + +// Module: cubetruss_joiner() +// Usage: +// cubetruss_joiner([w], [vert], [size], [strut], [clipthick]); +// Description: +// Creates a part to join two cubetruss trusses end-to-end. +// Arguments: +// w = The number of cube segments to span between the clips. Default: 1 +// vert = If true, add vertical risers to clip to the ends of the cubetruss trusses. Default: true +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples: +// cubetruss_joiner(w=1, vert=false); +// cubetruss_joiner(w=1, vert=true); +// cubetruss_joiner(w=2, vert=true, anchor=BOT); +module cubetruss_joiner(w=1, vert=true, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + clipsize = 0.5; + s = [cubetruss_dist(w,1)+2*clipthick, cubetruss_dist(2,0)-0.1, strut+clipthick]; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, offset=[0,0,-(clipthick-strut)/2], chain=true) { + down(clipthick) { + // Base + cube([w*(size-strut)+strut+2*clipthick, size, clipthick], anchor=BOT); + + xspread(w*(size-strut)+strut+clipthick) { + cube([clipthick, size, clipthick+strut*3/4], anchor=BOT); + } + + // Use feet + yspread(size) { + cubetruss_foot(w=w, size=size, strut=strut, clipthick=clipthick, anchor=BOT); + } + + if (vert) { + // Vert Walls + xspread(w*(size-strut)+strut+clipthick) { + up(clipthick-0.01) { + prismoid([clipthick, size], [clipthick, 2*strut+2*clipthick], h=size*0.6, anchor=BOT); + } + } + + // Vert Wall Clips + up(size/2) { + xflip_copy(offset=(w*(size-strut)+strut+0.02)/2) { + yflip_copy(offset=strut+$slop/2) { + yrot(-90) { + back_half() { + prismoid([size/3.5, clipthick*2], [size/3.5-4*2*clipsize, 0.1], h=2*clipsize, anchor=BOT); + } + } + } + } + } + } + } + children(); + } +} + + +// Module: cubetruss_uclip() +// Usage: +// cubetruss_uclip(dual, [size], [strut], [clipthick]); +// Description: +// Arguments: +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples: +// cubetruss_uclip(dual=false); +// cubetruss_uclip(dual=true); +module cubetruss_uclip(dual=true, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + clipsize = 0.5; + s = [(dual?2:1)*strut+2*clipthick+$slop, strut+2*clipthick, size/3.5]; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, chain=true) { + union() { + difference() { + cube(s, center=true); + back(clipthick) cube([(dual?2:1)*strut+$slop, strut+2*clipthick, size+1], center=true); + } + back((strut+$slop)/2) { + xflip_copy(offset=(dual?1:0.5)*strut+$slop/2) { + yrot(-90) { + back_half() { + prismoid([size/3.5, clipthick*1.87], [size/3.5, 0.1], h=clipsize, anchor=BOT); + } + } + } + } + } + children(); + } +} + + +// Module: cubetruss() +// Usage: +// cubetruss(extents, clips, bracing, size, strut, clipthick); +// Description: +// Creates a cubetruss truss, assembled out of one or more cubical segments. +// Arguments: +// 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. +// clips = List of vectors pointing towards the sides to add clips to. +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true) +// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples(FlatSpin): +// cubetruss(extents=3); +// cubetruss(extents=3, clips=FRONT); +// cubetruss(extents=3, clips=[FRONT,BACK]); +// cubetruss(extents=[2,3]); +// cubetruss(extents=[1,4,2]); +// cubetruss(extents=[1,4,2], bracing=false); +module cubetruss(extents=6, clips=[], bracing=undef, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + clips = is_vector(clips)? [clips] : clips; + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + bracing = is_undef(bracing)? $cubetruss_bracing : bracing; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + extents = is_vector(extents)? point3d(extents,fill=1) : [1,extents,1]; + w = extents[0]; + l = extents[1]; + h = extents[2]; + s = [cubetruss_dist(w,1), cubetruss_dist(l,1), cubetruss_dist(h,1)]; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, chain=true) { + union() { + for (zrow = [0:h-1]) { + up((zrow-(h-1)/2)*(size-strut)) { + for (xcol = [0:w-1]) { + right((xcol-(w-1)/2)*(size-strut)) { + for (ycol = [0:l-1]) { + back((ycol-(l-1)/2)*(size-strut)) { + cubetruss_segment(size=size, strut=strut, bracing=bracing); + } + } + } + } + } + } + if (clipthick > 0) { + for (vec = clips) { + exts = vabs(rot(from=FWD, to=vec, p=extents)); + rot(from=FWD,to=vec) { + for (zrow = [0:1:exts.z-1]) { + up((zrow-(exts.z-1)/2)*(size-strut)) { + fwd((exts.y*(size-strut)+strut)/2) { + cubetruss_clip(size=size, strut=strut, extents=exts.x, clipthick=clipthick); + } + } + } + } + } + } + } + children(); + } +} + + +// Module: cubetruss_corner() +// Usage: +// cubetruss_corner(h, extents, [bracing], [size], [strut], [clipthick); +// Description: +// Creates a corner cubetruss with extents jutting out in one or more directions. +// Arguments: +// h = The number of cubes high to make the base and horizontal extents. +// 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. +// size = The length of each side of the cubetruss cubes. Default: `$cubetruss_size` (usually 30) +// strut = The width of the struts on the cubetruss cubes. Default: `$cubetruss_strut_size` (usually 3) +// bracing = If true, adds internal cross-braces. Default: `$cubetruss_bracing` (usually true) +// clipthick = The thickness of the clips. Default: `$cubetruss_clip_thickness` (usually 1.6) +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#orient). Default: `UP` +// Examples(FlatSpin): +// cubetruss_corner(extents=2); +// cubetruss_corner(extents=2, h=2); +// cubetruss_corner(extents=[3,3,0,0,2]); +// cubetruss_corner(extents=[3,0,3,0,2]); +// cubetruss_corner(extents=[3,3,3,3,2]); +module cubetruss_corner(h=1, extents=[1,1,0,0,1], bracing=undef, size=undef, strut=undef, clipthick=undef, anchor=CENTER, spin=0, orient=UP) { + size = is_undef(size)? $cubetruss_size : size; + strut = is_undef(strut)? $cubetruss_strut_size : strut; + bracing = is_undef(bracing)? $cubetruss_bracing : bracing; + clipthick = is_undef(clipthick)? $cubetruss_clip_thickness : clipthick; + exts = is_vector(extents)? list_fit(extents,5,fill=0) : [extents, extents, 0, 0, extents]; + s = [cubetruss_dist(1+exts[0]+exts[2],1), cubetruss_dist(1+exts[1]+exts[3],1), cubetruss_dist(h+exts[4],1)]; + offset = [cubetruss_dist(exts[0]-exts[2],0), cubetruss_dist(exts[1]-exts[3],0), cubetruss_dist(exts[4],0)]/2; + orient_and_anchor(size=s, anchor=anchor, spin=spin, orient=orient, offset=offset, chain=true) { + union() { + for (zcol = [0:h-1]) { + up((size-strut+0.01)*zcol) { + cubetruss_segment(size=size, strut=strut, bracing=bracing); + } + } + for (dir = [0:3]) { + if (exts[dir] != undef && exts[dir] > 0) { + zrot(dir*90) { + for (zcol = [0:h-1]) { + up((size-strut+0.01)*zcol) { + for (i = [1:exts[dir]]) { + right((size-strut+0.01)*i) cubetruss_segment(size=size, strut=strut, bracing=bracing); + } + if (clipthick > 0) { + right(exts[dir]*(size-strut)+size/2) { + zrot(90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick); + } + } + } + } + } + } + } + if (exts[4] != undef && exts[4] > 0) { + for (i = [1:exts[4]]) { + up((size-strut+0.01)*(i+h-1)) cubetruss_segment(size=size, strut=strut, bracing=bracing); + } + if (clipthick > 0) { + up((exts[4]+h-1)*(size-strut)+size/2) { + xrot(-90) cubetruss_clip(size=size, strut=strut, clipthick=clipthick); + } + } + } + } + children(); + } +} + + + +// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/scripts/make_all_docs.sh b/scripts/make_all_docs.sh index b00f93a..2f4a709 100755 --- a/scripts/make_all_docs.sh +++ b/scripts/make_all_docs.sh @@ -14,7 +14,7 @@ done if [[ "$FILES" != "" ]]; then PREVIEW_LIBS="$FILES" else - PREVIEW_LIBS="common errors attachments math arrays vectors affine coords geometry triangulation quaternions strings structs hull constants edges transforms primitives shapes masks shapes2d paths beziers roundcorners walls metric_screws threading involute_gears sliders joiners linear_bearings nema_steppers wiring phillips_drive torx_drive polyhedra debug" + PREVIEW_LIBS="common errors attachments math arrays vectors affine coords geometry triangulation quaternions strings structs hull constants edges transforms primitives shapes masks shapes2d paths beziers roundcorners walls metric_screws threading involute_gears sliders joiners linear_bearings nema_steppers wiring phillips_drive torx_drive polyhedra cubetruss debug" fi dir="$(basename $PWD)"