From f8075093520cf6798999f33b7878ee10fd57a49c Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sat, 8 May 2021 17:22:23 -0700 Subject: [PATCH 1/5] Tweaks to edges.scad docs. --- edges.scad | 55 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/edges.scad b/edges.scad index fbc4786e..43d58c5a 100644 --- a/edges.scad +++ b/edges.scad @@ -60,7 +60,6 @@ function _edges_text(edges) = // Section: Edge Constants -// Constants for working with edges. // Constant: EDGES_NONE // Topics: Edges @@ -83,6 +82,7 @@ EDGES_ALL = [[1,1,1,1], [1,1,1,1], [1,1,1,1]]; // Constant: EDGES_OFFSETS +// Topics: Edges // See Also: EDGES_NONE, EDGES_ALL, edges() // Description: // The vectors pointing to the center of each edge of a unit sized cube. @@ -110,11 +110,15 @@ EDGE_OFFSETS = [ // Section: Edge Helpers // Function: is_edge_array() +// Topics: Edges, Type Checking // Usage: -// is_edge_array(v) +// bool = is_edge_array(x); // Description: // Returns true if the given value has the form of an edge array. -function is_edge_array(v) = is_list(v) && is_vector(v[0]) && len(v)==3 && len(v[0])==4; +// Arguments: +// x = The item to check the type of. +// See Also: edges(), EDGES_NONE, EDGES_ALL +function is_edge_array(x) = is_list(x) && is_vector(x[0]) && len(x)==3 && len(x[0])==4; function _edge_set(v) = @@ -150,18 +154,22 @@ function _edge_set(v) = // Function: normalize_edges() +// Topics: Edges // Usage: -// normalize_edges(v); +// edges = normalize_edges(v); // Description: // Normalizes all values in an edge array to be `1`, if it was originally greater than `0`, // or `0`, if it was originally less than or equal to `0`. +// See Also: is_edge_array(), edges(), EDGES_NONE, EDGES_ALL function normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]]; // Function: edges() +// Topics: Edges // Usage: -// edges(v) -// edges(v, except) +// edgs = edges(v); +// edgs = edges(v, except); +// // Description: // Takes a list of edge set descriptors, and returns a normalized edges array // that represents all those given edges. If the `except` argument is given @@ -251,6 +259,8 @@ function normalize_edges(v) = [for (ax=v) [for (edge=ax) edge>0? 1 : 0]]; // v = The edge set to include. // except = The edge set to specifically exclude, even if they are in `v`. // +// See Also: is_edge_array(), normalize_edges(), EDGES_NONE, EDGES_ALL +// // Example(3D): Just the front-top edge // edg = edges(FRONT+TOP); // show_edges(edges=edg); @@ -283,6 +293,7 @@ function edges(v, except=[]) = // Module: show_edges() +// Topics: Edges, Debugging // Usage: // show_edges(edges, , , ); // Description: @@ -292,6 +303,7 @@ function edges(v, except=[]) = // size = The scalar size of the cube. // text = The text to show on the front of the cube. // txtsize = The size of the text. +// See Also: is_edge_array(), edges(), EDGES_NONE, EDGES_ALL // Example: // show_edges(size=30, edges=["X","Y"]); module show_edges(edges="ALL", size=20, text, txtsize=3) { @@ -319,28 +331,31 @@ module show_edges(edges="ALL", size=20, text, txtsize=3) { // Constant: CORNERS_NONE -// See Also: CORNERS_ALL, corners() +// Topics: Corners // Description: // The set of no corners. // Figure(3D): // show_corners(corners="NONE"); +// See Also: CORNERS_ALL, corners() CORNERS_NONE = [0,0,0,0,0,0,0,0]; // No corners. // Constant: CORNERS_ALL -// See Also: CORNERS_NONE, corners() +// Topics: Corners // Description: // The set of all corners. // Figure(3D): // show_corners(corners="ALL"); +// See Also: CORNERS_NONE, corners() CORNERS_ALL = [1,1,1,1,1,1,1,1]; // Constant: CORNER_OFFSETS -// See Also: CORNERS_NONE, CORNERS_ALL, corners() +// Topics: Corners // Description: // The vectors pointing to each corner of a unit sized cube. // Each item in a corner array will have a corresponding vector in this array. +// See Also: CORNERS_NONE, CORNERS_ALL, corners() CORNER_OFFSETS = [ [-1,-1,-1], [ 1,-1,-1], [-1, 1,-1], [ 1, 1,-1], [-1,-1, 1], [ 1,-1, 1], [-1, 1, 1], [ 1, 1, 1] @@ -351,19 +366,23 @@ CORNER_OFFSETS = [ // Section: Corner Helpers // Function: is_corner_array() +// Topics: Corners, Type Checking // Usage: -// is_corner_array(v) +// bool = is_corner_array(x) // Description: // Returns true if the given value has the form of a corner array. -function is_corner_array(v) = is_vector(v) && len(v)==8 && all([for (x=v) x==1||x==0]); +// See Also: CORNERS_NONE, CORNERS_ALL, corners() +function is_corner_array(x) = is_vector(x) && len(x)==8 && all([for (xx=x) xx==1||xx==0]); // Function: normalize_corners() +// Topics: Corners // Usage: -// normalize_corners(v); +// corns = normalize_corners(v); // Description: // Normalizes all values in a corner array to be `1`, if it was originally greater than `0`, // or `0`, if it was originally less than or equal to `0`. +// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners() function normalize_corners(v) = [for (x=v) x>0? 1 : 0]; @@ -387,9 +406,10 @@ function _corner_set(v) = // Function: corners() +// Topics: Corners // Usage: -// corners(v) -// corners(v, except) +// corns = corners(v); +// corns = corners(v, except); // Description: // Takes a list of corner set descriptors, and returns a normalized corners array // that represents all those given corners. If the `except` argument is given @@ -460,6 +480,7 @@ function _corner_set(v) = // show_corners(corners="ALL"); // show_corners(corners="NONE"); // } +// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), normalize_corners() // Example(3D): Just the front-top-right corner // crn = corners(FRONT+TOP+RIGHT); // show_corners(corners=crn); @@ -486,22 +507,26 @@ function corners(v, except=[]) = // Function: corner_edges() +// Topics: Corners // Description: // Returns [XCOUNT,YCOUNT,ZCOUNT] where each is the count of edges aligned with that // axis that are in the edge set and touch the given corner. // Arguments: // edges = Standard edges array. // v = Vector pointing to the corner to count edge intersections at. +// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners(), corner_edge_count() function corner_edges(edges, v) = let(u = (v+[1,1,1])/2) [edges[0][u.y+u.z*2], edges[1][u.x+u.z*2], edges[2][u.x+u.y*2]]; // Function: corner_edge_count() +// Topics: Corners // Description: // Counts how many given edges intersect at a specific corner. // Arguments: // edges = Standard edges array. // v = Vector pointing to the corner to count edge intersections at. +// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners(), corner_edges() function corner_edge_count(edges, v) = let(u = (v+[1,1,1])/2) edges[0][u.y+u.z*2] + edges[1][u.x+u.z*2] + edges[2][u.x+u.y*2]; @@ -528,6 +553,7 @@ function _corners_text(corners) = // Module: show_corners() +// Topics: Corners, Debugging // Usage: // show_corners(corners, , , ); // Description: @@ -537,6 +563,7 @@ function _corners_text(corners) = // size = The scalar size of the cube. // text = If given, overrides the text to be shown on the front of the cube. // txtsize = The size of the text. +// See Also: CORNERS_NONE, CORNERS_ALL, is_corner_array(), corners() // Example: // show_corners(corners=FWD+RIGHT, size=30); module show_corners(corners="ALL", size=20, text, txtsize=3) { From dff1fc10daf74b2d4ac2605ea5e49726a53415a4 Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 9 May 2021 16:43:48 -0700 Subject: [PATCH 2/5] Merged bottleecaps_adapters.scad into bottlecaps.scad. --- bottlecaps.scad | 563 +++++++++++++++++++++++++++++++++++++- bottlecaps_adapters.scad | 572 --------------------------------------- 2 files changed, 562 insertions(+), 573 deletions(-) delete mode 100644 bottlecaps_adapters.scad diff --git a/bottlecaps.scad b/bottlecaps.scad index 30916f91..a65da94f 100644 --- a/bottlecaps.scad +++ b/bottlecaps.scad @@ -329,7 +329,7 @@ function pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP) = // Module: pco1881_cap() // Usage: -// pco1881_cap(wall, [texture]); +// pco1881_cap(wall, ); // Description: // Creates a basic cap for a PCO1881 threaded beverage bottle. // Arguments: @@ -387,4 +387,565 @@ function pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) = +// Section: Generic Bottle Connectors + +// Module: generic_bottle_neck() +// Usage: +// generic_bottle_neck(, ...) +// Description: +// Creates a bottle neck given specifications. +// Arguments: +// wall = distance between ID and any wall that may be below the support +// neck_d = Outer diameter of neck without threads +// id = Inner diameter of neck +// thread_od = Outer diameter of thread +// height = Height of neck above support +// support_d = Outer diameter of support ring. Set to 0 for no support. +// pitch = Thread pitch +// round_supp = True to round the lower edge of the support ring +// --- +// 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` +// Extra Anchors: +// "support-ring" = Centered at the bottom of the support ring. +// Example: +// generic_bottle_neck(); +module generic_bottle_neck( + wall, + neck_d = 25, + id = 21.4, + thread_od = 27.2, + height = 17, + support_d = 33.0, + pitch = 3.2, + round_supp = false, + anchor = "support-ring", + spin = 0, + orient = UP +) { + inner_d = id; + neck_d = neck_d; + supp_d = max(neck_d, support_d); + thread_pitch = pitch; + thread_angle = 15; + + diamMagMult = neck_d / 26.19; + heightMagMult = height / 17.00; + + sup_r = 0.30 * (heightMagMult > 1 ? heightMagMult : 1); + support_r = floor(((supp_d == neck_d) ? sup_r : min(sup_r, (supp_d - neck_d) / 2)) * 5000) / 10000; + support_rad = (wall == undef || !round_supp) ? support_r : + min(support_r, floor((supp_d - (inner_d + 2 * wall)) * 5000) / 10000); + //Too small of a radius will cause errors with the arc, this limits granularity to .0001mm + support_width = 1 * (heightMagMult > 1 ? heightMagMult : 1) * sign(support_d); + roundover = 0.58 * diamMagMult; + lip_roundover_r = (roundover > (neck_d - inner_d) / 2) ? 0 : roundover; + h = height + support_width; + threadbase_d = neck_d - 0.8 * diamMagMult; + + $fn = segs(33 / 2); + thread_h = (thread_od - threadbase_d) / 2; + anchors = [ + anchorpt("support-ring", [0, 0, 0 - h / 2]) + ]; + attachable(anchor, spin, orient, d1 = neck_d, d2 = 0, l = h, anchors = anchors) { + down(h / 2) { + rotate_extrude(convexity = 10) { + polygon(turtle( + state = [inner_d / 2, 0], (supp_d != neck_d) ? [ + "untilx", supp_d / 2 - ((round_supp) ? support_rad : 0), + "arcleft", ((round_supp) ? support_rad : 0), 90, + "untily", support_width - support_rad, + "arcleft", support_rad, 90, + "untilx", neck_d / 2, + "right", 90, + "untily", h - lip_roundover_r, + "arcleft", lip_roundover_r, 90, + "untilx", inner_d / 2 + ] : [ + "untilx", supp_d / 2 - ((round_supp) ? support_rad : 0), + "arcleft", ((round_supp) ? support_rad : 0), 90, + "untily", h - lip_roundover_r, + "arcleft", lip_roundover_r, 90, + "untilx", inner_d / 2 + ] + )); + } + up(h - pitch / 2 - lip_roundover_r) { + difference() { + thread_helix( + d = threadbase_d - 0.1 * diamMagMult, + pitch = thread_pitch, + thread_depth = thread_h + 0.1 * diamMagMult, + thread_angle = thread_angle, + twist = 360 * (height - pitch - lip_roundover_r) * .6167 / pitch, + higbee = thread_h * 2, + anchor = TOP + ); + zrot_copies(rots = [90, 270]) { + zrot_copies(rots = [-28, 28], r = threadbase_d / 2) { + prismoid( + [20 * heightMagMult, 1.82 * diamMagMult], + [20 * heightMagMult, 1.82 * diamMagMult * .6 + 2 * sin(29) * thread_h], + h = thread_h + 0.1 * diamMagMult, + anchor = BOT, + orient = RIGHT + ); + } + } + } + } + } + children(); + } +} + +function generic_bottle_neck( + neck_d, + id, + thread_od, + height, + support_d, + pitch, + round_supp, + wall, + anchor, spin, orient +) = no_function("generic_bottle_neck"); + + +// Module: generic_bottle_cap() +// Usage: +// generic_bottle_cap(wall, , ...); +// Description: +// Creates a basic threaded cap given specifications. +// Arguments: +// wall = Wall thickness in mm. +// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" +// --- +// height = Interior height of the cap in mm. +// thread_od = Outer diameter of the threads in mm. +// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. +// neck_od = Outer diameter of neck in mm. +// thread_angle = Angle of taper on threads. +// pitch = Thread pitch in mm. +// 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` +// Extra Anchors: +// "inside-top" = Centered on the inside top of the cap. +// Examples: +// generic_bottle_cap(); +// generic_bottle_cap(texture="knurled"); +// generic_bottle_cap(texture="ribbed"); +module generic_bottle_cap( + wall = 2, + texture = "none", + height = 11.2, + thread_od = 28.58, + tolerance = .2, + neck_od = 25.5, + thread_angle = 15, + pitch = 4, + anchor = BOTTOM, + spin = 0, + orient = UP +) { + $fn = segs(33 / 2); + threadOuterDTol = thread_od + 2 * tolerance; + w = threadOuterDTol + 2 * wall; + h = height + wall; + neckOuterDTol = neck_od + 2 * tolerance; + threadDepth = (thread_od - neck_od) / 2 + .8; + + diamMagMult = (w > 32.58) ? w / 32.58 : 1; + heightMagMult = (height > 11.2) ? height / 11.2 : 1; + + anchors = [ + anchorpt("inside-top", [0, 0, -(h / 2 - wall)]) + ]; + attachable(anchor, spin, orient, d = w, l = h, anchors = anchors) { + down(h / 2) { + difference() { + union() { + // For the knurled and ribbed caps the PCO caps in BOSL2 cut into the wall + // thickness so the wall+texture are the specified wall thickness. That + // seems wrong so this does specified thickness+texture + if (texture == "knurled") { + knurled_cylinder(d = w + 1.5 * diamMagMult, helix = 45, l = h, anchor = BOTTOM); + cyl(d = w, l = h, anchor = BOTTOM); + } else if (texture == "ribbed") { + zrot_copies(n = 30, r = (w + .2 * diamMagMult) / 2) { + cube([1 * diamMagMult, 1 * diamMagMult, h], anchor = BOTTOM); + } + cyl(d = w, l = h, anchor = BOTTOM); + } else { + cyl(d = w, l = h, anchor = BOTTOM); + } + } + up(wall) cyl(d = threadOuterDTol, h = h, anchor = BOTTOM); + } + difference(){ + up(wall + pitch / 2) { + thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, thread_angle = thread_angle, twist = 360 * ((height - pitch) / pitch), higbee = threadDepth, internal = true, anchor = BOTTOM); + } + } + } + children(); + } +} + +function generic_bottle_cap( + wall, texture, height, + thread_od, tolerance, + neck_od, thread_angle, pitch, + anchor, spin, orient +) = no_function("generic_bottle_cap"); + + +// Module: thread_adapter_NC() +// Usage: +// thread_adapter_NC(wall, ); +// Description: +// Creates a threaded neck to cap adapter +// Arguments: +// wall = Thickness of wall between neck and cap when d=0. Leave undefined to have the outside of the tube go from the OD of the neck support ring to the OD of the cap. Default: undef +// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" +// cap_wall = Wall thickness of the cap in mm. +// cap_h = Interior height of the cap in mm. +// cap_thread_od = Outer diameter of cap threads in mm. +// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. +// cap_neck_od = Inner diameter of the cap threads. +// cap_neck_id = Inner diameter of the hole through the cap. +// cap_thread_taper = Angle of taper on threads. +// cap_thread_pitch = Thread pitch in mm +// neck_d = Outer diameter of neck w/o threads +// neck_id = Inner diameter of neck +// neck_thread_od = 27.2 +// neck_h = Height of neck down to support ring +// neck_thread_pitch = Thread pitch in mm. +// neck_support_od = Outer diameter of neck support ring. Leave undefined to set equal to OD of cap. Set to 0 for no ring. Default: undef +// d = Distance between bottom of neck and top of cap +// taper_lead_in = Length to leave straight before tapering on tube between neck and cap if exists. +// Examples: +// thread_adapter_NC(); +module thread_adapter_NC( + wall, + texture = "none", + cap_wall = 2, + cap_h = 11.2, + cap_thread_od = 28.58, + tolerance = .2, + cap_neck_od = 25.5, + cap_neck_id, + cap_thread_taper = 15, + cap_thread_pitch = 4, + neck_d = 25, + neck_id = 21.4, + neck_thread_od = 27.2, + neck_h = 17, + neck_thread_pitch = 3.2, + neck_support_od, + d = 0, + taper_lead_in = 0 +) { + neck_support_od = (neck_support_od == undef || (d == 0 && neck_support_od < cap_thread_od + 2 * tolerance)) ? cap_thread_od + 2 * (cap_wall + tolerance) : neck_support_od; + cap_neck_id = (cap_neck_id == undef) ? neck_id : cap_neck_id; + wall = (wall == undef) ? neck_support_od + neck_d + cap_thread_od + neck_id : wall; + + $fn = segs(33 / 2); + wallt1 = min(wall, (max(neck_support_od, neck_d) - neck_id) / 2); + wallt2 = min(wall, (cap_thread_od + 2 * (cap_wall + tolerance) - cap_neck_id) / 2); + + difference(){ + union(){ + up(d / 2) { + generic_bottle_neck(neck_d = neck_d, + id = neck_id, + thread_od = neck_thread_od, + height = neck_h, + support_d = neck_support_od, + pitch = neck_thread_pitch, + round_supp = ((wallt1 < (neck_support_od - neck_id) / 2) && (d > 0 || neck_support_od > (cap_thread_od + 2 * (cap_wall + tolerance)))), + wall = (d > 0) ? wallt1 : min(wallt1, ((cap_thread_od + 2 * (cap_wall + tolerance) - neck_id) / 2)) + ); + } + if (d != 0) { + rotate_extrude(){ + polygon(points = [ + [0, d / 2], + [neck_id / 2 + wallt1, d / 2], + [neck_id / 2 + wallt1, d / 2 - taper_lead_in], + [cap_neck_id / 2 + wallt2, taper_lead_in - d / 2], + [cap_neck_id / 2 + wallt2, -d / 2], + [0, -d / 2] + ]); + } + } + down(d / 2){ + generic_bottle_cap(wall = cap_wall, + texture = texture, + height = cap_h, + thread_od = cap_thread_od, + tolerance = tolerance, + neck_od = cap_neck_od, + thread_angle = cap_thread_taper, + orient = DOWN, + pitch = cap_thread_pitch + ); + } + } + rotate_extrude() { + polygon(points = [ + [0, d / 2 + 0.1], + [neck_id / 2, d / 2], + [neck_id / 2, d / 2 - taper_lead_in], + [cap_neck_id / 2, taper_lead_in - d / 2], + [cap_neck_id / 2, -d / 2 - cap_wall], + [0, -d / 2 - cap_wall - 0.1] + ]); + } + } +} + +function thread_adapter_NC( + wall, texture, cap_wall, cap_h, cap_thread_od, + tolerance, cap_neck_od, cap_neck_id, cap_thread_taper, + cap_thread_pitch, neck_d, neck_id, neck_thread_od, + neck_h, neck_thread_pitch, neck_support_od, d, taper_lead_in +) = no_fuction("thread_adapter_NC"); + + +// Module: thread_adapter_CC() +// Usage: +// thread_adapter_CC(wall, ); +// Description: +// Creates a threaded cap to cap adapter. +// Arguments: +// wall = Wall thickness in mm. +// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" +// cap_h1 = Interior height of top cap. +// cap_thread_od1 = Outer diameter of threads on top cap. +// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. +// cap_neck_od1 = Inner diameter of threads on top cap. +// cap_thread_pitch1 = Thread pitch of top cap in mm. +// cap_h2 = Interior height of bottom cap. Leave undefined to duplicate cap_h1. +// cap_thread_od2 = Outer diameter of threads on bottom cap. Leave undefined to duplicate capThread1. +// cap_neck_od2 = Inner diameter of threads on top cap. Leave undefined to duplicate cap_neck_od1. +// cap_thread_pitch2 = Thread pitch of bottom cap in mm. Leave undefinced to duplicate cap_thread_pitch1. +// d = Distance between caps. +// neck_id1 = Inner diameter of cutout in top cap. +// neck_id2 = Inner diameter of cutout in bottom cap. +// taper_lead_in = Length to leave straight before tapering on tube between caps if exists. +// Examples: +// thread_adapter_CC(); +module thread_adapter_CC( + wall = 2, + texture = "none", + cap_h1 = 11.2, + cap_thread_od1 = 28.58, + tolerance = .2, + cap_neck_od1 = 25.5, + cap_thread_pitch1 = 4, + cap_h2, + cap_thread_od2, + cap_neck_od2, + cap_thread_pitch2, + d = 0, + neck_id1, neck_id2, + taper_lead_in = 0 +) { + cap_h2 = (cap_h2 == undef) ? cap_h1 : cap_h2; + cap_thread_od2 = (cap_thread_od2 == undef) ? cap_thread_od1 : cap_thread_od2; + cap_neck_od2 = (cap_neck_od2 == undef) ? cap_neck_od1 : cap_neck_od2; + cap_thread_pitch2 = (cap_thread_pitch2 == undef) ? cap_thread_pitch1 : cap_thread_pitch2; + neck_id2 = (neck_id2 == undef && neck_id1 != undef) ? neck_id1 : neck_id2; + taper_lead_in = (d >= taper_lead_in * 2) ? taper_lead_in : d / 2; + + + $fn = segs(33 / 2); + + difference(){ + union(){ + up(d / 2){ + generic_bottle_cap( + orient = UP, + wall = wall, + texture = texture, + height = cap_h1, + thread_od = cap_thread_od1, + tolerance = tolerance, + neck_od = cap_neck_od1, + pitch = cap_thread_pitch1 + ); + } + if (d != 0) { + rotate_extrude() { + polygon(points = [ + [0, d / 2], + [cap_thread_od1 / 2 + (wall + tolerance), d / 2], + [cap_thread_od1 / 2 + (wall + tolerance), d / 2 - taper_lead_in], + [cap_thread_od2 / 2 + (wall + tolerance), taper_lead_in - d / 2], + [cap_thread_od2 / 2 + (wall + tolerance), -d / 2], + [0, -d / 2] + ]); + } + } + down(d / 2){ + generic_bottle_cap( + orient = DOWN, + wall = wall, + texture = texture, + height = cap_h2, + thread_od = cap_thread_od2, + tolerance = tolerance, + neck_od = cap_neck_od2, + pitch = cap_thread_pitch2 + ); + } + } + if (neck_id1 != undef || neck_id2 != undef) { + neck_id1 = (neck_id1 == undef) ? neck_id2 : neck_id1; + neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2; + + rotate_extrude() { + polygon(points = [ + [0, wall + d / 2 + 0.1], + [neck_id1 / 2, wall + d / 2], + [neck_id1 / 2, wall + d / 2 - taper_lead_in], + [neck_id2 / 2, taper_lead_in - d / 2 - wall], + [neck_id2 / 2, -d / 2 - wall], + [0, -d / 2 - wall - 0.1] + ]); + } + } + } +} + +function thread_adapter_CC( + wall, texture, cap_h1, cap_thread_od1, tolerance, + cap_neck_od1, cap_thread_pitch1, cap_h2, cap_thread_od2, + cap_neck_od2, cap_thread_pitch2, d, neck_id1, neck_id2, taper_lead_in +) = no_function("thread_adapter_CC"); + + +// Module: thread_adapter_NN() +// Usage: +// thread_adapter_NN(); +// Description: +// Creates a threaded neck to neck adapter. +// Arguments: +// d = Distance between bottoms of necks +// neck_od1 = Outer diameter of top neck w/o threads +// neck_id1 = Inner diameter of top neck +// thread_od1 = Outer diameter of threads on top neck +// height1 = Height of top neck above support ring. +// support_od1 = Outer diameter of the support ring on the top neck. Set to 0 for no ring. +// thread_pitch1 = Thread pitch of top neck. +// neck_od2 = Outer diameter of bottom neck w/o threads. Leave undefined to duplicate neck_od1 +// neck_id2 = Inner diameter of bottom neck. Leave undefined to duplicate neck_id1 +// thread_od2 = Outer diameter of threads on bottom neck. Leave undefined to duplicate thread_od1 +// height2 = Height of bottom neck above support ring. Leave undefined to duplicate height1 +// support_od2 = Outer diameter of the support ring on bottom neck. Set to 0 for no ring. Leave undefined to duplicate support_od1 +// pitch2 = Thread pitch of bottom neck. Leave undefined to duplicate thread_pitch1 +// taper_lead_in = Length to leave straight before tapering on tube between necks if exists. +// wall = Thickness of tube wall between necks. Leave undefined to match outer diameters with the neckODs/supportODs. +// Examples: +// thread_adapter_NN(); +module thread_adapter_NN( + d = 0, + neck_od1 = 25, + neck_id1 = 21.4, + thread_od1 = 27.2, + height1 = 17, + support_od1 = 33.0, + thread_pitch1 = 3.2, + neck_od2, neck_id2, + thread_od2, height2, + support_od2, pitch2, + taper_lead_in = 0, wall +) { + neck_od2 = (neck_od2 == undef) ? neck_od1 : neck_od2; + neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2; + thread_od2 = (thread_od2 == undef) ? thread_od1 : thread_od2; + height2 = (height2 == undef) ? height1 : height2; + support_od2 = (support_od2 == undef) ? support_od1 : support_od2; + pitch2 = (pitch2 == undef) ? thread_pitch1 : pitch2; + wall = (wall == undef) ? support_od1 + support_od2 + neck_id1 + neck_id2 : wall; + + supprtOD2 = (d == 0 && support_od2 != 0) ? max(neck_od1, support_od2) : support_od2; + supprtOD1 = (d == 0 && support_od1 != 0) ? max(neck_od2, support_od1) : support_od1; + + $fn = segs(33 / 2); + wallt1 = min(wall, (max(supprtOD1, neck_od1) - neck_id1) / 2); + wallt2 = min(wall, (max(supprtOD2, neck_od2) - neck_id2) / 2); + + taper_lead_in = (d >= taper_lead_in * 2) ? taper_lead_in : d / 2; + + difference(){ + union(){ + up(d / 2){ + generic_bottle_neck(orient = UP, + neck_d = neck_od1, + id = neck_id1, + thread_od = thread_od1, + height = height1, + support_d = supprtOD1, + pitch = thread_pitch1, + round_supp = ((wallt1 < (supprtOD1 - neck_id1) / 2) || (support_od1 > max(neck_od2, support_od2) && d == 0)), + wall = (d > 0) ? wallt1 : min(wallt1, ((max(neck_od2, support_od2)) - neck_id1) / 2) + ); + } + if (d != 0) { + rotate_extrude() { + polygon(points = [ + [0, d / 2], + [neck_id1 / 2 + wallt1, d / 2], + [neck_id1 / 2 + wallt1, d / 2 - taper_lead_in], + [neck_id2 / 2 + wallt2, taper_lead_in - d / 2], + [neck_id2 / 2 + wallt2, -d / 2], + [0, -d / 2] + ]); + } + } + down(d / 2){ + generic_bottle_neck(orient = DOWN, + neck_d = neck_od2, + id = neck_id2, + thread_od = thread_od2, + height = height2, + support_d = supprtOD2, + pitch = pitch2, + round_supp = ((wallt2 < (supprtOD2 - neck_id2) / 2) || (support_od2 > max(neck_od1, support_od1) && d == 0)), + wall = (d > 0) ? wallt2 : min(wallt2, ((max(neck_od1, support_od1)) - neck_id2) / 2) + ); + } + } + if (neck_id1 != undef || neck_id2 != undef) { + neck_id1 = (neck_id1 == undef) ? neck_id2 : neck_id1; + neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2; + + rotate_extrude() { + polygon(points = [ + [0, d / 2], + [neck_id1 / 2, d / 2], + [neck_id1 / 2, d / 2 - taper_lead_in], + [neck_id2 / 2, taper_lead_in - d / 2], + [neck_id2 / 2, -d / 2], + [0, -d / 2] + ]); + } + } + } +} + +function thread_adapter_NN( + d, neck_od1, neck_id1, thread_od1, height1, + support_od1, thread_pitch1, neck_od2, neck_id2, + thread_od2, height2, support_od2, + pitch2, taper_lead_in, wall +) = no_fuction("thread_adapter_NN"); + + + // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/bottlecaps_adapters.scad b/bottlecaps_adapters.scad deleted file mode 100644 index cf865691..00000000 --- a/bottlecaps_adapters.scad +++ /dev/null @@ -1,572 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// LibFile: bottlecaps_adapters.scad -// Adapters for various combinations of bottle necks and caps. -// Includes: -// include -// include -////////////////////////////////////////////////////////////////////// - -include -include - - -// Module: generic_bottle_neck() -// Usage: -// generic_bottle_neck() -// Description: -// Creates a bottle neck given specifications. -// Arguments: -// neckDiam = Outer diameter of neck without threads -// innerDiam = Inner diameter of neck -// threadOuterD = Outer diameter of thread -// height = Height of neck above support -// supportDiam = Outer diameter of support ring. Set to 0 for no support. -// threadPitch = Thread pitch -// wall = distance between ID and any wall that may be below the support -// roundLowerSupport = True to round the lower edge of the support ring -// --- -// 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` -// Extra Anchors: -// "support-ring" = Centered at the bottom of the support ring. -// Example: -// generic_bottle_neck(); -module generic_bottle_neck( - neckDiam = 25, - innerDiam = 21.4, - threadOuterD = 27.2, - height = 17, - supportDiam = 33.0, - threadPitch = 3.2, - roundLowerSupport = false, - wall, - anchor = "support-ring", - spin = 0, - orient = UP -) { - inner_d = innerDiam; - neck_d = neckDiam; - support_d = max(neckDiam, supportDiam); - thread_pitch = threadPitch; - thread_angle = 15; - thread_od = threadOuterD; - - diamMagMult = neckDiam / 26.19; - heightMagMult = height / 17.00; - - sup_r = 0.30 * (heightMagMult > 1 ? heightMagMult : 1); - support_r = floor(((support_d == neck_d) ? sup_r : min(sup_r, (support_d - neck_d) / 2)) * 5000) / 10000; - support_rad = (wall == undef || !roundLowerSupport) ? support_r : - min(support_r, floor((support_d - (inner_d + 2 * wall)) * 5000) / 10000); - //Too small of a radius will cause errors with the arc, this limits granularity to .0001mm - support_width = 1 * (heightMagMult > 1 ? heightMagMult : 1) * sign(supportDiam); - roundover = 0.58 * diamMagMult; - lip_roundover_r = (roundover > (neck_d - inner_d) / 2) ? 0 : roundover; - h = height + support_width; - threadbase_d = neck_d - 0.8 * diamMagMult; - - $fn = segs(33 / 2); - thread_h = (thread_od - threadbase_d) / 2; - anchors = [ - anchorpt("support-ring", [0, 0, 0 - h / 2]) - ]; - attachable(anchor, spin, orient, d1 = neck_d, d2 = 0, l = h, anchors = anchors) { - down(h / 2) { - rotate_extrude(convexity = 10) { - polygon(turtle( - state = [inner_d / 2, 0], (support_d != neck_d) ? [ - "untilx", support_d / 2 - ((roundLowerSupport) ? support_rad : 0), - "arcleft", ((roundLowerSupport) ? support_rad : 0), 90, - "untily", support_width - support_rad, - "arcleft", support_rad, 90, - "untilx", neck_d / 2, - "right", 90, - "untily", h - lip_roundover_r, - "arcleft", lip_roundover_r, 90, - "untilx", inner_d / 2 - ] : [ - "untilx", support_d / 2 - ((roundLowerSupport) ? support_rad : 0), - "arcleft", ((roundLowerSupport) ? support_rad : 0), 90, - "untily", h - lip_roundover_r, - "arcleft", lip_roundover_r, 90, - "untilx", inner_d / 2 - ] - )); - } - up(h - threadPitch / 2 - lip_roundover_r) { - difference() { - thread_helix( - d = threadbase_d - 0.1 * diamMagMult, - pitch = thread_pitch, - thread_depth = thread_h + 0.1 * diamMagMult, - thread_angle = thread_angle, - twist = 360 * (height - threadPitch - lip_roundover_r) * .6167 / threadPitch, - higbee = thread_h * 2, - anchor = TOP - ); - zrot_copies(rots = [90, 270]) { - zrot_copies(rots = [-28, 28], r = threadbase_d / 2) { - prismoid( - [20 * heightMagMult, 1.82 * diamMagMult], - [20 * heightMagMult, 1.82 * diamMagMult * .6 + 2 * sin(29) * thread_h], - h = thread_h + 0.1 * diamMagMult, - anchor = BOT, - orient = RIGHT - ); - } - } - } - } - } - children(); - } -} - -function generic_bottle_neck( - neckDiam, - innerDiam, - threadOuterD, - height, - supportDiam, - threadPitch, - roundLowerSupport, - wall, - anchor, spin, orient -) = no_function("generic_bottle_neck"); - - -// Module: generic_bottle_cap() -// Usage: -// generic_bottle_cap(wall, , ...); -// Description: -// Creates a basic threaded cap given specifications. -// Arguments: -// wall = Wall thickness in mm. -// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" -// --- -// height = Interior height of the cap in mm. -// threadOuterD = Outer diameter of the threads in mm. -// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. -// neckOuterD = Outer diameter of neck in mm. -// threadAngle = Angle of taper on threads. -// threadPitch = Thread pitch in mm. -// 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` -// Extra Anchors: -// "inside-top" = Centered on the inside top of the cap. -// Examples: -// generic_bottle_cap(); -// generic_bottle_cap(texture="knurled"); -// generic_bottle_cap(texture="ribbed"); -module generic_bottle_cap( - wall = 2, - texture = "none", - height = 11.2, - threadOuterD = 28.58, - tolerance = .2, - neckOuterD = 25.5, - threadAngle = 15, - threadPitch = 4, - anchor = BOTTOM, - spin = 0, - orient = UP -) { - $fn = segs(33 / 2); - threadOuterDTol = threadOuterD + 2 * tolerance; - w = threadOuterDTol + 2 * wall; - h = height + wall; - neckOuterDTol = neckOuterD + 2 * tolerance; - threadDepth = (threadOuterD - neckOuterD) / 2 + .8; - - diamMagMult = (w > 32.58) ? w / 32.58 : 1; - heightMagMult = (height > 11.2) ? height / 11.2 : 1; - - anchors = [ - anchorpt("inside-top", [0, 0, -(h / 2 - wall)]) - ]; - attachable(anchor, spin, orient, d = w, l = h, anchors = anchors) { - down(h / 2) { - difference() { - union() { - // For the knurled and ribbed caps the PCO caps in BOSL2 cut into the wall - // thickness so the wall+texture are the specified wall thickness. That - // seems wrong so this does specified thickness+texture - if (texture == "knurled") { - knurled_cylinder(d = w + 1.5 * diamMagMult, helix = 45, l = h, anchor = BOTTOM); - cyl(d = w, l = h, anchor = BOTTOM); - } else if (texture == "ribbed") { - zrot_copies(n = 30, r = (w + .2 * diamMagMult) / 2) { - cube([1 * diamMagMult, 1 * diamMagMult, h], anchor = BOTTOM); - } - cyl(d = w, l = h, anchor = BOTTOM); - } else { - cyl(d = w, l = h, anchor = BOTTOM); - } - } - up(wall) cyl(d = threadOuterDTol, h = h, anchor = BOTTOM); - } - difference(){ - up(wall + threadPitch / 2) { - thread_helix(d = neckOuterDTol, pitch = threadPitch, thread_depth = threadDepth, thread_angle = threadAngle, twist = 360 * ((height - threadPitch) / threadPitch), higbee = threadDepth, internal = true, anchor = BOTTOM); - } - } - } - children(); - } -} - -function generic_bottle_cap( - wall, texture, height, - threadOuterD, tolerance, - neckOuterD, threadAngle, threadPitch, - anchor, spin, orient -) = no_function("generic_bottle_cap"); - - -// Module: thread_adapter_NC() -// Usage: -// thread_adapter_NC(wall, [texture]); -// Description: -// Creates a threaded neck to cap adapter -// Arguments: -// wall = Thickness of wall between neck and cap when d=0. Leave undefined to have the outside of the tube go from the OD of the neck support ring to the OD of the cap. Default: undef -// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" -// capWall = Wall thickness of the cap in mm. -// capHeight = Interior height of the cap in mm. -// capThreadOD = Outer diameter of cap threads in mm. -// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. -// capNeckOD = Inner diameter of the cap threads. -// capNeckID = Inner diameter of the hole through the cap. -// capThreadTaperAngle = Angle of taper on threads. -// capThreadPitch = Thread pitch in mm -// neckDiam = Outer diameter of neck w/o threads -// neckID = Inner diameter of neck -// neckThreadOD = 27.2 -// neckHeight = Height of neck down to support ring -// neckThreadPitch = Thread pitch in mm. -// neckSupportOD = Outer diameter of neck support ring. Leave undefined to set equal to OD of cap. Set to 0 for no ring. Default: undef -// d = Distance between bottom of neck and top of cap -// taperLeadIn = Length to leave straight before tapering on tube between neck and cap if exists. -// Examples: -// thread_adapter_NC(); -module thread_adapter_NC( - wall, - texture = "none", - capWall = 2, - capHeight = 11.2, - capThreadOD = 28.58, - tolerance = .2, - capNeckOD = 25.5, - capNeckID, - capThreadTaperAngle = 15, - capThreadPitch = 4, - neckDiam = 25, - neckID = 21.4, - neckThreadOD = 27.2, - neckHeight = 17, - neckThreadPitch = 3.2, - neckSupportOD, - d = 0, - taperLeadIn = 0 -) { - neckSupportOD = (neckSupportOD == undef || (d == 0 && neckSupportOD < capThreadOD + 2 * tolerance)) ? capThreadOD + 2 * (capWall + tolerance) : neckSupportOD; - capNeckID = (capNeckID == undef) ? neckID : capNeckID; - wall = (wall == undef) ? neckSupportOD + neckDiam + capThreadOD + neckID : wall; - - $fn = segs(33 / 2); - wallt1 = min(wall, (max(neckSupportOD, neckDiam) - neckID) / 2); - wallt2 = min(wall, (capThreadOD + 2 * (capWall + tolerance) - capNeckID) / 2); - - difference(){ - union(){ - up(d / 2) { - generic_bottle_neck(neckDiam = neckDiam, - innerDiam = neckID, - threadOuterD = neckThreadOD, - height = neckHeight, - supportDiam = neckSupportOD, - threadPitch = neckThreadPitch, - roundLowerSupport = ((wallt1 < (neckSupportOD - neckID) / 2) && (d > 0 || neckSupportOD > (capThreadOD + 2 * (capWall + tolerance)))), - wall = (d > 0) ? wallt1 : min(wallt1, ((capThreadOD + 2 * (capWall + tolerance) - neckID) / 2)) - ); - } - if (d != 0) { - rotate_extrude(){ - polygon(points = [ - [0, d / 2], - [neckID / 2 + wallt1, d / 2], - [neckID / 2 + wallt1, d / 2 - taperLeadIn], - [capNeckID / 2 + wallt2, taperLeadIn - d / 2], - [capNeckID / 2 + wallt2, -d / 2], - [0, -d / 2] - ]); - } - } - down(d / 2){ - generic_bottle_cap(wall = capWall, - texture = texture, - height = capHeight, - threadOuterD = capThreadOD, - tolerance = tolerance, - neckOuterD = capNeckOD, - threadAngle = capThreadTaperAngle, - orient = DOWN, - threadPitch = capThreadPitch - ); - } - } - rotate_extrude() { - polygon(points = [ - [0, d / 2 + 0.1], - [neckID / 2, d / 2], - [neckID / 2, d / 2 - taperLeadIn], - [capNeckID / 2, taperLeadIn - d / 2], - [capNeckID / 2, -d / 2 - capWall], - [0, -d / 2 - capWall - 0.1] - ]); - } - } -} - -function thread_adapter_NC( - wall, texture, capWall, capHeight, capThreadOD, - tolerance, capNeckOD, capNeckId, capThreadTaperAngle, - capThreadPitch, neckDiam, neckID, neckThreadOD, - neckHeight, neckThreadPitch, neckSupportOD, d, taperLeadIn -) = no_fuction("thread_adapter_NC"); - - -// Module: thread_adapter_CC() -// Usage: -// thread_adapter_CC(wall, [texture]); -// Description: -// Creates a threaded cap to cap adapter. -// Arguments: -// wall = Wall thickness in mm. -// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none" -// capHeight1 = Interior height of top cap. -// capThreadOD1 = Outer diameter of threads on top cap. -// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius. -// capNeckOD1 = Inner diameter of threads on top cap. -// capThreadPitch1 = Thread pitch of top cap in mm. -// capHeight2 = Interior height of bottom cap. Leave undefined to duplicate capHeight1. -// capThreadOD2 = Outer diameter of threads on bottom cap. Leave undefined to duplicate capThread1. -// capNeckOD2 = Inner diameter of threads on top cap. Leave undefined to duplicate capNeckOD1. -// capThreadPitch2 = Thread pitch of bottom cap in mm. Leave undefinced to duplicate capThreadPitch1. -// d = Distance between caps. -// neckID1 = Inner diameter of cutout in top cap. -// neckID2 = Inner diameter of cutout in bottom cap. -// taperLeadIn = Length to leave straight before tapering on tube between caps if exists. -// Examples: -// thread_adapter_CC(); -module thread_adapter_CC( - wall = 2, - texture = "none", - capHeight1 = 11.2, - capThreadOD1 = 28.58, - tolerance = .2, - capNeckOD1 = 25.5, - capThreadPitch1 = 4, - capHeight2, - capThreadOD2, - capNeckOD2, - capThreadPitch2, - d = 0, - neckID1, neckID2, - taperLeadIn = 0 -) { - capHeight2 = (capHeight2 == undef) ? capHeight1 : capHeight2; - capThreadOD2 = (capThreadOD2 == undef) ? capThreadOD1 : capThreadOD2; - capNeckOD2 = (capNeckOD2 == undef) ? capNeckOD1 : capNeckOD2; - capThreadPitch2 = (capThreadPitch2 == undef) ? capThreadPitch1 : capThreadPitch2; - neckID2 = (neckID2 == undef && neckID1 != undef) ? neckID1 : neckID2; - taperLeadIn = (d >= taperLeadIn * 2) ? taperLeadIn : d / 2; - - - $fn = segs(33 / 2); - - difference(){ - union(){ - up(d / 2){ - generic_bottle_cap( - orient = UP, - wall = wall, - texture = texture, - height = capHeight1, - threadOuterD = capThreadOD1, - tolerance = tolerance, - neckOuterD = capNeckOD1, - threadPitch = capThreadPitch1 - ); - } - if (d != 0) { - rotate_extrude() { - polygon(points = [ - [0, d / 2], - [capThreadOD1 / 2 + (wall + tolerance), d / 2], - [capThreadOD1 / 2 + (wall + tolerance), d / 2 - taperLeadIn], - [capThreadOD2 / 2 + (wall + tolerance), taperLeadIn - d / 2], - [capThreadOD2 / 2 + (wall + tolerance), -d / 2], - [0, -d / 2] - ]); - } - } - down(d / 2){ - generic_bottle_cap( - orient = DOWN, - wall = wall, - texture = texture, - height = capHeight2, - threadOuterD = capThreadOD2, - tolerance = tolerance, - neckOuterD = capNeckOD2, - threadPitch = capThreadPitch2 - ); - } - } - if (neckID1 != undef || neckID2 != undef) { - neckID1 = (neckID1 == undef) ? neckID2 : neckID1; - neckID2 = (neckID2 == undef) ? neckID1 : neckID2; - - rotate_extrude() { - polygon(points = [ - [0, wall + d / 2 + 0.1], - [neckID1 / 2, wall + d / 2], - [neckID1 / 2, wall + d / 2 - taperLeadIn], - [neckID2 / 2, taperLeadIn - d / 2 - wall], - [neckID2 / 2, -d / 2 - wall], - [0, -d / 2 - wall - 0.1] - ]); - } - } - } -} - -function thread_adapter_CC( - wall, texture, capHeight1, capThreadOD1, tolerance, - capNeckOD1, capThreadPitch1, capHeight2, capThreadOD2, - capNeckOD2, capThreadPitch2, d, neckID1, neckID2, taperLeadIn -) = no_function("thread_adapter_CC"); - - -// Module: thread_adapter_NN() -// Usage: -// thread_adapter_NN(); -// Description: -// Creates a threaded neck to neck adapter. -// Arguments: -// d = Distance between bottoms of necks -// neckOD1 = Outer diameter of top neck w/o threads -// neckID1 = Inner diameter of top neck -// threadOD1 = Outer diameter of threads on top neck -// height1 = Height of top neck above support ring. -// supportOD1 = Outer diameter of the support ring on the top neck. Set to 0 for no ring. -// threadPitch1 = Thread pitch of top neck. -// neckOD2 = Outer diameter of bottom neck w/o threads. Leave undefined to duplicate neckOD1 -// neckID2 = Inner diameter of bottom neck. Leave undefined to duplicate neckID1 -// threadOD2 = Outer diameter of threads on bottom neck. Leave undefined to duplicate threadOD1 -// height2 = Height of bottom neck above support ring. Leave undefined to duplicate height1 -// supportOD2 = Outer diameter of the support ring on bottom neck. Set to 0 for no ring. Leave undefined to duplicate supportOD1 -// threadPitch2 = Thread pitch of bottom neck. Leave undefined to duplicate threadPitch1 -// taperLeadIn = Length to leave straight before tapering on tube between necks if exists. -// wall = Thickness of tube wall between necks. Leave undefined to match outer diameters with the neckODs/supportODs. -// Examples: -// thread_adapter_NN(); -module thread_adapter_NN( - d = 0, - neckOD1 = 25, - neckID1 = 21.4, - threadOD1 = 27.2, - height1 = 17, - supportOD1 = 33.0, - threadPitch1 = 3.2, - neckOD2, neckID2, - threadOD2, height2, - supportOD2, threadPitch2, - taperLeadIn = 0, wall -) { - neckOD2 = (neckOD2 == undef) ? neckOD1 : neckOD2; - neckID2 = (neckID2 == undef) ? neckID1 : neckID2; - threadOD2 = (threadOD2 == undef) ? threadOD1 : threadOD2; - height2 = (height2 == undef) ? height1 : height2; - supportOD2 = (supportOD2 == undef) ? supportOD1 : supportOD2; - threadPitch2 = (threadPitch2 == undef) ? threadPitch1 : threadPitch2; - wall = (wall == undef) ? supportOD1 + supportOD2 + neckID1 + neckID2 : wall; - - supprtOD2 = (d == 0 && supportOD2 != 0) ? max(neckOD1, supportOD2) : supportOD2; - supprtOD1 = (d == 0 && supportOD1 != 0) ? max(neckOD2, supportOD1) : supportOD1; - - $fn = segs(33 / 2); - wallt1 = min(wall, (max(supprtOD1, neckOD1) - neckID1) / 2); - wallt2 = min(wall, (max(supprtOD2, neckOD2) - neckID2) / 2); - - taperLeadIn = (d >= taperLeadIn * 2) ? taperLeadIn : d / 2; - - difference(){ - union(){ - up(d / 2){ - generic_bottle_neck(orient = UP, - neckDiam = neckOD1, - innerDiam = neckID1, - threadOuterD = threadOD1, - height = height1, - supportDiam = supprtOD1, - threadPitch = threadPitch1, - roundLowerSupport = ((wallt1 < (supprtOD1 - neckID1) / 2) || (supportOD1 > max(neckOD2, supportOD2) && d == 0)), - wall = (d > 0) ? wallt1 : min(wallt1, ((max(neckOD2, supportOD2)) - neckID1) / 2) - ); - } - if (d != 0) { - rotate_extrude() { - polygon(points = [ - [0, d / 2], - [neckID1 / 2 + wallt1, d / 2], - [neckID1 / 2 + wallt1, d / 2 - taperLeadIn], - [neckID2 / 2 + wallt2, taperLeadIn - d / 2], - [neckID2 / 2 + wallt2, -d / 2], - [0, -d / 2] - ]); - } - } - down(d / 2){ - generic_bottle_neck(orient = DOWN, - neckDiam = neckOD2, - innerDiam = neckID2, - threadOuterD = threadOD2, - height = height2, - supportDiam = supprtOD2, - threadPitch = threadPitch2, - roundLowerSupport = ((wallt2 < (supprtOD2 - neckID2) / 2) || (supportOD2 > max(neckOD1, supportOD1) && d == 0)), - wall = (d > 0) ? wallt2 : min(wallt2, ((max(neckOD1, supportOD1)) - neckID2) / 2) - ); - } - } - if (neckID1 != undef || neckID2 != undef) { - neckID1 = (neckID1 == undef) ? neckID2 : neckID1; - neckID2 = (neckID2 == undef) ? neckID1 : neckID2; - - rotate_extrude() { - polygon(points = [ - [0, d / 2], - [neckID1 / 2, d / 2], - [neckID1 / 2, d / 2 - taperLeadIn], - [neckID2 / 2, taperLeadIn - d / 2], - [neckID2 / 2, -d / 2], - [0, -d / 2] - ]); - } - } - } -} - -function thread_adapter_NN( - d, neckOD1, neckID1, threadOD1, height1, - supportOD1, threadPitch1, neckOD2, neckID2, - threadOD2, height2, supportOD2, - threadPitch2, taperLeadIn, wall -) = no_fuction("thread_adapter_NN"); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap From c859cd67bc527c161aa0883528defef683c39d3f Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 9 May 2021 16:44:51 -0700 Subject: [PATCH 3/5] Improvements for bosl1compat.scad --- bosl1compat.scad | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bosl1compat.scad b/bosl1compat.scad index dba7fd0f..fb512b9d 100644 --- a/bosl1compat.scad +++ b/bosl1compat.scad @@ -37,15 +37,15 @@ module chamfcube(size=[1,1,1],chamfer=0.25,chamfaxes=[1,1,1],chamfcorners=false) ); } -module trapezoid(size1=[1,1], size2=[1,1], h=1, center=false) - prismoid(size1=size1, size2=size2, h=h, anchor=center?CENTER:BOT); +module trapezoid(size1=[1,1], size2=[1,1], h=1, shift=[0,0], align=CTR, orient=0, center) + prismoid(size1=size1, size2=size2, h=h, shift=shift, spin=orient, anchor=center==undef? -align : center?CENTER:BOT); module pyramid(n=4, h=1, l=1, r, d, circum=false) { radius = get_radius(r=r, d=d, dflt=l/2/sin(180/n)); cyl(r1=radius, r2=0, l=h, circum=circum, $fn=n, realign=true, anchor=BOT); } -module prism(n=3, h=1, l=1, r=undef, d=undef, circum=false, center=false) { +module prism(n=3, h=1, l=1, r, d, circum=false, center=false) { radius = get_radius(r=r, d=d, dflt=l/2/sin(180/n)); cyl(r=radius, l=h, circum=circum, $fn=n, realign=true, anchor=center?CENTER:BOT); } @@ -60,7 +60,7 @@ module chamf_cyl(h=1, r, d, chamfer=0.25, chamfedge, angle=45, center=false, top cyl(h=h, r=r, d=d, chamfer1=(bottom?chamf:0), chamfer2=(top?chamf:0), chamfang=angle, anchor=center?CENTER:BOT); } -module filleted_cylinder(h=1, r=undef, d=undef, r1, r2, d1, d2, fillet=0.25, center=false) +module filleted_cylinder(h=1, r, d, r1, r2, d1, d2, fillet=0.25, center=false) cyl(l=h, r=r, d=d, r1=r1, r2=r2, d1=d1, d2=d2, rounding=fillet, anchor=center?CENTER:BOT); module rcylinder(h=1, r=1, r1, r2, d, d1, d2, fillet=0.25, center=false) From 9668eefb7d5a1cf8a55cb11be590b0e2cbe4f571 Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 9 May 2021 16:45:37 -0700 Subject: [PATCH 4/5] Tweaks to beziers.scad docs formatting. --- beziers.scad | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/beziers.scad b/beziers.scad index 90b97900..feacb48e 100644 --- a/beziers.scad +++ b/beziers.scad @@ -25,8 +25,8 @@ // Topics: Bezier Paths // See Also: bez_tang(), bez_joint(), bez_end() // Usage: -// pts = bez_begin(pt,a,r,); -// pts = bez_begin(pt,VECTOR,,); +// pts = bez_begin(pt, a, r, ); +// pts = bez_begin(pt, VECTOR, , ); // Description: // This is used to create the first endpoint and control point of a cubic bezier path. // Arguments: @@ -94,8 +94,8 @@ function bez_begin(pt,a,r,p) = // Topics: Bezier Paths // See Also: bez_begin(), bez_joint(), bez_end() // Usage: -// pts = bez_tang(pt,a,r1,r2,); -// pts = bez_tang(pt,VECTOR,,,); +// pts = bez_tang(pt, a, r1, r2, ); +// pts = bez_tang(pt, VECTOR, , , ); // Description: // This creates a smooth joint in a cubic bezier path. It creates three points, being the // approaching control point, the fixed bezier control point, and the departing control @@ -128,8 +128,8 @@ function bez_tang(pt,a,r1,r2,p) = // Topics: Bezier Paths // See Also: bez_begin(), bez_tang(), bez_end() // Usage: -// pts = bez_joint(pt,a1,a2,r1,r2,,); -// pts = bez_joint(pt,VEC1,VEC2,,,,); +// pts = bez_joint(pt, a1, a2, r1, r2, , ); +// pts = bez_joint(pt, VEC1, VEC2, , , , ); // Description: // This creates a disjoint corner joint in a cubic bezier path. It creates three points, being // the aproaching control point, the fixed bezier control point, and the departing control point. @@ -167,8 +167,8 @@ function bez_joint(pt,a1,a2,r1,r2,p1,p2) = // Topics: Bezier Paths // See Also: bez_tang(), bez_joint(), bez_end() // Usage: -// pts = bez_end(pt,a,r,); -// pts = bez_end(pt,VECTOR,,); +// pts = bez_end(pt, a, r, ); +// pts = bez_end(pt, VECTOR, , ); // Description: // This is used to create the approaching control point, and the endpoint of a cubic bezier path. // See {{bez_begin()}} for examples. @@ -621,7 +621,7 @@ function bezier_path_point(path, seg, u, N=3) = // Function: bezier_path_closest_point() // Usage: -// res = bezier_path_closest_point(bezier,pt); +// res = bezier_path_closest_point(bezier, pt); // Topics: Bezier Paths // See Also: bezier_points(), bezier_curve(), bezier_segment_closest_point() // Description: @@ -919,7 +919,7 @@ function bezier_offset(offset, bezier, N=3) = // Module: bezier_polygon() // Usage: -// bezier_polygon(bezier, , ) { +// bezier_polygon(bezier, , ); // Topics: Bezier Paths // See Also: bezier_path() // Description: @@ -951,7 +951,7 @@ module bezier_polygon(bezier, splinesteps=16, N=3) { // Module: trace_bezier() // Usage: -// trace_bezier(bez, , ) { +// trace_bezier(bez, , ); // Topics: Bezier Paths, Debugging // See Also: bezier_path() // Description: @@ -1530,13 +1530,14 @@ function bezier_surface(patches=[], splinesteps=16, vnf=EMPTY_VNF, style="defaul // Module: trace_bezier_patches() // Usage: -// trace_bezier_patches(patches, [size], [splinesteps], [showcps], [showdots], [showpatch], [convexity], [style]); +// trace_bezier_patches(patches, , , , , , , ); // Topics: Bezier Patches, Debugging // See Also: bezier_patch_points(), bezier_patch_flat(), bezier_surface() // Description: // Shows the surface, and optionally, control points of a list of bezier patches. // Arguments: // patches = A list of rectangular bezier patches. +// --- // splinesteps = Number of steps to divide each bezier segment into. default=16 // showcps = If true, show the controlpoints as well as the surface. Default: true. // showdots = If true, shows the calculated surface vertices. Default: false. From bd3210022dc70a3c6b1153d98ee4bc5af187f42a Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Mon, 10 May 2021 23:26:35 -0700 Subject: [PATCH 5/5] Verified examples scadfiles. --- examples/conical_anchors.scad | 8 -------- examples/cube_anchors.scad | 8 -------- examples/cylinder_anchors.scad | 8 -------- examples/prismoid_anchors.scad | 8 -------- examples/randomized_fractal_tree.scad | 6 ++---- examples/sphere_anchors.scad | 8 -------- 6 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 examples/conical_anchors.scad delete mode 100644 examples/cube_anchors.scad delete mode 100644 examples/cylinder_anchors.scad delete mode 100644 examples/prismoid_anchors.scad delete mode 100644 examples/sphere_anchors.scad diff --git a/examples/conical_anchors.scad b/examples/conical_anchors.scad deleted file mode 100644 index 42e9de34..00000000 --- a/examples/conical_anchors.scad +++ /dev/null @@ -1,8 +0,0 @@ -include -include - - -cylinder(h=30, d1=50, d2=30) show_anchors(); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/examples/cube_anchors.scad b/examples/cube_anchors.scad deleted file mode 100644 index db122ded..00000000 --- a/examples/cube_anchors.scad +++ /dev/null @@ -1,8 +0,0 @@ -include -include - - -cube(40, center=true) show_anchors(); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/examples/cylinder_anchors.scad b/examples/cylinder_anchors.scad deleted file mode 100644 index 1c3d6053..00000000 --- a/examples/cylinder_anchors.scad +++ /dev/null @@ -1,8 +0,0 @@ -include -include - - -cylinder(h=30, d=30) show_anchors(); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/examples/prismoid_anchors.scad b/examples/prismoid_anchors.scad deleted file mode 100644 index 7bf4fc42..00000000 --- a/examples/prismoid_anchors.scad +++ /dev/null @@ -1,8 +0,0 @@ -include -include - - -prismoid([60,40], [30,20], h=40) show_anchors(); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/examples/randomized_fractal_tree.scad b/examples/randomized_fractal_tree.scad index 5dd6f875..f7b9d0ed 100644 --- a/examples/randomized_fractal_tree.scad +++ b/examples/randomized_fractal_tree.scad @@ -9,10 +9,8 @@ module leaf(s) { [-1.5,-1], [0,0] ]; xrot(90) - linear_sweep_bezier( - path * s/2, - height=0.02 - ); + linear_extrude(height=0.02) + bezier_polygon(path*s/2); } module branches(minsize, s1, s2){ diff --git a/examples/sphere_anchors.scad b/examples/sphere_anchors.scad deleted file mode 100644 index b1fc43a0..00000000 --- a/examples/sphere_anchors.scad +++ /dev/null @@ -1,8 +0,0 @@ -include -include - - -spheroid(d=30) show_anchors(); - - -// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap