internal: can set bevel to true and get non-garbage result

bevel is always set by thread depth
   acme takes tpi
   square threads are at angle 0
   added generic_threaded_{rod,nut}
   eliminated metric_trapezoidal_*
   cleaned up matrices some in generic_threaded_rod
   threaded_rod can produce spec-true ISO/UTS profile with a triplet input for the diameter.
   Added bevel1 and bevel2 to all modules.  Made default uniformly false for every case instead of
       sometimes true, sometimes false
   Profiles that go over zero are not clipped, and bevels are based on actual profile top, not nominal
   When bevel is given to nuts it bevels the outside of the nut by thread depth
   higbee looks best with quincunx, but it's more expensive.  Select quincunx when higbee is used, min_edge otherwise
   Current code uses difference to remove excess length in the rod.  This gives faster renders at the cost
      of more complex code and green top/bottom surfaces.
   Changed slop to 4 * $slop.  I got good results printing with $slop=0.05 with this setting.
   Don't generate excess threads when starts>1, and don't force threads to be even
This commit is contained in:
Adrian Mariano 2021-08-22 21:53:08 -04:00
parent 5cd0b5d03c
commit ce0b4e9d32
4 changed files with 734 additions and 499 deletions

View file

@ -1040,6 +1040,9 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
// --- // ---
// d = Diameter of the spiral to extrude along. // d = Diameter of the spiral to extrude along.
// higbee = Length to taper thread ends over. // higbee = Length to taper thread ends over.
// higbee1 = Taper length at start
// higbee2 = Taper length at end
// internal = direction to taper the threads with higbee. Default: false
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER` // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `CENTER`
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0`
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP` // orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP`
@ -1047,7 +1050,11 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
// Example: // Example:
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]]; // poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
// spiral_sweep(poly, h=200, r=50, twist=1080, $fn=36); // spiral_sweep(poly, h=200, r=50, twist=1080, $fn=36);
module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, anchor, spin=0, orient=UP) { module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, higbee1, higbee2, internal=false, anchor, spin=0, orient=UP) {
bounds = pointlist_bounds(poly);
yctr = (bounds[0].y+bounds[1].y)/2;
xmin = bounds[0].x;
xmax = bounds[1].x;
poly = path3d(poly); poly = path3d(poly);
anchor = get_anchor(anchor,center,BOT,BOT); anchor = get_anchor(anchor,center,BOT,BOT);
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50); r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50);
@ -1062,7 +1069,6 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
higsteps2 = ceil(higang2/360*sides); higsteps2 = ceil(higang2/360*sides);
assert(higang1 < twist/2); assert(higang1 < twist/2);
assert(higang2 < twist/2); assert(higang2 < twist/2);
function higsize(a) = lookup(a,[ function higsize(a) = lookup(a,[
[-0.001, 0], [-0.001, 0],
for (x=[0.125:0.125:1]) [ x*higang1, pow(x,1/2)], for (x=[0.125:0.125:1]) [ x*higang1, pow(x,1/2)],
@ -1071,9 +1077,11 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
]); ]);
us = [ us = [
for (i=[0:higsteps1/10:higsteps1]) i, 0,
for (i=[higsteps1/10:higsteps1/10:higsteps1]) i,
for (i=[higsteps1+1:1:steps-higsteps2-1]) i, for (i=[higsteps1+1:1:steps-higsteps2-1]) i,
for (i=[steps-higsteps2:higsteps2/10:steps]) i, for (i=[steps-higsteps2:higsteps2/10:steps-higsteps2/10]) i,
steps
]; ];
zang = atan2(r2-r1,h); zang = atan2(r2-r1,h);
points = [ points = [
@ -1086,7 +1094,8 @@ module spiral_sweep(poly, h, r, twist=360, higbee, center, r1, r2, d, d1, d2, hi
affine3d_translate([r, 0, h * (u-0.5)]) * affine3d_translate([r, 0, h * (u-0.5)]) *
affine3d_xrot(90) * affine3d_xrot(90) *
affine3d_skew_xz(xa=zang) * affine3d_skew_xz(xa=zang) *
affine3d_scale([hsc,lerp(hsc,1,0.25),1]), //affine3d_scale([hsc,lerp(hsc,1,0.25),1]),
scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
pts = apply(mat, poly) pts = apply(mat, poly)
) pts ) pts
]; ];

View file

@ -1243,38 +1243,30 @@ function thread_specification(screw_spec, internal=false, tolerance=undef) =
function _thread_profile(thread) = function _thread_profile(thread) =
let( let(
pitch = struct_val(thread,"pitch"), pitch = struct_val(thread,"pitch"),
basicrad = struct_val(thread,"basic")/2,
meanpitchrad = mean(struct_val(thread,"d_pitch"))/2, meanpitchrad = mean(struct_val(thread,"d_pitch"))/2,
meanminorrad = mean(struct_val(thread,"d_minor"))/2, meanminorrad = mean(struct_val(thread,"d_minor"))/2,
meanmajorrad = mean(struct_val(thread,"d_major"))/2, meanmajorrad = mean(struct_val(thread,"d_major"))/2,
depth = (meanmajorrad-meanminorrad)/pitch, depth = meanmajorrad-meanminorrad,
crestwidth = (pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3))/pitch crestwidth = pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3)
) )
[
[-depth/sqrt(3)-crestwidth/2, -depth],
[ -crestwidth/2, 0],
[ crestwidth/2, 0],
[ depth/sqrt(3)+crestwidth/2, -depth]
]/pitch;
/* Old non-centered profile
[ [
[-1/2,-depth], [-1/2,-depth],
[depth/sqrt(3)-1/2,0], [depth/sqrt(3)-1/2,0],
[depth/sqrt(3)+crestwidth-1/2, 0], [depth/sqrt(3)+crestwidth-1/2, 0],
[crestwidth + 2*depth/sqrt(3)-1/2,-depth] [crestwidth + 2*depth/sqrt(3)-1/2,-depth]
]; ]
;
function _thread_profile_e(thread) = */
let(
pitch = struct_val(thread,"pitch"),
basicrad = struct_val(thread,"basic")/2,
meanpitchrad = mean(struct_val(thread,"d_pitch"))/2,
meanminorrad = mean(struct_val(thread,"d_minor"))/2,
meanmajorrad = mean(struct_val(thread,"d_major"))/2,
depth = (meanmajorrad-meanminorrad)/pitch,
crestwidth = (pitch/2 - 2*(meanmajorrad-meanpitchrad)/sqrt(3))/pitch
)
[
[-1/2,-1], // -1 instead of -depth?
[depth/sqrt(3)-1/2,0],
[depth/sqrt(3)+crestwidth-1/2, 0],
[crestwidth + 2*depth/sqrt(3)-1/2,-1]
];
module _rod(spec, length, tolerance, orient=UP, spin=0, anchor=CENTER) module _rod(spec, length, tolerance, orient=UP, spin=0, anchor=CENTER)
@ -1283,11 +1275,19 @@ module _rod(spec, length, tolerance, orient=UP, spin=0, anchor=CENTER)
echo(d_major_mean = mean(struct_val(threadspec, "d_major"))); echo(d_major_mean = mean(struct_val(threadspec, "d_major")));
echo(bolt_profile=_thread_profile(threadspec)); echo(bolt_profile=_thread_profile(threadspec));
trapezoidal_threaded_rod( d=mean(struct_val(threadspec, "d_major")), threaded_rod([mean(struct_val(threadspec, "d_minor")),
mean(struct_val(threadspec, "d_pitch")),
mean(struct_val(threadspec, "d_major"))],
pitch = struct_val(threadspec, "pitch"),
l=length, left_handed=false,
bevel=false, orient=orient, anchor=anchor, spin=spin);
/*
generic_threaded_rod( d=mean(struct_val(threadspec, "d_major")),
l=length, l=length,
pitch = struct_val(threadspec, "pitch"), pitch = struct_val(threadspec, "pitch"),
profile = _thread_profile(threadspec),left_handed=false, profile = _thread_profile(threadspec),left_handed=false,
bevel=false, orient=orient, anchor=anchor, spin=spin); bevel=false, orient=orient, anchor=anchor, spin=spin);
*/
} }
@ -1352,7 +1352,7 @@ module nut(name, diameter, thickness, thread="coarse", oversize=0, spec, toleran
threadspec = thread_specification(spec, internal=true, tolerance=tolerance); threadspec = thread_specification(spec, internal=true, tolerance=tolerance);
echo(threadspec=threadspec,"for nut threads"); echo(threadspec=threadspec,"for nut threads");
echo(nut_minor_diam = mean(struct_val(threadspec,"d_minor"))); echo(nut_minor_diam = mean(struct_val(threadspec,"d_minor")));
trapezoidal_threaded_nut( generic_threaded_nut(
od=diameter, id=mean(struct_val(threadspec, "d_major")), h=thickness, od=diameter, id=mean(struct_val(threadspec, "d_major")), h=thickness,
pitch=struct_val(threadspec, "pitch"), pitch=struct_val(threadspec, "pitch"),
profile=_thread_profile(threadspec), profile=_thread_profile(threadspec),

File diff suppressed because it is too large Load diff

View file

@ -216,7 +216,7 @@ function vnf_triangulate(vnf) =
// Function: vnf_vertex_array() // Function: vnf_vertex_array()
// Usage: // Usage:
// vnf = vnf_vertex_array(points, [caps], [cap1], [cap2], [reverse], [col_wrap], [row_wrap], [vnf]); // vnf = vnf_vertex_array(points, [caps], [cap1], [cap2], [style], [reverse], [col_wrap], [row_wrap], [vnf]);
// Description: // Description:
// Creates a VNF structure from a vertex list, by dividing the vertices into columns and rows, // Creates a VNF structure from a vertex list, by dividing the vertices into columns and rows,
// adding faces to tile the surface. You can optionally have faces added to wrap the last column // adding faces to tile the surface. You can optionally have faces added to wrap the last column