2017-08-30 00:00:16 +00:00
//////////////////////////////////////////////////////////////////////
2021-11-12 00:34:16 +00:00
// LibFile: masks3d.scad
// This file defines 3D masks for applying chamfers, roundovers, and teardrop roundovers to straight edges and circular
// edges in three dimensions.
2021-01-05 09:20:01 +00:00
// Includes:
2019-04-19 07:25:10 +00:00
// include <BOSL2/std.scad>
2021-12-13 23:48:30 +00:00
// FileGroup: Basic Modeling
2022-04-21 04:26:20 +00:00
// FileSummary: 3D masks for rounding or chamfering edges and corners.
2021-12-13 23:48:30 +00:00
// FileFootnotes: STD=Included in std.scad
2017-08-30 00:00:16 +00:00
//////////////////////////////////////////////////////////////////////
2021-10-24 03:28:40 +00:00
// Section: Chamfer Masks
2019-03-23 04:13:18 +00:00
2021-10-24 09:02:32 +00:00
// Module: chamfer_edge_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to chamfer a 90° edge.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Chamfers, Shapes (3D)
2023-10-03 18:41:46 +00:00
// See Also: chamfer_corner_mask(), chamfer_cylinder_mask(), chamfer_edge_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2023-03-07 00:27:37 +00:00
// chamfer_edge_mask(l|h=|length=|height=, chamfer, [excess]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
2023-03-30 19:11:56 +00:00
// Creates a shape that can be used to chamfer a 90° edge.
2019-03-23 04:13:18 +00:00
// Difference it from the object to be chamfered. The center of
// the mask object should align exactly with the edge to be chamfered.
// Arguments:
2023-03-07 00:27:37 +00:00
// l/h/length/height = Length of mask.
2020-08-19 02:09:26 +00:00
// chamfer = Size of chamfer.
// excess = The extra amount to add to the length of the mask so that it differences away from other shapes cleanly. Default: `0.1`
2022-04-08 23:37:46 +00:00
// ---
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2019-03-23 04:13:18 +00:00
// Example:
2021-10-24 09:02:32 +00:00
// chamfer_edge_mask(l=50, chamfer=10);
2021-10-24 03:28:40 +00:00
// Example:
2019-03-23 04:13:18 +00:00
// difference() {
2019-05-17 21:41:45 +00:00
// cube(50, anchor=BOTTOM+FRONT);
2021-10-24 09:02:32 +00:00
// #chamfer_edge_mask(l=50, chamfer=10, orient=RIGHT);
2019-03-23 04:13:18 +00:00
// }
2021-10-24 09:02:32 +00:00
// Example: Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2021-10-24 09:02:32 +00:00
// cube(50, center=true) {
// edge_mask(TOP+RIGHT)
// #chamfer_edge_mask(l=50, chamfer=10);
// }
2023-03-07 00:27:37 +00:00
function chamfer_edge_mask ( l , chamfer = 1 , excess = 0.1 , h , length , height , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "chamfer_edge_mask" ) ;
module chamfer_edge_mask ( l , chamfer = 1 , excess = 0.1 , h , length , height , anchor = CENTER , spin = 0 , orient = UP ) {
l = one_defined ( [ l , h , height , length ] , "l,h,height,length" ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = [ chamfer * 2 , chamfer * 2 , l ] ) {
cylinder ( r = chamfer , h = l + excess , center = true , $fn = 4 ) ;
children ( ) ;
}
2020-05-30 02:04:34 +00:00
}
2019-03-23 04:13:18 +00:00
}
2021-10-24 09:02:32 +00:00
// Module: chamfer_corner_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to chamfer a 90° corner.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Chamfers, Shapes (3D)
2023-10-03 18:41:46 +00:00
// See Also: chamfer_corner_mask(), chamfer_cylinder_mask(), chamfer_edge_mask(), default_tag(), diff()
2021-10-24 09:02:32 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// chamfer_corner_mask(chamfer) [ATTACHMENTS];
2021-10-24 09:02:32 +00:00
// Description:
2023-03-30 19:11:56 +00:00
// Creates a shape that can be used to chamfer a 90° corner.
2021-10-24 09:02:32 +00:00
// Difference it from the object to be chamfered. The center of
// the mask object should align exactly with the corner to be chamfered.
// Arguments:
// chamfer = Size of chamfer.
// ---
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2021-10-24 09:02:32 +00:00
// Example:
// chamfer_corner_mask(chamfer=10);
// Example:
// difference() {
// cuboid(50, chamfer=10, trimcorners=false);
// move(25*[1,-1,1]) #chamfer_corner_mask(chamfer=10);
// }
// Example: Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2021-10-24 09:02:32 +00:00
// cuboid(100, chamfer=20, trimcorners=false) {
// corner_mask(TOP+FWD+RIGHT)
// chamfer_corner_mask(chamfer=20);
// }
2021-10-24 22:26:27 +00:00
// Example: Anchors
// chamfer_corner_mask(chamfer=20)
// show_anchors();
2022-04-08 23:37:46 +00:00
function chamfer_corner_mask ( chamfer = 1 , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "chamfer_corner_mask" ) ;
2021-10-24 09:02:32 +00:00
module chamfer_corner_mask ( chamfer = 1 , anchor = CENTER , spin = 0 , orient = UP ) {
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
octahedron ( chamfer * 4 , anchor = anchor , spin = spin , orient = orient ) children ( ) ;
}
2021-10-24 09:02:32 +00:00
}
2019-03-23 04:13:18 +00:00
// Module: chamfer_cylinder_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to chamfer the end of a cylinder.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Chamfers, Cylinders
2023-10-03 18:41:46 +00:00
// See Also: chamfer_corner_mask(), chamfer_cylinder_mask(), chamfer_edge_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// chamfer_cylinder_mask(r|d=, chamfer, [ang], [from_end]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
// Create a mask that can be used to bevel/chamfer the end of a cylindrical region.
2020-04-07 01:53:12 +00:00
// Difference it from the end of the region to be chamfered. The center of the mask
2019-03-23 04:13:18 +00:00
// object should align exactly with the center of the end of the cylindrical region
2020-04-07 01:53:12 +00:00
// to be chamfered.
2019-03-23 04:13:18 +00:00
// Arguments:
// r = Radius of cylinder to chamfer.
2022-04-08 23:37:46 +00:00
// chamfer = Size of the edge chamfered, inset from edge.
// ---
2019-03-23 04:13:18 +00:00
// d = Diameter of cylinder to chamfer. Use instead of r.
2022-11-30 03:21:59 +00:00
// ang = Angle of chamfer in degrees from the horizontal. (Default: 45)
2019-03-23 04:13:18 +00:00
// from_end = If true, chamfer size is measured from end of cylinder. If false, chamfer is measured outset from the radius of the cylinder. (Default: false)
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2019-03-23 04:13:18 +00:00
// Example:
// difference() {
// cylinder(r=50, h=100, center=true);
// up(50) #chamfer_cylinder_mask(r=50, chamfer=10);
// }
2019-05-17 21:41:45 +00:00
// Example:
// difference() {
// cylinder(r=50, h=100, center=true);
// up(50) chamfer_cylinder_mask(r=50, chamfer=10);
// }
2022-11-30 03:21:59 +00:00
// Example: Changing the chamfer angle
// difference() {
// cylinder(r=50, h=100, center=true);
// up(50) #chamfer_cylinder_mask(r=50, chamfer=10, ang=70);
// }
// Example:
// difference() {
// cylinder(r=50, h=100, center=true);
// up(50) chamfer_cylinder_mask(r=50, chamfer=10, ang=70);
// }
2021-10-24 09:02:32 +00:00
// Example: Masking by Attachment
2022-11-30 03:21:59 +00:00
// diff()
// cyl(d=100,h=40)
// attach([TOP,BOT])
// tag("remove")chamfer_cylinder_mask(d=100, chamfer=10);
2022-04-08 23:37:46 +00:00
function chamfer_cylinder_mask ( r , chamfer , d , ang = 45 , from_end = false , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "chamfer_cylinder_mask" ) ;
module chamfer_cylinder_mask ( r , chamfer , d , ang = 45 , from_end = false , anchor = CENTER , spin = 0 , orient = UP )
2019-03-23 04:13:18 +00:00
{
2020-05-30 02:04:34 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2022-11-30 03:23:59 +00:00
dummy = assert ( all_nonnegative ( [ chamfer ] ) , "Chamfer must be a nonnegative number" ) ;
2022-11-30 03:21:59 +00:00
ch = from_end ? chamfer : opp_ang_to_adj ( chamfer , 90 - ang ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , r = r , l = ch * 2 ) {
difference ( ) {
cyl ( r = r + chamfer , l = ch * 2 , anchor = CENTER ) ;
cyl ( r = r , l = ch * 3 , chamfer = chamfer , chamfang = ang , from_end = from_end , anchor = TOP ) ;
}
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
2019-02-23 00:20:26 +00:00
}
2021-10-24 03:28:40 +00:00
// Section: Rounding Masks
2019-03-23 04:13:18 +00:00
2021-10-24 03:28:40 +00:00
// Module: rounding_edge_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round a 90° edge.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masks, Rounding, Shapes (3D)
2023-10-03 18:41:46 +00:00
// See Also: rounding_angled_edge_mask(), rounding_corner_mask(), rounding_angled_corner_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2023-03-07 00:27:37 +00:00
// rounding_edge_mask(l|h=|length=|height=, r|d=, [excess=]) [ATTACHMENTS];
// rounding_edge_mask(l|h=|length=|height=, r1=|d1=, r2=|d2=, [excess=]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
2023-03-30 19:11:56 +00:00
// Creates a shape that can be used to round a vertical 90° edge.
2019-04-25 02:42:38 +00:00
// Difference it from the object to be rounded. The center of the mask
// object should align exactly with the edge to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2023-03-07 00:27:37 +00:00
// l/h/length/height = Length of mask.
2019-04-25 02:42:38 +00:00
// r = Radius of the rounding.
2022-04-08 23:37:46 +00:00
// ---
2019-06-24 01:47:35 +00:00
// r1 = Bottom radius of rounding.
// r2 = Top radius of rounding.
2020-08-27 03:39:45 +00:00
// d = Diameter of the rounding.
// d1 = Bottom diameter of rounding.
// d2 = Top diameter of rounding.
2021-10-24 03:28:40 +00:00
// excess = Extra size for the mask. Defaults: 0.1
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2021-10-24 09:02:32 +00:00
// Example(VPD=200,VPR=[55,0,120]):
// rounding_edge_mask(l=50, r1=10, r2=25);
2021-10-24 03:28:40 +00:00
// Example:
2017-08-30 00:00:16 +00:00
// difference() {
// cube(size=100, center=false);
2021-10-24 03:28:40 +00:00
// #rounding_edge_mask(l=100, r=25, orient=UP, anchor=BOTTOM);
2017-08-30 00:00:16 +00:00
// }
2019-06-24 01:47:35 +00:00
// Example: Varying Rounding Radius
// difference() {
2021-10-24 09:02:32 +00:00
// cube(size=50, center=false);
// #rounding_edge_mask(l=50, r1=25, r2=10, orient=UP, anchor=BOTTOM);
2019-06-24 01:47:35 +00:00
// }
2019-05-26 06:31:05 +00:00
// Example: Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2019-05-26 06:31:05 +00:00
// cube(100, center=true)
2021-10-24 03:28:40 +00:00
// edge_mask(FRONT+RIGHT)
// #rounding_edge_mask(l=$parent_size.z+0.01, r=25);
2019-05-26 06:31:05 +00:00
// Example: Multiple Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2019-05-26 06:31:05 +00:00
// cube([80,90,100], center=true) {
2021-10-24 03:28:40 +00:00
// let(p = $parent_size*1.01) {
// edge_mask(TOP)
// rounding_edge_mask(l=p.z, r=25);
2019-05-26 06:31:05 +00:00
// }
// }
2023-03-07 00:27:37 +00:00
function rounding_edge_mask ( l , r , 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 , r1 , r2 , d , d1 , d2 , excess = 0.1 , anchor = CENTER , spin = 0 , orient = UP , h , height , length )
2017-08-30 00:00:16 +00:00
{
2023-03-07 00:27:37 +00:00
l = one_defined ( [ l , h , height , length ] , "l,h,height,length" ) ;
2020-08-27 03:39:45 +00:00
r1 = get_radius ( r1 = r1 , r = r , d1 = d1 , d = d , dflt = 1 ) ;
r2 = get_radius ( r1 = r2 , r = r , d1 = d2 , d = d , dflt = 1 ) ;
2020-05-30 02:04:34 +00:00
sides = quantup ( segs ( max ( r1 , r2 ) ) , 4 ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = [ 2 * r1 , 2 * r1 , l ] , size2 = [ 2 * r2 , 2 * r2 ] ) {
if ( r1 < r2 ) {
zflip ( ) {
linear_extrude ( height = l , convexity = 4 , center = true , scale = r1 / r2 ) {
difference ( ) {
translate ( - excess * [ 1 , 1 ] ) square ( r2 + excess ) ;
translate ( [ r2 , r2 ] ) circle ( r = r2 , $fn = sides ) ;
}
2020-05-30 02:04:34 +00:00
}
}
2023-10-03 18:41:46 +00:00
} else {
linear_extrude ( height = l , convexity = 4 , center = true , scale = r2 / r1 ) {
difference ( ) {
translate ( - excess * [ 1 , 1 ] ) square ( r1 + excess ) ;
translate ( [ r1 , r1 ] ) circle ( r = r1 , $fn = sides ) ;
}
2020-05-30 02:04:34 +00:00
}
}
2023-10-03 18:41:46 +00:00
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
2017-08-30 00:00:16 +00:00
}
2021-10-24 03:28:40 +00:00
// Module: rounding_corner_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round 90° corners.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Rounding, Shapes (3D)
2023-10-03 18:41:46 +00:00
// See Also: rounding_angled_corner_mask(), rounding_edge_mask(), rounding_angled_edge_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// rounding_corner_mask(r|d, [excess=], [style=]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
2023-03-30 19:11:56 +00:00
// Creates a shape that you can use to round 90° corners.
2021-10-24 03:28:40 +00:00
// Difference it from the object to be rounded. The center of the mask
// object should align exactly with the corner to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2021-10-24 03:28:40 +00:00
// r = Radius of corner rounding.
// ---
2022-04-08 23:37:46 +00:00
// d = Diameter of corner rounding.
2021-10-24 03:28:40 +00:00
// excess = Extra size for the mask. Defaults: 0.1
// style = The style of the sphere cutout's construction. One of "orig", "aligned", "stagger", "octa", or "icosa". Default: "octa"
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2019-03-23 04:13:18 +00:00
// Example:
2021-10-24 03:28:40 +00:00
// rounding_corner_mask(r=20.0);
2019-03-23 04:13:18 +00:00
// Example:
// difference() {
2021-10-24 03:28:40 +00:00
// cube(size=[50, 60, 70], center=true);
// translate([-25, -30, 35])
// #rounding_corner_mask(r=20, spin=90, orient=DOWN);
// translate([25, -30, 35])
// #rounding_corner_mask(r=20, orient=DOWN);
// translate([25, -30, -35])
// #rounding_corner_mask(r=20, spin=90);
2019-03-23 04:13:18 +00:00
// }
2021-10-24 03:28:40 +00:00
// Example: Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2021-10-24 03:28:40 +00:00
// cube(size=[50, 60, 70]) {
// corner_mask(TOP)
// #rounding_corner_mask(r=20);
2019-03-23 04:13:18 +00:00
// }
2022-04-08 23:37:46 +00:00
function rounding_corner_mask ( r , d , style = "octa" , excess = 0.1 , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "rounding_corner_mask" ) ;
2021-10-24 03:28:40 +00:00
module rounding_corner_mask ( r , d , style = "octa" , excess = 0.1 , anchor = CENTER , spin = 0 , orient = UP )
2019-02-20 04:53:27 +00:00
{
2020-08-27 03:39:45 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = [ 2 , 2 , 2 ] * r ) {
difference ( ) {
translate ( - excess * [ 1 , 1 , 1 ] )
cube ( size = r + excess , center = false ) ;
translate ( [ r , r , r ] )
spheroid ( r = r , style = style ) ;
}
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
2019-02-20 04:53:27 +00:00
}
2019-04-25 02:42:38 +00:00
// Module: rounding_angled_edge_mask()
2023-03-31 02:28:29 +00:00
// Synopsis: Creates a shape to round edges of any angle.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masks, Rounding
2023-10-03 18:41:46 +00:00
// See Also: rounding_angled_corner_mask(), rounding_edge_mask(), rounding_corner_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2023-03-07 00:27:37 +00:00
// rounding_angled_edge_mask(h|l=|length=|height=, r|d=, [ang=]) [ATTACHMENTS];
// rounding_angled_edge_mask(h|l=|length=|height=, r1=|d1=, r2=|d2=, [ang=]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
2019-06-24 01:47:35 +00:00
// Creates a vertical mask that can be used to round the edge where two face meet, at any arbitrary
// angle. Difference it from the object to be rounded. The center of the mask should align exactly
// with the edge to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2023-03-07 00:27:37 +00:00
// h/l/height/length = Height of vertical mask.
2019-06-24 01:47:35 +00:00
// r = Radius of the rounding.
2022-04-08 23:37:46 +00:00
// ---
2019-06-24 01:47:35 +00:00
// r1 = Bottom radius of rounding.
// r2 = Top radius of rounding.
2020-08-27 03:39:45 +00:00
// d = Diameter of the rounding.
// d1 = Bottom diameter of rounding.
// d2 = Top diameter of rounding.
2022-04-08 23:37:46 +00:00
// ang = Angle that the planes meet at. Default: 90
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2017-08-30 00:00:16 +00:00
// Example:
2018-11-26 09:53:02 +00:00
// difference() {
2021-10-24 09:02:32 +00:00
// pie_slice(ang=70, h=50, d=100, center=true);
2019-04-25 02:42:38 +00:00
// #rounding_angled_edge_mask(h=51, r=20.0, ang=70, $fn=32);
2018-11-26 09:53:02 +00:00
// }
2019-06-24 01:47:35 +00:00
// Example: Varying Rounding Radius
// difference() {
2021-10-24 09:02:32 +00:00
// pie_slice(ang=70, h=50, d=100, center=true);
2019-06-24 01:47:35 +00:00
// #rounding_angled_edge_mask(h=51, r1=10, r2=25, ang=70, $fn=32);
// }
2023-03-07 00:27:37 +00:00
function rounding_angled_edge_mask ( h , r , r1 , r2 , d , d1 , d2 , ang = 90 , anchor = CENTER , spin = 0 , orient = UP , l , height , length ) = no_function ( "rounding_angled_edge_mask" ) ;
module rounding_angled_edge_mask ( h , r , r1 , r2 , d , d1 , d2 , ang = 90 , anchor = CENTER , spin = 0 , orient = UP , l , height , length )
2017-08-30 00:00:16 +00:00
{
2020-05-30 02:04:34 +00:00
function _mask_shape ( r ) = [
for ( i = [ 0 : 1 : n ] ) let ( a = 90 + ang + i * sweep / n ) [ r * cos ( a ) + x , r * sin ( a ) + r ] ,
for ( i = [ 0 : 1 : n ] ) let ( a = 90 + i * sweep / n ) [ r * cos ( a ) + x , r * sin ( a ) - r ] ,
[ min ( - 1 , r * cos ( 270 - ang ) + x - 1 ) , r * sin ( 270 - ang ) - r ] ,
[ min ( - 1 , r * cos ( 90 + ang ) + x - 1 ) , r * sin ( 90 + ang ) + r ] ,
] ;
2023-03-07 00:27:37 +00:00
h = one_defined ( [ l , h , height , length ] , "l,h,height,length" ) ;
2020-05-30 02:04:34 +00:00
sweep = 180 - ang ;
2020-08-27 03:39:45 +00:00
r1 = get_radius ( r1 = r1 , r = r , d1 = d1 , d = d , dflt = 1 ) ;
r2 = get_radius ( r1 = r2 , r = r , d1 = d2 , d = d , dflt = 1 ) ;
2020-05-30 02:04:34 +00:00
n = ceil ( segs ( max ( r1 , r2 ) ) * sweep / 360 ) ;
x = sin ( 90 - ( ang / 2 ) ) / sin ( ang / 2 ) * ( r1 < r2 ? r2 : r1 ) ;
if ( r1 < r2 ) {
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = [ 2 * x * r1 / r2 , 2 * r1 , h ] , size2 = [ 2 * x , 2 * r2 ] ) {
zflip ( ) {
linear_extrude ( height = h , convexity = 4 , center = true , scale = r1 / r2 ) {
polygon ( _mask_shape ( r2 ) ) ;
}
2020-05-30 02:04:34 +00:00
}
2023-10-03 18:41:46 +00:00
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
} else {
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = [ 2 * x , 2 * r1 , h ] , size2 = [ 2 * x * r2 / r1 , 2 * r2 ] ) {
linear_extrude ( height = h , convexity = 4 , center = true , scale = r2 / r1 ) {
polygon ( _mask_shape ( r1 ) ) ;
}
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
}
2017-08-30 00:00:16 +00:00
}
2019-04-25 02:42:38 +00:00
// Module: rounding_angled_corner_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round the corner of an arbitrary angle.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masks, Rounding, Shapes (3D)
2023-10-03 18:41:46 +00:00
// See Also: rounding_angled_edge_mask(), rounding_corner_mask(), rounding_edge_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// rounding_angled_corner_mask(r|d=, [ang]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
2019-04-25 02:42:38 +00:00
// Creates a shape that can be used to round the corner of an angle.
// Difference it from the object to be rounded. The center of the mask
// object should align exactly with the point of the corner to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2019-04-25 02:42:38 +00:00
// r = Radius of the rounding.
2022-04-08 23:37:46 +00:00
// ---
2020-08-27 03:39:45 +00:00
// d = Diameter of the rounding.
2022-04-08 23:37:46 +00:00
// ang = Angle between planes that you need to round the corner of. Default: 90
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2019-05-16 20:21:59 +00:00
// Example(Med):
2018-11-26 09:53:02 +00:00
// ang=60;
// difference() {
2021-10-24 03:28:40 +00:00
// pie_slice(ang=ang, h=50, r=200, center=true);
// up(50/2) #rounding_angled_corner_mask(r=20, ang=ang);
2018-11-26 09:53:02 +00:00
// }
2022-04-08 23:37:46 +00:00
function rounding_angled_corner_mask ( r , ang = 90 , d , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "rounding_angled_corner_mask" ) ;
2020-08-27 03:39:45 +00:00
module rounding_angled_corner_mask ( r , ang = 90 , d , anchor = CENTER , spin = 0 , orient = UP )
2017-08-30 00:00:16 +00:00
{
2020-08-27 03:39:45 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2020-05-30 02:04:34 +00:00
dx = r / tan ( ang / 2 ) ;
dx2 = dx / cos ( ang / 2 ) + 1 ;
fn = quantup ( segs ( r ) , 4 ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , d = dx2 , l = 2 * r ) {
difference ( ) {
down ( r ) cylinder ( r = dx2 , h = r + 1 , center = false ) ;
yflip_copy ( ) {
translate ( [ dx , r , - r ] ) {
hull ( ) {
sphere ( r = r , $fn = fn ) ;
down ( r * 3 ) sphere ( r = r , $fn = fn ) ;
zrot_copies ( [ 0 , ang ] ) {
right ( r * 3 ) sphere ( r = r , $fn = fn ) ;
}
2020-05-30 02:04:34 +00:00
}
}
}
}
2023-10-03 18:41:46 +00:00
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
2017-08-30 00:00:16 +00:00
}
2019-04-25 02:42:38 +00:00
// Module: rounding_cylinder_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round the end of a cylinder.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Rounding, Cylinders
2023-10-03 18:41:46 +00:00
// See Also: rounding_hole_mask(), rounding_angled_edge_mask(), rounding_corner_mask(), rounding_angled_corner_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// rounding_cylinder_mask(r|d=, rounding);
2019-03-23 04:13:18 +00:00
// Description:
// Create a mask that can be used to round the end of a cylinder.
2019-04-25 02:42:38 +00:00
// Difference it from the cylinder to be rounded. The center of the
2019-03-23 04:13:18 +00:00
// mask object should align exactly with the center of the end of the
2019-04-25 02:42:38 +00:00
// cylinder to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2022-04-08 23:37:46 +00:00
// r = Radius of cylinder.
// rounding = Radius of the edge rounding.
// ---
// d = Diameter of cylinder.
2022-09-26 03:56:04 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2017-08-30 00:00:16 +00:00
// Example:
// difference() {
2019-03-23 04:13:18 +00:00
// cylinder(r=50, h=50, center=false);
2019-04-25 02:42:38 +00:00
// up(50) #rounding_cylinder_mask(r=50, rounding=10);
2019-03-23 04:13:18 +00:00
// }
// Example:
// difference() {
2019-05-16 20:21:59 +00:00
// cylinder(r=50, h=50, center=false);
// up(50) rounding_cylinder_mask(r=50, rounding=10);
2017-08-30 00:00:16 +00:00
// }
2021-10-24 03:28:40 +00:00
// Example: Masking by Attachment
2022-08-21 07:51:39 +00:00
// diff()
2021-10-24 03:28:40 +00:00
// cyl(h=30, d=30) {
// attach(TOP)
2022-08-21 07:51:39 +00:00
// #tag("remove")
// rounding_cylinder_mask(d=30, rounding=5);
2021-10-24 03:28:40 +00:00
// }
2022-09-26 03:56:04 +00:00
function rounding_cylinder_mask ( r , rounding , d , anchor , spin , orient ) = no_function ( "rounding_cylinder_mask" ) ;
module rounding_cylinder_mask ( r , rounding , d , anchor = CENTER , spin = 0 , orient = UP )
2017-08-30 00:00:16 +00:00
{
2020-08-27 03:39:45 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , r = r + rounding , l = rounding * 2 ) {
difference ( ) {
cyl ( r = r + rounding , l = rounding * 2 , anchor = CENTER ) ;
cyl ( r = r , l = rounding * 3 , rounding = rounding , anchor = TOP ) ;
}
children ( ) ;
2022-09-26 03:56:04 +00:00
}
2021-10-24 03:28:40 +00:00
}
2017-08-30 00:00:16 +00:00
}
2019-04-25 02:42:38 +00:00
// Module: rounding_hole_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round the edge of a round hole.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Rounding
2023-10-03 18:41:46 +00:00
// See Also: rounding_cylinder_mask(), rounding_hole_mask(), rounding_angled_edge_mask(), rounding_corner_mask(), rounding_angled_corner_mask(), default_tag(), diff()
2019-03-23 04:13:18 +00:00
// Usage:
2022-04-08 23:37:46 +00:00
// rounding_hole_mask(r|d, rounding, [excess]) [ATTACHMENTS];
2019-03-23 04:13:18 +00:00
// Description:
// Create a mask that can be used to round the edge of a circular hole.
2019-04-25 02:42:38 +00:00
// Difference it from the hole to be rounded. The center of the
2019-03-23 04:13:18 +00:00
// mask object should align exactly with the center of the end of the
2019-04-25 02:42:38 +00:00
// hole to be rounded.
2019-03-23 04:13:18 +00:00
// Arguments:
2019-04-25 02:42:38 +00:00
// r = Radius of hole.
2022-04-08 23:37:46 +00:00
// rounding = Radius of the rounding.
2020-08-19 02:09:26 +00:00
// excess = The extra thickness of the mask. Default: `0.1`.
2022-09-26 03:56:04 +00:00
// ---
2023-03-07 00:27:37 +00:00
// d = Diameter of hole to rounding.
2021-11-20 03:33:16 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2021-10-24 09:02:32 +00:00
// Example:
// rounding_hole_mask(r=40, rounding=20, $fa=2, $fs=2);
2019-05-16 20:21:59 +00:00
// Example(Med):
2017-08-30 00:00:16 +00:00
// difference() {
// cube([150,150,100], center=true);
// cylinder(r=50, h=100.1, center=true);
2019-04-25 02:42:38 +00:00
// up(50) #rounding_hole_mask(r=50, rounding=10);
2017-08-30 00:00:16 +00:00
// }
2019-05-17 21:41:45 +00:00
// Example(Med):
// difference() {
// cube([150,150,100], center=true);
// cylinder(r=50, h=100.1, center=true);
// up(50) rounding_hole_mask(r=50, rounding=10);
// }
2022-04-08 23:37:46 +00:00
function rounding_hole_mask ( r , rounding , excess = 0.1 , d , anchor = CENTER , spin = 0 , orient = UP ) = no_function ( "rounding_hole_mask" ) ;
module rounding_hole_mask ( r , rounding , excess = 0.1 , d , anchor = CENTER , spin = 0 , orient = UP )
2017-08-30 00:00:16 +00:00
{
2020-05-30 02:04:34 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , r = r + rounding , l = 2 * rounding ) {
rotate_extrude ( convexity = 4 ) {
difference ( ) {
right ( r - excess ) fwd ( rounding ) square ( rounding + excess , center = false ) ;
right ( r + rounding ) fwd ( rounding ) circle ( r = rounding ) ;
}
2020-05-30 02:04:34 +00:00
}
2023-10-03 18:41:46 +00:00
children ( ) ;
2020-05-30 02:04:34 +00:00
}
}
2017-08-30 00:00:16 +00:00
}
2021-10-24 03:28:40 +00:00
// Section: Teardrop Masking
2021-10-24 09:02:32 +00:00
// Module: teardrop_edge_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round a 90° edge but limit the angle of overhang.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Rounding, Shapes (3D), FDM Optimized
2023-10-03 18:41:46 +00:00
// See Also: teardrop_corner_mask(), teardrop_edge_mask(), default_tag(), diff()
2020-04-11 08:22:04 +00:00
// Usage:
2023-03-07 00:27:37 +00:00
// teardrop_edge_mask(l|h=|length=|height=, r|d=, [angle], [excess], [anchor], [spin], [orient]) [ATTACHMENTS];
2020-04-11 08:22:04 +00:00
// Description:
2023-03-30 19:11:56 +00:00
// Makes an apropriate 3D edge rounding mask that keeps within `angle` degrees of vertical.
2020-04-11 08:22:04 +00:00
// Arguments:
2023-03-07 00:27:37 +00:00
// l/h/length/height = length of mask
2020-04-11 08:22:04 +00:00
// r = Radius of the mask rounding.
// angle = Maximum angle from vertical. Default: 45
// excess = Excess mask size. Default: 0.1
2022-09-26 03:56:04 +00:00
// ---
2022-11-09 21:54:27 +00:00
// d = Diameter of the mask rounding.
2022-09-26 03:56:04 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2021-10-24 09:02:32 +00:00
// Example(VPD=50,VPR=[55,0,120]):
// teardrop_edge_mask(l=20, r=10, angle=40);
// Example(VPD=300,VPR=[75,0,25]):
2022-08-21 07:51:39 +00:00
// diff()
2020-04-11 08:22:04 +00:00
// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) {
2021-10-24 09:02:32 +00:00
// edge_mask(BOT)
// teardrop_edge_mask(l=max($parent_size)+1, r=10, angle=40);
2021-10-24 03:28:40 +00:00
// corner_mask(BOT)
// teardrop_corner_mask(r=10, angle=40);
2020-04-11 08:22:04 +00:00
// }
2023-03-07 00:27:37 +00:00
function teardrop_edge_mask ( l , r , angle = 45 , excess = 0.1 , d , anchor , spin , orient , h , height , length ) = no_function ( "teardrop_edge_mask" ) ;
module teardrop_edge_mask ( l , r , angle = 45 , excess = 0.1 , d , anchor = CTR , spin = 0 , orient = UP , h , height , length )
2022-04-08 23:37:46 +00:00
{
2023-03-07 00:27:37 +00:00
l = one_defined ( [ l , h , height , length ] , "l,h,height,length" ) ;
2022-11-09 21:54:27 +00:00
check =
assert ( is_num ( l ) && l > 0 , "Length of mask must be positive" )
assert ( is_num ( angle ) && angle > 0 && angle < 90 , "Angle must be a number between 0 and 90" )
assert ( is_num ( excess ) ) ;
2020-05-30 02:04:34 +00:00
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2022-09-26 03:56:04 +00:00
path = mask2d_teardrop ( r = r , angle = angle , excess = excess ) ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
linear_sweep ( path , height = l , center = true , atype = "bbox" , anchor = anchor , spin = spin , orient = orient ) children ( ) ;
}
2020-04-11 08:22:04 +00:00
}
2021-10-24 09:02:32 +00:00
// Module: teardrop_corner_mask()
2023-03-30 19:11:56 +00:00
// Synopsis: Creates a shape to round a 90° corner but limit the angle of overhang.
2023-04-14 22:53:35 +00:00
// SynTags: Geom
2023-03-30 19:11:56 +00:00
// Topics: Masking, Rounding, Shapes (3D), FDM Optimized
2023-10-03 18:41:46 +00:00
// See Also: teardrop_corner_mask(), teardrop_edge_mask(), default_tag(), diff()
2021-10-24 03:28:40 +00:00
// Usage:
2022-11-09 21:54:27 +00:00
// teardrop_corner_mask(r|d=, [angle], [excess], [anchor], [spin], [orient]) [ATTACHMENTS];
2021-10-24 03:28:40 +00:00
// Description:
// Makes an apropriate 3D corner rounding mask that keeps within `angle` degrees of vertical.
// Arguments:
// r = Radius of the mask rounding.
// angle = Maximum angle from vertical. Default: 45
// excess = Excess mask size. Default: 0.1
2022-04-08 23:37:46 +00:00
// ---
// d = Diameter of the mask rounding.
2022-09-26 03:56:04 +00:00
// 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`
2023-10-03 18:41:46 +00:00
// Side Effects:
2023-10-04 05:46:58 +00:00
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
2021-10-24 09:02:32 +00:00
// Example:
// teardrop_corner_mask(r=20, angle=40);
// Example:
2022-08-21 07:51:39 +00:00
// diff()
2021-10-24 03:28:40 +00:00
// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) {
2021-10-24 09:02:32 +00:00
// edge_profile(BOT)
// mask2d_teardrop(r=10, angle=40);
// corner_mask(BOT)
// teardrop_corner_mask(r=10, angle=40);
2021-10-24 03:28:40 +00:00
// }
2023-03-07 00:28:25 +00:00
function teardrop_corner_mask ( r , angle = 45 , excess = 0.1 , d , anchor , spin , orient ) = no_function ( "teardrop_corner_mask" ) ;
module teardrop_corner_mask ( r , angle = 45 , excess = 0.1 , d , anchor = CTR , spin = 0 , orient = UP )
2022-04-08 23:37:46 +00:00
{
2021-10-24 03:28:40 +00:00
assert ( is_num ( angle ) ) ;
assert ( is_num ( excess ) ) ;
assert ( angle > 0 && angle < 90 ) ;
r = get_radius ( r = r , d = d , dflt = 1 ) ;
2022-09-26 03:56:04 +00:00
size = ( r + excess ) * [ 1 , 1 , 1 ] ;
midpt = ( r - excess ) / 2 * [ 1 , 1 , 1 ] ;
2023-10-03 18:41:46 +00:00
default_tag ( "remove" ) {
attachable ( anchor , spin , orient , size = size , offset = midpt ) {
difference ( ) {
translate ( - [ 1 , 1 , 1 ] * excess ) cube ( r + excess , center = false ) ;
translate ( [ 1 , 1 , 1 ] * r ) onion ( r = r , ang = angle , orient = DOWN ) ;
}
children ( ) ;
2022-09-26 03:56:04 +00:00
}
2021-10-24 03:28:40 +00:00
}
}
2020-05-30 02:04:34 +00:00
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap