diff --git a/attachments.scad b/attachments.scad index 80235a4..3969801 100644 --- a/attachments.scad +++ b/attachments.scad @@ -934,6 +934,67 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) { } } +// Module: corner_profile() +// Usage: +// corner_profile([corners], [except], [convexity]) ... +// Description: +// Takes a 2D mask shape, rotationally extrudes and converts it into a corner mask, and attaches it +// to the selected corners with the appropriate orientation. Tags it as a "mask" to allow it to be +// `diff()`ed away, to give the corner a matching profile. +// Arguments: +// corners = Edges to mask. See the docs for [`corners()`](edges.scad#corners) to see acceptable values. Default: All corners. +// except = Edges to explicitly NOT mask. See the docs for [`corners()`](edges.scad#corners) to see acceptable values. Default: No corners. +// r = Radius of corner mask. +// d = Diameter of corner mask. +// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10 +// Side Effects: +// Sets `$tags = "mask"` for all children. +// Example: +// diff("mask") +// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) { +// corner_profile(BOT,r=10) +// mask2d_teardrop(r=10, angle=40); +// } +module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) { + assert($parent_geom != undef, "No object to attach to!"); + r = get_radius(r=r, d=d, dflt=undef); + assert(is_num(r)); + corners = corners(corners, except=except); + vecs = [for (i = [0:7]) if (corners[i]>0) CORNER_OFFSETS[i]]; + for (vec = vecs) { + vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0); + assert(vcount == 3, "Not an edge vector!"); + anch = find_anchor(vec, $parent_geom); + $attach_to = undef; + $attach_anchor = anch; + $attach_norot = true; + $tags = "mask"; + rotang = vec.z<0? + [ 0,0,180+vang(point2d(vec))-45] : + [180,0,-90+vang(point2d(vec))-45]; + translate(anch[1]) { + rot(rotang) { + render(convexity=convexity) + difference() { + translate(-0.1*[1,1,1]) cube(r+0.1, center=false); + right(r) back(r) zrot(180) { + rotate_extrude(angle=90, convexity=convexity) { + xflip() left(r) { + difference() { + square(r,center=false); + children(); + } + } + } + } + } + } + } + } +} + + + // Module: edge_mask() // Usage: diff --git a/masks.scad b/masks.scad index 01f9a03..102e972 100644 --- a/masks.scad +++ b/masks.scad @@ -781,4 +781,39 @@ module rounding_hole_mask(r=undef, d=undef, rounding=0.25, overage=0.1, anchor=C } +// Module: teardrop_corner_mask() +// Usage: +// teardrop_corner_mask(r|d, [angle], [excess]); +// Description: +// Makes an apropriate 3D corner rounding mask that keeps within `angle` degrees of vertical. +// Arguments: +// r = Radius of the mask rounding. +// d = Diameter of the mask rounding. +// angle = Maximum angle from vertical. Default: 45 +// excess = Excess mask size. Default: 0.1 +// 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 after anchor. See [spin](attachments.scad#spin). Default: `0` +// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` +// Example: +// teardrop_corner_mask(r=20, angle=40); +// Example: +// diff("mask") +// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) { +// edge_profile(BOT) +// mask2d_teardrop(r=10, angle=40); +// corner_profile(BOT,r=10) +// mask2d_teardrop(r=10, angle=40); +// } +module teardrop_corner_mask(r, d, angle, excess=0.1, anchor=CENTER, spin=0, orient=UP) { + assert(is_num(angle)); + assert(is_num(excess)); + assert(angle>0 && angle<90); + r = get_radius(r=r, d=d, dflt=1); + difference() { + translate(-[1,1,1]*excess) cube(r+excess, center=false); + translate([1,1,1]*r) onion(r=r,maxang=angle,orient=DOWN); + } +} + + // vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/shapes2d.scad b/shapes2d.scad index 295bc0c..5ebd73e 100644 --- a/shapes2d.scad +++ b/shapes2d.scad @@ -1405,7 +1405,7 @@ function mask2d_teardrop(r,d,angle=45,excess=0.1,anchor=CENTER,spin=0) = bp, bp-[0,excess], [-excess,-excess], [-excess,r], for (i=[0:1:n]) cp+polar_to_xy(r,180+i*step) ] - ) echo(cp=cp,tp=tp,bp=bp,path=path) reorient(anchor,spin, two_d=true, path=path, p=path); + ) reorient(anchor,spin, two_d=true, path=path, p=path); module mask2d_teardrop(r,d,angle=45,excess=0.1,anchor=CENTER,spin=0) { path = mask2d_teardrop(r=r, d=d, angle=angle, excess=excess); diff --git a/version.scad b/version.scad index 031f683..91c00bc 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,262]; +BOSL_VERSION = [2,0,263]; // Section: BOSL Library Version Functions