From 7179bc7711ef8f21ef8a1b1b156776cab7ec25c2 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Tue, 4 Apr 2023 19:55:05 -0400 Subject: [PATCH] Screw update: 4x faster, higbee renamed blunt start and on by default --- bottlecaps.scad | 42 ++- screws.scad | 100 +++-- skin.scad | 250 +++++++------ threading.scad | 949 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 887 insertions(+), 454 deletions(-) diff --git a/bottlecaps.scad b/bottlecaps.scad index 4668e7e..3b48d46 100644 --- a/bottlecaps.scad +++ b/bottlecaps.scad @@ -117,7 +117,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP) thread_depth=thread_h+0.1, flank_angle=flank_angle, turns=810/360, - taper=-thread_h*2, + lead_in=-thread_h*2, anchor=TOP ); zrot_copies(rots=[90,270]) { @@ -190,7 +190,7 @@ module pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) } up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM); } - up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, taper=-thread_depth, internal=true, anchor=BOTTOM); + up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, lead_in=-thread_depth, internal=true, anchor=BOTTOM); } children(); } @@ -306,7 +306,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP) thread_depth=thread_h+0.1, flank_angle=flank_angle, turns=650/360, - taper=-thread_h*2, + lead_in=-thread_h*2, anchor=TOP ); zrot_copies(rots=[90,270]) { @@ -371,7 +371,7 @@ module pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP) } up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM); } - up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, taper=-1.6, internal=true, anchor=BOTTOM); + up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, lead_in=-1.6, internal=true, anchor=BOTTOM); } children(); } @@ -475,7 +475,7 @@ module generic_bottle_neck( thread_depth = thread_h + 0.1 * diamMagMult, flank_angle = flank_angle, turns = (height - pitch - lip_roundover_r) * .6167 / pitch, - taper = -thread_h * 2, + lead_in = -thread_h * 2, anchor = TOP ); zrot_copies(rots = [90, 270]) { @@ -579,7 +579,7 @@ module generic_bottle_cap( difference(){ up(wall + pitch / 2) { thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle, - turns = ((height - pitch) / pitch), taper = -threadDepth, internal = true, anchor = BOTTOM); + turns = ((height - pitch) / pitch), lead_in = -threadDepth, internal = true, anchor = BOTTOM); } } } @@ -954,8 +954,9 @@ function bottle_adapter_neck_to_neck( // 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410 // neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread. // You can also choose between the L style thread, which is symmetric and -// the M style thread, which is an asymmetric buttress thread. You can -// specify the wall thickness (measured from the base of the threads) or +// the M style thread, which is an asymmetric buttress thread. The M style +// may be good for 3d printing if printed with the flat face up. +// You can specify the wall thickness (measured from the base of the threads) or // the inner diameter, and you can specify an optional bead at the base of the threads. // Arguments: // diam = nominal outer diameter of threads @@ -1094,6 +1095,8 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) H = entry[2]; S = entry[3]; tpi = entry[4]; + + // a is the width of the thread a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi); twist = struct_val(_sp_twist, type); @@ -1126,7 +1129,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) up((H+extra_bot)/2){ difference(){ union(){ - thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP); + thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, lead_in=taperlen, anchor=TOP); cylinder(d=T-depth*2,h=H,anchor=TOP); if (bead) down(bead_shift) @@ -1154,12 +1157,15 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) // the M style thread, which is an asymmetric buttress thread. Note that it // is OK to mix styles, so you can put an L-style cap onto an M-style neck. // . -// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick. -// If you don't include this, your cap may bottom out on the bead on the neck instead of sealing -// against the top. If you set top_adj to 1 it will make the top space 1mm smaller so that the -// cap will not bottom out. The 410 and 415 caps have very long unthreaded sections at the bottom. -// The bot_adj parameter specifies an amount to reduce that bottom extension. Be careful that -// you don't shrink past the threads. +// The 410 and 415 caps have very long unthreaded sections at the bottom. +// The bot_adj parameter specifies an amount to reduce that bottom extension, which might be +// necessary if the cap bottoms out on the bead. Be careful that you don't shrink past the threads, +// especially if making adjustments to 400 caps which have a very small bottom extension. +// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick, and +// would cause the cap to stop in a higher position. +// . +// You can also adjust the space between the top of the cap and the threads using top_adj. This +// will change how the threads engage when the cap is fully seated. // . // The inner diameter of the cap is set to allow 10% of the thread depth in clearance. The diameter // is further increased by `2 * $slop` so you can increase clearance if necessary. @@ -1182,6 +1188,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient) // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP` // Examples: // sp_cap(48,400,2); +// sp_cap(22,400,2); // sp_cap(22,410,2); // sp_cap(28,415,1.5,style="M"); module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anchor, spin, orient) @@ -1194,13 +1201,14 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anc T = entry[0]; I = entry[1]; - H = entry[2]-1; + H = entry[2]-0.5; S = entry[3]; tpi = entry[4]; a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi); twist = struct_val(_sp_twist, type); + echo(top_adj=top_adj,bot_adj=bot_adj); dum3=assert(top_adj0 ? flat_height:0; // Adjustment because flathead height doesn't count toward shoulder length shoulder_full = _shoulder_len==0 ? 0 : _shoulder_len + flat_height; shank_len = is_def(user_thread_len) ? length - user_thread_len - (_shoulder_len==0?flat_height:0) : 0; @@ -647,6 +652,8 @@ module screw(spec, head, drive, thread, drive_size, : is_def(vnf) ? undef : head_height+flat_height+flat_cbore_height; bevelsize = default(bevelsize, d_major/12); + bevel1 = first_defined([bevel1,bevel,true]); + bevel2 = first_defined([bevel2,bevel,headless && _shoulder_len==0 && shank_len==0]); attachable( vnf = vnf, d = u_add(u_mul(attach_d, rad_scale), islop), @@ -671,8 +678,16 @@ module screw(spec, head, drive, thread, drive_size, if (shank_len>0 || pitch==0){ L = pitch==0 ? length - (_shoulder_len==0?flat_height:0) : shank_len; bevsize = (_internal ? -1 : 1)*bevelsize; - bev1 = details && pitch==0 && first_defined([bevel1,bevel,!_internal]) ? bevsize : 0; - bev2 = details && pitch==0 && first_defined([bevel2,bevel,headless && !_internal]) ? bevsize : 0; + bev1 = pitch!=0 ? 0 + : bevel1==true ? bevsize + : bevel1==false ? 0 + : bevel1=="reverse" ? -bevsize + : bevel1; + bev2 = pitch!=0 ? 0 + : bevel2==true ? bevsize + : bevel2==false ? 0 + : bevel2=="reverse" ? -bevsize + : bevel2; down(_shoulder_len+flat_height-eps_shank) if (_teardrop) teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2); @@ -680,18 +695,15 @@ module screw(spec, head, drive, thread, drive_size, cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2); } if (thread_len>0 && pitch>0){ - bev1 = details && first_defined([bevel1,bevel,!_internal]); - bev2 = details && first_defined([bevel2,bevel,!_internal && (flathead || _shoulder_len>0 || headless)]); down(_shoulder_len+flat_height+shank_len-eps_thread) threaded_rod([mean(struct_val(threadspec, "d_minor")), mean(struct_val(threadspec, "d_pitch")), d_major], pitch = struct_val(threadspec, "pitch"), l=thread_len+eps_thread, left_handed=false, internal=_internal, - bevel1=bev1, - bevel2=bev2, - higbee1=higbee && !_internal, - higbee2=(!headless && !_internal) || is_undef(higbee) ? false : higbee, + bevel1=bevel1, + bevel2=bevel2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, $fn=sides, anchor=TOP); } @@ -704,10 +716,9 @@ module screw(spec, head, drive, thread, drive_size, - // Module: screw_hole() // Usage: -// screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS]; +// screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [blunt_start=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS]; // Description: // Create a screw hole mask. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on the parameters that define a screw. // The screw hole can be threaded to receive a screw or it can be an unthreaded clearance hole. @@ -755,7 +766,9 @@ module screw(spec, head, drive, thread, drive_size, // bevel = if true create bevel at both ends of hole. Default: see below // bevel1 = if true create bevel at bottom end of hole. Default: false // bevel2 = if true create bevel at top end of hole. Default: true when tolerance="self tap", false otherwise -// higbee = if true and hole is threaded, create blunt start threads at the top of the hole. Default: false +// blunt_start = if true and hole is threaded, create blunt start threads. Default: true +// blunt_start1 = if true and hole is threaded, create blunt start threads at bottom end. +// blunt_start2 = if true and hole is threaded, create blunt start threads top end. // $slop = add extra gap to account for printer overextrusion. Default: 0 // atype = anchor type, one of "screw", "head", "shaft", "threads", "shank" // anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` @@ -795,14 +808,20 @@ module screw(spec, head, drive, thread, drive_size, // cuboid(20) // attach(TOP) // screw_hole("1/4-20,.5",head="flat",counterbore=0,anchor=TOP); -// Example: Threaded hole -// diff() -// cuboid(20) -// attach(FRONT) -// screw_hole("M16,15",anchor=TOP,thread=true); +// Example: Threaded hole, with inward bevel at the base +// bottom_half() +// diff() +// cuboid(20) +// attach(FRONT) +// screw_hole("M16,15",anchor=TOP,thread=true,bevel1="reverse"); +function screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, + length, l, thread_len, tolerance=undef, counterbore, teardrop=false, + bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2, + atype="screw",anchor=CENTER,spin=0, orient=UP) + = no_function("screw_hole"); module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, length, l, thread_len, tolerance=undef, counterbore, teardrop=false, - bevel, bevel1, bevel2, higbee=false, + bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2, atype="screw",anchor=CENTER,spin=0, orient=UP) { screwspec = _get_spec(spec, "screw_info", "screw_hole", @@ -821,9 +840,10 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, head_oversize = first_defined([head_oversize, oversize[1],struct_val(screwspec,"head_oversize")]); if (threaded || is_def(hole_oversize) || tolerance==0 || tolerance=="none") { default_tag("remove") - screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize), higbee=higbee, + screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize), + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore, - bevel=bevel, bevel1=bevel1, bevel2=bevel2, + bevel1=bevel1, bevel2=bevel2, atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop) children(); } @@ -944,7 +964,7 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, default_tag("remove") screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize, length=length,l=l,thread_len=thread_len, _counterbore=counterbore, - bevel=bevel, bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef, higbee=higbee, + bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef, atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop) children(); } @@ -1025,8 +1045,13 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize, // shoulder_screw("iso", 16, length=20, head="none"); // Example: Changing head height // shoulder_screw("iso", 16, length=20, head_size=[24,5]); +function shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread, + undersize, shaft_undersize, head_undersize, shoulder_undersize=0, + blunt_start, blunt_start1, blunt_start2, + atype="screw", anchor=BOT, orient,spin) = no_function("shoulder_screw"); module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread, - undersize, shaft_undersize, head_undersize, shoulder_undersize=0, + undersize, shaft_undersize, head_undersize, shoulder_undersize=0, + blunt_start, blunt_start1, blunt_start2, atype="screw", anchor=BOT, orient,spin) { d1= assert(is_num(d) && d>0, "Must specify shoulder diameter") @@ -1121,6 +1146,7 @@ module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, screw(struct_set(info, headfields), _shoulder_len = length, _shoulder_diam = shoulder_diam-shoulder_tol, length=thread_len, tolerance=tolerance, shaft_undersize=shaft_undersize, head_undersize=head_undersize, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, atype=atype, anchor=anchor, orient=orient, spin=spin) children(); } @@ -1486,9 +1512,9 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. // tolerance = nut tolerance. Determines actual nut thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and "6H" for ISO. // $slop = extra space left to account for printing over-extrusion. Default: 0 // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` @@ -1537,7 +1563,7 @@ function nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize, bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0) = no_function("nut"); module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize, - bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0) + bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2,blunt_start, blunt_start1, blunt_start2, anchor=BOTTOM, spin=0, orient=UP, oversize=0) { dummyA = assert(is_undef(nutwidth) || (is_num(nutwidth) && nutwidth>0)); @@ -1565,11 +1591,15 @@ module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize, shape=shape, bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang, ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, anchor=anchor,spin=spin,orient=orient) children(); } + + + + // Module: nut_trap_side() // Usage: // nut_trap_side(trap_width, [spec], [shape], [thickness], [nutwidth=], [poke_len=], [poke_diam=], [$slop=], [anchor=], [orient=], [spin=]) [ATTACHMENTS]; diff --git a/skin.scad b/skin.scad index 560a630..c709418 100644 --- a/skin.scad +++ b/skin.scad @@ -1053,132 +1053,140 @@ module rotate_sweep( // Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path // of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius. // If turns is positive the path will be right-handed; if turns is negative the path will be left-handed. +// Such an extrusion can be used to make screw threads. // . -// The taper options specify tapering at of the ends of the extrusion, and are given as the linear distance -// over which to taper. If taper is positive the extrusion lengthened by the specified distance; if taper -// is negative, the taper is included in the extrusion length specified by `turns`. +// The lead_in options specify a lead-in setiton where the ends of the spiral scale down to avoid a sharp cut face at the ends. +// You can specify the length of this scaling directly with the lead_in parameters or as an angle using the lead_in_ang parameters. +// If you give a positive value, the extrusion is lengthenend by the specified distance or angle; if you give a negative +// value then the scaled end is included in the extrusion length specified by `turns`. If the value is zero then no scaled ends +// are produced. The shape of the scaled ends can be controlled with the lead_in_shape parameter. Supported options are "sqrt", "linear" +// "smooth" and "cut". +// . +// The inside argument changes how the extrusion lead-in sections are formed. If it is true then they scale +// towards the outside, like would be needed for internal threading. If internal is fale then the lead-in sections scale +// towards the inside, like would be appropriate for external threads. // Arguments: // poly = Array of points of a polygon path, to be extruded. -// h = height of the spiral to extrude along. -// r = Radius of the spiral to extrude along. -// turns = number of revolutions to spiral up along the height. +// h = height of the spiral extrusion path +// r = Radius of the spiral extrusion path +// turns = number of revolutions to include in the spiral // --- -// d = Diameter of the spiral to extrude along. +// d = Diameter of the spiral extrusion path. // d1/r1 = Bottom inside diameter or radius of spiral to extrude along. // d2/r2 = Top inside diameter or radius of spiral to extrude along. -// taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0 -// taper1 = Length of taper for bottom thread end -// taper2 = Length of taper for top thread end -// internal = if true make internal threads. The only effect this has is to change how the extrusion tapers if tapering is selected. When true, the extrusion tapers towards the outside; when false, it tapers towards the inside. Default: false +// lead_in = Specify linear length of the lead-in scaled section of the spiral. Default: 0 +// lead_in1 = Specify linear length of the lead-in scaled section of the spiral at the bottom +// lead_in2 = Specify linear length of the lead-in scaled section of the spiral at the top +// lead_in_ang = Specify angular length of the lead-in scaled section of the spiral +// lead_in_ang1 = Specify angular length of the lead-in scaled section of the spiral at the bottom +// lead_in_ang2 = Specify angular length of the lead-in scaled section of the spiral at the top +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "sqrt" +// lead_in_shape1 = Specify the shape of the thread lead-in at the bottom by giving a text string or function. +// lead_in_shape2 = Specify the shape of the thread lead-in at the top by giving a text string or function. +// lead_in_sample = Factor to increase sample rate in the lead-in section. Default: 10 +// internal = if true make internal threads. The only effect this has is to change how the extrusion lead-in section are formed. When true, the extrusion scales towards the outside; when false, it scales towards the inside. Default: false // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis 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` -// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`. -// See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep() +// See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep(), thread_helix() // Example: // poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]]; // spiral_sweep(poly, h=200, r=50, turns=3, $fn=36); -function _taperfunc_orig_1d(x,L) = - x>1 ? 1 : x<0 ? 0: - let( - higofs = pow(0.05,2) // Smallest hig scale is the square root of this value - ) - sqrt((1-higofs)*x+higofs); - -function _taperfunc_orig(x,L) = - let(s=_taperfunc_orig_1d(x)) - x>1 ? [1,1] - : x<0 ? [0,0] - - : [lerp(s,1,.25),s]; -function _taperfunc_ellipse(x) = - sqrt(1-(1-x)^2); -function _taperfunc_linear(x) = - x>1 ? 1 : x<0 ? 0 : x; -function _taperfunc_ogive_width(x,L) = - let( minscale = .2, +_leadin_ogive=function (x,L) + let( minscale = .05, r=(L^2+(1-minscale^2))/2/(1-minscale), scale = sqrt(r^2-(L*(1-x))^2) -(r-1) ) x>1 ? [1,1] - : x<0 ? [0,0] - : [scale,1]; -function _taperfunc_ogive_width_circle(x,L,h) = - let( minscale = .2, - r=(L^2+(1-minscale^2))/2/(1-minscale), - scale = sqrt(r^2-(L*(1-x))^2) -(r-1), - vscale = x*L>h ? h : sqrt(h^2-(x*L-h)^2) - ) + : x<0 ? [lerp(minscale,1,.25),0] + : [lerp(scale,1,.25),scale]; + +_leadin_cut = function(x,L) x>0 ? [1,1] : [1,0]; + +_leadin_sqrt = function(x,L) + let(end=0.05) // Smallest scale at the end x>1 ? [1,1] - : x<0.02 ? [0,0] - : [scale,vscale/h]; -function _taperfunc_ogive_height(x,L) = - let( minscale = .1,L=3*L, - r=(L^2+(1-minscale^2))/2/(1-minscale), - scale = sqrt(r^2-(L*(1-x))^2) -(r-1) + : x<0 ? [lerp(end,1,.25),0] + : let( + s = sqrt(x + end^2 * (1-x)) ) + [lerp(s,1,.25),s]; // thread width scale, thread height scale + +_leadin_linear = function(x,L) + let(minscale=.1) x>1 ? [1,1] - : x<0 ? [0,0] //minscale,0] - : [1,scale]; -function _taperfunc_ogive(x,L) = - let( minscale = .3, - r=(L^2+(1-minscale^2))/2/(1-minscale), - scale = sqrt(r^2-(L*(1-x))^2) -(r-1) - ) - x>1 ? [1,1] - : x<0 ? [0,0] - : [scale,scale]; -function _taperfunc_ogive_orig(x,L) = - let( minscale = .3, - r=(L^2+(1-minscale^2))/2/(1-minscale), - scale = sqrt(r^2-(L*(1-x))^2) -(r-1) - ) - x>1 ? [1,1] - : x<0 ? [0,0] - : [lerp(_taperfunc_orig_1d(x),1,.25),scale]; - -function _taperfunc_cut(x,L) = x>1 ? [1,1] : [0,0]; - - -function _taperfunc(x,L,h) = _taperfunc_ogive_width_circle(x,L,h); -//function _taperfunc(x,L,h) = _taperfunc_orig(x,L); -//function _taperfunc(x,L,h) = _taperfunc_ogive_width(x,L); -function _taperfunc(x,L,h) = _taperfunc_orig(x,L); - + : x<0 ? [lerp(minscale,1,.25),0] + : let(scale = lerp(minscale,1,x)) + [lerp(scale,1,.25),scale]; +_lead_in_table = [ + ["default", _leadin_sqrt], + ["sqrt", _leadin_sqrt], + ["cut", _leadin_cut], + ["smooth", _leadin_ogive], + ["linear", _leadin_linear] +]; + function _ss_polygon_r(N,theta) = let( alpha = 360/N ) cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2)); -function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) = +function spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false, + lead_in_shape,lead_in_shape1, lead_in_shape2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + height,l,length, + lead_in_sample = 10, + anchor=CENTER, spin=0, orient=UP) = assert(is_num(turns) && turns != 0, "turns must be a nonzero number") assert(all_positive([h]), "Spiral height must be a positive number") let( - tapersample = 10, // Oversample factor for higbee tapering dir = sign(turns), - r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50), - r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50), + r1 = get_radius(r1=r1, r=r, d1=d1, d=d), + r2 = get_radius(r1=r2, r=r, d1=d2, d=d), bounds = pointlist_bounds(poly), yctr = (bounds[0].y+bounds[1].y)/2, xmin = bounds[0].x, xmax = bounds[1].x, poly = path3d(clockwise_polygon(poly)), - anchor = get_anchor(anchor,center,BOT,BOT), sides = segs(max(r1,r2)), ang_step = 360/sides, turns = abs(turns), - taper1 = first_defined([taper1, taper, 0]), - taper2 = first_defined([taper2, taper, 0]), - taperang1 = 360 * abs(taper1) / (2 * r1 * PI), - taperang2 = 360 * abs(taper2) / (2 * r2 * PI), - minang = taper1<=0 ? 0 : -taperang1, - tapercut1 = taper1<=0 ? taperang1 : 0, - maxang = taper2<=0 ? 360*turns : 360*turns+taperang2, - tapercut2 = taper2<=0 ? 360*turns-taperang2 : 360*turns + lead_in1 = first_defined([lead_in1, lead_in]), + lead_in2 = first_defined([lead_in1, lead_in]), + lead_in_ang1 = + let( + user_ang = first_defined([lead_in_ang1,lead_in_ang]) + ) + assert(is_undef(user_ang) || is_undef(lead_in1), "Cannot define lead_in/lead_in1 by both length and angle") + is_def(user_ang) ? user_ang : default(lead_in1,0)*360/(2*PI*r1), + lead_in_ang2 = + let( + user_ang = first_defined([lead_in_ang2,lead_in_ang]) + ) + assert(is_undef(user_ang) || is_undef(lead_in2), "Cannot define lead_in/lead_in2 by both length and angle") + is_def(user_ang) ? user_ang : default(lead_in2,0)*360/(2*PI*r2), + minang = -max(0,lead_in_ang1), + maxang = 360*turns + max(0,lead_in_ang2), + cut_ang1 = minang+abs(lead_in_ang1), + cut_ang2 = maxang-abs(lead_in_ang1), + lead_in_shape1 = first_defined([lead_in_shape1, lead_in_shape, "default"]), + lead_in_shape2 = first_defined([lead_in_shape2, lead_in_shape, "default"]), + lead_in_func1 = is_func(lead_in_shape1) ? lead_in_shape1 + : assert(is_string(lead_in_shape1),"lead_in_shape/lead_in_shape1 must be a function or string") + let(ind = search([lead_in_shape1], _lead_in_table,0)[0]) + assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape1,"\"")) + _lead_in_table[ind[0]][1], + lead_in_func2 = is_func(lead_in_shape2) ? lead_in_shape2 + : assert(is_string(lead_in_shape2),"lead_in_shape/lead_in_shape2 must be a function or string") + let(ind = search([lead_in_shape2], _lead_in_table,0)[0]) + assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape2,"\"")) + _lead_in_table[ind[0]][1] ) - assert( tapercut1tapercut1+EPSILON && atapercut2+EPSILON) a + for(a=orig_anglist) if (acut_ang1+EPSILON && acut_ang2+EPSILON) a ], interp_ang = [ - for(i=idx(anglist,e=-2)) + for(i=idx(anglist,e=-2)) each lerpn(anglist[i],anglist[i+1], - (taper1!=0 && anglist[i+1]<=tapercut1) || (taper2!=0 && anglist[i]>=tapercut2) - ? ceil((anglist[i+1]-anglist[i])/ang_step*tapersample) + (lead_in_ang1!=0 && anglist[i+1]<=cut_ang1) || (lead_in_ang2!=0 && anglist[i]>=cut_ang2) + ? ceil((anglist[i+1]-anglist[i])/ang_step*lead_in_sample) : 1, endpoint=false), last(anglist) @@ -1207,8 +1215,8 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)), points = [ for (a = interp_ang) let ( - hsc = atapercut2 ? _taperfunc((maxang-a)/taperang2,abs(taper2),xmax-xmin) + hsc = acut_ang2 ? lead_in_func2((maxang-a)/abs(lead_in_ang2),abs(lead_in_ang2)*2*PI*r2/360) : [1,1], u = a/(360*turns), r = lerp(r1,r2,u), @@ -1230,15 +1238,30 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap -module spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) { - vnf = spiral_sweep(poly, h, r, turns, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal); - r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50); - r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50); - taper1 = first_defined([taper1,taper,0]); - taper2 = first_defined([taper2,taper,0]); - extra = PI/2*(max(0,taper1/r1)+max(0,taper2/r2)); +module spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false, + lead_in_shape,lead_in_shape1, lead_in_shape2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + height,l,length, + lead_in_sample=10, + anchor=CENTER, spin=0, orient=UP) +{ + vnf = spiral_sweep(poly=poly, h=h, r=r, turns=turns, r1=r1, r2=r2, d=d, d1=d1, d2=d2, internal=internal, + lead_in_shape=lead_in_shape,lead_in_shape1=lead_in_shape1, lead_in_shape2=lead_in_shape2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + height=height,l=length,length=length, + lead_in_sample=lead_in_sample); + h = one_defined([h,height,length,l],"h,height,length,l"); + r1 = get_radius(r1=r1, r=r, d1=d1, d=d); + r2 = get_radius(r1=r2, r=r, d1=d2, d=d); + lead_in1 = u_mul(first_defined([lead_in1,lead_in]),1/(2*PI*r1)); + lead_in2 = u_mul(first_defined([lead_in2,lead_in]),1/(2*PI*r2)); + lead_in_ang1 = first_defined([lead_in_ang1,lead_in_ang]); + lead_in_ang2 = first_defined([lead_in_ang2,lead_in_ang]); + extra_turns = max(0,first_defined([lead_in1,lead_in_ang1,0]))+max(0,first_defined([lead_in2,lead_in_ang2,0])); attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { - vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra))); + vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra_turns))); children(); } } @@ -1796,7 +1819,22 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0, ) assert(approx(ynormal*znormal,0),str("Supplied normal is parallel to the path tangent at point ",i)) translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i]) - ] + ] + : method=="cross"? + let( + crossnormal_mid = [for(i=[(closed?0:1):L-(closed?1:2)]) + let(v= cross( select(path,i+1)-path[i], path[i]-select(path,i-1)), + f=assert(norm(v)>EPSILON) + ) + v + ], + crossnormal = closed ? crossnormal_mid : [crossnormal_mid[0], each crossnormal_mid, last(crossnormal_mid)] + ) + [for(i=[0:L-(closed?0:1)]) let( + rotation = frame_map(x=crossnormal[i%L], z=tangents[i%L]) + ) + translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i]) + ] : method=="natural" ? // map x axis of shape to the path normal, which points in direction of curvature let (pathnormal = path_normals(path, tangents, closed)) assert(all_defined(pathnormal),"Natural normal vanishes on your curve, select a different method") diff --git a/threading.scad b/threading.scad index 465af98..1fbb746 100644 --- a/threading.scad +++ b/threading.scad @@ -22,7 +22,7 @@ // using the specification parameters. // Arguments: // d = Outer diameter of threaded rod, or a triplet of [d_min, d_pitch, d_major]. -// l / length = length of threaded rod. +// l / length / h / height = length of threaded rod. // pitch = Length between threads. // --- // left_handed = if true, create left-handed threads. Default = false @@ -33,9 +33,19 @@ // internal = If true, make this a mask for making internal threads. // d1 = Bottom outside diameter of threads. // d2 = Top outside diameter of threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -44,18 +54,19 @@ // projection(cut=true) // threaded_rod(d=10, l=15, pitch=1.5, orient=BACK); // Examples(Med): +// threaded_rod(d=25, height=20, pitch=2, $fa=1, $fs=1); // threaded_rod(d=10, l=20, pitch=1.25, left_handed=true, $fa=1, $fs=1); -// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1); -// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, bevel=true); -// rot(90)threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, higbee=true); +// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, end_len=1.5, bevel=true); +// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, blunt_start=false); // Example: Diamond threading where both left-handed and right-handed nuts travel (in the same direction) on the threaded rod: +// $fn=32; // $slop = 0.075; // d = 3/8*INCH; // pitch = 1/16*INCH; // starts=3; // xdistribute(19){ // intersection(){ -// threaded_rod(l=40, pitch=pitch, d=d,starts=starts,anchor=BOTTOM); +// threaded_rod(l=40, pitch=pitch, d=d,starts=starts,anchor=BOTTOM,end_len=.44); // threaded_rod(l=40, pitch=pitch, d=d, left_handed=true,starts=starts,anchor=BOTTOM); // } // threaded_nut(nutwidth=4.5/8*INCH,id=d,h=3/8*INCH,pitch=pitch,starts=starts,anchor=BOTTOM); @@ -66,8 +77,12 @@ function threaded_rod( left_handed=false, bevel,bevel1,bevel2,starts=1, internal=false, - d1, d2, - higbee, higbee1, higbee2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("threaded_rod"); @@ -76,14 +91,17 @@ module threaded_rod( left_handed=false, bevel,bevel1,bevel2,starts=1, internal=false, - d1, d2, length, - higbee, higbee1, higbee2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy1= assert(all_positive(pitch)) - assert(all_positive(d)) - assert(all_positive(l)); + assert(all_positive(d) || (is_undef(d) && all_positive([d1,d2]))); basic = is_num(d) || is_undef(d) || is_def(d1) || is_def(d2); dummy2 = assert(basic || is_vector(d,3)); depth = basic ? cos(30) * 5/8 @@ -116,10 +134,11 @@ module threaded_rod( profile=profile,starts=starts, left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, - internal=internal, length=length, - higbee=higbee, - higbee1=higbee1, - higbee2=higbee2, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, anchor=anchor, spin=spin, orient=orient @@ -136,7 +155,7 @@ module threaded_rod( // Arguments: // nutwidth = flat to flat width of nut // id = diameter of threaded rod to screw onto. -// h / height / thickness = height/thickness of nut. +// h / height / l / length / thickness = height/thickness of nut. // pitch = Distance between threads, or zero for no threads. // --- // shape = specifies shape of nut, either "hex" or "square". Default: "hex" @@ -149,9 +168,19 @@ module threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -161,18 +190,29 @@ module threaded_rod( // threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, left_handed=true, bevel=false, $slop=0.1, $fa=1, $fs=1); // threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, $slop=0.1, $fa=1, $fs=1); // threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, bevel2=true, $slop=0.1, $fa=1, $fs=1); -// rot(90)threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25,higbee=true, $slop=0.1, $fa=1, $fs=1); +// rot(90)threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25,blunt_start=false, $slop=0.1, $fa=1, $fs=1); function threaded_nut( nutwidth, id, h, pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2, - ibevel1, ibevel2, ibevel, bevang=30, thickness, height, + ibevel1, ibevel2, ibevel, bevang=30, thickness, height, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient )=no_function("threaded_nut"); module threaded_nut( nutwidth, id, h, pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2, ibevel1, ibevel2, ibevel, bevang=30, thickness, height, - higbee, higbee1, higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy1= @@ -207,8 +247,11 @@ module threaded_nut( left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, ibevel1=ibevel1, ibevel2=ibevel2, ibevel=ibevel, - height=height, thickness=thickness, bevang=bevang, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + l=l,length=length, anchor=anchor, spin=spin, orient=orient ) children(); @@ -255,7 +298,7 @@ module threaded_nut( // } // Arguments: // d = Outer diameter of threaded rod. -// l / length = Length of threaded rod. +// l / length / h / height = Length of threaded rod. // pitch = Thread spacing. // thread_angle = Angle between two thread faces. Default: 30 // thread_depth = Depth of threads. Default: pitch/2 @@ -268,9 +311,19 @@ module threaded_nut( // internal = If true, make this a mask for making internal threads. Default: false // d1 = Bottom outside diameter of threads. // d2 = Top outside diameter of threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -280,16 +333,18 @@ module threaded_nut( // trapezoidal_threaded_rod(d=10, l=15, pitch=2, orient=BACK); // Examples(Med): // trapezoidal_threaded_rod(d=10, l=40, pitch=2, $fn=32); // Standard metric threading -// rot(-65)trapezoidal_threaded_rod(d=10, l=17, pitch=2, higbee=25, $fn=32); // Standard metric threading +// rot(-65)trapezoidal_threaded_rod(d=10, l=17, pitch=2, blunt_start=false, $fn=32); // Standard metric threading // trapezoidal_threaded_rod(d=10, l=17, pitch=2, bevel=true, $fn=32); // Standard metric threading -// trapezoidal_threaded_rod(d=10, l=30, pitch=2, left_handed=true, $fa=1, $fs=1); // Standard metric threading +// trapezoidal_threaded_rod(d=10, h=30, pitch=2, left_handed=true, $fa=1, $fs=1); // Standard metric threading // trapezoidal_threaded_rod(d=10, l=40, pitch=3, left_handed=true, starts=3, $fn=36); // trapezoidal_threaded_rod(l=25, d=10, pitch=2, starts=3, $fa=1, $fs=1, bevel=true, orient=RIGHT, anchor=BOTTOM); -// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, $fa=2, $fs=2); -// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, starts=4, $fa=2, $fs=2); +// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, blunt_start=false, $fa=2, $fs=2); +// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, end_len=0, $fa=2, $fs=2); +// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, starts=4, $fa=2, $fs=2,end_len=0); // trapezoidal_threaded_rod(d=16, l=40, pitch=2, thread_angle=60); -// trapezoidal_threaded_rod(d=25, l=40, pitch=10, thread_depth=8/3, thread_angle=100, starts=4, anchor=BOT, $fa=2, $fs=2); -// trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=60, starts=11, higbee=true,$fn=120); +// trapezoidal_threaded_rod(d=25, l=40, pitch=10, thread_depth=8/3, thread_angle=100, starts=4, anchor=BOT, $fa=2, $fs=2,end_len=-2); +// trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=60, starts=11, lead_in=3, $fn=120); +// trapezoidal_threaded_rod(d=10, l=40, end_len2=10, pitch=2, $fn=32); // Unthreaded top end section // Example(Med): Using as a Mask to Make Internal Threads // bottom_half() difference() { // cube(50, center=true); @@ -301,9 +356,14 @@ function trapezoidal_threaded_rod( thread_depth=undef, left_handed=false, bevel,bevel1,bevel2, - starts=1, length, + starts=1, internal=false, - higbee, higbee1, higbee2,d1,d2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("trapezoidal_threaded_rod"); module trapezoidal_threaded_rod( @@ -312,9 +372,14 @@ module trapezoidal_threaded_rod( thread_depth=undef, left_handed=false, bevel,bevel1,bevel2, - starts=1, length, + starts=1, internal=false, - higbee, higbee1, higbee2,d1,d2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy0 = assert(all_positive(pitch)); @@ -332,8 +397,13 @@ module trapezoidal_threaded_rod( [ z2, rr1], ]; generic_threaded_rod(d=d,l=l,pitch=pitch,profile=profile, - left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts,internal=internal,d1=d1,d2=d2, - higbee=higbee,higbee1=higbee1,higbee2=higbee2,anchor=anchor,spin=spin,orient=orient,length=length) + left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts,d1=d1,d2=d2, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + anchor=anchor,spin=spin,orient=orient) children(); } @@ -349,7 +419,7 @@ module trapezoidal_threaded_rod( // Arguments: // nutwidth = flat to flat width of nut // id = diameter of threaded rod to screw onto. -// h / height / thickness = height/thickness of nut. +// h / height / l / length / thickness = height/thickness of nut. // pitch = Thread spacing. // thread_angle = Angle between two thread faces. Default: 30 // thread_depth = Depth of the threads. Default: pitch/2 @@ -364,19 +434,29 @@ module trapezoidal_threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` // $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads. // Examples(Med): // trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, $slop=0.1, anchor=UP); -// trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, bevel=true, $slop=0.05, anchor=UP); +// trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, bevel=false, $slop=0.05, anchor=UP); // trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, $slop=0.1, left_handed=true); // trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15); -// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15, higbee=true); +// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15, blunt_start=false); // trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=0, $slop=0.2); // No threads function trapezoidal_threaded_nut( nutwidth, @@ -391,7 +471,12 @@ function trapezoidal_threaded_nut( ibevel1,ibevel2,ibevel, thickness,height, id1,id2, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("trapezoidal_threaded_nut"); module trapezoidal_threaded_nut( @@ -407,7 +492,12 @@ module trapezoidal_threaded_nut( ibevel1,ibevel2,ibevel, thickness,height, id1,id2, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy1 = assert(is_num(pitch) && pitch>=0 && thread_angle>=0 && thread_angle<180); @@ -426,7 +516,11 @@ module trapezoidal_threaded_nut( generic_threaded_nut(nutwidth=nutwidth,id=id,h=h,pitch=pitch,profile=profile,id1=id1,id2=id2, shape=shape,left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts, ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,bevang=bevang,height=height,thickness=thickness, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + l=l,length=length, anchor=anchor,spin=spin,orient=orient) children(); } @@ -440,7 +534,7 @@ module trapezoidal_threaded_nut( // symmetric trapezoidal thread. // Arguments: // d = Outer diameter of threaded rod. -// l / length = length of threaded rod. +// l / length / h / height = Length of threaded rod. // tpi = threads per inch. // --- // pitch = thread spacing (alternative to tpi) @@ -450,9 +544,19 @@ module trapezoidal_threaded_nut( // bevel1 = if true bevel the bottom end. // bevel2 = if true bevel the top end. // internal = If true, this is a mask for making internal threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -468,8 +572,13 @@ function acme_threaded_rod( starts=1, left_handed=false, bevel,bevel1,bevel2, - internal=false, length, - higbee, higbee1, higbee2, + internal=false, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("acme_threaded_rod"); module acme_threaded_rod( @@ -477,8 +586,13 @@ module acme_threaded_rod( starts=1, left_handed=false, bevel,bevel1,bevel2, - internal=false, length, - higbee, higbee1, higbee2, + internal=false, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy = assert(num_defined([pitch,tpi])==1,"Must give exactly one of pitch and tpi"); @@ -490,8 +604,11 @@ module acme_threaded_rod( starts=starts, left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, - internal=internal, length=length, - higbee=higbee, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, anchor=anchor, spin=spin, orient=orient @@ -508,7 +625,7 @@ module acme_threaded_rod( // Arguments: // nutwidth = flat to flat width of nut. // id = diameter of threaded rod to screw onto. -// h / height / thickness = height/thickness of nut. +// h / height / l / length / thickness = height/thickness of nut. // tpi = threads per inch // --- // pitch = Thread spacing (alternative to tpi) @@ -522,17 +639,27 @@ module acme_threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` // $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads. // Examples(Med): -// acme_threaded_nut(nutwidth=16, id=3/8*INCH, h=8, tpi=8, $slop=0.05); +// acme_threaded_nut(nutwidth=16, id=3/8*INCH, h=8, tpi=8, $slop=0.05,end_len=0,ibevel=1); // acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1); -// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1,ibevel=false,higbee=true); +// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1, blunt_start=false); function acme_threaded_nut( nutwidth, id, h, tpi, pitch, starts=1, @@ -540,7 +667,12 @@ function acme_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel,ibevel1,ibevel2, height,thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("acme_threaded_nut"); module acme_threaded_nut( @@ -550,7 +682,12 @@ module acme_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel,ibevel1,ibevel2, height,thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { dummy = assert(num_defined([pitch,tpi])==1,"Must give exactly one of pitch and tpi"); @@ -564,8 +701,12 @@ module acme_threaded_nut( bevel=bevel,bevel1=bevel1,bevel2=bevel2, ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2, height=height,thickness=thickness, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + l=l,length=length, starts=starts, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, anchor=anchor, spin=spin, orient=orient @@ -684,7 +825,7 @@ module npt_threaded_rod( left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, internal=internal, - higbee=true + blunt_start=true ); if (hollow) cylinder(h=l+1, d=size*INCH, center=true); } @@ -705,7 +846,7 @@ module npt_threaded_rod( // vises, which are loaded only in one direction. // Arguments: // d = Outer diameter of threaded rod. -// l / length = length of threaded rod. +// l / length / h / height = Length of threaded rod. // pitch = Thread spacing. // --- // left_handed = if true, create left-handed threads. Default = false @@ -714,9 +855,19 @@ module npt_threaded_rod( // bevel1 = if true bevel the bottom end. // bevel2 = if true bevel the top end. // internal = If true, this is a mask for making internal threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // d1 = Bottom outside diameter of threads. // d2 = Top outside diameter of threads. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` @@ -727,49 +878,55 @@ module npt_threaded_rod( // projection(cut=true) // buttress_threaded_rod(d=10, l=15, pitch=2, orient=BACK); // Examples(Med): +// buttress_threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1,end_len=0); // buttress_threaded_rod(d=10, l=20, pitch=1.25, left_handed=true, $fa=1, $fs=1); -// buttress_threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1); function buttress_threaded_rod( d, l, pitch, - left_handed=false, + left_handed=false, starts=1, bevel,bevel1,bevel2, internal=false, - higbee, higbee1, higbee2, - d1,d2,starts=1,length, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("buttress_threaded_rod"); module buttress_threaded_rod( d, l, pitch, - left_handed=false, + left_handed=false, starts=1, bevel,bevel1,bevel2, internal=false, - higbee,higbee1,higbee2, - d1,d2,starts=1,length, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { depth = pitch * 3/4; profile = [ + [ -1/2, -0.77], [ -7/16, -0.75], [ 5/16, 0], [ 7/16, 0], [ 7/16, -0.75], - [ 1/ 2, -0.77], + [ 1/2, -0.77], ]; - higbee2 = !internal || (!higbee && !higbee2) ? higbee2 - : let (higval = first_defined([higbee2,higbee])) - is_num(higval) ? higval + 270 - : 270; generic_threaded_rod( d=d, l=l, pitch=pitch, profile=profile, left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, - internal=internal, - higbee=higbee, - higbee1=higbee1, - higbee2=higbee2, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, d1=d1,d2=d2, - anchor=anchor,length=length, + anchor=anchor, spin=spin,starts=starts, orient=orient ) children(); @@ -785,7 +942,7 @@ module buttress_threaded_rod( // Arguments: // nutwidth = diameter of the nut. // id = diameter of threaded rod to screw onto. -// h = height/thickness of nut. +// h / height / l / length / thickness = height/thickness of nut. // pitch = Thread spacing. // --- // shape = specifies shape of nut, either "hex" or "square". Default: "hex" @@ -798,9 +955,19 @@ module buttress_threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -812,7 +979,12 @@ function buttress_threaded_nut( pitch, shape="hex", left_handed=false, bevel,bevel1,bevel2,bevang=30,starts=1, ibevel,ibevel1,ibevel2,height,thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("buttress_threaded_nut"); module buttress_threaded_nut( @@ -820,21 +992,23 @@ module buttress_threaded_nut( pitch, shape="hex", left_handed=false, bevel,bevel1,bevel2,bevang=30,starts=1, ibevel,ibevel1,ibevel2,height,thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { depth = pitch * 3/4; profile = [ + [ -1/2, -0.77], [ -7/16, -0.75], [ 5/16, 0], [ 7/16, 0], [ 7/16, -0.75], [ 1/ 2, -0.77], ]; - higbee2 = !higbee && !higbee2 ? higbee2 - : let (higval = first_defined([higbee2,higbee])) - is_num(higval) ? higval + 270 - : 270; generic_threaded_nut( nutwidth=nutwidth, id=id, h=h, pitch=pitch, @@ -843,7 +1017,11 @@ module buttress_threaded_nut( left_handed=left_handed,starts=starts, bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang, ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + l=l,length=length, anchor=anchor, spin=spin, height=height, thickness=thickness, orient=orient ) children(); @@ -861,7 +1039,7 @@ module buttress_threaded_nut( // They produce no radial load on the nut. However, square threads cannot carry as much load as trapezoidal threads. // Arguments: // d = Outer diameter of threaded rod. -// l / length = length of threaded rod. +// l / length / h / height = Length of threaded rod. // pitch = Thread spacing. // --- // left_handed = if true, create left-handed threads. Default = false @@ -870,9 +1048,20 @@ module buttress_threaded_nut( // bevel1 = if true bevel the bottom end. // bevel2 = if true bevel the top end. // internal = If true, this is a mask for making internal threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. + +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // d1 = Bottom outside diameter of threads. // d2 = Top outside diameter of threads. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` @@ -890,8 +1079,12 @@ function square_threaded_rod( bevel,bevel1,bevel2, starts=1, internal=false, - higbee, higbee1, higbee2, - d1,d2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("square_threaded_rod"); module square_threaded_rod( @@ -900,8 +1093,12 @@ module square_threaded_rod( bevel,bevel1,bevel2, starts=1, internal=false, - higbee, higbee1, higbee2, - d1,d2,length, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { trapezoidal_threaded_rod( @@ -910,13 +1107,13 @@ module square_threaded_rod( left_handed=left_handed, bevel=bevel,bevel1=bevel1,bevel2=bevel2, starts=starts, - internal=internal, - higbee=higbee, - higbee1=higbee1, - higbee2=higbee2, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, d1=d1, d2=d2, - length=length, anchor=anchor, spin=spin, orient=orient @@ -933,7 +1130,7 @@ module square_threaded_rod( // Arguments: // nutwidth = diameter of the nut. // id = diameter of threaded rod to screw onto. -// h / height / thickness = height/thickness of nut. +// h / height / l / length / thickness = height/thickness of nut. // pitch = Length between threads. // --- // shape = specifies shape of nut, either "hex" or "square". Default: "hex" @@ -946,9 +1143,19 @@ module square_threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -962,8 +1169,13 @@ function square_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel,ibevel1,ibevel2, height,thickness, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", starts=1, - higbee,higbee1,higbee2, anchor, spin, orient ) = no_function("square_threaded_nut"); module square_threaded_nut( @@ -973,7 +1185,12 @@ module square_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel,ibevel1,ibevel2, height,thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", starts=1, anchor, spin, orient ) { @@ -986,7 +1203,11 @@ module square_threaded_nut( ibevel=ibevel, ibevel1=ibevel1, ibevel2=ibevel2, height=height,thickness=thickness, starts=starts, - higbee=higbee, higbee1=higbee1, higbee2=higbee2, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, + l=l,length=length, anchor=anchor, spin=spin, orient=orient @@ -1003,7 +1224,7 @@ module square_threaded_nut( // Constructs a ball screw rod. This type of rod is used with ball bearings. // Arguments: // d = Outer diameter of threaded rod. -// l / length = length of threaded rod. +// l / length / h / height = Length of threaded rod. // pitch = Thread spacing. Also, the diameter of the ball bearings used. // ball_diam = The diameter of the ball bearings to use with this ball screw. // ball_arc = The arc portion that should touch the ball bearings. Default: 120 degrees. @@ -1014,27 +1235,46 @@ module square_threaded_nut( // bevel1 = if true bevel the bottom end. // bevel2 = if true bevel the top end. // internal = If true, make this a mask for making internal threads. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` // $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads. // Example(2D): Thread Profile, ball_diam=4, ball_arc=100 -// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=100, orient=BACK, $fn=24); +// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=100, orient=BACK, $fn=24, blunt_start=false); // Example(2D): Thread Profile, ball_diam=4, ball_arc=120 -// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=120, orient=BACK, $fn=24); +// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=120, orient=BACK, $fn=24, blunt_start=false); // Example(2D): Thread Profile, ball_diam=3, ball_arc=120 -// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=3, ball_arc=120, orient=BACK, $fn=24); +// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=3, ball_arc=120, orient=BACK, $fn=24, blunt_start=false); // Examples(Med): -// ball_screw_rod(d=15, l=20, pitch=8, ball_diam=5, ball_arc=120, $fa=1, $fs=0.5); -// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, $fa=1, $fs=0.5); -// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, left_handed=true, $fa=1, $fs=0.5); +// ball_screw_rod(d=15, l=20, pitch=8, ball_diam=5, ball_arc=120, $fa=1, $fs=0.5, blunt_start=false); +// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, $fa=1, $fs=0.5, blunt_start=false); +// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, left_handed=true, $fa=1, $fs=0.5, blunt_start=false); function ball_screw_rod( d, l, pitch, ball_diam=5, ball_arc=100, starts=1, left_handed=false, internal=false, - bevel,bevel1,bevel2, length, + length, h, height, + bevel, bevel1, bevel2, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("ball_screw_rod"); module ball_screw_rod( @@ -1043,7 +1283,13 @@ module ball_screw_rod( starts=1, left_handed=false, internal=false, - bevel,bevel1,bevel2, length, + length, h, height, + bevel, bevel1, bevel2, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { n = max(3,ceil(segs(ball_diam/2)*ball_arc/2/360)); @@ -1059,8 +1305,11 @@ module ball_screw_rod( left_handed=left_handed, starts=starts, bevel=bevel,bevel1=bevel1,bevel2=bevel2, - internal=internal, - higbee=false, length=length, + internal=internal, length=length, height=height, h=h, + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2, anchor=anchor, spin=spin, orient=orient @@ -1068,7 +1317,6 @@ module ball_screw_rod( } - // Section: Generic Threading // Module: generic_threaded_rod() @@ -1082,7 +1330,7 @@ module ball_screw_rod( // must be between -1/2 and 1/2. The Y=0 point will align with the specified rod diameter, so generally you want a Y value of zero at the peak (which // makes your specified diameter the outer diameter of the threads). // The value in the valleys of the thread should then be `-depth/pitch` due to the scaling by the thread pitch. The segment between the end -// of one thread and the start of the next is added automatically, so you should not have the path start and end at equivalent points (X = ±1/2 with the same Y value). +// of one thread and the start of the next is added automatically, so you should not have the path start and end at equivalent points (X = +-1/2 with the same Y value). // Generally you should center the profile horizontally in the interval [-1/2, 1/2]. // . // If internal is true then produce a thread mask to difference from an object. @@ -1100,21 +1348,31 @@ module ball_screw_rod( // giving more space at the end. Higbee works on both internal and external threads. // Arguments: // d = Outer diameter of threaded rod. -// l / length = Length of threaded rod. +// l / length / h / height = Length of threaded rod. // pitch = Thread spacing. // profile = A 2D path giving the shape of a thread // --- // left_handed = If true, create left-handed threads. Default: false // starts = The number of lead starts. Default: 1 -// bevel = if true, bevel the thread ends. Default: false -// bevel1 = if true bevel the bottom end. -// bevel2 = if true bevel the top end. // internal = If true, make this a mask for making internal threads. Default: false // d1 = Bottom outside diameter of threads. // d2 = Top outside diameter of threads. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. +// bevel = set to true to bevel both ends, a number to specify a bevel size, false for no bevel, and "reverse" for an inverted bevel +// bevel1 = set bevel for bottom end. +// bevel2 = set bevel for top end. +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -1143,185 +1401,243 @@ module ball_screw_rod( // [ 7/16, -depth/pitch*1.07] // ]; // generic_threaded_rod(d=10, l=40, pitch=2, profile=profile); + function generic_threaded_rod( d, l, pitch, profile, - left_handed=false, - bevel, - bevel1, bevel2, + left_handed=false, internal=false, + bevel, bevel1, bevel2, starts=1, - internal=false, - d1, d2, length, - higbee, higbee1, higbee2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("generic_threaded_rod"); module generic_threaded_rod( d, l, pitch, profile, - left_handed=false, - bevel, - bevel1, bevel2, + left_handed=false, internal=false, + bevel, bevel1, bevel2, starts=1, - internal=false, - d1, d2, length, - higbee, higbee1, higbee2, + d1, d2, length, h, height, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { - l = one_defined([l,length],"l,length"); - bevel1 = first_defined([bevel1,bevel,false]); - bevel2 = first_defined([bevel2,bevel,false]); - thigbee1 = first_defined([higbee1,higbee,false]); - thigbee2 = first_defined([higbee2,higbee,false]); - // Zero higbee should be treated as "true", default angle, but it tests as false so adjust - higbee1 = thigbee1==0 ? true : thigbee1; - higbee2 = thigbee2==0 ? true : thigbee2; - extra_thread1 = higbee1==false && internal ? 1 : 0; - extra_thread2 = higbee2==false && internal ? 1 : 0; + len = one_defined([l,length,h,height],"l,length,h,height"); + bevel1 = first_defined([bevel1,bevel]); + bevel2 = first_defined([bevel2,bevel]); + blunt_start1 = first_defined([blunt_start1, blunt_start, true]); + blunt_start2 = first_defined([blunt_start2, blunt_start, true]); r1 = get_radius(d1=d1, d=d); r2 = get_radius(d1=d2, d=d); + lead_in1 = first_defined([lead_in1, lead_in]); + lead_in2 = first_defined([lead_in2, lead_in]); + lead_in_func = is_func(lead_in_shape) ? lead_in_shape + : assert(is_string(lead_in_shape),"lead_in_shape must be a function or string") + let(ind = search([lead_in_shape], _lead_in_table,0)[0]) + assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape,"\"")) + _lead_in_table[ind[0]][1]; dummy0 = assert(all_positive([pitch]),"Thread pitch must be a positive value") - assert(all_positive([l]),"Length must be a postive value") + assert(all_positive([len]),"Length must be a postive value") assert(is_path(profile),"Profile must be a path") - assert(is_finite(higbee1) || is_bool(higbee1), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number")) - assert(is_finite(higbee2) || is_bool(higbee2), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number")) + assert(is_bool(blunt_start1), "blunt_start1/blunt_start must be boolean") + assert(is_bool(blunt_start2), "blunt_start2/blunt_start must be boolean") assert(is_bool(left_handed)) - assert(all_positive([r1,r2]), "Must give d or both d1 and d2 as positive values"); + assert(all_positive([r1,r2]), "Must give d or both d1 and d2 as positive values") + assert(is_undef(bevel1) || is_num(bevel1) || is_bool(bevel1) || bevel1=="reverse", "bevel1/bevel must be a number, boolean or \"reverse\"") + assert(is_undef(bevel2) || is_num(bevel2) || is_bool(bevel2) || bevel2=="reverse", "bevel2/bevel must be a number, boolean or \"reverse\""); sides = quantup(segs(max(r1,r2)), starts); - rsc = internal? (1/cos(180/sides)) : 1; + rsc = internal? (1/cos(180/sides)) : 1; // Internal radius adjusted for faceting islop = internal? 2*get_slop() : 0; - _r1 = r1 * rsc + islop; - _r2 = r2 * rsc + islop; - threads = extra_thread1+extra_thread2+quantup(l/pitch+2,1); // Was quantup(1/pitch+2,2*starts); - dir = left_handed? -1 : 1; - twist = 360 * l / pitch / starts; - profile = !internal ? profile - : [ - for(entry=profile) if (entry.x>=0) [entry.x-1/2,entry.y], - for(entry=profile) if (entry.x<0) [entry.x+1/2,entry.y] + r1adj = r1 * rsc + islop; + r2adj = r2 * rsc + islop; + + extreme = internal? max(column(profile,1)) : min(column(profile,1)); + profile = !internal ? profile + : let( + maxidx = [for(i=idx(profile)) if (profile[i].y==extreme) i], + cutpt = len(maxidx)==1 ? profile(maxidx[0]).x + : mean([profile[maxidx[0]].x, profile[maxidx[1]].x]) + ) + [ + for(entry=profile) if (entry.x>=cutpt) [entry.x-cutpt-1/2,entry.y], + for(entry=profile) if (entry.xdepth && _r2>depth, "Screw profile deeper than rod radius"); - map_threads = right((_r1 + _r2) / 2) // Shift profile out to thread radius - * affine3d_skew(sxz=(_r2-_r1)/l) // Skew correction for tapered threads + rmax = max(r1adj,r2adj)+pmax; + + // These parameters give the size of the bevel, negative for an outward bevel (e.g. on internal thread mask) + bev1 = (bevel1=="reverse"?-1:1)*(internal?-1:1) * + ( is_num(bevel1)? bevel1 + : bevel1==false? 0 + : blunt_start1? (bevel1==undef?0 + :internal ? r1/6 + :(r1+profmin)/6) + : pmax-profmin); + bev2 = (bevel2=="reverse"?-1:1)*(internal?-1:1) * + ( is_num(bevel2)? bevel2 + : bevel2==false? 0 + : blunt_start2? (bevel2==undef?0 + :internal ? r2/6 + :(r2+profmin)/6) + : pmax-profmin); + // This is the bevel size used for constructing the polyhedron. The bevel is integrated when blunt start is on, but + // applied later via difference/union if blunt start is off, so set bevel to zero in the latter case. + bevel_size1 = blunt_start1?bev1:0; + bevel_size2 = blunt_start2?bev2:0; + // This is the bevel size for clipping, which is only done when blunt start is off + clip_bev1 = blunt_start1?0:bev1; + clip_bev2 = blunt_start2?0:bev2; + end_len1_base = !blunt_start1? 0 : first_defined([end_len1,end_len, 0]); + end_len2_base = !blunt_start2? 0 : first_defined([end_len2,end_len, 0]); + // Enlarge end lengths to give sufficient room for requested bevel + end_len1 = abs(bevel_size1)>0 ? max(end_len1_base, abs(bevel_size1)) : end_len1_base; + end_len2 = abs(bevel_size2)>0 ? max(end_len2_base, abs(bevel_size2)) : end_len2_base; + // length to create below/above z=0, with an extra revolution in non-blunt-start case so + // the threads can continue to the specified length and we can clip off the blunt start + len1 = -len/2 - (blunt_start1?0:pitch); + len2 = len/2 + (blunt_start2?0:pitch); + + // Thread turns below and above z=0, with extra to ensure we go beyond the length needed + turns1 = len1/pitch-1; + turns2 = len2/pitch+1; + dir = left_handed? -1 : 1; + dummy2= + assert(abs(bevel_size1)+abs(bevel_size2)0, "bevel1 is too large to fit screw diameter") + assert(r2adj+extreme*pitch-bevel_size2>0, "bevel2 is too large to fit screw diameter"); + + margin1 = profile[0].y==extreme ? profile[0].x : -1/2; + margin2 = last(profile).y==extreme? last(profile).x : 1/2; + lead_in_default = pmax-profmin;//2*pitch; + // 0*360/10;// /4/32*360; higlen_default;//0*4/32*360; //2/32*360;//360*max(pitch/2, pmax-depth)/(2*PI*r2adj); + // lead_in length needs to be quantized to match the samples + lead_in_ang1 = !blunt_start1? 0 : + let( + user_ang = first_defined([lead_in_ang1,lead_in_ang]) + ) + assert(is_undef(user_ang) || is_undef(lead_in1), "Cannot define lead_in/lead_in1 by both length and angle") + quantup( + is_def(user_ang) ? user_ang : default(lead_in1, lead_in_default)*360/(2*PI*r1adj) + , 360/sides); + lead_in_ang2 = !blunt_start2? 0 : + let( + user_ang = first_defined([lead_in_ang2,lead_in_ang]) + ) + assert(is_undef(user_ang) || is_undef(lead_in2), "Cannot define lead_in/lead_in2 by both length and angle") + quantup( + is_def(user_ang) ? user_ang : default(lead_in2, lead_in_default)*360/(2*PI*r2adj) + , 360/sides); + // cut_ang also need to be quantized, but the comparison is offset by 36*turns1/starts, so we need to pull that factor out + // of the quantization. (The loop over angle starts at 360*turns1/starts, not at a multiple of 360/sides.) +// cut_ang1 = 360 * (len1/pitch-margin1+end_len1/pitch) / starts + lead_in_ang1; +// cut_ang2 = 360 * (len2/pitch-margin2-end_len2/pitch) / starts - lead_in_ang2; + cut_ang1 = quantup(360 * (len1/pitch-margin1+end_len1/pitch) / starts + lead_in_ang1-360*turns1/starts,360/sides)+360*turns1/starts; + cut_ang2 = quantdn(360 * (len2/pitch-margin2-end_len2/pitch) / starts - lead_in_ang2-360*turns1/starts,360/sides)+360*turns1/starts; + dummy1 = + assert(cut_ang10 && r2adj+profmin>0, "Screw profile deeper than rod radius"); + map_threads = right((r1adj + r2adj) / 2) // Shift profile out to thread radius + * affine3d_skew(sxz=(r2adj-r1adj)/len) // Skew correction for tapered threads * frame_map(x=[0,0,1], y=[1,0,0]) // Map profile to 3d, parallel to z axis * scale(pitch); // scale profile by pitch start_steps = sides / starts; - higlen = 2/32*360;//360*max(pitch/2, pmax-depth)/(2*PI*_r2); - echo(higlen=higlen); + + // This is the location for clipping the polyhedron, below the bevel, if one is present, or at length otherwise + // Clipping is done before scaling to pitch, so we need to divide by the pitch + rod_clip1 = (len1+abs(bevel_size1))/pitch; + rod_clip2 = (len2-abs(bevel_size2))/pitch; + prof3d=path3d(profile,1); thread_verts = [ // Outer loop constructs a vertical column of the screw at each angle - // covering 1/starts * 360 degrees of the cylinder. + // covering 360/starts degrees of the cylinder. for (step = [0:1:start_steps]) let( ang = 360 * step/sides, dz = step / start_steps, // z offset for threads at this angle rot_prof = zrot(ang*dir)*map_threads, // Rotate profile to correct angular location full_profile = [ // profile for the entire rod - for (thread = [-threads/2:1:threads/2-1]) + for (turns = [turns1:1:turns2]) let( - tang = thread/starts * 360 + ang, - hsc = tang < -twist/2+higang1 ? _taperfunc(1-(-twist/2+higang1-tang)/higlen,PI*2*_r1*higlen/360 ) - : tang > twist/2-higang2 ? _taperfunc(1-(tang-twist/2+higang2)/higlen,PI*2*_r2*higlen/360 ) + tang = turns/starts * 360 + ang, + // EPSILON offset prevents funny looking extensions of the thread from its very tip + // by forcing values near the tip to evaluate as less than zero = beyond the tip end + hsc = tang < cut_ang1 ? lead_in_func(-EPSILON+1-(cut_ang1-tang)/lead_in_ang1,PI*2*r1adj*lead_in_ang1/360 ) + : tang > cut_ang2 ? lead_in_func(-EPSILON+1-(tang-cut_ang2)/lead_in_ang2,PI*2*r2adj*lead_in_ang2/360 ) : [1,1], - higscale=scale([hsc.x, hsc.y,1], cp=[0,internal ? pmax/pitch:-pdepth, 0]) -// higscale=scale([lerp(hsc,1,0.25),hsc,1], cp=[0,internal ? pmax/pitch:-pdepth, 0]) -// higscale=scale([lerp(hsc,1,0.25),1,1], cp=[0,internal ? pmax/pitch:-pdepth, 0]) -// higscale=scale([1,hsc,1], cp=[0,internal ? pmax/pitch:-pdepth, 0]) + shift_and_scale = [[hsc.x, 0], [0,hsc.y], [dz+turns,(1-hsc.y)*extreme]] ) + // This is equivalent to apply(right(dz+turns)*higscale, profile) + // // The right movement finds the position of the thread along - // what will be the z axis after the profile is mapped to 3d - each apply(right(dz + thread) * higscale, prof3d) - ] + // what will be the z axis after the profile is mapped to 3d, + // and higscale creates a taper and the end of the threads. + each prof3d*shift_and_scale + ], + // Clip profile at the ends of the rod and add a z coordinate + full_profile_clipped = [ + for(pts=full_profile) [max(rod_clip1,min(rod_clip2,pts.x)), pts.y, 0] + ] ) [ - [0, 0, -l/2-pitch-1-extra_thread1*pitch], - each apply(rot_prof , full_profile), - [0, 0, +l/2+pitch+1+extra_thread2*pitch] + [0,0,len1], + //if (true) apply(rot_prof, [len1/pitch,extreme+2/pitch ,0]), + if (bevel_size1) apply(rot_prof, [len1/pitch,extreme-bevel_size1/pitch ,0]), + each apply(rot_prof, full_profile_clipped), + if (bevel_size2) apply(rot_prof, [len2/pitch,extreme-bevel_size2/pitch ,0]), + //if (true) apply(rot_prof, [len2/pitch,extreme+2/pitch ,0]), + [0, 0, len2] ] ]; style=internal?"concave":"convex"; - - thread_vnfs = vnf_join( - [ - // Main thread faces - for (i=[0:1:starts-1]) - zrot(i*360/starts, p=vnf_vertex_array(thread_verts, reverse=left_handed, style=style)), - // Top closing face(s) of thread - for (i=[0:1:starts-1]) - let( - rmat = zrot(i*360/starts), - pts = deduplicate(list_head(thread_verts[0], len(prof3d)+1)), - faces = [for (i=idx(pts,e=-2)) left_handed ? [0, i, i+1] : [0, i+1, i]] - ) - [apply(rmat,pts), faces], - // Bottom closing face(s) of thread - for (i=[0:1:starts-1]) - let( - rmat = zrot(i*360/starts), - pts = deduplicate(list_tail(last(thread_verts), -len(prof3d)-2)), - faces = [for (i=idx(pts,e=-2)) left_handed ? [len(pts)-1, i+1, i] : [len(pts)-1, i, i+1]] - ) - [apply(rmat,pts), faces] - ] - ); - - slope = (_r1-_r2)/l; - maxlen = 5*pitch; - attachable(anchor,spin,orient, r1=_r1, r2=_r2, l=l) { + thread_vnf = vnf_join([ + for (i=[0:1:starts-1]) + zrot(i*360/starts, p=vnf_vertex_array(thread_verts, reverse=left_handed, style=style,col_wrap=false)), + ]); + slope = (r1adj-r2adj)/len; + dummy3 = + assert(r1adj+pmax-clip_bev1>0, "bevel1 is too large to fit screw diameter") + assert(r2adj+pmax-clip_bev2>0, "bevel2 is too large to fit screw diameter") + assert(abs(clip_bev1)+abs(clip_bev2)0) + rotate_extrude() + polygon([[ 0,-len/2], + [r1adj+pmax-clip_bev1 ,-len/2], + [r1adj+pmax-slope*clip_bev1,-len/2+clip_bev1], + [ rmax+1,-len/2+clip_bev1], + [ rmax+1, len1-1], + [ 0, len1-1]]); + if (clip_bev2>0) + rotate_extrude() + polygon([[ 0, len/2], + [r2adj+pmax-clip_bev2 , len/2], + [r2adj+pmax+slope*clip_bev2, len/2-clip_bev2], + [ rmax+1, len/2-clip_bev2], + [ rmax+1, len2+1], + [ 0, len2+1]]); + if (!blunt_start1 && clip_bev1<=0) + down(len/2) cuboid([2*rmax+1,2*rmax+1, -len1+1], anchor=TOP); + if (!blunt_start2 && clip_bev2<=0) + up(len/2) cuboid([2*rmax+1,2*rmax+1, len2+1], anchor=BOTTOM); } - /* // slower, simpler approach for beveling - intersection(){ - //vnf_validate(vnf_quantize(thread_vnfs), size=0.1); - vnf_polyhedron(vnf_quantize(thread_vnfs), convexity=10); - cyl(l=l, r1=_r1+pmax, r2=_r2+pmax, chamfer1=bevel1?depth:undef, chamfer2=bevel2?depth:undef); - } - */ - // Add bevel for internal thread mask - if (internal) { - if (bevel1) - down(l/2+.001)cyl(l=depth, r1=_r1+pmax, r2=_r1+pmax-slope*depth-depth,anchor=BOTTOM); - if (bevel2) - up(l/2+.001)cyl(l=depth, r2=_r2+pmax, r1=_r2+pmax+slope*depth-depth,anchor=TOP); - } + if (clip_bev1<0) + down(len/2+.001)cyl(l=-clip_bev1, r2=r1adj+profmin, r1=r1adj+profmin+slope*clip_bev1-clip_bev1,anchor=BOTTOM); + if (clip_bev2<0) + up(len/2+.001)cyl(l=-clip_bev2, r1=r2adj+profmin, r2=r2adj+profmin+slope*clip_bev1-clip_bev2,anchor=TOP); } children(); } @@ -1345,6 +1661,8 @@ module generic_threaded_rod( // shape = specifies shape of nut, either "hex" or "square". Default: "hex" // left_handed = if true, create left-handed threads. Default = false // starts = The number of lead starts. Default = 1 +// id1 = inner diameter at the bottom +// id2 = inner diameter at the top // bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts // bevel1 = if true, bevel the outside of the nut bottom. // bevel2 = if true, bevel the outside of the nut top. @@ -1352,11 +1670,19 @@ module generic_threaded_rod( // ibevel = if true, bevel the inside (the hole). Default: true // ibevel1 = if true bevel the inside, bottom end. // ibevel2 = if true bevel the inside, top end. -// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false -// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point. -// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point. -// id1 = inner diameter at the bottom -// id2 = inner diameter at the top +// blunt_start = If true apply truncated blunt start threads at both ends. Default: true +// blunt_start1 = If true apply truncated blunt start threads bottom end. +// blunt_start2 = If true apply truncated blunt start threads top end. +// end_len = Specify the unthreaded length at the end after blunt start threads. Default: 0 +// end_len1 = Specify unthreaded length at the bottom +// end_len2 = Specify unthreaded length at the top +// lead_in = Specify linear length of the lead in section of the threading with blunt start threads +// lead_in1 = Specify linear length of the lead in section of the threading at the bottom with blunt start threads +// lead_in2 = Specify linear length of the lead in section of the threading at the top with blunt start threads +// lead_in_ang = Specify angular length in degrees of the lead in section of the threading with blunt start threads +// lead_in_ang1 = Specify angular length in degrees of the lead in section of the threading at the bottom with blunt start threads +// lead_in_ang2 = Specify angular length in degrees of the lead in section of the threading at the top with blunt start threads +// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default" // 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` @@ -1373,7 +1699,12 @@ function generic_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel, ibevel1, ibevel2, id1,id2, height, thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) = no_function("generic_threaded_nut"); module generic_threaded_nut( @@ -1388,14 +1719,19 @@ module generic_threaded_nut( bevel,bevel1,bevel2,bevang=30, ibevel, ibevel1, ibevel2, id1,id2, height, thickness, - higbee,higbee1,higbee2, + length, l, + blunt_start, blunt_start1, blunt_start2, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + end_len, end_len1, end_len2, + lead_in_shape="default", anchor, spin, orient ) { extra = 0.01; id1 = first_defined([id1,id]); id2 = first_defined([id2,id]); - h = one_defined([h,height,thickness],"h,height,thickness"); + h = one_defined([h,height,thickness,l,length],"h,height,thickness,l,length"); dummyA = assert(is_num(pitch) && pitch>=0, "pitch must be a nonnegative number") assert(is_num(h) && h>0, "height/thickness must be a positive number") assert(in_list(shape,["square","hex"]), "shape must be \"hex\" or \"square\"") @@ -1414,7 +1750,9 @@ module generic_threaded_nut( difference() { _nutshape(nutwidth,h, shape,bevel1,bevel2); if (pitch==0) - cyl(l=h+extra, d1=full_id1+4*get_slop(), d2=full_id2+4*get_slop(), chamfer1=ibevel1?-IBEV*full_id1:undef, chamfer2=ibevel2?-IBEV*full_id2:undef); + cyl(l=h+extra, d1=full_id1+4*get_slop(), d2=full_id2+4*get_slop(), + chamfer1=ibevel1?-IBEV*full_id1:undef, + chamfer2=ibevel2?-IBEV*full_id2:undef); else generic_threaded_rod( d1=full_id1,d2=full_id2, @@ -1425,7 +1763,10 @@ module generic_threaded_nut( starts=starts, internal=true, bevel1=ibevel1,bevel2=ibevel2, - higbee=higbee, higbee1=higbee1, higbee2=higbee2 + blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, lead_in_shape=lead_in_shape, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + end_len=end_len, end_len1=end_len1, end_len2=end_len2 ); } children(); @@ -1535,9 +1876,9 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2) // } // Examples: // thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, $fn=72); -// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, taper=1, $fn=72); -// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2, taper=2, internal=true, $fn=72); -// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=1, left_handed=true, taper=1, $fn=36); +// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, lead_in=1, $fn=72); +// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2, lead_in=2, internal=true, $fn=72); +// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=1, left_handed=true, lead_in=1, $fn=36); function thread_helix( d, pitch, thread_depth, flank_angle, turns, profile, starts=1, left_handed=false, internal=false, @@ -1545,13 +1886,19 @@ function thread_helix( anchor, spin, orient ) = no_function("thread_helix"); module thread_helix( - d, pitch, thread_depth, flank_angle, turns=2, + d, pitch, thread_depth, flank_angle, turns, profile, starts=1, left_handed=false, internal=false, - d1, d2, taper, taper1, taper2, + d1, d2, + lead_in_shape, + lead_in, lead_in1, lead_in2, + lead_in_ang, lead_in_ang1, lead_in_ang2, + lead_in_sample=10, anchor, spin, orient ) { dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile") - assert(all_positive([turns]), "The turns parameter must be a positive number"); + assert(all_positive([turns]), "The turns parameter must be a positive number") + assert(is_def(profile) || is_def(thread_depth), "If profile is not given, must give thread depth"); + flank_angle = default(flank_angle,15); h = pitch*starts*abs(turns); r1 = get_radius(d1=d1, d=d, dflt=10); r2 = get_radius(d1=d2, d=d, dflt=10); @@ -1578,8 +1925,13 @@ module thread_helix( pline = mirror([-1,1], p = profile * pitch); dir = left_handed? -1 : 1; attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) { - zrot_copies(n=starts) { - spiral_sweep(pline, h=h, r1=r1, r2=r2, turns=turns*dir, taper=taper, taper1=taper1, taper2=taper2, internal=internal, anchor=CENTER); + union(){ + zrot_copies(n=starts) + spiral_sweep(pline, h=h, r1=r1, r2=r2, turns=turns*dir, internal=internal, + lead_in_shape=lead_in_shape, + lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2, + lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2, + lead_in_sample=lead_in_sample,anchor=CENTER); } children(); } @@ -1594,3 +1946,8 @@ module thread_helix( // // Need explanation of what exactly the diff is between threaded_rod and helix_threads. // Higbee is different, angle in one and length in another. Need to reconcile + +// end_len = 0 default? +// What about blunt_start for ball screws? +// Fold in nuts +// Should default bevel be capped at 1mm or 2mm or something like that? Including/especially inner bevel on nuts