diff --git a/masks3d.scad b/masks3d.scad index 0774217..aebbf60 100644 --- a/masks3d.scad +++ b/masks3d.scad @@ -249,20 +249,6 @@ module chamfer_cylinder_mask(r, chamfer, d, ang=45, from_end=false, anchor=CENTE // rounding_edge_mask(l=p.z, r=25); // } // } -// Example: Acute angle -// ang=60; -// difference() { -// pie_slice(ang=ang, h=50, r=100); -// zflip_copy(z=25) -// #rounding_corner_mask(r=20, ang=ang); -// } -// Example: Obtuse angle -// ang=120; -// difference() { -// pie_slice(ang=ang, h=50, r=30); -// zflip_copy(z=25) -// #rounding_corner_mask(r=20, ang=ang); -// } function rounding_edge_mask(l, r, ang=90, r1, r2, d, d1, d2, excess=0.1, anchor=CENTER, spin=0, orient=UP, h,height,length) = no_function("rounding_edge_mask"); module rounding_edge_mask(l, r, ang=90, r1, r2, excess=0.01, d1, d2,d,r,length, h, height, anchor=CENTER, spin=0, orient=UP, @@ -274,7 +260,7 @@ module rounding_edge_mask(l, r, ang=90, r1, r2, excess=0.01, d1, d2,d,r,length, dummy = assert(all_nonnegative([r1,r2]), "radius/diameter value(s) must be nonnegative") assert(all_positive([length]), "length/l/h/height must be a positive value") assert(is_finite(ang) && ang>0 && ang<180, "ang must be a number between 0 and 180"); - steps = ceil(segs(r)*(180-ang)/360); + steps = ceil(segs(max(r1,r2))*(180-ang)/360); function make_path(r) = let( arc = r==0 ? repeat([0,0],steps+1) @@ -383,8 +369,21 @@ module rounding_edge_mask(l, r, ang=90, r1, r2, excess=0.01, d1, d2,d,r,length, // corner_mask(TOP) // #rounding_corner_mask(r=20); // } -// Example: Acute angle mask -// +// Example(VPR=[71.8,0,345.8],VPT=[57.0174,43.8496,24.5863],VPD=263.435,NoScales): Acute angle +// ang=60; +// difference() { +// pie_slice(ang=ang, h=50, r=100); +// zflip_copy(z=25) +// #rounding_corner_mask(r=20, ang=ang); +// } +// Example(VPR=[62.7,0,5.4],VPT=[6.9671,22.7592,20.7513],VPD=192.044): Obtuse angle +// ang=120; +// difference() { +// pie_slice(ang=ang, h=50, r=30); +// zflip_copy(z=25) +// #rounding_corner_mask(r=20, ang=ang); +// } + function rounding_corner_mask(r, ang, d, style="octa", excess=0.1, anchor=CENTER, spin=0, orient=UP) = no_function("rounding_corner_mask"); module rounding_corner_mask(r, ang=90, d, style="octa", excess=0.1, anchor=CENTER, spin=0, orient=UP) { diff --git a/walls.scad b/walls.scad index a188a9c..ca0a467 100644 --- a/walls.scad +++ b/walls.scad @@ -16,7 +16,7 @@ // Synopsis: Makes an open cross-braced rectangular wall. // SynTags: Geom // Topics: FDM Optimized, Walls -// See Also: sparse_wall(), corrugated_wall(), thinning_wall(), thinning_triangle(), narrowing_strut() +// See Also: corrugated_wall(), thinning_wall(), thinning_triangle(), narrowing_strut() // // Usage: // sparse_wall(h, l, thick, [maxang=], [strut=], [max_bridge=]) [ATTACHMENTS]; @@ -30,9 +30,9 @@ // l = length of strut wall. // thick = thickness of strut wall. // --- -// maxang = maximum overhang angle of cross-braces. -// strut = the width of the cross-braces. -// max_bridge = maximum bridging distance between cross-braces. +// maxang = maximum overhang angle of cross-braces, measured down from vertical. Default: 30 +// strut = the width of the cross-braces. Default: 5 +// max_bridge = maximum bridging distance between cross-braces. Default: 20 // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` @@ -87,6 +87,75 @@ module sparse_wall(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, anch } +// Module: sparse_cuboid() +// Synopsis: Makes an open cross-braced cuboid +// SynTags: Geom +// Topics: FDM Optimized, Walls +// See Also: sparse_wall(), corrugated_wall(), thinning_wall(), thinning_triangle(), narrowing_strut(), cuboid() +// Usage: +// sparse_cuboid(size, [dir], [maxang=], [struct=] +// Description: +// Makes an open rectangular cuboid with X-shaped cross-bracing to reduce the need for material in 3d printing. +// The direction of the cross bracing can be aligned with the X, Y or Z axis. This module can be +// used as a drop-in replacement for {{cuboid()}} if you belatedly decide that your model would benefit from +// the sparse construction. +// Arguments: +// size = The size of sparse wall, a number or length 3 vector. +// dir = direction of holes through the cuboid, must be a vector parallel to the X, Y or Z axes, or one of "X", "Y" or "Z". Default: "Y" +// --- +// maxang = maximum overhang angle of cross-braces, measured down from vertical. Default: 30 +// strut = the width of the cross-braces. Default: 5 +// max_bridge = maximum bridging distance between cross-braces. Default: 20 +// chamfer = Size of chamfer, inset from sides. Default: No chamfering. +// rounding = Radius of the edge rounding. Default: No rounding. +// edges = Edges to mask. See [Specifying Edges](attachments.scad#section-specifying-edges). Default: all edges. +// except = Edges to explicitly NOT mask. See [Specifying Edges](attachments.scad#section-specifying-edges). Default: No edges. +// trimcorners = If true, rounds or chamfers corners where three chamfered/rounded edges meet. Default: `true` +// teardrop = If given as a number, rounding around the bottom edge of the cuboid won't exceed this many degrees from vertical. If true, the limit angle is 45 degrees. Default: `false` +// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` +// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0` +// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP` +// Examples: +// sparse_cuboid([10,20,30], strut=1); +// sparse_cuboid([10,20,30], "Y", strut=1); +// sparse_cuboid([10,20,30], UP, strut=1); +// sparse_cuboid(30, FWD, strut=2, rounding=2); +module sparse_cuboid(size, dir=RIGHT, strut=5, maxang=30, max_bridge=20, + chamfer, + rounding, + edges=EDGES_ALL, + except=[], + except_edges, + trimcorners=true, + teardrop=false, + anchor=CENTER, spin=0, orient=UP) +{ + size = scalar_vec3(size); + dummy1=assert(in_list(dir,["X","Y","Z"]) || is_vector(dir,3), "dir must be a 3-vector or one of \"X\", \"Y\", or \"Z\""); + count = len([for(d=dir) if (d!=0) d]); + dummy2=assert(is_string(dir) || (count==1 && len(dir)<=3), "vector valued dir must have exactly one non-zero component"); + dir = is_string(dir) ? dir + : dir.x ? "X" + : dir.y ? "Y" + : "Z"; + attachable(anchor,spin,orient,size=size){ + intersection(){ + if (dir=="X") + sparse_wall(size.z,size.y,size.x,strut=strut,maxang=maxang, max_bridge=max_bridge); + else if (dir=="Y") + zrot(90) + sparse_wall(size.z,size.x,size.y,strut=strut,maxang=maxang, max_bridge=max_bridge); + else + yrot(90) + sparse_wall(size.x,size.y,size.z,strut=strut,maxang=maxang, max_bridge=max_bridge); + cuboid(size=size, chamfer=chamfer, rounding=rounding,edges=edges, except=except, except_edges=except_edges, + trimcorners=trimcorners, teardrop=teardrop); + } + children(); + } +} + + // Module: corrugated_wall() // Synopsis: Makes a corrugated rectangular wall. // SynTags: Geom