mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Fix bug in nut beveling, fix teardrop bugs, add chamfer to teardrop,
add tap and self tap screw hole tolerances.
This commit is contained in:
parent
3dd605f87b
commit
66fce69e4d
4 changed files with 177 additions and 129 deletions
112
screws.scad
112
screws.scad
|
@ -242,7 +242,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
||||||
// undersize_shaft = amount to decrease diameter of the shaft of screw
|
// undersize_shaft = amount to decrease diameter of the shaft of screw
|
||||||
// undersize_head = amount to decrease the head diameter of the screw
|
// undersize_head = amount to decrease the head diameter of the screw
|
||||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
// 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: `BOTTOM`
|
// anchor = Translate so anchor point on the shaft 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`
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
|
@ -257,9 +257,9 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
||||||
// top = top of screw
|
// top = top of screw
|
||||||
// bot = bottom of screw
|
// bot = bottom of screw
|
||||||
// center = center of screw
|
// center = center of screw
|
||||||
// head_top = top of head (invalid for headless screws)
|
// head_top = top of head (same as top for headless screws)
|
||||||
// head_bot = bottom of head (invalid for headless screws)
|
// head_bot = bottom of head (same as top for headless screws)
|
||||||
// head_center = center of head (invalid for headless screws)
|
// head_center = center of head (same as top for headless screws)
|
||||||
// shaft_top = top of shaft
|
// shaft_top = top of shaft
|
||||||
// shaft_bot = bottom of shaft
|
// shaft_bot = bottom of shaft
|
||||||
// shaft_center = center of shaft
|
// shaft_center = center of shaft
|
||||||
|
@ -446,18 +446,23 @@ function _get_spec(spec, needtype, origin, thread, // common parameters
|
||||||
let(spec=is_undef(spec) ? $screw_spec : spec)
|
let(spec=is_undef(spec) ? $screw_spec : spec)
|
||||||
assert(is_string(spec) || is_struct(spec), "Screw/nut specification must be a string or struct")
|
assert(is_string(spec) || is_struct(spec), "Screw/nut specification must be a string or struct")
|
||||||
let(
|
let(
|
||||||
|
specname = is_struct(spec) ? struct_val(spec,"name") : undef,
|
||||||
name = is_string(spec) ? spec
|
name = is_string(spec) ? spec
|
||||||
: struct_val(spec,"type") != needtype ? struct_val(spec,"name")
|
: struct_val(spec,"type") != needtype ? // if we switch between screw and nut we need a name
|
||||||
|
let(specname=struct_val(spec,"name"))
|
||||||
|
assert(is_string(specname),
|
||||||
|
"Parent screw_info or nut_info structure doesn't have a valid name, but a name is needed when child is of a different type")
|
||||||
|
specname
|
||||||
: undef,
|
: undef,
|
||||||
thread =
|
p = is_struct(spec) ? struct_val(spec,"pitch") : undef,
|
||||||
is_def(thread) ? thread
|
thread = // If the origin of the struct is a hole with pitch zero and we are making a screw, try to find a nonzero pitch
|
||||||
: origin=="screw_hole" ? false
|
is_undef(name) && struct_val(spec,"origin")=="screw_hole" && origin!="screw_hole" && p==0 && is_string(specname)
|
||||||
: is_string(spec) ? thread
|
? let(temp_info = screw_info(specname,thread))
|
||||||
: let(p=struct_val(spec,"pitch"))
|
struct_val(temp_info,"pitch")
|
||||||
struct_val(spec,"origin")=="screw_hole" && origin!="screw_hole" && p==0? undef
|
: thread
|
||||||
: p
|
|
||||||
)
|
)
|
||||||
is_def(name) ? (needtype=="screw_info" ? screw_info(name,_origin=origin, thread=thread, head=head, drive=drive, drive_size=drive_size)
|
is_def(name) ? (needtype=="screw_info" ? screw_info(name,_origin=origin, thread= origin=="screw_hole" ? default(thread,true) : thread,
|
||||||
|
head=head, drive=drive, drive_size=drive_size)
|
||||||
: nut_info(name,_origin=origin, thread=thread, shape=shape, thickness=thickness))
|
: nut_info(name,_origin=origin, thread=thread, shape=shape, thickness=thickness))
|
||||||
:
|
:
|
||||||
assert(in_list(struct_val(spec,"type"), ["nut_info","screw_info"]), "Screw/nut spec is invalid struct type")
|
assert(in_list(struct_val(spec,"type"), ["nut_info","screw_info"]), "Screw/nut spec is invalid struct type")
|
||||||
|
@ -469,7 +474,8 @@ function _get_spec(spec, needtype, origin, thread, // common parameters
|
||||||
assert(is_undef(shape), "You cannot change nut shape when using a struct specification")
|
assert(is_undef(shape), "You cannot change nut shape when using a struct specification")
|
||||||
let(
|
let(
|
||||||
spec = _struct_reset(spec,
|
spec = _struct_reset(spec,
|
||||||
[
|
[
|
||||||
|
if (origin=="screw") ["counterbore",0],
|
||||||
if (head=="none") ["head","none"],
|
if (head=="none") ["head","none"],
|
||||||
if (head=="none") ["drive","none"],
|
if (head=="none") ["drive","none"],
|
||||||
if (thread==false || thread=="none") ["pitch",0]
|
if (thread==false || thread=="none") ["pitch",0]
|
||||||
|
@ -503,8 +509,9 @@ function screw(spec, head, drive, thread, drive_size,
|
||||||
module screw(spec, head, drive, thread, drive_size,
|
module screw(spec, head, drive, thread, drive_size,
|
||||||
length, l, thread_len, tolerance, details=true,
|
length, l, thread_len, tolerance, details=true,
|
||||||
undersize, shaft_undersize, head_undersize,
|
undersize, shaft_undersize, head_undersize,
|
||||||
atype="screw",anchor=BOTTOM, spin=0, orient=UP,
|
atype="screw",anchor, spin=0, orient=UP,
|
||||||
_shoulder_diam=0, _shoulder_len=0,
|
_shoulder_diam=0, _shoulder_len=0,
|
||||||
|
bevel,bevel1,bevel2,bevelsize,
|
||||||
_internal=false, _counterbore, _teardrop=false)
|
_internal=false, _counterbore, _teardrop=false)
|
||||||
{
|
{
|
||||||
tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw",
|
tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw",
|
||||||
|
@ -584,16 +591,16 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
: atype=="threads" ? _shoulder_len + shoulder_adj + length-thread_len + thread_len/2
|
: atype=="threads" ? _shoulder_len + shoulder_adj + length-thread_len + thread_len/2
|
||||||
: atype=="screw" ? (length-head_height+_shoulder_len+shoulder_adj-flat_cbore_height)/2
|
: atype=="screw" ? (length-head_height+_shoulder_len+shoulder_adj-flat_cbore_height)/2
|
||||||
: assert(false,"Unknown atype");
|
: assert(false,"Unknown atype");
|
||||||
dummyM = assert(!headless || !in_list(anchor,["head_top","head_bot","head_center"]), str("Anchor \"",anchor,"\" not allowed for headless screw"))
|
dummyM = //assert(!headless || !in_list(anchor,["head_top","head_bot","head_center"]), str("Anchor \"",anchor,"\" not allowed for headless screw"))
|
||||||
assert(shank_len>0 || !in_list(anchor,["shank_top","shank_bot","shank_center"]),
|
assert(shank_len>0 || !in_list(anchor,["shank_top","shank_bot","shank_center"]),
|
||||||
str("Screw has no unthreaded shank so anchor \"",anchor,"\" is not allowed"));
|
str("Screw has no unthreaded shank so anchor \"",anchor,"\" is not allowed"));
|
||||||
anchor_list = [
|
anchor_list = [
|
||||||
named_anchor("top", [0,0,offset+head_height+flat_cbore_height]),
|
named_anchor("top", [0,0,offset+head_height+flat_cbore_height]),
|
||||||
named_anchor("bot", [0,0,-length-shoulder_full+offset]),
|
named_anchor("bot", [0,0,-length-shoulder_full+offset]),
|
||||||
named_anchor("center", [0,0, -length/2 - shoulder_full/2 + head_height/2 + offset]),
|
named_anchor("center", [0,0, -length/2 - shoulder_full/2 + head_height/2 + offset]),
|
||||||
if (!headless) named_anchor("head_top", [0,0,head_height+offset]),
|
named_anchor("head_top", [0,0,head_height+offset]),
|
||||||
if (!headless) named_anchor("head_bot", [0,0,-flat_height+offset]),
|
named_anchor("head_bot", [0,0,-flat_height+offset]),
|
||||||
if (!headless) named_anchor("head_center", [0,0,(head_height-flat_height)/2+offset]),
|
named_anchor("head_center", [0,0,(head_height-flat_height)/2+offset]),
|
||||||
if (_shoulder_len>0) named_anchor("shoulder_top", [0,0,offset-flat_height]),
|
if (_shoulder_len>0) named_anchor("shoulder_top", [0,0,offset-flat_height]),
|
||||||
if (_shoulder_len>0) named_anchor("shoulder_bot", [0,0,offset-shoulder_full]),
|
if (_shoulder_len>0) named_anchor("shoulder_bot", [0,0,offset-shoulder_full]),
|
||||||
if (_shoulder_len>0) named_anchor("shoulder_center", [0,0,offset-flat_height-_shoulder_len/2]),
|
if (_shoulder_len>0) named_anchor("shoulder_center", [0,0,offset-flat_height-_shoulder_len/2]),
|
||||||
|
@ -623,6 +630,7 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
: atype=="screw" ? length+head_height+shoulder_full + flat_cbore_height
|
: atype=="screw" ? length+head_height+shoulder_full + flat_cbore_height
|
||||||
: is_def(vnf) ? undef
|
: is_def(vnf) ? undef
|
||||||
: head_height+flat_height+flat_cbore_height;
|
: head_height+flat_height+flat_cbore_height;
|
||||||
|
bevelsize = default(bevelsize, d_major/12);
|
||||||
attachable(
|
attachable(
|
||||||
vnf = vnf,
|
vnf = vnf,
|
||||||
d = u_add(u_mul(attach_d, rad_scale), islop),
|
d = u_add(u_mul(attach_d, rad_scale), islop),
|
||||||
|
@ -646,22 +654,29 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
}
|
}
|
||||||
if (shank_len>0 || pitch==0){
|
if (shank_len>0 || pitch==0){
|
||||||
L = pitch==0 ? length - (_shoulder_len==0?flat_height:0) : shank_len;
|
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;
|
||||||
down(_shoulder_len+flat_height-eps_shank)
|
down(_shoulder_len+flat_height-eps_shank)
|
||||||
if (_teardrop)
|
if (_teardrop)
|
||||||
teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides);
|
teardrop(d=d_major*rad_scale+islop, 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);
|
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)
|
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)
|
down(_shoulder_len+flat_height+shank_len-eps_thread)
|
||||||
threaded_rod([mean(struct_val(threadspec, "d_minor")),
|
threaded_rod([mean(struct_val(threadspec, "d_minor")),
|
||||||
mean(struct_val(threadspec, "d_pitch")),
|
mean(struct_val(threadspec, "d_pitch")),
|
||||||
d_major],
|
d_major],
|
||||||
pitch = struct_val(threadspec, "pitch"),
|
pitch = struct_val(threadspec, "pitch"),
|
||||||
l=thread_len+eps_thread, left_handed=false, internal=_internal,
|
l=thread_len+eps_thread, left_handed=false, internal=_internal,
|
||||||
bevel1=details,
|
bevel1=bev1,
|
||||||
bevel2=details && (flathead || _shoulder_len>0 || headless),
|
bevel2=bev2,
|
||||||
$fn=sides, anchor=TOP);
|
$fn=sides, anchor=TOP);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!_internal) _driver(spec);
|
if (!_internal) _driver(spec);
|
||||||
}
|
}
|
||||||
|
@ -688,7 +703,13 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
// For clearance holes, the UTS tolerances are "normal", "loose" and "close". ASME also specifies the same naming for metric clearance holes.
|
// For clearance holes, the UTS tolerances are "normal", "loose" and "close". ASME also specifies the same naming for metric clearance holes.
|
||||||
// However, ISO gives "fine", "medium" and "coarse" instead. This function accepts all of these in either system. It also takes "tight" to be equivalent to "close",
|
// However, ISO gives "fine", "medium" and "coarse" instead. This function accepts all of these in either system. It also takes "tight" to be equivalent to "close",
|
||||||
// even though no standard suggests it, because it's a natural opposite of "loose". The official tolerance designations for ISO are "H12" for "fine", "H13" for "medium"
|
// even though no standard suggests it, because it's a natural opposite of "loose". The official tolerance designations for ISO are "H12" for "fine", "H13" for "medium"
|
||||||
// and "H14" for "coarse". These designations will also work, but only for metric holes. You can also set tolerance to 0 or "none" to produce holes at the nominal size.
|
// and "H14" for "coarse". These designations will also work, but only for metric holes. You can also set tolerance to 0 or "none" to produce holes at the nominal size.
|
||||||
|
// .
|
||||||
|
// If you want to produce holes for tapping you can use a tolerance of "tap". This produces a hole of the nominal screw diameter reduced by the thread pitch. You may still
|
||||||
|
// need to adjust $slop for best results. Some people screw machine screws directly into plastic without tapping. This works better with a somewhat larger hole, so
|
||||||
|
// a tolerance of "self tap" produces such a hole. Note that this tolerance also makes the default bevel2=true to bevel the top, which makes it much easier
|
||||||
|
// to start the screw. The "self tap" tolerance subtracts `0.72 * pitch` when pitch is below 1mm, `0.6 * pitch` when the pitch is over 1.5mm, and it interpolates between.
|
||||||
|
// It was tested in PLA with a Prusa MK3S and $slop=0.5 and worked on UTS screws from #2 up to 1/2 inch.
|
||||||
// .
|
// .
|
||||||
// The counterbore parameter adds a cylindrical clearance hole above the screw shaft. For flat heads it extends above the flathead and for other screw types it
|
// The counterbore parameter adds a cylindrical clearance hole above the screw shaft. For flat heads it extends above the flathead and for other screw types it
|
||||||
// replaces the head with a cylinder large enough in diameter for the head to fit. For a flat head you must specify the length of the counterbore. For other heads you can
|
// replaces the head with a cylinder large enough in diameter for the head to fit. For a flat head you must specify the length of the counterbore. For other heads you can
|
||||||
|
@ -713,9 +734,12 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
// length / l= length of screw (in mm)
|
// length / l= length of screw (in mm)
|
||||||
// counterbore = set to length of counterbore, or true to make a counterbore equal to head height. Default: false for flat heads and headless, true otherwise
|
// counterbore = set to length of counterbore, or true to make a counterbore equal to head height. Default: false for flat heads and headless, true otherwise
|
||||||
// tolerance = threading or clearance hole tolerance. For internal threads, detrmines actual thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and 6H for ISO. For clearance holes, determines how much clearance to add. Default is "normal".
|
// tolerance = threading or clearance hole tolerance. For internal threads, detrmines actual thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and 6H for ISO. For clearance holes, determines how much clearance to add. Default is "normal".
|
||||||
|
// 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
|
||||||
// $slop = add extra gap to account for printer overextrusion. Default: 0
|
// $slop = add extra gap to account for printer overextrusion. Default: 0
|
||||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
// 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: `BOTTOM`
|
// anchor = Translate so anchor point on the shaft 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`
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
|
@ -759,10 +783,14 @@ module screw(spec, head, drive, thread, drive_size,
|
||||||
// screw_hole("M16,15",anchor=TOP,thread=true);
|
// screw_hole("M16,15",anchor=TOP,thread=true);
|
||||||
module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||||
length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
|
length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
|
||||||
atype="screw",anchor=BOTTOM,spin=0, orient=UP)
|
bevel, bevel1, bevel2,
|
||||||
|
atype="screw",anchor=CENTER,spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
screwspec = _get_spec(spec, "screw_info", "screw_hole",
|
screwspec = _get_spec(spec, "screw_info", "screw_hole",
|
||||||
thread=thread, head=head);
|
thread=thread, head=head);
|
||||||
|
bevel1 = first_defined([bevel1,bevel,false]);
|
||||||
|
bevel2 = first_defined([bevel2,bevel,tolerance=="self tap"]);
|
||||||
|
thread = default(thread,false);
|
||||||
checkhead = struct_val(screwspec,"head");
|
checkhead = struct_val(screwspec,"head");
|
||||||
default_counterbore = checkhead=="none" || starts_with(checkhead,"flat") ? 0 : true;
|
default_counterbore = checkhead=="none" || starts_with(checkhead,"flat") ? 0 : true;
|
||||||
counterbore = default(counterbore, default_counterbore);
|
counterbore = default(counterbore, default_counterbore);
|
||||||
|
@ -775,11 +803,15 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||||
default_tag("remove")
|
default_tag("remove")
|
||||||
screw(spec,head=head,thread=thread,undersize=undersize,
|
screw(spec,head=head,thread=thread,undersize=undersize,
|
||||||
length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore,
|
length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore,
|
||||||
|
bevel=bevel, bevel1=bevel1, bevel2=bevel2,
|
||||||
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tolerance = default(tolerance, "normal");
|
tolerance = default(tolerance, "normal");
|
||||||
|
pitch = struct_val(screwspec,"pitch");
|
||||||
|
dummy3 = assert((downcase(tolerance) != "tap" && downcase(tolerance)!="self tap") || pitch!=0,
|
||||||
|
"\"tap\" clearance requires a pitch size, but pitch is set to zero");
|
||||||
// UTS clearances from ASME B18.2.8
|
// UTS clearances from ASME B18.2.8
|
||||||
UTS_clearance = [
|
UTS_clearance = [
|
||||||
[ // Close fit
|
[ // Close fit
|
||||||
|
@ -876,7 +908,7 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
tol_ind = in_list(downcase(tolerance), ["close", "fine", "tight"]) ? 0
|
tol_ind = in_list(downcase(tolerance), ["close", "fine", "tight"]) ? 0
|
||||||
: in_list(downcase(tolerance), ["normal", "medium"]) ? 1
|
: in_list(downcase(tolerance), ["normal", "medium", "tap", "self tap"]) ? 1
|
||||||
: in_list(downcase(tolerance), ["loose", "coarse"]) ? 2
|
: in_list(downcase(tolerance), ["loose", "coarse"]) ? 2
|
||||||
: in_list(tolerance, ["H12","H13","H14"]) ?
|
: in_list(tolerance, ["H12","H13","H14"]) ?
|
||||||
assert(struct_val(screwspec,"system")=="ISO", str("Hole tolerance ", tolerance, " only allowed with ISO screws"))
|
assert(struct_val(screwspec,"system")=="ISO", str("Hole tolerance ", tolerance, " only allowed with ISO screws"))
|
||||||
|
@ -884,15 +916,18 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||||
: assert(false,str("Unknown tolerance ",tolerance, " for clearance hole"));
|
: assert(false,str("Unknown tolerance ",tolerance, " for clearance hole"));
|
||||||
tol_table = struct_val(screwspec,"system")=="UTS" ? UTS_clearance[tol_ind] : ISO_clearance[tol_ind];
|
tol_table = struct_val(screwspec,"system")=="UTS" ? UTS_clearance[tol_ind] : ISO_clearance[tol_ind];
|
||||||
// If we got here, hole_oversize is undefined and oversize is undefined
|
// If we got here, hole_oversize is undefined and oversize is undefined
|
||||||
hole_oversize = lookup(_nominal_diam(screwspec), tol_table);
|
hole_oversize = downcase(tolerance)=="tap" ? -pitch
|
||||||
|
: downcase(tolerance)=="self tap" ? -pitch*lookup(pitch,[[1,0.72],[1.5,.6]])
|
||||||
|
: lookup(_nominal_diam(screwspec), tol_table);
|
||||||
head_oversize = first_defined([head_oversize,hole_oversize]);
|
head_oversize = first_defined([head_oversize,hole_oversize]);
|
||||||
default_tag("remove")
|
default_tag("remove")
|
||||||
screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize,
|
screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize,
|
||||||
length=length,l=l,thread_len=thread_len, _counterbore=counterbore,
|
length=length,l=l,thread_len=thread_len, _counterbore=counterbore,
|
||||||
|
bevel=bevel, bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef,
|
||||||
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module: shoulder_screw()
|
// Module: shoulder_screw()
|
||||||
// Usage:
|
// Usage:
|
||||||
|
@ -1388,11 +1423,7 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,oversize=0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (head=="hex")
|
if (head=="hex")
|
||||||
intersection(){
|
_nutshape(head_size,head_height,"hex",false,true);
|
||||||
linear_extrude(height=head_height) hexagon(id=head_size);
|
|
||||||
if (details)
|
|
||||||
down(.01)cyl(l=head_height+.02,d=2*head_size/sqrt(3), chamfer=head_size*(1/sqrt(3)-1/2), anchor=BOTTOM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,7 +1440,11 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,oversize=0
|
||||||
// As with screws, you can give the specification in `spec` and then omit the name. The diameter is the flat-to-flat
|
// As with screws, you can give the specification in `spec` and then omit the name. The diameter is the flat-to-flat
|
||||||
// size of the nut produced. The thickness can be "thin", "normal" or "thick" to choose standard nut dimensions. For metric
|
// size of the nut produced. The thickness can be "thin", "normal" or "thick" to choose standard nut dimensions. For metric
|
||||||
// nuts you can also use thickness values of "DIN" or "undersized". The nut's shape is hexagonal by default; set shape to "square" for
|
// nuts you can also use thickness values of "DIN" or "undersized". The nut's shape is hexagonal by default; set shape to "square" for
|
||||||
// a square nut.
|
// a square nut.
|
||||||
|
// .
|
||||||
|
// By default all nuts have the internal holes beveled and hex nuts have their corners beveled. Square nuts get no outside bevel by default.
|
||||||
|
// ASME specifies that small square nuts should not be beveled, and many square nuts are beveled only on one side. The bevel angle, specified with bevang,
|
||||||
|
// gives the angle for the bevel. The default of 15 is shallow and may not be printable. Internal hole are beveled at 45 deg by the depth of one thread.
|
||||||
// .
|
// .
|
||||||
// The tolerance determines the actual thread sizing based on the nominal size in accordance with standards.
|
// The tolerance determines the actual thread sizing based on the nominal size in accordance with standards.
|
||||||
// The $slop parameter determines extra gaps left to account for printing overextrusion. It defaults to 0.
|
// The $slop parameter determines extra gaps left to account for printing overextrusion. It defaults to 0.
|
||||||
|
@ -1421,7 +1456,7 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,oversize=0
|
||||||
// nutwidth = width of nut (overrides table values)
|
// nutwidth = width of nut (overrides table values)
|
||||||
// thread = thread type or specification. See [screw pitch](#subsection-standard-screw-pitch). Default: "coarse"
|
// thread = thread type or specification. See [screw pitch](#subsection-standard-screw-pitch). Default: "coarse"
|
||||||
// hole_oversize = amount to increase hole diameter. Default: 0
|
// hole_oversize = amount to increase hole diameter. Default: 0
|
||||||
// bevel = if true, bevel the outside of the nut.
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 15
|
||||||
|
@ -2808,7 +2843,6 @@ function _validate_screw_spec(spec) =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function: thread_specification()
|
// Function: thread_specification()
|
||||||
// Usage:
|
// Usage:
|
||||||
// thread_specification(screw_spec, [tolerance], [internal])
|
// thread_specification(screw_spec, [tolerance], [internal])
|
||||||
|
|
|
@ -1190,6 +1190,8 @@ module jittered_poly(path, dist=1/512) {
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Makes a 2D teardrop shape. Useful for extruding into 3D printable holes. Uses "intersect" style anchoring.
|
// Makes a 2D teardrop shape. Useful for extruding into 3D printable holes. Uses "intersect" style anchoring.
|
||||||
|
// The cap_h parameter truncates the top of the teardrop. If cap_h is taller than the untruncated form then
|
||||||
|
// the result will be the full, untruncated shape.
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// teardrop2d(r/d=, [ang], [cap_h]) [ATTACHMENTS];
|
// teardrop2d(r/d=, [ang], [cap_h]) [ATTACHMENTS];
|
||||||
|
@ -1205,7 +1207,7 @@ module jittered_poly(path, dist=1/512) {
|
||||||
// ang = angle of hat walls from the Y axis. (Default: 45 degrees)
|
// ang = angle of hat walls from the Y axis. (Default: 45 degrees)
|
||||||
// cap_h = if given, height above center where the shape will be truncated.
|
// cap_h = if given, height above center where the shape will be truncated.
|
||||||
// ---
|
// ---
|
||||||
// d = diameter of spherical portion of bottom. (Use instead of r)
|
// d = diameter of circular portion of bottom. (Use instead of r)
|
||||||
// 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`
|
||||||
//
|
//
|
||||||
|
@ -1224,24 +1226,25 @@ module teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _extrapt = true causes the point to be duplicated so a teardrop with no cap
|
||||||
|
// has the same point count as one with a cap.
|
||||||
|
|
||||||
function teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0) =
|
function teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0, _extrapt=false) =
|
||||||
let(
|
let(
|
||||||
r = get_radius(r=r, d=d, dflt=1),
|
r = get_radius(r=r, d=d, dflt=1),
|
||||||
ang2 = 90-ang,
|
ang2=90-ang,
|
||||||
prepath = zrot(90, p=circle(r=r)),
|
minheight = r*sin(ang),
|
||||||
eps=1e-9,
|
maxheight = r/cos(ang2)
|
||||||
prepath2 = [for (p=prepath) let(a=atan2(p.y,p.x)) if(a<=90-ang2+eps || a>=90+ang2-eps) p],
|
)
|
||||||
hyp = is_undef(cap_h)
|
assert(is_undef(cap_h) || cap_h>=minheight, str("cap_h cannot be less than ",minheight," but it is ",cap_h))
|
||||||
? opp_ang_to_hyp(abs(prepath2[0].x), ang)
|
let(
|
||||||
: adj_ang_to_hyp(cap_h-prepath2[0].y, ang),
|
firstpt = is_undef(cap_h) || cap_h>=maxheight ? [[0,maxheight]]
|
||||||
p1 = prepath2[0] + polar_to_xy(hyp, 90+ang),
|
: [[(maxheight-cap_h)*tan(ang), cap_h]],
|
||||||
p2 = last(prepath2) + polar_to_xy(hyp, 90-ang),
|
lastpt = !_extrapt && (is_undef(cap_h) || cap_h>=maxheight) ? [] : [[-firstpt[0].x,firstpt[0].y]],
|
||||||
path = deduplicate([p1, each prepath2, p2], closed=true)
|
path = concat(firstpt, arc(angle=[ang, -180-ang], r=r), lastpt)
|
||||||
) reorient(anchor,spin, two_d=true, path=path, p=path, extent=false);
|
) reorient(anchor,spin, two_d=true, path=path, p=path, extent=false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: egg()
|
// Function&Module: egg()
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// egg(length, r1|d1=, r2|d2=, R|D=) [ATTACHMENTS];
|
// egg(length, r1|d1=, r2|d2=, R|D=) [ATTACHMENTS];
|
||||||
|
|
102
shapes3d.scad
102
shapes3d.scad
|
@ -2479,10 +2479,15 @@ function torus(
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Makes a teardrop shape in the XZ plane. Useful for 3D printable holes.
|
// Makes a teardrop shape in the XZ plane. Useful for 3D printable holes.
|
||||||
|
// Optional chamfers can be added with positive or negative distances. A positive distance
|
||||||
|
// specifies the amount to inset the chamfer along the front/back faces of the shape.
|
||||||
|
// The chamfer will extend the same y distance into the shape. If the radii are the same
|
||||||
|
// then the chamfer will be a 45 degree chamfer, but in other cases it will not.
|
||||||
|
// Note that with caps, the chamfer must not be so big that it makes the cap height illegal.
|
||||||
//
|
//
|
||||||
// Usage: Typical
|
// Usage: Typical
|
||||||
// teardrop(h|l, r, [ang], [cap_h], ...) [ATTACHMENTS];
|
// teardrop(h|l|length|height, r, [ang], [cap_h], [chamfer=], ...) [ATTACHMENTS];
|
||||||
// teardrop(h|l, d=, [ang=], [cap_h=], ...) [ATTACHMENTS];
|
// teardrop(h|l|length|height, d=, [ang=], [cap_h=], [chamfer=], ...) [ATTACHMENTS];
|
||||||
// Usage: Psuedo-Conical
|
// Usage: Psuedo-Conical
|
||||||
// teardrop(h|l, r1=, r2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
|
// teardrop(h|l, r1=, r2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
|
||||||
// teardrop(h|l, d1=, d2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
|
// teardrop(h|l, d1=, d2=, [ang=], [cap_h1=], [cap_h2=], ...) [ATTACHMENTS];
|
||||||
|
@ -2504,6 +2509,9 @@ function torus(
|
||||||
// d2 = Diameter of circular portion of the back end of the teardrop shape.
|
// d2 = Diameter of circular portion of the back end of the teardrop shape.
|
||||||
// cap_h1 = If given, height above center where the shape will be truncated, on the front side. Default: `undef` (no truncation)
|
// cap_h1 = If given, height above center where the shape will be truncated, on the front side. Default: `undef` (no truncation)
|
||||||
// cap_h2 = If given, height above center where the shape will be truncated, on the back side. Default: `undef` (no truncation)
|
// cap_h2 = If given, height above center where the shape will be truncated, on the back side. Default: `undef` (no truncation)
|
||||||
|
// chamfer = Specifies size of chamfer as distance along the bottom and top faces. Default: 0
|
||||||
|
// chamfer1 = Specifies size of chamfer on bottom as distance along bottom face. Default: 0
|
||||||
|
// chamfer2 = Specifies size of chamfer on top as distance along top face. Default: 0
|
||||||
// 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`
|
||||||
|
@ -2521,6 +2529,8 @@ function torus(
|
||||||
// teardrop(r=30, h=10, ang=30, cap_h=20);
|
// teardrop(r=30, h=10, ang=30, cap_h=20);
|
||||||
// Example: Psuedo-Conical
|
// Example: Psuedo-Conical
|
||||||
// teardrop(r1=20, r2=30, h=40, cap_h1=25, cap_h2=35);
|
// teardrop(r1=20, r2=30, h=40, cap_h1=25, cap_h2=35);
|
||||||
|
// Example: Adding chamfers can be useful for a teardrop hole mask
|
||||||
|
// teardrop(r=10, l=50, chamfer1=2, chamfer2=-1.5);
|
||||||
// Example: Getting a VNF
|
// Example: Getting a VNF
|
||||||
// vnf = teardrop(r1=25, r2=30, l=20, cap_h1=25, cap_h2=35);
|
// vnf = teardrop(r1=25, r2=30, l=20, cap_h1=25, cap_h2=35);
|
||||||
// vnf_polyhedron(vnf);
|
// vnf_polyhedron(vnf);
|
||||||
|
@ -2531,78 +2541,70 @@ function torus(
|
||||||
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
||||||
// show_anchors(std=false);
|
// show_anchors(std=false);
|
||||||
|
|
||||||
module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, anchor=CENTER, spin=0, orient=UP)
|
module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, length, height, chamfer, chamfer1, chamfer2,anchor=CENTER, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1);
|
length = one_defined([l, h, length, height],"l,h,length,height");
|
||||||
r2 = get_radius(r=r, r1=r2, d=d, d1=d2, dflt=1);
|
r1 = get_radius(r=r, r1=r1, d=d, d1=d1);
|
||||||
l = first_defined([l, h, 1]);
|
r2 = get_radius(r=r, r1=r2, d=d, d1=d2);
|
||||||
cap_h1 = first_defined([cap_h1, cap_h]);
|
tip_y1 = r1/cos(90-ang);
|
||||||
cap_h2 = first_defined([cap_h2, cap_h]);
|
tip_y2 = r2/cos(90-ang);
|
||||||
sides = segs(max(r1,r2));
|
|
||||||
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides);
|
|
||||||
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides);
|
|
||||||
tip_y1 = max(column(profile1,1));
|
|
||||||
tip_y2 = max(column(profile2,1));
|
|
||||||
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1);
|
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1);
|
||||||
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2);
|
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2);
|
||||||
capvec = unit([0, _cap_h1-_cap_h2, l]);
|
f= echo(fff=_cap_h1,_cap_h2);
|
||||||
|
capvec = unit([0, _cap_h1-_cap_h2, length]);
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
||||||
named_anchor("cap_fwd", [0,-l/2,_cap_h1], unit((capvec+FWD)/2)),
|
named_anchor("cap_fwd", [0,-length/2,_cap_h1], unit((capvec+FWD)/2)),
|
||||||
named_anchor("cap_back", [0,+l/2,_cap_h2], unit((capvec+BACK)/2), 180),
|
named_anchor("cap_back", [0,+length/2,_cap_h2], unit((capvec+BACK)/2), 180),
|
||||||
];
|
];
|
||||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=l, axis=BACK, anchors=anchors) {
|
attachable(anchor,spin,orient, r1=r1, r2=r2, l=length, axis=BACK, anchors=anchors)
|
||||||
rot(from=UP,to=FWD) {
|
{
|
||||||
if (l > 0) {
|
vnf_polyhedron(teardrop(ang=ang,cap_h=cap_h,r1=r1,r2=r2,,cap_h1=cap_h1,cap_h2=cap_h2,
|
||||||
if (r1 == r2) {
|
length=length, chamfer1=chamfer1,chamfer2=chamfer2,chamfer=chamfer));
|
||||||
linear_extrude(height=l, center=true, slices=2) {
|
|
||||||
polygon(profile1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hull() {
|
|
||||||
up(l/2-0.001) {
|
|
||||||
linear_extrude(height=0.001, center=false) {
|
|
||||||
polygon(profile1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
down(l/2) {
|
|
||||||
linear_extrude(height=0.001, center=false) {
|
|
||||||
polygon(profile2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, anchor=CENTER, spin=0, orient=UP) =
|
function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, chamfer, chamfer1, chamfer2,
|
||||||
|
l, length, height, anchor=CENTER, spin=0, orient=UP) =
|
||||||
let(
|
let(
|
||||||
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1),
|
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1),
|
||||||
r2 = get_radius(r=r, r1=r2, d=d, d1=d2, dflt=1),
|
r2 = get_radius(r=r, r1=r2, d=d, d1=d2, dflt=1),
|
||||||
l = first_defined([l, h, 1]),
|
length = one_defined([l, h, length, height],"l,h,length,height"),
|
||||||
cap_h1 = first_defined([cap_h1, cap_h]),
|
cap_h1 = first_defined([cap_h1, cap_h]),
|
||||||
cap_h2 = first_defined([cap_h2, cap_h]),
|
cap_h2 = first_defined([cap_h2, cap_h]),
|
||||||
|
chamfer1 = first_defined([chamfer1,chamfer,0]),
|
||||||
|
chamfer2 = first_defined([chamfer2,chamfer,0]),
|
||||||
sides = segs(max(r1,r2)),
|
sides = segs(max(r1,r2)),
|
||||||
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides),
|
profile1 = teardrop2d(r=r1, ang=ang, cap_h=cap_h1, $fn=sides, _extrapt=true),
|
||||||
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides),
|
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides, _extrapt=true),
|
||||||
tip_y1 = max(column(profile1,1)),
|
tip_y1 = r1/cos(90-ang),
|
||||||
tip_y2 = max(column(profile2,1)),
|
tip_y2 = r2/cos(90-ang),
|
||||||
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
|
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
|
||||||
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2),
|
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2),
|
||||||
capvec = unit([0, _cap_h1-_cap_h2, l]),
|
capvec = unit([0, _cap_h1-_cap_h2, length]),
|
||||||
|
dummy=
|
||||||
|
assert(abs(chamfer1)+abs(chamfer2) <= length,"chamfers are too big to fit in the length")
|
||||||
|
assert(chamfer1<=r1 && chamfer2<=r2, "Chamfers cannot be larger than raduis")
|
||||||
|
assert(is_undef(cap_h1) || cap_h1-chamfer1 > r1*sin(ang), "chamfer1 is too big to work with the specified cap_h1")
|
||||||
|
assert(is_undef(cap_h2) || cap_h2-chamfer2 > r2*sin(ang), "chamfer2 is too big to work with the specified cap_h2"),
|
||||||
|
cprof1 = r1==chamfer1 ? repeat([0,0],len(profile1))
|
||||||
|
: teardrop2d(r=r1-chamfer1, ang=ang, cap_h=u_add(cap_h1,-chamfer1), $fn=sides, _extrapt=true),
|
||||||
|
cprof2 = r2==chamfer2 ? repeat([0,0],len(profile2))
|
||||||
|
: teardrop2d(r=r2-chamfer2, ang=ang, cap_h=u_add(cap_h2,-chamfer2), $fn=sides, _extrapt=true),
|
||||||
|
fefda= echo(lens=len(cprof1),len(cprof2)),
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
named_anchor("cap", [0,0,(_cap_h1+_cap_h2)/2], capvec),
|
||||||
named_anchor("cap_fwd", [0,-l/2,_cap_h1], unit((capvec+FWD)/2)),
|
named_anchor("cap_fwd", [0,-length/2,_cap_h1], unit((capvec+FWD)/2)),
|
||||||
named_anchor("cap_back", [0,+l/2,_cap_h2], unit((capvec+BACK)/2), 180),
|
named_anchor("cap_back", [0,+length/2,_cap_h2], unit((capvec+BACK)/2), 180),
|
||||||
],
|
],
|
||||||
vnf = vnf_vertex_array(
|
vnf = vnf_vertex_array(
|
||||||
points = [
|
points = [
|
||||||
fwd(l/2, p=xrot(90, p=path3d(profile1))),
|
if (chamfer1!=0) fwd(length/2, xrot(90, path3d(cprof1))),
|
||||||
back(l/2, p=xrot(90, p=path3d(profile2))),
|
fwd(length/2-abs(chamfer1), xrot(90, path3d(profile1))),
|
||||||
|
back(length/2-abs(chamfer2), xrot(90, path3d(profile2))),
|
||||||
|
if (chamfer2!=0) back(length/2, xrot(90, path3d(cprof2))),
|
||||||
],
|
],
|
||||||
caps=true, col_wrap=true, reverse=true
|
caps=true, col_wrap=true, reverse=true
|
||||||
)
|
)
|
||||||
|
|
|
@ -143,7 +143,7 @@ module threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -157,13 +157,13 @@ module threaded_rod(
|
||||||
function threaded_nut(
|
function threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
||||||
ibevel1, ibevel2, ibevel, bevang=15, thickness, height,
|
ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
)=no_function("threaded_nut");
|
)=no_function("threaded_nut");
|
||||||
module threaded_nut(
|
module threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
|
||||||
ibevel1, ibevel2, ibevel, bevang=15, thickness, height,
|
ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
) {
|
) {
|
||||||
dummy1=
|
dummy1=
|
||||||
|
@ -350,7 +350,7 @@ module trapezoidal_threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -373,7 +373,7 @@ function trapezoidal_threaded_nut(
|
||||||
thread_depth, shape="hex",
|
thread_depth, shape="hex",
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
starts=1,
|
starts=1,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel1,ibevel2,ibevel,
|
ibevel1,ibevel2,ibevel,
|
||||||
thickness,height,
|
thickness,height,
|
||||||
id1,id2,
|
id1,id2,
|
||||||
|
@ -388,7 +388,7 @@ module trapezoidal_threaded_nut(
|
||||||
thread_depth, shape="hex",
|
thread_depth, shape="hex",
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
starts=1,
|
starts=1,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel1,ibevel2,ibevel,
|
ibevel1,ibevel2,ibevel,
|
||||||
thickness,height,
|
thickness,height,
|
||||||
id1,id2,
|
id1,id2,
|
||||||
|
@ -500,7 +500,7 @@ module acme_threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -515,7 +515,7 @@ function acme_threaded_nut(
|
||||||
nutwidth, id, h, tpi, pitch,
|
nutwidth, id, h, tpi, pitch,
|
||||||
starts=1,
|
starts=1,
|
||||||
left_handed=false,shape="hex",
|
left_handed=false,shape="hex",
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel,ibevel1,ibevel2,
|
ibevel,ibevel1,ibevel2,
|
||||||
height,thickness,
|
height,thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
|
@ -524,7 +524,7 @@ module acme_threaded_nut(
|
||||||
nutwidth, id, h, tpi, pitch,
|
nutwidth, id, h, tpi, pitch,
|
||||||
starts=1,
|
starts=1,
|
||||||
left_handed=false,shape="hex",
|
left_handed=false,shape="hex",
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel,ibevel1,ibevel2,
|
ibevel,ibevel1,ibevel2,
|
||||||
height,thickness,
|
height,thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
|
@ -769,7 +769,7 @@ module buttress_threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -782,14 +782,14 @@ module buttress_threaded_rod(
|
||||||
function buttress_threaded_nut(
|
function buttress_threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch, shape="hex", left_handed=false,
|
pitch, shape="hex", left_handed=false,
|
||||||
bevel,bevel1,bevel2,bevang=15,starts=1,
|
bevel,bevel1,bevel2,bevang=30,starts=1,
|
||||||
ibevel,ibevel1,ibevel2,height,thickness,
|
ibevel,ibevel1,ibevel2,height,thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
) = no_function("buttress_threaded_nut");
|
) = no_function("buttress_threaded_nut");
|
||||||
module buttress_threaded_nut(
|
module buttress_threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch, shape="hex", left_handed=false,
|
pitch, shape="hex", left_handed=false,
|
||||||
bevel,bevel1,bevel2,bevang=15,starts=1,
|
bevel,bevel1,bevel2,bevang=30,starts=1,
|
||||||
ibevel,ibevel1,ibevel2,height,thickness,
|
ibevel,ibevel1,ibevel2,height,thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
) {
|
) {
|
||||||
|
@ -907,7 +907,7 @@ module square_threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -921,7 +921,7 @@ function square_threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch,
|
pitch,
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel,ibevel1,ibevel2,
|
ibevel,ibevel1,ibevel2,
|
||||||
height,thickness,
|
height,thickness,
|
||||||
starts=1,
|
starts=1,
|
||||||
|
@ -931,7 +931,7 @@ module square_threaded_nut(
|
||||||
nutwidth, id, h,
|
nutwidth, id, h,
|
||||||
pitch,
|
pitch,
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel,ibevel1,ibevel2,
|
ibevel,ibevel1,ibevel2,
|
||||||
height,thickness,
|
height,thickness,
|
||||||
starts=1,
|
starts=1,
|
||||||
|
@ -1277,7 +1277,7 @@ module generic_threaded_rod(
|
||||||
// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
|
// 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.
|
// bevel1 = if true, bevel the outside of the nut bottom.
|
||||||
// bevel2 = if true, bevel the outside of the nut top.
|
// bevel2 = if true, bevel the outside of the nut top.
|
||||||
// bevang = set the angle for the outside nut bevel. Default: 15
|
// bevang = set the angle for the outside nut bevel. Default: 30
|
||||||
// ibevel = if true, bevel the inside (the hole). Default: true
|
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||||
// ibevel1 = if true bevel the inside, bottom end.
|
// ibevel1 = if true bevel the inside, bottom end.
|
||||||
// ibevel2 = if true bevel the inside, top end.
|
// ibevel2 = if true bevel the inside, top end.
|
||||||
|
@ -1296,7 +1296,7 @@ function generic_threaded_nut(
|
||||||
shape="hex",
|
shape="hex",
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
starts=1,
|
starts=1,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel, ibevel1, ibevel2,
|
ibevel, ibevel1, ibevel2,
|
||||||
id1,id2, height, thickness,
|
id1,id2, height, thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
|
@ -1310,7 +1310,7 @@ module generic_threaded_nut(
|
||||||
shape="hex",
|
shape="hex",
|
||||||
left_handed=false,
|
left_handed=false,
|
||||||
starts=1,
|
starts=1,
|
||||||
bevel,bevel1,bevel2,bevang=15,
|
bevel,bevel1,bevel2,bevang=30,
|
||||||
ibevel, ibevel1, ibevel2,
|
ibevel, ibevel1, ibevel2,
|
||||||
id1,id2, height, thickness,
|
id1,id2, height, thickness,
|
||||||
anchor, spin, orient
|
anchor, spin, orient
|
||||||
|
@ -1332,19 +1332,11 @@ module generic_threaded_nut(
|
||||||
bevel1 = first_defined([bevel1,bevel,shape=="hex"?true:false]);
|
bevel1 = first_defined([bevel1,bevel,shape=="hex"?true:false]);
|
||||||
bevel2 = first_defined([bevel2,bevel,shape=="hex"?true:false]);
|
bevel2 = first_defined([bevel2,bevel,shape=="hex"?true:false]);
|
||||||
depth = -pitch*min(column(profile,1));
|
depth = -pitch*min(column(profile,1));
|
||||||
bevel_d=0.975;
|
|
||||||
IBEV=0.05;
|
IBEV=0.05;
|
||||||
vnf = linear_sweep(hexagon(id=nutwidth), height=h, center=true);
|
vnf = linear_sweep(hexagon(id=nutwidth), height=h, center=true);
|
||||||
attachable(anchor,spin,orient, size=shape=="square" ? [nutwidth,nutwidth,h] : undef, vnf=shape=="hex" ? vnf : undef) {
|
attachable(anchor,spin,orient, size=shape=="square" ? [nutwidth,nutwidth,h] : undef, vnf=shape=="hex" ? vnf : undef) {
|
||||||
difference() {
|
difference() {
|
||||||
intersection(){
|
_nutshape(nutwidth,h, shape,bevel1,bevel2);
|
||||||
if (shape=="hex")
|
|
||||||
vnf_polyhedron(vnf);
|
|
||||||
else
|
|
||||||
cuboid([nutwidth,nutwidth,h]);
|
|
||||||
if (bevel2) cyl(h=h+.01, d2=nutwidth*bevel_d,d1=nutwidth*bevel_d+h/tan(bevang), $fn=64);
|
|
||||||
if (bevel1) down(.01) cyl(h=h+.01, d1=nutwidth*bevel_d,d2=nutwidth*bevel_d+h/tan(bevang), $fn=64);
|
|
||||||
}
|
|
||||||
if (pitch==0)
|
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
|
else
|
||||||
|
@ -1364,6 +1356,23 @@ module generic_threaded_nut(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module _nutshape(nutwidth, h, shape, bevel1, bevel2)
|
||||||
|
{
|
||||||
|
bevel_d=0.9;
|
||||||
|
intersection(){
|
||||||
|
if (shape=="hex")
|
||||||
|
cyl(d=nutwidth, circum=true, $fn=6, l=h, chamfer1=bevel1?0:nutwidth*.01, chamfer2=bevel2?0:nutwidth*.01);
|
||||||
|
//vnf_polyhedron(vnf);
|
||||||
|
else
|
||||||
|
cuboid([nutwidth,nutwidth,h],chamfer=nutwidth*.01, except=[if (bevel1) BOT, if(bevel2) TOP]);
|
||||||
|
fn = quantup(segs(r=nutwidth/2),shape=="hex"?6:4);
|
||||||
|
d = shape=="hex" ? 2*nutwidth/sqrt(3) : sqrt(2)*nutwidth;
|
||||||
|
chamfsize = (d-nutwidth)/2/bevel_d;
|
||||||
|
cyl(d=d*.99,h=h+.01,realign=true,circum=true,$fn=fn,chamfer1=bevel1?chamfsize:0,chamfer2=bevel2?chamfsize:0,chamfang=90-30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Module: thread_helix()
|
// Module: thread_helix()
|
||||||
// Usage:
|
// Usage:
|
||||||
// thread_helix(d, pitch, [thread_depth], [flank_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]);
|
// thread_helix(d, pitch, [thread_depth], [flank_angle], [twist], [profile=], [left_handed=], [higbee=], [internal=]);
|
||||||
|
|
Loading…
Reference in a new issue