mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
commit
76c3b9a210
5 changed files with 904 additions and 473 deletions
|
@ -120,7 +120,7 @@ module pco1810_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
thread_depth=thread_h+0.1,
|
||||
flank_angle=flank_angle,
|
||||
turns=810/360,
|
||||
taper=-thread_h*2,
|
||||
lead_in=-thread_h*2,
|
||||
anchor=TOP
|
||||
);
|
||||
zrot_copies(rots=[90,270]) {
|
||||
|
@ -196,7 +196,7 @@ module pco1810_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
|
|||
}
|
||||
up(wall) cyl(d=cap_id, h=tamper_ring_h+wall, anchor=BOTTOM);
|
||||
}
|
||||
up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, taper=-thread_depth, internal=true, anchor=BOTTOM);
|
||||
up(wall+2) thread_helix(d=thread_od-thread_depth*2, pitch=thread_pitch, thread_depth=thread_depth, flank_angle=flank_angle, turns=810/360, lead_in=-thread_depth, internal=true, anchor=BOTTOM);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ module pco1881_neck(wall=2, anchor="support-ring", spin=0, orient=UP)
|
|||
thread_depth=thread_h+0.1,
|
||||
flank_angle=flank_angle,
|
||||
turns=650/360,
|
||||
taper=-thread_h*2,
|
||||
lead_in=-thread_h*2,
|
||||
anchor=TOP
|
||||
);
|
||||
zrot_copies(rots=[90,270]) {
|
||||
|
@ -383,7 +383,7 @@ module pco1881_cap(wall=2, texture="none", anchor=BOTTOM, spin=0, orient=UP)
|
|||
}
|
||||
up(wall) cyl(d=28.58, h=11.2+wall, anchor=BOTTOM);
|
||||
}
|
||||
up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, taper=-1.6, internal=true, anchor=BOTTOM);
|
||||
up(wall+2) thread_helix(d=25.5, pitch=2.7, thread_depth=1.6, flank_angle=15, turns=650/360, lead_in=-1.6, internal=true, anchor=BOTTOM);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ module generic_bottle_neck(
|
|||
thread_depth = thread_h + 0.1 * diamMagMult,
|
||||
flank_angle = flank_angle,
|
||||
turns = (height - pitch - lip_roundover_r) * .6167 / pitch,
|
||||
taper = -thread_h * 2,
|
||||
lead_in = -thread_h * 2,
|
||||
anchor = TOP
|
||||
);
|
||||
zrot_copies(rots = [90, 270]) {
|
||||
|
@ -597,7 +597,7 @@ module generic_bottle_cap(
|
|||
difference(){
|
||||
up(wall + pitch / 2) {
|
||||
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = threadDepth, flank_angle = flank_angle,
|
||||
turns = ((height - pitch) / pitch), taper = -threadDepth, internal = true, anchor = BOTTOM);
|
||||
turns = ((height - pitch) / pitch), lead_in = -threadDepth, internal = true, anchor = BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -984,8 +984,9 @@ function bottle_adapter_neck_to_neck(
|
|||
// 400, 410 and 415. The 400 type neck has 360 degrees of thread, the 410
|
||||
// neck has 540 degrees of thread, and the 415 neck has 720 degrees of thread.
|
||||
// You can also choose between the L style thread, which is symmetric and
|
||||
// the M style thread, which is an asymmetric buttress thread. You can
|
||||
// specify the wall thickness (measured from the base of the threads) or
|
||||
// the M style thread, which is an asymmetric buttress thread. The M style
|
||||
// may be good for 3d printing if printed with the flat face up.
|
||||
// You can specify the wall thickness (measured from the base of the threads) or
|
||||
// the inner diameter, and you can specify an optional bead at the base of the threads.
|
||||
// Arguments:
|
||||
// diam = nominal outer diameter of threads
|
||||
|
@ -1124,6 +1125,8 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
H = entry[2];
|
||||
S = entry[3];
|
||||
tpi = entry[4];
|
||||
|
||||
// a is the width of the thread
|
||||
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
|
||||
|
||||
twist = struct_val(_sp_twist, type);
|
||||
|
@ -1156,7 +1159,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
up((H+extra_bot)/2){
|
||||
difference(){
|
||||
union(){
|
||||
thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP);
|
||||
thread_helix(d=T-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, lead_in=taperlen, anchor=TOP);
|
||||
cylinder(d=T-depth*2,h=H,anchor=TOP);
|
||||
if (bead)
|
||||
down(bead_shift)
|
||||
|
@ -1187,12 +1190,15 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
// the M style thread, which is an asymmetric buttress thread. Note that it
|
||||
// is OK to mix styles, so you can put an L-style cap onto an M-style neck.
|
||||
// .
|
||||
// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick.
|
||||
// If you don't include this, your cap may bottom out on the bead on the neck instead of sealing
|
||||
// against the top. If you set top_adj to 1 it will make the top space 1mm smaller so that the
|
||||
// cap will not bottom out. The 410 and 415 caps have very long unthreaded sections at the bottom.
|
||||
// The bot_adj parameter specifies an amount to reduce that bottom extension. Be careful that
|
||||
// you don't shrink past the threads.
|
||||
// The 410 and 415 caps have very long unthreaded sections at the bottom.
|
||||
// The bot_adj parameter specifies an amount to reduce that bottom extension, which might be
|
||||
// necessary if the cap bottoms out on the bead. Be careful that you don't shrink past the threads,
|
||||
// especially if making adjustments to 400 caps which have a very small bottom extension.
|
||||
// These caps often contain a cardboard or foam sealer disk, which can be as much as 1mm thick, and
|
||||
// would cause the cap to stop in a higher position.
|
||||
// .
|
||||
// You can also adjust the space between the top of the cap and the threads using top_adj. This
|
||||
// will change how the threads engage when the cap is fully seated.
|
||||
// .
|
||||
// The inner diameter of the cap is set to allow 10% of the thread depth in clearance. The diameter
|
||||
// is further increased by `2 * $slop` so you can increase clearance if necessary.
|
||||
|
@ -1215,6 +1221,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
|
|||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// Examples:
|
||||
// sp_cap(48,400,2);
|
||||
// sp_cap(22,400,2);
|
||||
// sp_cap(22,410,2);
|
||||
// sp_cap(28,415,1.5,style="M");
|
||||
module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anchor, spin, orient)
|
||||
|
@ -1227,13 +1234,14 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anc
|
|||
|
||||
T = entry[0];
|
||||
I = entry[1];
|
||||
H = entry[2]-1;
|
||||
H = entry[2]-0.5;
|
||||
S = entry[3];
|
||||
tpi = entry[4];
|
||||
a = (style=="M" && tpi==12) ? 1.3 : struct_val(_sp_thread_width,tpi);
|
||||
|
||||
twist = struct_val(_sp_twist, type);
|
||||
|
||||
echo(top_adj=top_adj,bot_adj=bot_adj);
|
||||
dum3=assert(top_adj<S+0.75*a, str("The top_adj value is too large so the thread won't fit. It must be smaller than ",S+0.75*a));
|
||||
oprofile = _sp_thread_profile(tpi,a,S+0.75*a-top_adj,style,flip=true);
|
||||
bounds=pointlist_bounds(oprofile);
|
||||
|
@ -1257,7 +1265,7 @@ module sp_cap(diam,type,wall,style="L",top_adj=0, bot_adj=0, texture="none", anc
|
|||
}
|
||||
cyl(d=T+space, l=H-bot_adj+1, anchor=TOP);
|
||||
}
|
||||
thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, taper=taperlen, anchor=TOP, internal=true);
|
||||
thread_helix(d=T+space-.01, profile=profile, pitch = INCH/tpi, turns=twist/360, lead_in=taperlen, anchor=TOP, internal=true);
|
||||
}
|
||||
children();
|
||||
}
|
||||
|
|
36
lists.scad
36
lists.scad
|
@ -54,7 +54,7 @@ function _same_type(a,b, depth) =
|
|||
|
||||
|
||||
// Function: min_length()
|
||||
// Synopsis: Returns the length of the shortest list.
|
||||
// Synopsis: Given a list of sublists, returns the length of the shortest sublist.
|
||||
// Topics: List Handling
|
||||
// See Also: max_length()
|
||||
// Usage:
|
||||
|
@ -71,7 +71,7 @@ function min_length(list) =
|
|||
|
||||
|
||||
// Function: max_length()
|
||||
// Synopsis: Returns the length of the longest list.
|
||||
// Synopsis: Given a list of sublists, returns the length of the longest sublist.
|
||||
// Topics: List Handling
|
||||
// See Also: min_length()
|
||||
// Usage:
|
||||
|
@ -233,7 +233,7 @@ function select(list, start, end) =
|
|||
|
||||
|
||||
// Function: slice()
|
||||
// Synopsis: Returns part of a list, not including the last index.
|
||||
// Synopsis: Returns part of a list without wrapping.
|
||||
// Topics: List Handling
|
||||
// See Also: select(), column(), last()
|
||||
// Usage:
|
||||
|
@ -286,7 +286,7 @@ function last(list) =
|
|||
|
||||
|
||||
// Function: list_head()
|
||||
// Synopsis: Returns the head of the given list.
|
||||
// Synopsis: Returns the elements at the beginning of a list.
|
||||
// Topics: List Handling
|
||||
// See Also: select(), slice(), list_tail(), last()
|
||||
// Usage:
|
||||
|
@ -315,7 +315,7 @@ function list_head(list, to=-2) =
|
|||
|
||||
|
||||
// Function: list_tail()
|
||||
// Synopsis: Returns the tail of the given list.
|
||||
// Synopsis: Returns the elements at the end of a list.
|
||||
// Topics: List Handling
|
||||
// See Also: select(), slice(), list_tail(), last()
|
||||
// Usage:
|
||||
|
@ -346,7 +346,7 @@ function list_tail(list, from=1) =
|
|||
|
||||
|
||||
// Function: bselect()
|
||||
// Synopsis: Cherry-picks specific items from a list.
|
||||
// Synopsis: Select list items using boolean index list.
|
||||
// Topics: List Handling
|
||||
// See Also: list_bset()
|
||||
// Usage:
|
||||
|
@ -369,7 +369,7 @@ function bselect(list,index) =
|
|||
|
||||
|
||||
// Function: repeat()
|
||||
// Synopsis: Returns a list of N copies of a value.
|
||||
// Synopsis: Returns a list of repeated copies of a value.
|
||||
// Topics: List Handling
|
||||
// See Also: count(), lerpn()
|
||||
// Usage:
|
||||
|
@ -395,7 +395,7 @@ function repeat(val, n, i=0) =
|
|||
|
||||
|
||||
// Function: list_bset()
|
||||
// Synopsis: Returns a list where specific values are set from a list of values.
|
||||
// Synopsis: Returns a list where values are spread to locations indicated by a boolean index list.
|
||||
// Topics: List Handling
|
||||
// See Also: bselect()
|
||||
// Usage:
|
||||
|
@ -473,7 +473,7 @@ function force_list(value, n=1, fill) =
|
|||
// Section: List Modification
|
||||
|
||||
// Function: reverse()
|
||||
// Synopsis: Reverses the ordering of a list.
|
||||
// Synopsis: Reverses the elements of a list.
|
||||
// Topics: List Handling
|
||||
// See Also: select(), list_rotate()
|
||||
// Usage:
|
||||
|
@ -529,7 +529,7 @@ function list_rotate(list,n=1) =
|
|||
|
||||
|
||||
// Function: shuffle()
|
||||
// Synopsis: Randomizes the ordering of a list.
|
||||
// Synopsis: Randomizes the order of a list.
|
||||
// Topics: List Handling
|
||||
// See Also: sort(), sortidx(), unique(), unique_count()
|
||||
// Usage:
|
||||
|
@ -563,7 +563,7 @@ function shuffle(list,seed) =
|
|||
|
||||
|
||||
// Function: repeat_entries()
|
||||
// Synopsis: Repeats items in a list to expand it to a given length.
|
||||
// Synopsis: Repeats list entries (as uniformly as possible) to make list of specified length.
|
||||
// Topics: List Handling
|
||||
// See Also: repeat()
|
||||
// Usage:
|
||||
|
@ -605,7 +605,7 @@ function repeat_entries(list, N, exact=true) =
|
|||
|
||||
|
||||
// Function: list_pad()
|
||||
// Synopsis: Adds items to the end of a list until it is a given length.
|
||||
// Synopsis: Extend list to specified length.
|
||||
// Topics: List Handling
|
||||
// See Also: force_list(), scalar_vec3()
|
||||
// Usage:
|
||||
|
@ -717,7 +717,7 @@ function list_insert(list, indices, values) =
|
|||
|
||||
|
||||
// Function: list_remove()
|
||||
// Synopsis: Removes items from the middle of a list.
|
||||
// Synopsis: Removes items by index from a list.
|
||||
// Topics: List Handling
|
||||
// See Also: list_set(), list_insert(), list_remove_values()
|
||||
// Usage:
|
||||
|
@ -760,7 +760,7 @@ function list_remove(list, ind) =
|
|||
|
||||
|
||||
// Function: list_remove_values()
|
||||
// Synopsis: Removes specific values from a list.
|
||||
// Synopsis: Removes items by value from a list.
|
||||
// Topics: List Handling
|
||||
// See Also: list_set(), list_insert(), list_remove()
|
||||
// Usage:
|
||||
|
@ -861,7 +861,7 @@ function idx(list, s=0, e=-1, step=1) =
|
|||
|
||||
|
||||
// Function: pair()
|
||||
// Synopsis: Returns a list of consecutive pairs in a list.
|
||||
// Synopsis: Returns a list of overlapping consecutive pairs in a list.
|
||||
// Topics: List Handling, Iteration
|
||||
// See Also: idx(), triplet(), combinations(), permutations()
|
||||
// Usage:
|
||||
|
@ -895,7 +895,7 @@ function pair(list, wrap=false) =
|
|||
|
||||
|
||||
// Function: triplet()
|
||||
// Synopsis: Returns a list of consecutive triplets in a list.
|
||||
// Synopsis: Returns a list of overlapping consecutive triplets in a list.
|
||||
// Topics: List Handling, Iteration
|
||||
// See Also: idx(), pair(), combinations(), permutations()
|
||||
// Usage:
|
||||
|
@ -935,7 +935,7 @@ function triplet(list, wrap=false) =
|
|||
|
||||
|
||||
// Function: combinations()
|
||||
// Synopsis: Returns a list of all item combinations in a list.
|
||||
// Synopsis: Returns a list of all combinations of the list entries.
|
||||
// Topics: List Handling, Iteration
|
||||
// See Also: idx(), pair(), triplet(), permutations()
|
||||
// Usage:
|
||||
|
@ -962,7 +962,7 @@ function combinations(l,n=2,_s=0) =
|
|||
|
||||
|
||||
// Function: permutations()
|
||||
// Synopsis: Returns a list of all item permutations in a list.
|
||||
// Synopsis: Returns a list of all permutations of the list entries.
|
||||
// Topics: List Handling, Iteration
|
||||
// See Also: idx(), pair(), triplet(), combinations()
|
||||
// Usage:
|
||||
|
|
100
screws.scad
100
screws.scad
|
@ -192,7 +192,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
|||
// Topics: Threading, Screws
|
||||
// See Also: screw_hole(), shoulder_screw()
|
||||
// Usage:
|
||||
// screw([spec], [head], [drive], [thread=], [drive_size=], [length=|l=], [thread_len=], [undersize=], [shaft_undersize=], [head_undersize=], [tolerance=], [details=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
|
||||
// screw([spec], [head], [drive], [thread=], [drive_size=], [length=|l=], [thread_len=], [undersize=], [shaft_undersize=], [head_undersize=], [tolerance=], [blunt_start=], [details=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Create a screw. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on
|
||||
// the parameters that define a screw. The tolerance determines the dimensions of the screw based
|
||||
|
@ -248,9 +248,11 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
|||
// shaft_undersize = amount to decrease diameter of the shaft of screw; replaces rather than adding to the shaft_oversize value in a screw specification.
|
||||
// head_undersize = amount to decrease the head diameter of the screw; replaces rather than adding to the head_oversize value in a screw specification.
|
||||
// bevel1 = bevel bottom end of screw. Default: true
|
||||
// bevel2 = bevel top end of threaded section. Default: true for headless, false otherwise
|
||||
// bevel2 = bevel top end of threaded section. Default: true for fully threaded or unthreaded headless, false otherwise
|
||||
// bevel = bevel both ends of the threaded section.
|
||||
// higbee = if true create blunt start threads at both ends for headless screws, and bottom only for other screws. Default: false
|
||||
// blunt_start = if true and hole is threaded, create blunt start threads. Default: true
|
||||
// blunt_start1 = if true and hole is threaded, create blunt start threads at bottom end.
|
||||
// blunt_start2 = if true and hole is threaded, create blunt start threads top end.
|
||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
||||
// anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
|
@ -426,7 +428,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc
|
|||
// $fn=32;
|
||||
// projection(cut=true)xrot(-90){
|
||||
// screw("1/4-20,3/8", head="hex",orient=UP,anchor=BOTTOM,tolerance="1A");
|
||||
// down(INCH*1/20*1.395) nut("1/4-20", thickness=8, nutwidth=0.5*INCH, tolerance="1B");
|
||||
// down(INCH*1/20*1.5) nut("1/4-20", thickness=8, nutwidth=0.5*INCH, tolerance="1B");
|
||||
// }
|
||||
// Example: Here is a screw with nonstandard threading and a weird head size, which we create by modifying the screw structure:
|
||||
// spec = screw_info("M6x2,12",head="socket");
|
||||
|
@ -517,19 +519,19 @@ function _nominal_diam(spec) = struct_val(spec,"diameter")+default(struct_val(sp
|
|||
function screw(spec, head, drive, thread, drive_size,
|
||||
length, l, thread_len, tolerance, details=true,
|
||||
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,
|
||||
bevel,bevel1,bevel2,bevelsize,
|
||||
higbee=false,
|
||||
_internal=false, _counterbore, _teardrop) = no_function("screw");
|
||||
|
||||
blunt_start,blunt_start1, blunt_start2,
|
||||
_internal=false, _counterbore, _teardrop=false)
|
||||
= no_function("screw");
|
||||
module screw(spec, head, drive, thread, drive_size,
|
||||
length, l, thread_len, tolerance, details=true,
|
||||
undersize, shaft_undersize, head_undersize,
|
||||
atype="screw",anchor, spin=0, orient=UP,
|
||||
_shoulder_diam=0, _shoulder_len=0,
|
||||
bevel,bevel1,bevel2,bevelsize,
|
||||
higbee,
|
||||
blunt_start,blunt_start1, blunt_start2,
|
||||
_internal=false, _counterbore, _teardrop=false)
|
||||
{
|
||||
tempspec = _get_spec(spec, "screw_info", _internal ? "screw_hole" : "screw",
|
||||
|
@ -587,6 +589,9 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
: (struct_val(spec,"head_size_sharp")+struct_val(spec,"head_oversize",0)-d_major)/2/tan(struct_val(spec,"head_angle")/2);
|
||||
flat_cbore_height = flathead && is_num(counterbore) ? counterbore : 0;
|
||||
|
||||
blunt_start1 = first_defined([blunt_start1,blunt_start,true]);
|
||||
blunt_start2 = first_defined([blunt_start2,blunt_start,true]);
|
||||
|
||||
shoulder_adj = _shoulder_len>0 ? flat_height:0; // Adjustment because flathead height doesn't count toward shoulder length
|
||||
shoulder_full = _shoulder_len==0 ? 0 : _shoulder_len + flat_height;
|
||||
shank_len = is_def(user_thread_len) ? length - user_thread_len - (_shoulder_len==0?flat_height:0) : 0;
|
||||
|
@ -649,6 +654,8 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
: is_def(vnf) ? undef
|
||||
: head_height+flat_height+flat_cbore_height;
|
||||
bevelsize = default(bevelsize, d_major/12);
|
||||
bevel1 = first_defined([bevel1,bevel,true]);
|
||||
bevel2 = first_defined([bevel2,bevel,headless && _shoulder_len==0 && shank_len==0]);
|
||||
attachable(
|
||||
vnf = vnf,
|
||||
d = u_add(u_mul(attach_d, rad_scale), islop),
|
||||
|
@ -673,8 +680,16 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
if (shank_len>0 || pitch==0){
|
||||
L = pitch==0 ? length - (_shoulder_len==0?flat_height:0) : shank_len;
|
||||
bevsize = (_internal ? -1 : 1)*bevelsize;
|
||||
bev1 = details && pitch==0 && first_defined([bevel1,bevel,!_internal]) ? bevsize : 0;
|
||||
bev2 = details && pitch==0 && first_defined([bevel2,bevel,headless && !_internal]) ? bevsize : 0;
|
||||
bev1 = pitch!=0 ? 0
|
||||
: bevel1==true ? bevsize
|
||||
: bevel1==false ? 0
|
||||
: bevel1=="reverse" ? -bevsize
|
||||
: bevel1;
|
||||
bev2 = pitch!=0 ? 0
|
||||
: bevel2==true ? bevsize
|
||||
: bevel2==false ? 0
|
||||
: bevel2=="reverse" ? -bevsize
|
||||
: bevel2;
|
||||
down(_shoulder_len+flat_height-eps_shank)
|
||||
if (_teardrop)
|
||||
teardrop(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=FRONT, orient=BACK, $fn=sides, chamfer1=bev1, chamfer2=bev2);
|
||||
|
@ -682,18 +697,15 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
cyl(d=d_major*rad_scale+islop, h=L+eps_shank, anchor=TOP, $fn=sides, chamfer1=bev1, chamfer2=bev2);
|
||||
}
|
||||
if (thread_len>0 && pitch>0){
|
||||
bev1 = details && first_defined([bevel1,bevel,!_internal]);
|
||||
bev2 = details && first_defined([bevel2,bevel,!_internal && (flathead || _shoulder_len>0 || headless)]);
|
||||
down(_shoulder_len+flat_height+shank_len-eps_thread)
|
||||
threaded_rod([mean(struct_val(threadspec, "d_minor")),
|
||||
mean(struct_val(threadspec, "d_pitch")),
|
||||
d_major],
|
||||
pitch = struct_val(threadspec, "pitch"),
|
||||
l=thread_len+eps_thread, left_handed=false, internal=_internal,
|
||||
bevel1=bev1,
|
||||
bevel2=bev2,
|
||||
higbee1=higbee && !_internal,
|
||||
higbee2=(!headless && !_internal) || is_undef(higbee) ? false : higbee,
|
||||
bevel1=bevel1,
|
||||
bevel2=bevel2,
|
||||
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
|
||||
$fn=sides, anchor=TOP);
|
||||
}
|
||||
|
||||
|
@ -706,13 +718,12 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
|
||||
|
||||
|
||||
|
||||
// Module: screw_hole()
|
||||
// Synopsis: Creates a screw hole.
|
||||
// Topics: Threading, Screws
|
||||
// See Also: screw()
|
||||
// Usage:
|
||||
// screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
|
||||
// screw_hole([spec], [head], [thread=], [length=|l=], [oversize=], [hole_oversize=], [teardrop=], [head_oversize], [tolerance=], [$slop=], [blunt_start=], [anchor=], [atype=], [orient=], [spin=]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Create a screw hole mask. See [screw and nut parameters](#section-screw-and-nut-parameters) for details on the parameters that define a screw.
|
||||
// The screw hole can be threaded to receive a screw or it can be an unthreaded clearance hole.
|
||||
|
@ -760,7 +771,9 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
// bevel = if true create bevel at both ends of hole. Default: see below
|
||||
// bevel1 = if true create bevel at bottom end of hole. Default: false
|
||||
// bevel2 = if true create bevel at top end of hole. Default: true when tolerance="self tap", false otherwise
|
||||
// higbee = if true and hole is threaded, create blunt start threads at the top of the hole. Default: false
|
||||
// blunt_start = if true and hole is threaded, create blunt start threads. Default: true
|
||||
// blunt_start1 = if true and hole is threaded, create blunt start threads at bottom end.
|
||||
// blunt_start2 = if true and hole is threaded, create blunt start threads top end.
|
||||
// $slop = add extra gap to account for printer overextrusion. Default: 0
|
||||
// atype = anchor type, one of "screw", "head", "shaft", "threads", "shank"
|
||||
// anchor = Translate so anchor point on the shaft is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -800,14 +813,20 @@ module screw(spec, head, drive, thread, drive_size,
|
|||
// cuboid(20)
|
||||
// attach(TOP)
|
||||
// screw_hole("1/4-20,.5",head="flat",counterbore=0,anchor=TOP);
|
||||
// Example: Threaded hole
|
||||
// diff()
|
||||
// cuboid(20)
|
||||
// attach(FRONT)
|
||||
// screw_hole("M16,15",anchor=TOP,thread=true);
|
||||
// Example: Threaded hole, with inward bevel at the base
|
||||
// bottom_half()
|
||||
// diff()
|
||||
// cuboid(20)
|
||||
// attach(FRONT)
|
||||
// screw_hole("M16,15",anchor=TOP,thread=true,bevel1="reverse");
|
||||
function screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||
length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
|
||||
bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2,
|
||||
atype="screw",anchor=CENTER,spin=0, orient=UP)
|
||||
= no_function("screw_hole");
|
||||
module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
||||
length, l, thread_len, tolerance=undef, counterbore, teardrop=false,
|
||||
bevel, bevel1, bevel2, higbee=false,
|
||||
bevel, bevel1, bevel2, blunt_start, blunt_start1, blunt_start2,
|
||||
atype="screw",anchor=CENTER,spin=0, orient=UP)
|
||||
{
|
||||
screwspec = _get_spec(spec, "screw_info", "screw_hole",
|
||||
|
@ -826,9 +845,10 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
|||
head_oversize = first_defined([head_oversize, oversize[1],struct_val(screwspec,"head_oversize")]);
|
||||
if (threaded || is_def(hole_oversize) || tolerance==0 || tolerance=="none") {
|
||||
default_tag("remove")
|
||||
screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize), higbee=higbee,
|
||||
screw(spec,head=head,thread=thread,shaft_undersize=u_mul(-1,hole_oversize), head_undersize=u_mul(-1,head_oversize),
|
||||
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
|
||||
length=length,l=l,thread_len=thread_len, tolerance=tolerance, _counterbore=counterbore,
|
||||
bevel=bevel, bevel1=bevel1, bevel2=bevel2,
|
||||
bevel1=bevel1, bevel2=bevel2,
|
||||
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
||||
children();
|
||||
}
|
||||
|
@ -949,7 +969,7 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
|||
default_tag("remove")
|
||||
screw(spec,head=head,thread=0,shaft_undersize=-hole_oversize, head_undersize=-head_oversize,
|
||||
length=length,l=l,thread_len=thread_len, _counterbore=counterbore,
|
||||
bevel=bevel, bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef, higbee=higbee,
|
||||
bevel1=bevel1, bevel2=bevel2, bevelsize=pitch>0?pitch:undef,
|
||||
atype=atype, anchor=anchor, spin=spin, orient=orient, _internal=true, _teardrop=teardrop)
|
||||
children();
|
||||
}
|
||||
|
@ -1033,8 +1053,13 @@ module screw_hole(spec, head, thread, oversize, hole_oversize, head_oversize,
|
|||
// shoulder_screw("iso", 16, length=20, head="none");
|
||||
// Example: Changing head height
|
||||
// shoulder_screw("iso", 16, length=20, head_size=[24,5]);
|
||||
function shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread,
|
||||
undersize, shaft_undersize, head_undersize, shoulder_undersize=0,
|
||||
blunt_start, blunt_start1, blunt_start2,
|
||||
atype="screw", anchor=BOT, orient,spin) = no_function("shoulder_screw");
|
||||
module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive, drive_size, thread,
|
||||
undersize, shaft_undersize, head_undersize, shoulder_undersize=0,
|
||||
undersize, shaft_undersize, head_undersize, shoulder_undersize=0,
|
||||
blunt_start, blunt_start1, blunt_start2,
|
||||
atype="screw", anchor=BOT, orient,spin)
|
||||
{
|
||||
d1= assert(is_num(d) && d>0, "Must specify shoulder diameter")
|
||||
|
@ -1129,6 +1154,7 @@ module shoulder_screw(s,d,length,head, thread_len, tolerance, head_size, drive,
|
|||
screw(struct_set(info, headfields),
|
||||
_shoulder_len = length, _shoulder_diam = shoulder_diam-shoulder_tol,
|
||||
length=thread_len, tolerance=tolerance, shaft_undersize=shaft_undersize, head_undersize=head_undersize,
|
||||
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
|
||||
atype=atype, anchor=anchor, orient=orient, spin=spin)
|
||||
children();
|
||||
}
|
||||
|
@ -1499,9 +1525,9 @@ module screw_head(screw_info,details=false, counterbore=0,flat_height,teardrop=f
|
|||
// ibevel = if true, bevel the inside (the hole). Default: true
|
||||
// ibevel1 = if true bevel the inside, bottom end.
|
||||
// ibevel2 = if true bevel the inside, top end.
|
||||
// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
|
||||
// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
|
||||
// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
|
||||
// blunt_start = If true apply truncated blunt start threads at both ends. Default: true
|
||||
// blunt_start1 = If true apply truncated blunt start threads bottom end.
|
||||
// blunt_start2 = If true apply truncated blunt start threads top end.
|
||||
// tolerance = nut tolerance. Determines actual nut thread geometry based on nominal sizing. See [tolerance](#subsection-tolerance). Default is "2B" for UTS and "6H" for ISO.
|
||||
// $slop = extra space left to account for printing over-extrusion. Default: 0
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
|
@ -1550,7 +1576,7 @@ function nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
|||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
= no_function("nut");
|
||||
module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2, higbee, higbee1, higbee2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
bevel,bevel1,bevel2,bevang=15,ibevel,ibevel1,ibevel2,blunt_start, blunt_start1, blunt_start2, anchor=BOTTOM, spin=0, orient=UP, oversize=0)
|
||||
{
|
||||
dummyA = assert(is_undef(nutwidth) || (is_num(nutwidth) && nutwidth>0));
|
||||
|
||||
|
@ -1578,11 +1604,15 @@ module nut(spec, shape, thickness, nutwidth, thread, tolerance, hole_oversize,
|
|||
shape=shape,
|
||||
bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang,
|
||||
ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
|
||||
higbee=higbee, higbee1=higbee1, higbee2=higbee2,
|
||||
blunt_start=blunt_start, blunt_start1=blunt_start1, blunt_start2=blunt_start2,
|
||||
anchor=anchor,spin=spin,orient=orient) children();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Module: nut_trap_side()
|
||||
// Synopsis: Creates a side nut trap mask.
|
||||
// Topics: Threading, Screws
|
||||
|
|
250
skin.scad
250
skin.scad
|
@ -1053,132 +1053,140 @@ module rotate_sweep(
|
|||
// Takes a closed 2D polygon path, centered on the XY plane, and sweeps/extrudes it along a 3D spiral path
|
||||
// of a given radius, height and degrees of rotation. The origin in the profile traces out the helix of the specified radius.
|
||||
// If turns is positive the path will be right-handed; if turns is negative the path will be left-handed.
|
||||
// Such an extrusion can be used to make screw threads.
|
||||
// .
|
||||
// The taper options specify tapering at of the ends of the extrusion, and are given as the linear distance
|
||||
// over which to taper. If taper is positive the extrusion lengthened by the specified distance; if taper
|
||||
// is negative, the taper is included in the extrusion length specified by `turns`.
|
||||
// The lead_in options specify a lead-in setiton where the ends of the spiral scale down to avoid a sharp cut face at the ends.
|
||||
// You can specify the length of this scaling directly with the lead_in parameters or as an angle using the lead_in_ang parameters.
|
||||
// If you give a positive value, the extrusion is lengthenend by the specified distance or angle; if you give a negative
|
||||
// value then the scaled end is included in the extrusion length specified by `turns`. If the value is zero then no scaled ends
|
||||
// are produced. The shape of the scaled ends can be controlled with the lead_in_shape parameter. Supported options are "sqrt", "linear"
|
||||
// "smooth" and "cut".
|
||||
// .
|
||||
// The inside argument changes how the extrusion lead-in sections are formed. If it is true then they scale
|
||||
// towards the outside, like would be needed for internal threading. If internal is fale then the lead-in sections scale
|
||||
// towards the inside, like would be appropriate for external threads.
|
||||
// Arguments:
|
||||
// poly = Array of points of a polygon path, to be extruded.
|
||||
// h = height of the spiral to extrude along.
|
||||
// r = Radius of the spiral to extrude along.
|
||||
// turns = number of revolutions to spiral up along the height.
|
||||
// h = height of the spiral extrusion path
|
||||
// r = Radius of the spiral extrusion path
|
||||
// turns = number of revolutions to include in the spiral
|
||||
// ---
|
||||
// d = Diameter of the spiral to extrude along.
|
||||
// d = Diameter of the spiral extrusion path.
|
||||
// d1/r1 = Bottom inside diameter or radius of spiral to extrude along.
|
||||
// d2/r2 = Top inside diameter or radius of spiral to extrude along.
|
||||
// taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0
|
||||
// taper1 = Length of taper for bottom thread end
|
||||
// taper2 = Length of taper for top thread end
|
||||
// internal = if true make internal threads. The only effect this has is to change how the extrusion tapers if tapering is selected. When true, the extrusion tapers towards the outside; when false, it tapers towards the inside. Default: false
|
||||
// lead_in = Specify linear length of the lead-in scaled section of the spiral. Default: 0
|
||||
// lead_in1 = Specify linear length of the lead-in scaled section of the spiral at the bottom
|
||||
// lead_in2 = Specify linear length of the lead-in scaled section of the spiral at the top
|
||||
// lead_in_ang = Specify angular length of the lead-in scaled section of the spiral
|
||||
// lead_in_ang1 = Specify angular length of the lead-in scaled section of the spiral at the bottom
|
||||
// lead_in_ang2 = Specify angular length of the lead-in scaled section of the spiral at the top
|
||||
// lead_in_shape = Specify the shape of the thread lead in by giving a text string or function. Default: "sqrt"
|
||||
// lead_in_shape1 = Specify the shape of the thread lead-in at the bottom by giving a text string or function.
|
||||
// lead_in_shape2 = Specify the shape of the thread lead-in at the top by giving a text string or function.
|
||||
// lead_in_sample = Factor to increase sample rate in the lead-in section. Default: 10
|
||||
// internal = if true make internal threads. The only effect this has is to change how the extrusion lead-in section are formed. When true, the extrusion scales towards the outside; when false, it scales towards the inside. Default: false
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=BOTTOM`.
|
||||
// See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep()
|
||||
// See Also: sweep(), linear_sweep(), rotate_sweep(), path_sweep(), thread_helix()
|
||||
// Example:
|
||||
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
|
||||
// spiral_sweep(poly, h=200, r=50, turns=3, $fn=36);
|
||||
function _taperfunc_orig_1d(x,L) =
|
||||
x>1 ? 1 : x<0 ? 0:
|
||||
let(
|
||||
higofs = pow(0.05,2) // Smallest hig scale is the square root of this value
|
||||
)
|
||||
sqrt((1-higofs)*x+higofs);
|
||||
|
||||
function _taperfunc_orig(x,L) =
|
||||
let(s=_taperfunc_orig_1d(x))
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
|
||||
: [lerp(s,1,.25),s];
|
||||
function _taperfunc_ellipse(x) =
|
||||
sqrt(1-(1-x)^2);
|
||||
function _taperfunc_linear(x) =
|
||||
x>1 ? 1 : x<0 ? 0 : x;
|
||||
function _taperfunc_ogive_width(x,L) =
|
||||
let( minscale = .2,
|
||||
_leadin_ogive=function (x,L)
|
||||
let( minscale = .05,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [scale,1];
|
||||
function _taperfunc_ogive_width_circle(x,L,h) =
|
||||
let( minscale = .2,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1),
|
||||
vscale = x*L>h ? h : sqrt(h^2-(x*L-h)^2)
|
||||
)
|
||||
: x<0 ? [lerp(minscale,1,.25),0]
|
||||
: [lerp(scale,1,.25),scale];
|
||||
|
||||
_leadin_cut = function(x,L) x>0 ? [1,1] : [1,0];
|
||||
|
||||
_leadin_sqrt = function(x,L)
|
||||
let(end=0.05) // Smallest scale at the end
|
||||
x>1 ? [1,1]
|
||||
: x<0.02 ? [0,0]
|
||||
: [scale,vscale/h];
|
||||
function _taperfunc_ogive_height(x,L) =
|
||||
let( minscale = .1,L=3*L,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
: x<0 ? [lerp(end,1,.25),0]
|
||||
: let(
|
||||
s = sqrt(x + end^2 * (1-x))
|
||||
)
|
||||
[lerp(s,1,.25),s]; // thread width scale, thread height scale
|
||||
|
||||
_leadin_linear = function(x,L)
|
||||
let(minscale=.1)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0] //minscale,0]
|
||||
: [1,scale];
|
||||
function _taperfunc_ogive(x,L) =
|
||||
let( minscale = .3,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [scale,scale];
|
||||
function _taperfunc_ogive_orig(x,L) =
|
||||
let( minscale = .3,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [lerp(_taperfunc_orig_1d(x),1,.25),scale];
|
||||
|
||||
function _taperfunc_cut(x,L) = x>1 ? [1,1] : [0,0];
|
||||
|
||||
|
||||
function _taperfunc(x,L,h) = _taperfunc_ogive_width_circle(x,L,h);
|
||||
//function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
|
||||
//function _taperfunc(x,L,h) = _taperfunc_ogive_width(x,L);
|
||||
function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
|
||||
|
||||
: x<0 ? [lerp(minscale,1,.25),0]
|
||||
: let(scale = lerp(minscale,1,x))
|
||||
[lerp(scale,1,.25),scale];
|
||||
|
||||
_lead_in_table = [
|
||||
["default", _leadin_sqrt],
|
||||
["sqrt", _leadin_sqrt],
|
||||
["cut", _leadin_cut],
|
||||
["smooth", _leadin_ogive],
|
||||
["linear", _leadin_linear]
|
||||
];
|
||||
|
||||
|
||||
function _ss_polygon_r(N,theta) =
|
||||
let( alpha = 360/N )
|
||||
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
||||
function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) =
|
||||
function spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false,
|
||||
lead_in_shape,lead_in_shape1, lead_in_shape2,
|
||||
lead_in, lead_in1, lead_in2,
|
||||
lead_in_ang, lead_in_ang1, lead_in_ang2,
|
||||
height,l,length,
|
||||
lead_in_sample = 10,
|
||||
anchor=CENTER, spin=0, orient=UP) =
|
||||
assert(is_num(turns) && turns != 0, "turns must be a nonzero number")
|
||||
assert(all_positive([h]), "Spiral height must be a positive number")
|
||||
let(
|
||||
tapersample = 10, // Oversample factor for higbee tapering
|
||||
dir = sign(turns),
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50),
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50),
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d),
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d),
|
||||
bounds = pointlist_bounds(poly),
|
||||
yctr = (bounds[0].y+bounds[1].y)/2,
|
||||
xmin = bounds[0].x,
|
||||
xmax = bounds[1].x,
|
||||
poly = path3d(clockwise_polygon(poly)),
|
||||
anchor = get_anchor(anchor,center,BOT,BOT),
|
||||
sides = segs(max(r1,r2)),
|
||||
ang_step = 360/sides,
|
||||
turns = abs(turns),
|
||||
taper1 = first_defined([taper1, taper, 0]),
|
||||
taper2 = first_defined([taper2, taper, 0]),
|
||||
taperang1 = 360 * abs(taper1) / (2 * r1 * PI),
|
||||
taperang2 = 360 * abs(taper2) / (2 * r2 * PI),
|
||||
minang = taper1<=0 ? 0 : -taperang1,
|
||||
tapercut1 = taper1<=0 ? taperang1 : 0,
|
||||
maxang = taper2<=0 ? 360*turns : 360*turns+taperang2,
|
||||
tapercut2 = taper2<=0 ? 360*turns-taperang2 : 360*turns
|
||||
lead_in1 = first_defined([lead_in1, lead_in]),
|
||||
lead_in2 = first_defined([lead_in1, lead_in]),
|
||||
lead_in_ang1 =
|
||||
let(
|
||||
user_ang = first_defined([lead_in_ang1,lead_in_ang])
|
||||
)
|
||||
assert(is_undef(user_ang) || is_undef(lead_in1), "Cannot define lead_in/lead_in1 by both length and angle")
|
||||
is_def(user_ang) ? user_ang : default(lead_in1,0)*360/(2*PI*r1),
|
||||
lead_in_ang2 =
|
||||
let(
|
||||
user_ang = first_defined([lead_in_ang2,lead_in_ang])
|
||||
)
|
||||
assert(is_undef(user_ang) || is_undef(lead_in2), "Cannot define lead_in/lead_in2 by both length and angle")
|
||||
is_def(user_ang) ? user_ang : default(lead_in2,0)*360/(2*PI*r2),
|
||||
minang = -max(0,lead_in_ang1),
|
||||
maxang = 360*turns + max(0,lead_in_ang2),
|
||||
cut_ang1 = minang+abs(lead_in_ang1),
|
||||
cut_ang2 = maxang-abs(lead_in_ang1),
|
||||
lead_in_shape1 = first_defined([lead_in_shape1, lead_in_shape, "default"]),
|
||||
lead_in_shape2 = first_defined([lead_in_shape2, lead_in_shape, "default"]),
|
||||
lead_in_func1 = is_func(lead_in_shape1) ? lead_in_shape1
|
||||
: assert(is_string(lead_in_shape1),"lead_in_shape/lead_in_shape1 must be a function or string")
|
||||
let(ind = search([lead_in_shape1], _lead_in_table,0)[0])
|
||||
assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape1,"\""))
|
||||
_lead_in_table[ind[0]][1],
|
||||
lead_in_func2 = is_func(lead_in_shape2) ? lead_in_shape2
|
||||
: assert(is_string(lead_in_shape2),"lead_in_shape/lead_in_shape2 must be a function or string")
|
||||
let(ind = search([lead_in_shape2], _lead_in_table,0)[0])
|
||||
assert(ind!=[],str("Unknown lead_in_shape, \"",lead_in_shape2,"\""))
|
||||
_lead_in_table[ind[0]][1]
|
||||
)
|
||||
assert( tapercut1<tapercut2 && tapercut1<maxang, "Tapers are too long to fit")
|
||||
assert( cut_ang1<cut_ang2, "Tapers are too long to fit")
|
||||
assert( all_positive([r1,r2]), "Diameter/radius must be positive")
|
||||
let(
|
||||
|
||||
// This complicated sampling scheme is designed to ensure that faceting always starts at angle zero
|
||||
// for alignment with cylinders, and there is always a facet boundary at the $fn specified locations,
|
||||
// regardless of what kind of subsampling occurs for tapers.
|
||||
|
@ -1189,17 +1197,17 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
|
|||
maxang
|
||||
],
|
||||
anglist = [
|
||||
for(a=orig_anglist) if (a<tapercut1-EPSILON) a,
|
||||
tapercut1,
|
||||
for(a=orig_anglist) if (a>tapercut1+EPSILON && a<tapercut2-EPSILON) a,
|
||||
tapercut2,
|
||||
for(a=orig_anglist) if (a>tapercut2+EPSILON) a
|
||||
for(a=orig_anglist) if (a<cut_ang1-EPSILON) a,
|
||||
cut_ang1,
|
||||
for(a=orig_anglist) if (a>cut_ang1+EPSILON && a<cut_ang2-EPSILON) a,
|
||||
cut_ang2,
|
||||
for(a=orig_anglist) if (a>cut_ang2+EPSILON) a
|
||||
],
|
||||
interp_ang = [
|
||||
for(i=idx(anglist,e=-2))
|
||||
for(i=idx(anglist,e=-2))
|
||||
each lerpn(anglist[i],anglist[i+1],
|
||||
(taper1!=0 && anglist[i+1]<=tapercut1) || (taper2!=0 && anglist[i]>=tapercut2)
|
||||
? ceil((anglist[i+1]-anglist[i])/ang_step*tapersample)
|
||||
(lead_in_ang1!=0 && anglist[i+1]<=cut_ang1) || (lead_in_ang2!=0 && anglist[i]>=cut_ang2)
|
||||
? ceil((anglist[i+1]-anglist[i])/ang_step*lead_in_sample)
|
||||
: 1,
|
||||
endpoint=false),
|
||||
last(anglist)
|
||||
|
@ -1207,8 +1215,8 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
|
|||
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)),
|
||||
points = [
|
||||
for (a = interp_ang) let (
|
||||
hsc = a<tapercut1 ? _taperfunc((a-minang)/taperang1,abs(taper1),xmax-xmin)
|
||||
: a>tapercut2 ? _taperfunc((maxang-a)/taperang2,abs(taper2),xmax-xmin)
|
||||
hsc = a<cut_ang1 ? lead_in_func1((a-minang)/abs(lead_in_ang1),abs(lead_in_ang1)*2*PI*r1/360)
|
||||
: a>cut_ang2 ? lead_in_func2((maxang-a)/abs(lead_in_ang2),abs(lead_in_ang2)*2*PI*r2/360)
|
||||
: [1,1],
|
||||
u = a/(360*turns),
|
||||
r = lerp(r1,r2,u),
|
||||
|
@ -1230,15 +1238,30 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
|
|||
|
||||
|
||||
|
||||
module spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) {
|
||||
vnf = spiral_sweep(poly, h, r, turns, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal);
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=50);
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=50);
|
||||
taper1 = first_defined([taper1,taper,0]);
|
||||
taper2 = first_defined([taper2,taper,0]);
|
||||
extra = PI/2*(max(0,taper1/r1)+max(0,taper2/r2));
|
||||
module spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=false,
|
||||
lead_in_shape,lead_in_shape1, lead_in_shape2,
|
||||
lead_in, lead_in1, lead_in2,
|
||||
lead_in_ang, lead_in_ang1, lead_in_ang2,
|
||||
height,l,length,
|
||||
lead_in_sample=10,
|
||||
anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
vnf = spiral_sweep(poly=poly, h=h, r=r, turns=turns, r1=r1, r2=r2, d=d, d1=d1, d2=d2, internal=internal,
|
||||
lead_in_shape=lead_in_shape,lead_in_shape1=lead_in_shape1, lead_in_shape2=lead_in_shape2,
|
||||
lead_in=lead_in, lead_in1=lead_in1, lead_in2=lead_in2,
|
||||
lead_in_ang=lead_in_ang, lead_in_ang1=lead_in_ang1, lead_in_ang2=lead_in_ang2,
|
||||
height=height,l=length,length=length,
|
||||
lead_in_sample=lead_in_sample);
|
||||
h = one_defined([h,height,length,l],"h,height,length,l");
|
||||
r1 = get_radius(r1=r1, r=r, d1=d1, d=d);
|
||||
r2 = get_radius(r1=r2, r=r, d1=d2, d=d);
|
||||
lead_in1 = u_mul(first_defined([lead_in1,lead_in]),1/(2*PI*r1));
|
||||
lead_in2 = u_mul(first_defined([lead_in2,lead_in]),1/(2*PI*r2));
|
||||
lead_in_ang1 = first_defined([lead_in_ang1,lead_in_ang]);
|
||||
lead_in_ang2 = first_defined([lead_in_ang2,lead_in_ang]);
|
||||
extra_turns = max(0,first_defined([lead_in1,lead_in_ang1,0]))+max(0,first_defined([lead_in2,lead_in_ang2,0]));
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
||||
vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra)));
|
||||
vnf_polyhedron(vnf, convexity=ceil(2*(abs(turns)+extra_turns)));
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
@ -1796,7 +1819,22 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
)
|
||||
assert(approx(ynormal*znormal,0),str("Supplied normal is parallel to the path tangent at point ",i))
|
||||
translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i])
|
||||
]
|
||||
]
|
||||
: method=="cross"?
|
||||
let(
|
||||
crossnormal_mid = [for(i=[(closed?0:1):L-(closed?1:2)])
|
||||
let(v= cross( select(path,i+1)-path[i], path[i]-select(path,i-1)),
|
||||
f=assert(norm(v)>EPSILON)
|
||||
)
|
||||
v
|
||||
],
|
||||
crossnormal = closed ? crossnormal_mid : [crossnormal_mid[0], each crossnormal_mid, last(crossnormal_mid)]
|
||||
)
|
||||
[for(i=[0:L-(closed?0:1)]) let(
|
||||
rotation = frame_map(x=crossnormal[i%L], z=tangents[i%L])
|
||||
)
|
||||
translate(path[i%L])*rotation*zrot(-twist*tpathfrac[i])
|
||||
]
|
||||
: method=="natural" ? // map x axis of shape to the path normal, which points in direction of curvature
|
||||
let (pathnormal = path_normals(path, tangents, closed))
|
||||
assert(all_defined(pathnormal),"Natural normal vanishes on your curve, select a different method")
|
||||
|
|
949
threading.scad
949
threading.scad
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue