Fix teardrop for threaded screws

This commit is contained in:
Adrian Mariano 2024-01-27 10:52:54 -05:00
parent bd5fd65e3d
commit d6fe226fca
5 changed files with 55 additions and 27 deletions

View File

@ -450,9 +450,6 @@ function affine3d_rot_from_to(from, to) =
]; ];
// Function: affine3d_mirror() // Function: affine3d_mirror()
// Synopsis: Returns a 3D (4x4) reflection transformation matrix. // Synopsis: Returns a 3D (4x4) reflection transformation matrix.
// SynTags: Mat // SynTags: Mat

View File

@ -2269,7 +2269,7 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b
vnf = vnf_join([ each column(top_samples,0), vnf = vnf_join([ each column(top_samples,0),
each column(bot_samples,0), each column(bot_samples,0),
for(pts=edge_points) vnf_vertex_array(pts), for(pts=edge_points) vnf_vertex_array(pts),
debug ? vnf_from_polygons(faces) debug ? vnf_from_polygons(faces,fast=true)
: vnf_triangulate(vnf_from_polygons(faces)) : vnf_triangulate(vnf_from_polygons(faces))
]) ])
) )

View File

@ -552,7 +552,9 @@ module screw(spec, head, drive, thread, drive_size,
: undersize; : undersize;
dummyA=assert(is_undef(undersize) || is_vector(undersize,2), "Undersize must be a scalar or 2-vector") dummyA=assert(is_undef(undersize) || is_vector(undersize,2), "Undersize must be a scalar or 2-vector")
assert(is_undef(undersize) || num_defined([shaft_undersize, head_undersize])==0, assert(is_undef(undersize) || num_defined([shaft_undersize, head_undersize])==0,
"Cannot combine \"undersize\" with other more specific undersize parameters"); "Cannot combine \"undersize\" with other more specific undersize parameters")
assert(is_bool(_teardrop) ||_teardrop=="max" || all_nonnegative([_teardrop]), str("Invalid teardrop parameter",_teardrop));
_teardrop = _teardrop==true ? .05 : _teardrop; // set teardrop default
shaft_undersize = first_defined([shaft_undersize, undersize[0]]); shaft_undersize = first_defined([shaft_undersize, undersize[0]]);
head_undersize = first_defined([head_undersize, undersize[1]]); head_undersize = first_defined([head_undersize, undersize[1]]);
dummyB=assert(is_undef(shaft_undersize) || is_finite(shaft_undersize), "shaft_undersize must be a number") dummyB=assert(is_undef(shaft_undersize) || is_finite(shaft_undersize), "shaft_undersize must be a number")
@ -683,8 +685,9 @@ module screw(spec, head, drive, thread, drive_size,
slop=islop,teardrop=_teardrop); slop=islop,teardrop=_teardrop);
if (_shoulder_len>0) if (_shoulder_len>0)
up(eps_shoulder-flat_height){ up(eps_shoulder-flat_height){
if (_teardrop) if (_teardrop!=false) //////
teardrop(d=_shoulder_diam*rad_scale+islop, h=_shoulder_len+eps_shoulder, anchor=FRONT, orient=BACK, $fn=sides); teardrop(d=_shoulder_diam*rad_scale+islop,cap_h=is_num(_teardrop) ? (_shoulder_diam*rad_scale+islop)/2*(1+_teardrop):undef,
h=_shoulder_len+eps_shoulder, anchor=FRONT, orient=BACK, $fn=sides);
else else
cyl(d=_shoulder_diam*rad_scale+islop, h=_shoulder_len+eps_shoulder, anchor=TOP, $fn=sides, chamfer1=details ? _shoulder_diam/30:0); cyl(d=_shoulder_diam*rad_scale+islop, h=_shoulder_len+eps_shoulder, anchor=TOP, $fn=sides, chamfer1=details ? _shoulder_diam/30:0);
} }
@ -702,8 +705,9 @@ module screw(spec, head, drive, thread, drive_size,
: bevel2=="reverse" ? -bevsize : bevel2=="reverse" ? -bevsize
: bevel2; : bevel2;
down(_shoulder_len+flat_height-eps_shank) down(_shoulder_len+flat_height-eps_shank)
if (_teardrop) if (_teardrop!=false) ///////
teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2); teardrop(d=d_major*rad_scale+islop, cap_h=is_num(_teardrop) ? (d_major*rad_scale+islop)/2*(1+_teardrop) : undef,
h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2);
else else
cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2); cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2);
} }
@ -773,7 +777,7 @@ module screw(spec, head, drive, thread, drive_size,
// head = head type. See [screw heads](#subsection-screw-heads) Default: none // head = head type. See [screw heads](#subsection-screw-heads) Default: none
// --- // ---
// thread = thread type or specification for threaded masks, true to make a threaded mask with the standard threads, or false to make an unthreaded mask. See [screw pitch](#subsection-standard-screw-pitch). Default: false // thread = thread type or specification for threaded masks, true to make a threaded mask with the standard threads, or false to make an unthreaded mask. See [screw pitch](#subsection-standard-screw-pitch). Default: false
// teardrop = if true produce teardrop hole. Default: false // teardrop = If true, adds a teardrop profile to the hole for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// oversize = amount to increase diameter of the screw hole (hole and countersink). A scalar or length 2 vector. Default: use computed tolerance // oversize = amount to increase diameter of the screw hole (hole and countersink). A scalar or length 2 vector. Default: use computed tolerance
// hole_oversize = amount to increase diameter of the hole. Overrides the use of tolerance and replaces any settings given in the screw specification. // hole_oversize = amount to increase diameter of the hole. Overrides the use of tolerance and replaces any settings given in the screw specification.
// head_oversize = amount to increase diameter of head. Overrides the user of tolerance and replaces any settings given in the screw specification. // head_oversize = amount to increase diameter of head. Overrides the user of tolerance and replaces any settings given in the screw specification.
@ -1419,7 +1423,7 @@ function _parse_drive(drive=undef, drive_size=undef) =
// details = true for more detailed model. Default: false // details = true for more detailed model. Default: false
// counterbore = counterbore height. Default: no counterbore // counterbore = counterbore height. Default: no counterbore
// flat_height = height of flat head // flat_height = height of flat head
// teardrop = if true make flathead and counterbores teardrop shaped // teardrop = if true make flathead and counterbores teardrop shaped with the flat 5% away from the edge of the screw. If numeric, specify the fraction of extra to add. Set to "max" for a pointed teardrop. Default: false
// slop = enlarge diameter by this extra amount (beyond that specified in the screw specification). Default: 0 // slop = enlarge diameter by this extra amount (beyond that specified in the screw specification). Default: 0
function screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=false,slop=0) = no_function("screw_head"); function screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=false,slop=0) = no_function("screw_head");
module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=false,slop=0) { module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=false,slop=0) {
@ -1428,7 +1432,9 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f
head = struct_val(screw_info, "head"); head = struct_val(screw_info, "head");
head_size = struct_val(screw_info, "head_size",0) + head_oversize; head_size = struct_val(screw_info, "head_size",0) + head_oversize;
head_height = struct_val(screw_info, "head_height"); head_height = struct_val(screw_info, "head_height");
dum0=assert(is_def(head_height) || in_list(head,["flat","none"]), "Undefined head height only allowed with flat head or headless screws"); dum0=assert(is_def(head_height) || in_list(head,["flat","none"]), "Undefined head height only allowed with flat head or headless screws")
assert(is_bool(teardrop) || teardrop=="max" || all_nonnegative([teardrop]),"Teardrop parameter invalid");
teardrop = teardrop==true ? .05 : teardrop;
heightok = (is_undef(head_height) && in_list(head,["flat","none"])) || all_positive(head_height); heightok = (is_undef(head_height) && in_list(head,["flat","none"])) || all_positive(head_height);
dum1=assert(heightok, "Head hight must be a postive number"); dum1=assert(heightok, "Head hight must be a postive number");
dum2=assert(counterbore==0 || counterbore==false || head!="none", "Cannot counterbore a headless screw"); dum2=assert(counterbore==0 || counterbore==false || head!="none", "Cannot counterbore a headless screw");
@ -1444,8 +1450,8 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f
union(){ union(){
if (head!="flat" && counterbore>0){ if (head!="flat" && counterbore>0){
d = head=="hex"? 2*head_size/sqrt(3) : head_size; d = head=="hex"? 2*head_size/sqrt(3) : head_size;
if (teardrop) if (teardrop!=false)
teardrop(d=d, l=counterbore, orient=BACK, anchor=BACK); teardrop(d=d, l=counterbore, cap_h=is_num(teardrop) ? d/2*(1+teardrop):undef, orient=BACK, anchor=BACK);
else else
cyl(d=d, l=counterbore, anchor=BOTTOM); cyl(d=d, l=counterbore, anchor=BOTTOM);
} }
@ -1458,8 +1464,8 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f
r1 = head_size/2; r1 = head_size/2;
r2 = r1 - tan(angle)*slopeheight; r2 = r1 - tan(angle)*slopeheight;
n = segs(r1); n = segs(r1);
prof1 = teardrop ? teardrop2d(r=r1,$fn=n) : circle(r=r1, $fn=n); prof1 = teardrop!=false ? teardrop2d(r=r1,cap_h=is_num(teardrop)?r1*(1+teardrop):undef,$fn=n) : circle(r=r1, $fn=n);
prof2 = teardrop ? teardrop2d(r=r2,$fn=n) : circle(r=r2, $fn=n); prof2 = teardrop!=false ? teardrop2d(r=r2,cap_h=is_num(teardrop)?r2*(1+teardrop):undef,$fn=n) : circle(r=r2, $fn=n);
skin([prof2,prof1,prof1], z=[-flat_height, -flat_height+slopeheight, counterbore],slices=0); skin([prof2,prof1,prof1], z=[-flat_height, -flat_height+slopeheight, counterbore],slices=0);
} }
if (head!="flat" && counterbore==0) { if (head!="flat" && counterbore==0) {

View File

@ -1603,7 +1603,7 @@ function ring(n,ring_width,r,r1,r2,angle,d,d1,d2,cp,points,corner, width,thickne
full = is_def(angle) ? false : full full = is_def(angle) ? false : full
) )
assert(is_undef(start) || is_def(angle), "start requires angle") assert(is_undef(start) || is_def(angle), "start requires angle")
assert(is_undef(angle) || num_defined([thickness,width,points,corner]), "Cannot give angle with points, corner, width or thickness") assert(is_undef(angle) || !any_defined([thickness,width,points,corner]), "Cannot give angle with points, corner, width or thickness")
assert(!is_vector(angle,2) || abs(angle[1]-angle[0]) <= 360, "angle gives more than 360 degrees") assert(!is_vector(angle,2) || abs(angle[1]-angle[0]) <= 360, "angle gives more than 360 degrees")
assert(is_undef(points) || is_path(points,2), str("Points must be a 2d vector",points)) assert(is_undef(points) || is_path(points,2), str("Points must be a 2d vector",points))
assert(!any_defined([points,thickness,width]) || num_defined([r1,r2])==0, "Cannot give r1, r2, d1, or d2 with points, width or thickness") assert(!any_defined([points,thickness,width]) || num_defined([r1,r2])==0, "Cannot give r1, r2, d1, or d2 with points, width or thickness")

View File

@ -170,7 +170,7 @@
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // 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` // 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -496,7 +496,7 @@ module threaded_nut(
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // 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` // 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -765,7 +765,7 @@ module trapezoidal_threaded_nut(
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // 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` // 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -1102,7 +1102,7 @@ module npt_threaded_rod(
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// d1 = Bottom outside diameter of threads. // d1 = Bottom outside diameter of threads.
// d2 = Top 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` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
@ -1318,7 +1318,7 @@ module buttress_threaded_nut(
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop. Default: false
// d1 = Bottom outside diameter of threads. // d1 = Bottom outside diameter of threads.
// d2 = Top 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` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
@ -1625,6 +1625,11 @@ module ball_screw_rod(
// running off the end of the shaft and leaving a sharp edged partial thread at the end of the screw. This makes // running off the end of the shaft and leaving a sharp edged partial thread at the end of the screw. This makes
// screws easier to start and prevents cross threading. Blunt start threads should always be superior, and they are // screws easier to start and prevents cross threading. Blunt start threads should always be superior, and they are
// faster to model, but if you really need standard threads that run off the end you can set `blunt_start=false`. // faster to model, but if you really need standard threads that run off the end you can set `blunt_start=false`.
// .
// The teardrop option cuts off the threads with a teardrop for 3d printability of horizontal holes. By default,
// if the screw outer radius is r then the flat top will be at distance 1.05r from the center, adding a 5% space.
// You can set teardrop to a numerical value to adjust that percentage, e.g. a value of 0.1 would give a 10% space.
// You can set teardrop to "max" to create a pointy-top teardrop with no flat section.
// Arguments: // Arguments:
// d = Outer diameter of threaded rod. // d = Outer diameter of threaded rod.
// l / length / h / height = Length of threaded rod. // l / length / h / height = Length of threaded rod.
@ -1652,7 +1657,7 @@ module ball_screw_rod(
// 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_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_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" // lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "default"
// teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, to help with making a threaded hole mask. Default: false // teardrop = If true, adds a teardrop profile to the back (Y+) side of the threaded rod, for 3d printability of horizontal holes. If numeric, specifies the proportional extra distance of the teardrop flat top from the screw center, or set to "max" for a pointed teardrop (see above). Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // 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` // 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` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
@ -1922,9 +1927,30 @@ module generic_threaded_rod(
up(len/2+.001)cyl(l=-clip_bev2, r1=r2adj+profmin, r2=r2adj+profmin+slope*clip_bev1-clip_bev2,anchor=TOP); up(len/2+.001)cyl(l=-clip_bev2, r1=r2adj+profmin, r2=r2adj+profmin+slope*clip_bev1-clip_bev2,anchor=TOP);
// Add teardrop profile // Add teardrop profile
if (teardrop) { if (teardrop!=false) {
ang = min(45,opp_hyp_to_ang(rmax+profmin, rmax+pmax)); fact = is_num(teardrop) ? assert(teardrop>=0,"teardrop value cannot be negative")1-1/sqrt(2)+teardrop
xrot(-90) teardrop(l=l, r1=r1adj+profmin, r2=r2adj+profmin, ang=ang, cap_h1=r1adj+pmax, cap_h2=r2adj+pmax); : is_bool(teardrop) ? 1-1/sqrt(2)+0.05
: teardrop=="max" ? 1/sqrt(2)
: assert(false,"invalid teardrop value");
dummy = assert(fact<=1/sqrt(2), "teardrop value too large");
pdepth = pmax-profmin;
trap1 = back((r1adj+pmax)/sqrt(2),path3d(list_rotate(trapezoid(ang=45,w1 = (r1adj+pmax)*sqrt(2), h = (r1adj+pmax)*fact,anchor=FWD),1),-l/2));
trap2 = back((r2adj+pmax)/sqrt(2),path3d(list_rotate(trapezoid(ang=45,w1 = (r2adj+pmax)*sqrt(2), h = (r2adj+pmax)*fact,anchor=FWD),1), l/2));
yproj = [[1,0,0],[0,0,0],[0,0,1]];
p1a=trap1[0]+unit([0,0,-l/2]-trap1[0])*pdepth*3/4;
p1b=last(trap1)+unit([0,0,-l/2]-last(trap1))*pdepth*3/4;
p2a=trap2[0]+unit([0,0,l/2]-trap2[0])*pdepth*3/4;
p2b=last(trap2)+ unit([0,0,l/2]-last(trap2))*pdepth*3/4 ;
cut1 = reverse([p1a, p1a*yproj, p1b*yproj, p1b]);
cut2 = reverse([p2a, p2a*yproj, p2b*yproj, p2b]);
vert = [
[each cut1, each trap1],
[each cut2, each trap2]
];
vnf_polyhedron(vnf_vertex_array(vert,caps=true,col_wrap=true));
// Old code creates an internal teardrop which unfortunately doesn't print well
//ang = min(45,opp_hyp_to_ang(rmax+profmin, rmax+pmax));
//xrot(-90) teardrop(l=l, r1=r1adj+profmin, r2=r2adj+profmin, ang=ang, cap_h1=r1adj+pmax, cap_h2=r2adj+pmax);
} }
} }
children(); children();
@ -2072,7 +2098,6 @@ module _nutshape(nutwidth, h, shape, bevel1, bevel2)
intersection(){ intersection(){
if (shape=="hex") if (shape=="hex")
cyl(d=nutwidth, circum=true, $fn=6, l=h, chamfer1=bevel1?0:nutwidth*.01, chamfer2=bevel2?0:nutwidth*.01); cyl(d=nutwidth, circum=true, $fn=6, l=h, chamfer1=bevel1?0:nutwidth*.01, chamfer2=bevel2?0:nutwidth*.01);
//vnf_polyhedron(vnf);
else else
cuboid([nutwidth,nutwidth,h],chamfer=nutwidth*.01, except=[if (bevel1) BOT, if(bevel2) TOP]); cuboid([nutwidth,nutwidth,h],chamfer=nutwidth*.01, except=[if (bevel1) BOT, if(bevel2) TOP]);
fn = quantup(segs(r=nutwidth/2),shape=="hex"?6:4); fn = quantup(segs(r=nutwidth/2),shape=="hex"?6:4);