From 5719439b052c355a084184b0020acb8c9acd6c01 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Tue, 30 Jan 2024 19:36:59 -0500 Subject: [PATCH 01/12] fix CENTER anchors for regions and vnfs to actually center --- attachments.scad | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/attachments.scad b/attachments.scad index c96e27b..671513f 100644 --- a/attachments.scad +++ b/attachments.scad @@ -3333,7 +3333,7 @@ function _find_anchor(anchor, geom) = ) [anchor, pos, vec, oang] ) : type == "vnf_isect"? ( //vnf let( vnf=geom[1] ) - approx(anchor,CTR)? [anchor, [0,0,0], UP, 0] : + approx(anchor,CTR)? [anchor, cp, UP, 0] : vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] : let( eps = 1/2048, @@ -3383,7 +3383,7 @@ function _find_anchor(anchor, geom) = [anchor, pos, n, oang] ) : type == "vnf_extent"? ( //vnf let( vnf=geom[1] ) - approx(anchor,CTR)? [anchor, [0,0,0], UP, 0] : + approx(anchor,CTR)? [anchor, cp, UP, 0] : vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] : let( rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]), @@ -3432,7 +3432,7 @@ function _find_anchor(anchor, geom) = anchor = _force_anchor_2d(anchor), rgn = force_region(move(-point2d(cp), p=geom[1])) ) - approx(anchor,[0,0])? [anchor, [0,0,0], BACK, 0] : + approx(anchor,[0,0])? [anchor, cp, BACK, 0] : let( isects = [ for (path=rgn, t=triplet(path,true)) let( @@ -3456,7 +3456,7 @@ function _find_anchor(anchor, geom) = ) [anchor, pos, vec, 0] ) : type == "rgn_extent"? ( //region let( anchor = _force_anchor_2d(anchor) ) - approx(anchor,[0,0])? [anchor, [0,0,0], BACK, 0] : + approx(anchor,[0,0])? [anchor, cp, BACK, 0] : let( rgn = force_region(geom[1]), rpts = rot(from=anchor, to=RIGHT, p=flatten(rgn)), From f078efe31418dde26064a0f972397e529c7dd7b4 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Thu, 1 Feb 2024 21:11:56 -0500 Subject: [PATCH 02/12] fix center anchors, offset_sweep anchors --- attachments.scad | 8 ++++---- rounding.scad | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/attachments.scad b/attachments.scad index 671513f..f375217 100644 --- a/attachments.scad +++ b/attachments.scad @@ -3333,7 +3333,7 @@ function _find_anchor(anchor, geom) = ) [anchor, pos, vec, oang] ) : type == "vnf_isect"? ( //vnf let( vnf=geom[1] ) - approx(anchor,CTR)? [anchor, cp, UP, 0] : + approx(anchor,CTR)? [anchor, cp, UP, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0] vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] : let( eps = 1/2048, @@ -3383,7 +3383,7 @@ function _find_anchor(anchor, geom) = [anchor, pos, n, oang] ) : type == "vnf_extent"? ( //vnf let( vnf=geom[1] ) - approx(anchor,CTR)? [anchor, cp, UP, 0] : + approx(anchor,CTR)? [anchor, cp, UP, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0] vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] : let( rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]), @@ -3432,7 +3432,7 @@ function _find_anchor(anchor, geom) = anchor = _force_anchor_2d(anchor), rgn = force_region(move(-point2d(cp), p=geom[1])) ) - approx(anchor,[0,0])? [anchor, cp, BACK, 0] : + approx(anchor,[0,0])? [anchor, cp, BACK, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0] let( isects = [ for (path=rgn, t=triplet(path,true)) let( @@ -3456,7 +3456,7 @@ function _find_anchor(anchor, geom) = ) [anchor, pos, vec, 0] ) : type == "rgn_extent"? ( //region let( anchor = _force_anchor_2d(anchor) ) - approx(anchor,[0,0])? [anchor, cp, BACK, 0] : + approx(anchor,[0,0])? [anchor, cp, BACK, 0] : // CENTER anchors anchor on cp, "origin" anchors on [0,0] let( rgn = force_region(geom[1]), rpts = rot(from=anchor, to=RIGHT, p=flatten(rgn)), diff --git a/rounding.scad b/rounding.scad index 75365cb..986c0b8 100644 --- a/rounding.scad +++ b/rounding.scad @@ -1365,8 +1365,13 @@ module offset_stroke(path, width=1, rounded=true, start, end, check_valid=true, // anchor = Translate so anchor point is at the origin. (module only) Default: "origin" // spin = Rotate this many degrees around Z axis after anchor. (module only) Default: 0 // orient = Vector to rotate top towards after spin (module only) -// atype = Select "hull" or "intersect" anchor types. Default: "hull" +// atype = Select "hull", "intersect", "surf_hull" or "surf_intersect" anchor types. Default: "hull" // cp = Centerpoint for determining "intersect" anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid" +// Anchor Types: +// hull = Anchors to the convex hull of the linear sweep of the path, ignoring any end roundings. +// intersect = Anchors to the surface of the linear sweep of the path, ignoring any end roundings. +// surf_hull = Anchors to the convex hull of the offset_sweep shape, including end treatments. +// surf_intersect = Anchors to the surface of the offset_sweep shape, including any end treatments. // Example: Rounding a star shaped prism with postive radius values // star = star(5, r=22, ir=13); // rounded_star = round_corners(star, cut=flatten(repeat([.5,0],5)), $fn=24); @@ -1641,12 +1646,21 @@ module offset_sweep(path, height, convexity=10,anchor="origin",cp="centroid", spin=0, orient=UP, atype="hull") { - assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\""); + assert(in_list(atype, ["intersect","hull","surf_hull","surf_intersect"]), "Anchor type must be \"hull\" or \"intersect\""); vnf = offset_sweep(path=path, height=height, h=h, l=l, top=top, bottom=bottom, offset=offset, r=r, steps=steps, quality=quality, check_valid=check_valid, extra=extra, cut=cut, chamfer_width=chamfer_width, chamfer_height=chamfer_height, joint=joint, k=k, angle=angle); - vnf_polyhedron(vnf,convexity=convexity,anchor=anchor, spin=spin, orient=orient, atype=atype, cp=cp) - children(); + + if (in_list(atype,["hull","intersect"])){ + h=first_defined([h,l,height]); + attachable(anchor,spin,orient,region=[path],h=h,extent=atype=="hull",cp=cp){ + down(h/2)polyhedron(vnf[0],vnf[1],convexity=convexity); + children(); + } + } + else + vnf_polyhedron(vnf,convexity=convexity,anchor=anchor, spin=spin, orient=orient, atype=atype=="surf_hull"?"hull":"intersect", cp=cp) + children(); } @@ -2032,7 +2046,7 @@ function _rp_compute_patches(top, bot, rtop, rsides, ktop, ksides, concave) = // k = continuous curvature rounding parameter for all edges. Default: 0.5 // k_top = continuous curvature rounding parameter for top // k_bot = continuous curvature rounding parameter for bottom -// k_bot = continuous curvature rounding parameter for bottom +// k_sides = continuous curvature rounding parameter side edges, a number or vector. // splinesteps = number of segments to use for curved patches. Default: 16 // debug = turn on debug mode which displays illegal polyhedra and shows the bezier corner patches for troubleshooting purposes. Default: False // convexity = convexity parameter for polyhedron(), only for module version. Default: 10 From 0ed6ce285d6695e4ee6e4d37b52b3c31d10456e6 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Fri, 2 Feb 2024 02:12:30 +0000 Subject: [PATCH 03/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 3a93162..c3eba25 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,709]; +BOSL_VERSION = [2,0,710]; // Section: BOSL Library Version Functions From 6ea79bfbf39d8e9c4ccdaa2bfae247f5100b23aa Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 3 Feb 2024 14:22:06 -0500 Subject: [PATCH 04/12] add override to attachments tutorial --- tutorials/Attachments.md | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tutorials/Attachments.md b/tutorials/Attachments.md index a55bf6f..cfaab74 100644 --- a/tutorials/Attachments.md +++ b/tutorials/Attachments.md @@ -1637,3 +1637,71 @@ sphere_pt = apply( ``` +## Overriding Standard Anchors + +Sometimes you may want to use the standard anchors but override some +of them. Returning to the square barebell example above, the anchors +at the right and left sides are on the cubes at each end, but the +anchors at x=0 are in floating in space. For prismoidal/cubic anchors +in 3D and trapezoidal/rectangular anchors in 2D we can override a single anchor by +specifying the override option and giving the anchor that is being +overridden, and then the replacement in the form +`[position, direction, spin]`. Below we override the FWD anchor: + +``` +module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { + override = [ + [FWD, [[0,-s/8,0], FWD, 0]] + ]; + attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { + union() { + xcopies(2*s) cube(s, center=true); + xcyl(h=2*s, d=s/4); + } + children(); + } +} +cubic_barbell(100) show_anchors(30); +``` + +Note how the FWD anchor is now rooted on the cylindrical portion. You +can override all of the x=0 anchors by supplying a list like this: + +``` +module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { + override = [ + for(j=[-1:1:1], k=[-1:1:1]) + if ([j,k]!=[0,0]) [[0,j,k], [s/8*unit([0,j,k]), unit([0,j,k]),0]] + ]; + attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { + union() { + xcopies(2*s) cube(s, center=true); + xcyl(h=2*s, d=s/4); + } + children(); + } +} +cubic_barbell(100) show_anchors(30); +``` + +Now the anchors in the middle are all rooted to the cylinder. Another +way to do the same thing is to use a function literal for override. +It will be called with the anchor and need to return undef to just use +the default, or a `[position, direction, spin]` triple to override the +default. Here is the same example using a function literal for the override: + +``` +module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { + override = function (anchor) + anchor.x!=0 || anchor==CTR ? undef // Keep these + : [s/8*unit(anchor), anchor, 0]; + attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { + union() { + xcopies(2*s) cube(s, center=true); + xcyl(h=2*s, d=s/4); + } + children(); + } +} +cubic_barbell(100) show_anchors(30); +``` From 478a5e8f16bde46f6ace4585d4500edccaf6e3d3 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sat, 3 Feb 2024 19:22:37 +0000 Subject: [PATCH 05/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index c3eba25..18225cb 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,710]; +BOSL_VERSION = [2,0,711]; // Section: BOSL Library Version Functions From 8f80872ba5af99377f9e8c304602b3252600d4ee Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sun, 4 Feb 2024 12:23:11 -0500 Subject: [PATCH 06/12] allow full cuboid rounding in rounded_prism; improve error checking --- rounding.scad | 52 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/rounding.scad b/rounding.scad index 986c0b8..bb88dc1 100644 --- a/rounding.scad +++ b/rounding.scad @@ -2026,6 +2026,11 @@ function _rp_compute_patches(top, bot, rtop, rsides, ktop, ksides, concave) = // joint_top[1] is negative the shape will flare upward. At least one value must be non-negative. The same rules apply for joint_bot. // The joint_sides parameter must be entirely nonnegative. // . +// If the roundings at two adjacent side edges exceed the width of the face then the polyhedron will have self-intersecting faces, so it will be invalid. +// Similarly, if the roundings on the top or bottom edges cross the top face and intersect with each other, the resulting polyhedron is invalid: +// the top face after the roundings are applied must be a valid, non-degenerate polyhedron. There are two exceptions: it is permissible to +// construct a top that is a single point or two points. This means you can completely round a cube by setting the joint to half of +// the cube's width. // If you set `debug` to true the module version will display the polyhedron even when it is invalid and it will show the bezier patches at the corners. // This can help troubleshoot problems with your parameters. With the function form setting debug to true causes it to return [patches,vnf] where // patches is a list of the bezier control points for the corner patches. @@ -2210,23 +2215,44 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b bot_patch = _rp_compute_patches(bottom, top, joint_bot, joint_sides_vec, k_bot, k_sides_vec, concave), vertbad = [for(i=[0:N-1]) - if (norm(top[i]-top_patch[i][4][2]) + norm(bottom[i]-bot_patch[i][4][2]) > norm(bottom[i]-top[i])) i], + if (norm(top[i]-top_patch[i][4][2]) + norm(bottom[i]-bot_patch[i][4][2]) > EPSILON + norm(bottom[i]-top[i])) i], + // Check that the patch fits on the polygon edge topbad = [for(i=[0:N-1]) if (norm(top_patch[i][2][4]-top_patch[i][2][2]) + norm(select(top_patch,i+1)[2][0]-select(top_patch,i+1)[2][2]) - > norm(top_patch[i][2][2] - select(top_patch,i+1)[2][2])) [i,(i+1)%N]], + > EPSILON + norm(top_patch[i][2][2] - select(top_patch,i+1)[2][2])) [i,(i+1)%N]], botbad = [for(i=[0:N-1]) if (norm(bot_patch[i][2][4]-bot_patch[i][2][2]) + norm(select(bot_patch,i+1)[2][0]-select(bot_patch,i+1)[2][2]) - > norm(bot_patch[i][2][2] - select(bot_patch,i+1)[2][2])) [i,(i+1)%N]], - topinbad = [for(i=[0:N-1]) + > EPSILON + norm(bot_patch[i][2][2] - select(bot_patch,i+1)[2][2])) [i,(i+1)%N]], + // If top/bot is L-shaped, check that arms of L from adjacent patches don't cross + topLbad = [for(i=[0:N-1]) if (norm(top_patch[i][0][2]-top_patch[i][0][4]) + norm(select(top_patch,i+1)[0][0]-select(top_patch,i+1)[0][2]) - > norm(top_patch[i][0][2]-select(top_patch,i+1)[0][2])) [i,(i+1)%N]], - botinbad = [for(i=[0:N-1]) + > EPSILON + norm(top_patch[i][0][2]-select(top_patch,i+1)[0][2])) [i,(i+1)%N]], + botLbad = [for(i=[0:N-1]) if (norm(bot_patch[i][0][2]-bot_patch[i][0][4]) + norm(select(bot_patch,i+1)[0][0]-select(bot_patch,i+1)[0][2]) - > norm(bot_patch[i][0][2]-select(bot_patch,i+1)[0][2])) [i,(i+1)%N]] + > EPSILON + norm(bot_patch[i][0][2]-select(bot_patch,i+1)[0][2])) [i,(i+1)%N]], + // Check that the inner edges of the patch don't cross + topinbad = [for(i=[0:N-1]) + let( + line1 = project_plane(top,[top_patch[i][2][0],top_patch[i][0][0]]), + line2 = project_plane(top,[select(top_patch,i+1)[2][4],select(top_patch,i+1)[0][4]]) + ) + if (!approx(line1[0],line1[1]) && !approx(line2[0],line2[1]) && + line_intersection(line1,line2, SEGMENT,SEGMENT)) + [i,(i+1)%N]], + botinbad = [for(i=[0:N-1]) + let( + line1 = project_plane(bottom,[bot_patch[i][2][0],bot_patch[i][0][0]]), + line2 = project_plane(bottom,[select(bot_patch,i+1)[2][4],select(bot_patch,i+1)[0][4]]) + ) + if (!approx(line1[0],line1[1]) && !approx(line2[0],line2[1]) && + line_intersection(line1,line2, SEGMENT,SEGMENT)) + [i,(i+1)%N]] ) assert(debug || vertbad==[], str("Top and bottom joint lengths are too large; they interfere with each other at vertices: ",vertbad)) - assert(debug || topbad==[], str("Joint lengths too large at top edges: ",topbad)) - assert(debug || botbad==[], str("Joint lengths too large at bottom edges: ",botbad)) + assert(debug || topbad==[], str("Joint lengths too large at top or side edges: ",topbad)) + assert(debug || botbad==[], str("Joint lengths too large at bottom or side edges: ",botbad)) + assert(debug || topLbad==[], str("Joint length too large on the top face or side at edges: ", topLbad)) + assert(debug || botLbad==[], str("Joint length too large on the bottom face or side at edges: ", botLbad)) assert(debug || topinbad==[], str("Joint length too large on the top face at edges: ", topinbad)) assert(debug || botinbad==[], str("Joint length too large on the bottom face at edges: ", botinbad)) let( @@ -2256,8 +2282,12 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b top_patch[i][4][4] ] ], - top_simple = is_path_simple(project_plane(faces[0],faces[0]),closed=true), - bot_simple = is_path_simple(project_plane(faces[1],faces[1]),closed=true), + top_collinear = is_collinear(faces[0]), + bot_collinear = is_collinear(faces[1]), + top_degen_ok = top_collinear && len(deduplicate(faces[0]))<=2, + bot_degen_ok = bot_collinear && len(deduplicate(faces[1]))<=2, + top_simple = top_degen_ok || (!top_collinear && is_path_simple(project_plane(faces[0],faces[0]),closed=true)), + bot_simple = bot_degen_ok || (!bot_collinear && is_path_simple(project_plane(faces[1],faces[1]),closed=true)), // verify vertical edges verify_vert = [for(i=[0:N-1],j=[0:4]) From af90c93192894ab936e773b63d5d3e708e8696c2 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sun, 4 Feb 2024 17:23:42 +0000 Subject: [PATCH 07/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 18225cb..d01bee7 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,711]; +BOSL_VERSION = [2,0,712]; // Section: BOSL Library Version Functions From c6b24793c99664f329ad1da08d3335f70678ec25 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sun, 4 Feb 2024 21:11:27 +0000 Subject: [PATCH 08/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index e6433fe..a84bdc6 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,712]; +BOSL_VERSION = [2,0,713]; From 6621a918b996e6b1b767212e0d74b54795bee35a Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sun, 4 Feb 2024 18:19:24 -0500 Subject: [PATCH 09/12] improve fillet() anchors, add example to attachments tutorial --- shapes3d.scad | 6 ++++- tutorials/Attachments.md | 50 +++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/shapes3d.scad b/shapes3d.scad index 26026ad..b1dcc4b 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -3349,7 +3349,11 @@ module fillet(l=1.0, r, ang=90, overlap=0.01, d, length, h, height, anchor=CENTE arc[0] + polar_to_xy(overlap, 90+ang), each arc ]; - attachable(anchor,spin,orient, size=[2*maxx,2*maxy,l]) { + override = function (anchor) + anchor.x>=0 && anchor.y>=0 ? undef + : + [[max(0,anchor.x)*maxx, max(0,anchor.y)*maxy, anchor.z*l/2]]; + attachable(anchor,spin,orient, size=[2*maxx,2*maxy,l],override=override) { if (l > 0) { linear_extrude(height=l, convexity=4, center=true) { polygon(path); diff --git a/tutorials/Attachments.md b/tutorials/Attachments.md index cfaab74..9efa7c5 100644 --- a/tutorials/Attachments.md +++ b/tutorials/Attachments.md @@ -1262,7 +1262,7 @@ module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { children(); } } -cubic_barbell(100) show_anchors(30); +cubic_barbell(100) show_anchors(60); ``` When the shape is prismoidal, where the top is a different size from the bottom, you can use @@ -1646,12 +1646,15 @@ anchors at x=0 are in floating in space. For prismoidal/cubic anchors in 3D and trapezoidal/rectangular anchors in 2D we can override a single anchor by specifying the override option and giving the anchor that is being overridden, and then the replacement in the form -`[position, direction, spin]`. Below we override the FWD anchor: +`[position, direction, spin]`. Most often you will only want to +override the position. If you omit the other list items then the +value drived from the standard anchor will be used. Below we override +position of the FWD anchor: ``` module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { override = [ - [FWD, [[0,-s/8,0], FWD, 0]] + [FWD, [[0,-s/8,0]]] ]; attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { union() { @@ -1661,17 +1664,41 @@ module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { children(); } } -cubic_barbell(100) show_anchors(30); +cubic_barbell(100) show_anchors(60); ``` -Note how the FWD anchor is now rooted on the cylindrical portion. You -can override all of the x=0 anchors by supplying a list like this: +Note how the FWD anchor is now rooted on the cylindrical portion. If +you wanted to also change its direction and spin you could do it like +this: +``` +module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { + override = [ + [FWD, [[0,-s/8,0], FWD+LEFT, 225]] + ]; + attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { + union() { + xcopies(2*s) cube(s, center=true); + xcyl(h=2*s, d=s/4); + } + children(); + } +} +cubic_barbell(100) show_anchors(60); +``` + +In the above example we give three values for the override. As +before, the first one places the anchor on the cylinder. We have +added the second entry which points the anchor off to the left. +The third entry gives a spin override, whose effect is shown by the +position of the red flag on the arrow. If you want to override all of +the x=0 anchors to be on the cylinder, with their standard directions, +you can do that by supplying a list: ``` module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { override = [ for(j=[-1:1:1], k=[-1:1:1]) - if ([j,k]!=[0,0]) [[0,j,k], [s/8*unit([0,j,k]), unit([0,j,k]),0]] + if ([j,k]!=[0,0]) [[0,j,k], [s/8*unit([0,j,k])]] ]; attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { union() { @@ -1684,17 +1711,18 @@ module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { cubic_barbell(100) show_anchors(30); ``` -Now the anchors in the middle are all rooted to the cylinder. Another +Now all of the anchors in the middle are all rooted to the cylinder. Another way to do the same thing is to use a function literal for override. -It will be called with the anchor and need to return undef to just use +It will be called with the anchor as its argument and needs to return undef to just use the default, or a `[position, direction, spin]` triple to override the -default. Here is the same example using a function literal for the override: +default. As before, you can omit values to keep their default. +Here is the same example using a function literal for the override: ``` module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) { override = function (anchor) anchor.x!=0 || anchor==CTR ? undef // Keep these - : [s/8*unit(anchor), anchor, 0]; + : [s/8*unit(anchor)]; attachable(anchor,spin,orient, size=[s*3,s,s],override=override) { union() { xcopies(2*s) cube(s, center=true); From fda2545e8d77c4457b96a908147c17e8b081dcf6 Mon Sep 17 00:00:00 2001 From: adrianVmariano Date: Sun, 4 Feb 2024 23:19:50 +0000 Subject: [PATCH 10/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index a84bdc6..fb8477d 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,713]; +BOSL_VERSION = [2,0,714]; From 8578478552b6da7010c85e6c804914734415c2fc Mon Sep 17 00:00:00 2001 From: revarbat Date: Tue, 6 Feb 2024 18:11:55 +0000 Subject: [PATCH 11/12] Version Bump --- version.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.scad b/version.scad index fb8477d..a5aeca2 100644 --- a/version.scad +++ b/version.scad @@ -10,7 +10,7 @@ -BOSL_VERSION = [2,0,714]; +BOSL_VERSION = [2,0,715]; From e58cfa0ba139172b62d1eb39d606d5c1a7ba2bdb Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Tue, 6 Feb 2024 10:26:34 -0800 Subject: [PATCH 12/12] Minor docs fixes. Removed VersionBump workflow. --- .github/workflows/pr_merge.yml | 28 ---------------------------- rounding.scad | 6 +++--- 2 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 .github/workflows/pr_merge.yml diff --git a/.github/workflows/pr_merge.yml b/.github/workflows/pr_merge.yml deleted file mode 100644 index fc8b618..0000000 --- a/.github/workflows/pr_merge.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: VersionBump -on: - push: - branches: - - master - -jobs: - VersionBumpJob: - runs-on: ubuntu-latest - - permissions: - contents: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - - - name: Bump Version - run: ./scripts/increment_version.sh - - - name: Checkin - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: Version Bump - file_pattern: version.scad - diff --git a/rounding.scad b/rounding.scad index bb88dc1..b2d973a 100644 --- a/rounding.scad +++ b/rounding.scad @@ -1383,15 +1383,15 @@ module offset_stroke(path, width=1, rounded=true, start, end, check_valid=true, // Example: If the shape has sharp corners, make sure to set `$fn/$fs/$fa`. The corners of this triangle are not round, even though `offset="round"` (the default) because the number of segments is small. // triangle = [[0,0],[10,0],[5,10]]; // offset_sweep(triangle, height=6, bottom = os_circle(r=-2),steps=4); -// Example: Can improve the result by increasing $fn +// Example: Can improve the result by increasing `$fn` // $fn=12; // triangle = [[0,0],[10,0],[5,10]]; // offset_sweep(triangle, height=6, bottom = os_circle(r=-2),steps=4); -// Example: Using $fa and $fs works too; it produces a different looking triangulation of the rounded corner +// Example: Using `$fa` and `$fs` works too; it produces a different looking triangulation of the rounded corner // $fa=1;$fs=0.3; // triangle = [[0,0],[10,0],[5,10]]; // offset_sweep(triangle, height=6, bottom = os_circle(r=-2),steps=4); -// Example: Here is the star chamfered at the top with a teardrop rounding at the bottom. Check out the rounded corners on the chamfer. The large $fn value ensures a smooth curve on the concave corners of the chamfer. It has no effect anywhere else on the model. Observe how the rounded star points vanish at the bottom in the teardrop: the number of vertices does not remain constant from layer to layer. +// Example: Here is the star chamfered at the top with a teardrop rounding at the bottom. Check out the rounded corners on the chamfer. The large `$fn` value ensures a smooth curve on the concave corners of the chamfer. It has no effect anywhere else on the model. Observe how the rounded star points vanish at the bottom in the teardrop: the number of vertices does not remain constant from layer to layer. // star = star(5, r=22, ir=13); // rounded_star = round_corners(star, cut=flatten(repeat([.5,0],5)), $fn=24); // offset_sweep(rounded_star, height=20, bottom=os_teardrop(r=4), top=os_chamfer(width=4),$fn=64);