mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
add attachable to bottlecaps & mutators
This commit is contained in:
parent
25aef90fc7
commit
1bee8c96f9
3 changed files with 418 additions and 352 deletions
127
bottlecaps.scad
127
bottlecaps.scad
|
@ -443,15 +443,17 @@ module generic_bottle_neck(
|
|||
diamMagMult = neck_d / 26.19;
|
||||
heightMagMult = height / 17.00;
|
||||
|
||||
assert(all_nonnegative([support_d]),"support_d must be a nonnegative number");
|
||||
sup_r = 0.30 * (heightMagMult > 1 ? heightMagMult : 1);
|
||||
support_r = floor(((supp_d == neck_d) ? sup_r : min(sup_r, (supp_d - neck_d) / 2)) * 5000) / 10000;
|
||||
support_rad = (wall == undef || !round_supp) ? support_r :
|
||||
min(support_r, floor((supp_d - (inner_d + 2 * wall)) * 5000) / 10000);
|
||||
//Too small of a radius will cause errors with the arc, this limits granularity to .0001mm
|
||||
support_width = 1 * (heightMagMult > 1 ? heightMagMult : 1) * sign(support_d);
|
||||
support_width = max(heightMagMult,1) * sign(support_d);
|
||||
roundover = 0.58 * diamMagMult;
|
||||
lip_roundover_r = (roundover > (neck_d - inner_d) / 2) ? 0 : roundover;
|
||||
h = height + support_width;
|
||||
echo(h=h);
|
||||
threadbase_d = neck_d - 0.8 * diamMagMult;
|
||||
|
||||
$fn = segs(33 / 2);
|
||||
|
@ -459,7 +461,7 @@ module generic_bottle_neck(
|
|||
anchors = [
|
||||
named_anchor("support-ring", [0, 0, 0 - h / 2])
|
||||
];
|
||||
attachable(anchor, spin, orient, d1 = neck_d, d2 = 0, l = h, anchors = anchors) {
|
||||
attachable(anchor, spin, orient, d = neck_d, l = h, anchors = anchors) {
|
||||
down(h / 2) {
|
||||
rotate_extrude(convexity = 10) {
|
||||
polygon(turtle(
|
||||
|
@ -555,7 +557,7 @@ module generic_bottle_cap(
|
|||
wall = 2,
|
||||
texture = "none",
|
||||
height = 11.2,
|
||||
thread_od = 28.58,
|
||||
thread_depth = 2.34,
|
||||
tolerance = .2,
|
||||
neck_od = 25.5,
|
||||
flank_angle = 15,
|
||||
|
@ -565,11 +567,10 @@ module generic_bottle_cap(
|
|||
orient = UP
|
||||
) {
|
||||
$fn = segs(33 / 2);
|
||||
threadOuterDTol = thread_od + 2 * tolerance;
|
||||
w = threadOuterDTol + 2 * wall;
|
||||
threadOuterDTol = neck_od + 2*(thread_depth - 0.8) + 2 * tolerance; // WTF; Engineered for consistency with old code, but
|
||||
w = threadOuterDTol + 2 * wall; // no clue why this was chosen
|
||||
h = height + wall;
|
||||
neckOuterDTol = neck_od + 2 * tolerance;
|
||||
threadDepth = (thread_od - neck_od) / 2 + .8;
|
||||
|
||||
diamMagMult = (w > 32.58) ? w / 32.58 : 1;
|
||||
heightMagMult = (height > 11.2) ? height / 11.2 : 1;
|
||||
|
@ -596,8 +597,8 @@ 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), lead_in = -threadDepth, internal = true, anchor = BOTTOM);
|
||||
thread_helix(d = neckOuterDTol, pitch = pitch, thread_depth = thread_depth, flank_angle = flank_angle,
|
||||
turns = ((height - pitch) / pitch), lead_in = -thread_depth, internal = true, anchor = BOTTOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +627,7 @@ function generic_bottle_cap(
|
|||
// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
|
||||
// cap_wall = Wall thickness of the cap in mm.
|
||||
// cap_h = Interior height of the cap in mm.
|
||||
// cap_thread_od = Outer diameter of cap threads in mm.
|
||||
// cap_thread_depth = Cap thread depth. Default: 2.34
|
||||
// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius.
|
||||
// cap_neck_od = Inner diameter of the cap threads.
|
||||
// cap_neck_id = Inner diameter of the hole through the cap.
|
||||
|
@ -640,6 +641,9 @@ function generic_bottle_cap(
|
|||
// neck_support_od = Outer diameter of neck support ring. Leave undefined to set equal to OD of cap. Set to 0 for no ring. Default: undef
|
||||
// d = Distance between bottom of neck and top of cap
|
||||
// taper_lead_in = Length to leave straight before tapering on tube between neck and cap if exists.
|
||||
// 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`
|
||||
// Examples:
|
||||
// bottle_adapter_neck_to_cap();
|
||||
module bottle_adapter_neck_to_cap(
|
||||
|
@ -647,7 +651,7 @@ module bottle_adapter_neck_to_cap(
|
|||
texture = "none",
|
||||
cap_wall = 2,
|
||||
cap_h = 11.2,
|
||||
cap_thread_od = 28.58,
|
||||
cap_thread_depth = 2.34,
|
||||
tolerance = .2,
|
||||
cap_neck_od = 25.5,
|
||||
cap_neck_id,
|
||||
|
@ -660,16 +664,24 @@ module bottle_adapter_neck_to_cap(
|
|||
neck_thread_pitch = 3.2,
|
||||
neck_support_od,
|
||||
d = 0,
|
||||
taper_lead_in = 0
|
||||
taper_lead_in = 0, anchor, spin,orient
|
||||
) {
|
||||
neck_support_od = (neck_support_od == undef || (d == 0 && neck_support_od < cap_thread_od + 2 * tolerance)) ? cap_thread_od + 2 * (cap_wall + tolerance) : neck_support_od;
|
||||
cap_neck_id = (cap_neck_id == undef) ? neck_id : cap_neck_id;
|
||||
wall = (wall == undef) ? neck_support_od + neck_d + cap_thread_od + neck_id : wall;
|
||||
cap_od = cap_neck_od + 2*(cap_thread_depth - 0.8) + 2 * tolerance;
|
||||
neck_support_od = (neck_support_od == undef || (d == 0 && neck_support_od < cap_od)) ? cap_od+2*cap_wall
|
||||
: neck_support_od;
|
||||
cap_neck_id = default(cap_neck_id,neck_id);
|
||||
wall = default(wall, neck_support_od + neck_d + cap_od + neck_id - 2*tolerance);
|
||||
echo(wall=wall);
|
||||
|
||||
$fn = segs(33 / 2);
|
||||
wallt1 = min(wall, (max(neck_support_od, neck_d) - neck_id) / 2);
|
||||
wallt2 = min(wall, (cap_thread_od + 2 * (cap_wall + tolerance) - cap_neck_id) / 2);
|
||||
wallt2 = min(wall, (cap_od + 2 * cap_wall - cap_neck_id) / 2);
|
||||
|
||||
top_h = neck_h + max(1,neck_h/17)*sign(neck_support_od);
|
||||
echo(top_h=top_h);
|
||||
bot_h = cap_h + cap_wall;
|
||||
attachable(anchor=anchor,orient=orient,spin=spin, r=max([neck_id/2+wallt1, cap_neck_id/2+wallt2, neck_support_od/2]), h=top_h+bot_h+d) {
|
||||
zmove((bot_h-top_h)/2)
|
||||
difference(){
|
||||
union(){
|
||||
up(d / 2) {
|
||||
|
@ -680,7 +692,7 @@ module bottle_adapter_neck_to_cap(
|
|||
support_d = neck_support_od,
|
||||
pitch = neck_thread_pitch,
|
||||
round_supp = ((wallt1 < (neck_support_od - neck_id) / 2) && (d > 0 || neck_support_od > (cap_thread_od + 2 * (cap_wall + tolerance)))),
|
||||
wall = (d > 0) ? wallt1 : min(wallt1, ((cap_thread_od + 2 * (cap_wall + tolerance) - neck_id) / 2))
|
||||
wall = (d > 0) ? wallt1 : min(wallt1, ((cap_od + 2 * (cap_wall) - neck_id) / 2))
|
||||
);
|
||||
}
|
||||
if (d != 0) {
|
||||
|
@ -699,7 +711,7 @@ module bottle_adapter_neck_to_cap(
|
|||
generic_bottle_cap(wall = cap_wall,
|
||||
texture = texture,
|
||||
height = cap_h,
|
||||
thread_od = cap_thread_od,
|
||||
thread_depth = cap_thread_depth,
|
||||
tolerance = tolerance,
|
||||
neck_od = cap_neck_od,
|
||||
flank_angle = cap_thread_taper,
|
||||
|
@ -719,10 +731,12 @@ module bottle_adapter_neck_to_cap(
|
|||
]);
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
function bottle_adapter_neck_to_cap(
|
||||
wall, texture, cap_wall, cap_h, cap_thread_od,
|
||||
wall, texture, cap_wall, cap_h, cap_thread_depth1,
|
||||
tolerance, cap_neck_od, cap_neck_id, cap_thread_taper,
|
||||
cap_thread_pitch, neck_d, neck_id, neck_thread_od,
|
||||
neck_h, neck_thread_pitch, neck_support_od, d, taper_lead_in
|
||||
|
@ -734,53 +748,64 @@ function bottle_adapter_neck_to_cap(
|
|||
// Topics: Bottles, Threading
|
||||
// See Also: bottle_adapter_neck_to_cap(), bottle_adapter_neck_to_neck()
|
||||
// Usage:
|
||||
// bottle_adapter_cap_to_cap(wall, [texture]);
|
||||
// bottle_adapter_cap_to_cap(wall, [texture]) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a threaded cap to cap adapter.
|
||||
// Arguments:
|
||||
// wall = Wall thickness in mm.
|
||||
// texture = The surface texture of the cap. Valid values are "none", "knurled", or "ribbed". Default: "none"
|
||||
// cap_h1 = Interior height of top cap.
|
||||
// cap_thread_od1 = Outer diameter of threads on top cap.
|
||||
// cap_thread_depth1 = Thread depth on top cap. Default: 2.34
|
||||
// tolerance = Extra space to add to the outer diameter of threads and neck in mm. Applied to radius.
|
||||
// cap_neck_od1 = Inner diameter of threads on top cap.
|
||||
// cap_thread_pitch1 = Thread pitch of top cap in mm.
|
||||
// cap_h2 = Interior height of bottom cap. Leave undefined to duplicate cap_h1.
|
||||
// cap_thread_od2 = Outer diameter of threads on bottom cap. Leave undefined to duplicate capThread1.
|
||||
// cap_thread_depth2 = Thread depth on bottom cap. Default: same as cap_thread_depth1
|
||||
// cap_neck_od2 = Inner diameter of threads on top cap. Leave undefined to duplicate cap_neck_od1.
|
||||
// cap_thread_pitch2 = Thread pitch of bottom cap in mm. Leave undefinced to duplicate cap_thread_pitch1.
|
||||
// d = Distance between caps.
|
||||
// neck_id1 = Inner diameter of cutout in top cap.
|
||||
// neck_id2 = Inner diameter of cutout in bottom cap.
|
||||
// taper_lead_in = Length to leave straight before tapering on tube between caps if exists.
|
||||
// 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`
|
||||
// Examples:
|
||||
// bottle_adapter_cap_to_cap();
|
||||
module bottle_adapter_cap_to_cap(
|
||||
wall = 2,
|
||||
texture = "none",
|
||||
cap_h1 = 11.2,
|
||||
cap_thread_od1 = 28.58,
|
||||
cap_thread_depth1 = 2.34,
|
||||
tolerance = .2,
|
||||
cap_neck_od1 = 25.5,
|
||||
cap_thread_pitch1 = 4,
|
||||
cap_h2,
|
||||
cap_thread_od2,
|
||||
cap_thread_depth2,
|
||||
cap_neck_od2,
|
||||
cap_thread_pitch2,
|
||||
d = 0,
|
||||
neck_id1, neck_id2,
|
||||
taper_lead_in = 0
|
||||
neck_id,
|
||||
taper_lead_in = 0, anchor, spin,orient
|
||||
) {
|
||||
cap_h2 = (cap_h2 == undef) ? cap_h1 : cap_h2;
|
||||
cap_thread_od2 = (cap_thread_od2 == undef) ? cap_thread_od1 : cap_thread_od2;
|
||||
cap_neck_od2 = (cap_neck_od2 == undef) ? cap_neck_od1 : cap_neck_od2;
|
||||
cap_thread_pitch2 = (cap_thread_pitch2 == undef) ? cap_thread_pitch1 : cap_thread_pitch2;
|
||||
neck_id2 = (neck_id2 == undef && neck_id1 != undef) ? neck_id1 : neck_id2;
|
||||
cap_h2 = default(cap_h2,cap_h1);
|
||||
cap_thread_depth2 = default(cap_thread_depth2,cap_thread_depth1);
|
||||
cap_neck_od2 = default(cap_neck_od2,cap_neck_od1);
|
||||
cap_thread_pitch2 = default(cap_thread_pitch2,cap_thread_pitch1);
|
||||
taper_lead_in = (d >= taper_lead_in * 2) ? taper_lead_in : d / 2;
|
||||
|
||||
neck_id = min(cap_neck_od1 - cap_thread_depth1, cap_neck_od2-cap_thread_depth2);
|
||||
|
||||
top_h = cap_h1+wall;
|
||||
bot_h = cap_h2+wall;
|
||||
|
||||
|
||||
cap_od1 = cap_neck_od1 + 2*(cap_thread_depth1 - 0.8) + 2 * tolerance; // WTF; Engineered for consistency with old code, but
|
||||
cap_od2 = cap_neck_od2 + 2*(cap_thread_depth2 - 0.8) + 2 * tolerance; // WTF; Engineered for consistency with old code, but
|
||||
|
||||
$fn = segs(33 / 2);
|
||||
|
||||
attachable(anchor=anchor,spin=spin,orient=orient, h=top_h+bot_h+d, d=max(cap_od1,cap_od2)+2*wall){
|
||||
zmove((bot_h-top_h)/2)
|
||||
difference(){
|
||||
union(){
|
||||
up(d / 2){
|
||||
|
@ -789,7 +814,7 @@ module bottle_adapter_cap_to_cap(
|
|||
wall = wall,
|
||||
texture = texture,
|
||||
height = cap_h1,
|
||||
thread_od = cap_thread_od1,
|
||||
thread_depth = cap_thread_depth1,
|
||||
tolerance = tolerance,
|
||||
neck_od = cap_neck_od1,
|
||||
pitch = cap_thread_pitch1
|
||||
|
@ -799,10 +824,10 @@ module bottle_adapter_cap_to_cap(
|
|||
rotate_extrude() {
|
||||
polygon(points = [
|
||||
[0, d / 2],
|
||||
[cap_thread_od1 / 2 + (wall + tolerance), d / 2],
|
||||
[cap_thread_od1 / 2 + (wall + tolerance), d / 2 - taper_lead_in],
|
||||
[cap_thread_od2 / 2 + (wall + tolerance), taper_lead_in - d / 2],
|
||||
[cap_thread_od2 / 2 + (wall + tolerance), -d / 2],
|
||||
[cap_od1 / 2 + wall, d / 2],
|
||||
[cap_od1 / 2 + wall, d / 2 - taper_lead_in],
|
||||
[cap_od2 / 2 + wall, taper_lead_in - d / 2],
|
||||
[cap_od2 / 2 + wall, -d / 2],
|
||||
[0, -d / 2]
|
||||
]);
|
||||
}
|
||||
|
@ -813,28 +838,25 @@ module bottle_adapter_cap_to_cap(
|
|||
wall = wall,
|
||||
texture = texture,
|
||||
height = cap_h2,
|
||||
thread_od = cap_thread_od2,
|
||||
thread_depth = cap_thread_depth2,
|
||||
tolerance = tolerance,
|
||||
neck_od = cap_neck_od2,
|
||||
pitch = cap_thread_pitch2
|
||||
);
|
||||
}
|
||||
}
|
||||
if (neck_id1 != undef || neck_id2 != undef) {
|
||||
neck_id1 = (neck_id1 == undef) ? neck_id2 : neck_id1;
|
||||
neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2;
|
||||
|
||||
rotate_extrude() {
|
||||
polygon(points = [
|
||||
[0, wall + d / 2 + 0.1],
|
||||
[neck_id1 / 2, wall + d / 2],
|
||||
[neck_id1 / 2, wall + d / 2 - taper_lead_in],
|
||||
[neck_id2 / 2, taper_lead_in - d / 2 - wall],
|
||||
[neck_id2 / 2, -d / 2 - wall],
|
||||
[neck_id / 2, wall + d / 2],
|
||||
[neck_id / 2, wall + d / 2 - taper_lead_in],
|
||||
[neck_id / 2, taper_lead_in - d / 2 - wall],
|
||||
[neck_id / 2, -d / 2 - wall],
|
||||
[0, -d / 2 - wall - 0.1]
|
||||
]);
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -850,7 +872,7 @@ function bottle_adapter_cap_to_cap(
|
|||
// Topics: Bottles, Threading
|
||||
// See Also: bottle_adapter_neck_to_cap(), bottle_adapter_cap_to_cap()
|
||||
// Usage:
|
||||
// bottle_adapter_neck_to_neck(...);
|
||||
// bottle_adapter_neck_to_neck(...) [ATTACHMENTS];
|
||||
// Description:
|
||||
// Creates a threaded neck to neck adapter.
|
||||
// Arguments:
|
||||
|
@ -870,6 +892,9 @@ function bottle_adapter_cap_to_cap(
|
|||
// pitch2 = Thread pitch of bottom neck. Leave undefined to duplicate thread_pitch1
|
||||
// taper_lead_in = Length to leave straight before tapering on tube between necks if exists.
|
||||
// wall = Thickness of tube wall between necks. Leave undefined to match outer diameters with the neckODs/supportODs.
|
||||
// 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`
|
||||
// Examples:
|
||||
// bottle_adapter_neck_to_neck();
|
||||
module bottle_adapter_neck_to_neck(
|
||||
|
@ -883,9 +908,8 @@ module bottle_adapter_neck_to_neck(
|
|||
neck_od2, neck_id2,
|
||||
thread_od2, height2,
|
||||
support_od2, pitch2,
|
||||
taper_lead_in = 0, wall
|
||||
taper_lead_in = 0, wall, anchor, spin, orient
|
||||
) {
|
||||
no_children($children);
|
||||
neck_od2 = (neck_od2 == undef) ? neck_od1 : neck_od2;
|
||||
neck_id2 = (neck_id2 == undef) ? neck_id1 : neck_id2;
|
||||
thread_od2 = (thread_od2 == undef) ? thread_od1 : thread_od2;
|
||||
|
@ -903,6 +927,11 @@ module bottle_adapter_neck_to_neck(
|
|||
|
||||
taper_lead_in = (d >= taper_lead_in * 2) ? taper_lead_in : d / 2;
|
||||
|
||||
top_h = height1 + max(1,height1/17)*sign(support_od1);
|
||||
bot_h = height2 + max(1,height2/17)*sign(support_od2);
|
||||
|
||||
attachable(anchor=anchor,orient=orient,spin=spin, h=top_h+bot_h+d, d=max(neck_od1,neck_od2)){
|
||||
zmove((bot_h-top_h)/2)
|
||||
difference(){
|
||||
union(){
|
||||
up(d / 2){
|
||||
|
@ -958,6 +987,8 @@ module bottle_adapter_neck_to_neck(
|
|||
}
|
||||
}
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
function bottle_adapter_neck_to_neck(
|
||||
|
|
|
@ -85,6 +85,8 @@ module bounding_box(excess=0, planar=false) {
|
|||
}
|
||||
}
|
||||
|
||||
req_children($children);
|
||||
attachable(){
|
||||
if(planar) {
|
||||
offset(excess-1/2) _oversize_bbox() children();
|
||||
} else {
|
||||
|
@ -95,6 +97,8 @@ module bounding_box(excess=0, planar=false) {
|
|||
_shrink_cube() _oversize_bbox() children();
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,10 +141,12 @@ module bounding_box(excess=0, planar=false) {
|
|||
// }
|
||||
module chain_hull()
|
||||
{
|
||||
union() {
|
||||
req_children($children);
|
||||
attachable(){
|
||||
if ($children == 1) {
|
||||
children();
|
||||
} else if ($children > 1) {
|
||||
}
|
||||
else {
|
||||
for (i =[1:1:$children-1]) {
|
||||
$idx = i;
|
||||
hull() {
|
||||
|
@ -149,6 +155,7 @@ module chain_hull()
|
|||
}
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +210,7 @@ module chain_hull()
|
|||
// move_copies([[-3.5,1.5],[0.0,3.0],[3.5,1.5]])
|
||||
// circle(r=1.5);
|
||||
module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
||||
req_children($children);
|
||||
extra_ang = 0.1; // Extra angle for overlap of joints
|
||||
check =
|
||||
assert(caps==false || closed==false, "Cannot have caps on a closed extrusion")
|
||||
|
@ -213,6 +221,8 @@ module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
|||
norm(b[1]-b[0]);
|
||||
check2 = assert(is_finite(s));
|
||||
L = len(path);
|
||||
attachable(){
|
||||
union(){
|
||||
for (i = [0:1:L-(closed?1:2)]) {
|
||||
seg = select(path, i, i+1);
|
||||
segv = seg[1] - seg[0];
|
||||
|
@ -266,6 +276,9 @@ module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
|||
rotate_extrude(angle=180)
|
||||
right_half(planar=true) children();
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -298,6 +311,7 @@ module path_extrude2d(path, caps=false, closed=false, s, convexity=10) {
|
|||
// cylindrical_extrude(or=40, ir=35, orient=BACK)
|
||||
// text(text="Hello World!", size=10, halign="center", valign="center");
|
||||
module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orient=UP) {
|
||||
req_children($children);
|
||||
check1 = assert(is_num(size) || is_vector(size,2));
|
||||
size = is_num(size)? [size,size] : size;
|
||||
ir = get_radius(r=ir,d=id);
|
||||
|
@ -310,6 +324,7 @@ module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orie
|
|||
sides = segs(or);
|
||||
step = circumf / sides;
|
||||
steps = ceil(width / step);
|
||||
attachable() {
|
||||
rot(from=UP, to=orient) rot(spin) {
|
||||
for (i=[0:1:steps-2]) {
|
||||
x = (i+0.5-steps/2) * step;
|
||||
|
@ -328,6 +343,8 @@ module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orie
|
|||
}
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,6 +370,7 @@ module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orie
|
|||
// xcopies(3) circle(3, $fn=32);
|
||||
// }
|
||||
module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
||||
req_children($children);
|
||||
check =
|
||||
assert(is_vector(pt1),"First point must be a vector")
|
||||
assert(is_vector(pt2),"Second point must be a vector");
|
||||
|
@ -391,6 +409,7 @@ module extrude_from_to(pt1, pt2, convexity, twist, scale, slices) {
|
|||
// path = [ [0, 0, 0], [33, 33, 33], [66, 33, 40], [100, 0, 0], [150,0,0] ];
|
||||
// path_extrude(path) circle(r=10, $fn=6);
|
||||
module path_extrude(path, convexity=10, clipsize=100) {
|
||||
req_children($children);
|
||||
rotmats = cumprod([
|
||||
for (i = idx(path,e=-2)) let(
|
||||
vec1 = i==0? UP : unit(path[i]-path[i-1], UP),
|
||||
|
@ -401,6 +420,7 @@ module path_extrude(path, convexity=10, clipsize=100) {
|
|||
interp = rot_resample(rotmats,n=2,method="count");
|
||||
epsilon = 0.0001; // Make segments ever so slightly too long so they overlap.
|
||||
ptcount = len(path);
|
||||
attachable(){
|
||||
for (i = [0:1:ptcount-2]) {
|
||||
pt1 = path[i];
|
||||
pt2 = path[i+1];
|
||||
|
@ -428,6 +448,8 @@ module path_extrude(path, convexity=10, clipsize=100) {
|
|||
}
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -459,6 +481,8 @@ module path_extrude(path, convexity=10, clipsize=100) {
|
|||
// sphere(r=10);
|
||||
// }
|
||||
module minkowski_difference(planar=false) {
|
||||
req_children($children);
|
||||
attachable(){
|
||||
difference() {
|
||||
bounding_box(excess=0, planar=planar) children(0);
|
||||
render(convexity=20) {
|
||||
|
@ -471,6 +495,8 @@ module minkowski_difference(planar=false) {
|
|||
}
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -491,7 +517,9 @@ module minkowski_difference(planar=false) {
|
|||
// size = Maximum size of object to be contracted, given as a scalar. Default: 100
|
||||
// convexity = Max number of times a line could intersect the walls of the object. Default: 10
|
||||
module offset3d(r, size=100, convexity=10) {
|
||||
req_children($children);
|
||||
n = quant(max(8,segs(abs(r))),4);
|
||||
attachable(){
|
||||
if (r==0) {
|
||||
children();
|
||||
} else if (r>0) {
|
||||
|
@ -515,6 +543,8 @@ module offset3d(r, size=100, convexity=10) {
|
|||
}
|
||||
}
|
||||
}
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -540,12 +570,16 @@ module offset3d(r, size=100, convexity=10) {
|
|||
// ir = Radius to round only inside (concave) corners to. Use instead of `r`.
|
||||
module round3d(r, or, ir, size=100)
|
||||
{
|
||||
req_children($children);
|
||||
or = get_radius(r1=or, r=r, dflt=0);
|
||||
ir = get_radius(r1=ir, r=r, dflt=0);
|
||||
attachable(){
|
||||
offset3d(or, size=size)
|
||||
offset3d(-ir-or, size=size)
|
||||
offset3d(ir, size=size)
|
||||
children();
|
||||
union();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -329,20 +329,20 @@ module regular_polyhedron(
|
|||
faces = entry[3];
|
||||
face_normals = entry[4];
|
||||
in_radius = entry[5];
|
||||
translate(translation){
|
||||
if (draw){
|
||||
if (rounding==0)
|
||||
polyhedron(move(translation, p=scaled_points), faces = face_triangles);
|
||||
polyhedron(scaled_points, faces = face_triangles);
|
||||
else {
|
||||
fn = segs(rounding);
|
||||
rounding = rounding/cos(180/fn);
|
||||
adjusted_scale = 1 - rounding / in_radius;
|
||||
minkowski(){
|
||||
sphere(r=rounding, $fn=fn);
|
||||
polyhedron(move(translation,p=adjusted_scale*scaled_points), faces = face_triangles);
|
||||
polyhedron(adjusted_scale*scaled_points, faces = face_triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
translate(translation)
|
||||
if ($children>0) {
|
||||
maxrange = repeat ? len(faces)-1 : $children-1;
|
||||
for(i=[0:1:maxrange]) {
|
||||
|
@ -363,6 +363,7 @@ module regular_polyhedron(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue