mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Added cuboid(), cyl(). Deprecated a bunch.
This commit is contained in:
parent
4ba0755f56
commit
9b0a0dc375
1 changed files with 408 additions and 216 deletions
624
shapes.scad
624
shapes.scad
|
@ -31,33 +31,156 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
|
||||
include <transforms.scad>
|
||||
include <math.scad>
|
||||
use <transforms.scad>
|
||||
use <math.scad>
|
||||
include <constants.scad>
|
||||
|
||||
|
||||
// For when you MUST pass a child to a module, but you want it to be nothing.
|
||||
module nil() union() {}
|
||||
|
||||
|
||||
// Makes a cube that is offset along the given vector by half the cube's size.
|
||||
// For example, if v=[-1,1,0], the cube's front right edge will be centered at the origin.
|
||||
// size = size of cube.
|
||||
// v = vector to offset along.
|
||||
// Example:
|
||||
// offsetcube([3,4,5], [-1,1,0]);
|
||||
module offsetcube(size=[1,1,1], v=[0,0,0]) {
|
||||
lx=len(size)==undef? size : size[0];
|
||||
ly=len(size)==undef? size : size[1];
|
||||
lz=len(size)==undef? size : size[2];
|
||||
ax=len(v)==undef? v : v[0];
|
||||
ay=len(v)==undef? v : v[1];
|
||||
az=len(v)==undef? v : v[2];
|
||||
translate([lx*ax/2, ly*ay/2, lz*az/2]) {
|
||||
cube(size, center=true);
|
||||
// Creates a cube or cuboid object.
|
||||
// size = The size of the cube.
|
||||
// align = The side of the origin to align to. Use V_ constants from constants.scad.
|
||||
// chamfer = Size of chamfer, inset from sides. Default: No chamferring.
|
||||
// fillet = Radius of fillet for edge rounding. Default: No filleting.
|
||||
// edges = Edges to chamfer/fillet. Use EDGE constants from constants.scad. Default: EDGES_ALL
|
||||
// trimcorners = If true, rounds or chamfers corners where three chamferred/filleted edges meet. Default: true
|
||||
// Examples:
|
||||
// cuboid(40);
|
||||
// cuboid(40, align=V_UP+V_BACK);
|
||||
// cuboid([20,40,60]);
|
||||
// cuboid([30,40,60], chamfer=5);
|
||||
// cuboid([30,40,60], fillet=10);
|
||||
// cuboid([30,40,60], chamfer=5, edges=EDGE_TOP_FR+EDGE_TOP_RT+EDGE_FR_RT, $fn=24);
|
||||
// cuboid([30,40,60], fillet=5, edges=EDGE_TOP_FR+EDGE_TOP_RT+EDGE_FR_RT, $fn=24);
|
||||
module cuboid(
|
||||
size=[1,1,1],
|
||||
align=[0,0,0],
|
||||
chamfer=undef,
|
||||
fillet=undef,
|
||||
edges=EDGES_ALL,
|
||||
trimcorners=true
|
||||
) {
|
||||
size = scalar_vec(size);
|
||||
majrots = [[0,90,0], [90,0,0], [0,0,0]];
|
||||
if (chamfer != undef) {
|
||||
if (version_num()>20190000) {
|
||||
assert(chamfer <= min(size)/2, "chamfer must be smaller than half the cube width, length, or height.");
|
||||
} else {
|
||||
if(chamfer > min(size)/2) {
|
||||
echo("WARNING: chamfer must be smaller than half the cube width, length, or height.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fillet != undef) {
|
||||
if (version_num()>20190000) {
|
||||
assert(fillet <= min(size)/2, "fillet must be smaller than half the cube width, length, or height.");
|
||||
} else {
|
||||
if(fillet > min(size)/2) {
|
||||
echo("WARNING: fillet must be smaller than half the cube width, length, or height.");
|
||||
}
|
||||
}
|
||||
}
|
||||
translate(vmul(size/2, align)) {
|
||||
if (chamfer != undef) {
|
||||
isize = [for (v = size) max(0.001, v-2*chamfer)];
|
||||
if (edges == EDGES_ALL && trimcorners) {
|
||||
hull() {
|
||||
cube([size[0], isize[1], isize[2]], center=true);
|
||||
cube([isize[0], size[1], isize[2]], center=true);
|
||||
cube([isize[0], isize[1], size[2]], center=true);
|
||||
}
|
||||
} else {
|
||||
difference() {
|
||||
cube(size, center=true);
|
||||
|
||||
// Chamfer edges
|
||||
for (i = [0:3], axis=[0:2]) {
|
||||
if (edges[axis][i]>0) {
|
||||
translate(vmul(EDGE_OFFSETS[axis][i], size/2)) {
|
||||
rotate(majrots[axis]) {
|
||||
zrot(45) cube([chamfer*sqrt(2), chamfer*sqrt(2), size[axis]+0.01], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chamfer triple-edge corners.
|
||||
if (trimcorners) {
|
||||
for (za=[-1,1], ya=[-1,1], xa=[-1,1]) {
|
||||
if (corner_edge_count(edges, [xa,ya,za]) > 2) {
|
||||
translate(vmul([xa,ya,za]/2, size-[1,1,1]*chamfer*4/3)) {
|
||||
rotate_from_to(V_UP, [xa,ya,za]) {
|
||||
upcube(chamfer*3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (fillet != undef) {
|
||||
sides = quantup(segs(fillet),4);
|
||||
sc = 1/cos(180/sides);
|
||||
isize = [for (v = size) max(0.001, v-2*fillet)];
|
||||
if (edges == EDGES_ALL) {
|
||||
minkowski() {
|
||||
cube(isize, center=true);
|
||||
if (trimcorners) {
|
||||
sphere(r=fillet*sc, $fn=sides);
|
||||
} else {
|
||||
intersection() {
|
||||
zrot(180/sides) cylinder(r=fillet*sc, h=fillet*2, center=true, $fn=sides);
|
||||
rotate([90,0,0]) zrot(180/sides) cylinder(r=fillet*sc, h=fillet*2, center=true, $fn=sides);
|
||||
rotate([0,90,0]) zrot(180/sides) cylinder(r=fillet*sc, h=fillet*2, center=true, $fn=sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
difference() {
|
||||
cube(size, center=true);
|
||||
|
||||
// Round edges.
|
||||
for (i = [0:3], axis=[0:2]) {
|
||||
if (edges[axis][i]>0) {
|
||||
difference() {
|
||||
translate(vmul(EDGE_OFFSETS[axis][i], size/2)) {
|
||||
rotate(majrots[axis]) cube([fillet*2, fillet*2, size[axis]+0.1], center=true);
|
||||
}
|
||||
translate(vmul(EDGE_OFFSETS[axis][i], size/2 - [1,1,1]*fillet)) {
|
||||
rotate(majrots[axis]) zrot(180/sides) cylinder(h=size[axis]+0.2, r=fillet*sc, center=true, $fn=sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Round triple-edge corners.
|
||||
if (trimcorners) {
|
||||
for (za=[-1,1], ya=[-1,1], xa=[-1,1]) {
|
||||
if (corner_edge_count(edges, [xa,ya,za]) > 2) {
|
||||
difference() {
|
||||
translate(vmul([xa,ya,za], size/2)) {
|
||||
cube(fillet*2, center=true);
|
||||
}
|
||||
translate(vmul([xa,ya,za], size/2-[1,1,1]*fillet)) {
|
||||
zrot(180/sides) sphere(r=fillet*sc*sc, $fn=sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cube(size=size, center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Creates a cube between two points.
|
||||
// p1 = Coordinate point of one cube corner.
|
||||
// p2 = Coordinate point of opposite cube corner.
|
||||
|
@ -70,29 +193,53 @@ module cube2pt(p1,p2) {
|
|||
}
|
||||
|
||||
|
||||
// Creates a cube that spans the X, Y, and Z ranges given.
|
||||
// xspan = [min, max] X axis range.
|
||||
// yspan = [min, max] Y axis range.
|
||||
// zspan = [min, max] Z axis range.
|
||||
// Example:
|
||||
// span_cube([10,40], [-10, 20], [10,30]);
|
||||
module span_cube(xspan, yspan, zspan) {
|
||||
cube2pt([xspan[0], yspan[0], zspan[0]], [xspan[1], yspan[1], zspan[1]]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Makes a cube that is offset along the given vector by half the cube's size.
|
||||
// For example, if v=[-1,1,0], the cube's front right edge will be centered at the origin.
|
||||
// size = size of cube.
|
||||
// v = vector to offset along.
|
||||
// Example:
|
||||
// offsetcube([3,4,5], [-1,1,0]);
|
||||
module offsetcube(size=[1,1,1], v=[0,0,0]) {
|
||||
echo("DEPRECATED: You should use cuboid() instead of offsetcube()");
|
||||
cuboid(size=size, align=v);
|
||||
}
|
||||
|
||||
|
||||
// Makes a cube that has its right face centered at the origin.
|
||||
module leftcube(size=[1,1,1]) {l=len(size)==undef? size : size[0]; left(l/2) cube(size, center=true);}
|
||||
module leftcube(size=[1,1,1]) cuboid(size=size, align=V_LEFT);
|
||||
|
||||
|
||||
// Makes a cube that has its left face centered at the origin.
|
||||
module rightcube(size=[1,1,1]) {l=len(size)==undef? size : size[0]; right(l/2) cube(size, center=true);}
|
||||
|
||||
|
||||
// Makes a cube that has its front face centered at the origin.
|
||||
module backcube(size=[1,1,1]) {l=len(size)==undef? size : size[1]; back(l/2) cube(size, center=true);}
|
||||
module rightcube(size=[1,1,1]) cuboid(size=size, align=V_RIGHT);
|
||||
|
||||
|
||||
// Makes a cube that has its back face centered at the origin.
|
||||
module fwdcube(size=[1,1,1]) {l=len(size)==undef? size : size[1]; fwd(l/2) cube(size, center=true);}
|
||||
module fwdcube(size=[1,1,1]) cuboid(size=size, align=V_FWD);
|
||||
|
||||
|
||||
// Makes a cube that has its bottom face centered at the origin.
|
||||
module upcube(size=[1,1,1]) {l=len(size)==undef? size : size[2]; up(l/2) cube(size, center=true);}
|
||||
// Makes a cube that has its front face centered at the origin.
|
||||
module backcube(size=[1,1,1]) cuboid(size=size, align=V_BACK);
|
||||
|
||||
|
||||
// Makes a cube that has its top face centered at the origin.
|
||||
module downcube(size=[1,1,1]) {l=len(size)==undef? size : size[2]; down(l/2) cube(size, center=true);}
|
||||
module downcube(size=[1,1,1]) cuboid(size=size, align=V_DOWN);
|
||||
|
||||
|
||||
// Makes a cube that has its bottom face centered at the origin.
|
||||
module upcube(size=[1,1,1]) cuboid(size=size, align=V_UP);
|
||||
|
||||
|
||||
// Makes a cube with chamfered edges.
|
||||
|
@ -102,75 +249,18 @@ module downcube(size=[1,1,1]) {l=len(size)==undef? size : size[2]; down(l/2) cub
|
|||
// chamfcorners = boolean to specify if corners should be flat chamferred.
|
||||
// Example:
|
||||
// chamfcube(size=[10,30,50], chamfer=1, chamfaxes=[1,1,1], chamfcorners=true);
|
||||
module chamfcube(
|
||||
size=[1,1,1],
|
||||
chamfer=0.25,
|
||||
chamfaxes=[1,1,1],
|
||||
chamfcorners=false
|
||||
) {
|
||||
ch_width = sqrt(2)*chamfer;
|
||||
ch_offset = 1;
|
||||
difference() {
|
||||
cube(size=size, center=true);
|
||||
for (xs = [-1,1]) {
|
||||
for (ys = [-1,1]) {
|
||||
if (chamfaxes[0] == 1) {
|
||||
translate([0,xs*size[1]/2,ys*size[2]/2]) {
|
||||
rotate(a=[45,0,0]) cube(size=[size[0]+0.1,ch_width,ch_width], center=true);
|
||||
}
|
||||
}
|
||||
if (chamfaxes[1] == 1) {
|
||||
translate([xs*size[0]/2,0,ys*size[2]/2]) {
|
||||
rotate(a=[0,45,0]) cube(size=[ch_width,size[1]+0.1,ch_width], center=true);
|
||||
}
|
||||
}
|
||||
if (chamfaxes[2] == 1) {
|
||||
translate([xs*size[0]/2,ys*size[1]/2],0) {
|
||||
rotate(a=[0,0,45]) cube(size=[ch_width,ch_width,size[2]+0.1], center=true);
|
||||
}
|
||||
}
|
||||
if (chamfcorners) {
|
||||
for (zs = [-1,1]) {
|
||||
translate([xs*size[0]/2,ys*size[1]/2,zs*size[2]/2]) {
|
||||
scale([chamfer,chamfer,chamfer]) {
|
||||
polyhedron(
|
||||
points=[
|
||||
[0,-1,-1], [0,-1,1], [0,1,1], [0,1,-1],
|
||||
[-1,0,-1], [-1,0,1], [1,0,1], [1,0,-1],
|
||||
[-1,-1,0], [-1,1,0], [1,1,0], [1,-1,0]
|
||||
],
|
||||
faces=[
|
||||
[ 8, 4, 9],
|
||||
[ 8, 9, 5],
|
||||
[ 9, 3, 10],
|
||||
[ 9, 10, 2],
|
||||
[10, 7, 11],
|
||||
[10, 11, 6],
|
||||
[11, 0, 8],
|
||||
[11, 8, 1],
|
||||
[ 0, 7, 3],
|
||||
[ 0, 3, 4],
|
||||
[ 1, 5, 2],
|
||||
[ 1, 2, 6],
|
||||
|
||||
[ 1, 8, 5],
|
||||
[ 5, 9, 2],
|
||||
[ 2, 10, 6],
|
||||
[ 6, 11, 1],
|
||||
|
||||
[ 0, 4, 8],
|
||||
[ 4, 3, 9],
|
||||
[ 3, 7, 10],
|
||||
[ 7, 0, 11],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
module chamfcube(size=[1,1,1], chamfer=0.25, chamfaxes=[1,1,1], chamfcorners=false) {
|
||||
echo("DEPRECATED: Use cuboid() instead of chamfcube()");
|
||||
cuboid(
|
||||
size=size,
|
||||
chamfer=chamfer,
|
||||
trimcorners=chamfcorners,
|
||||
edges = (
|
||||
(chamfaxes[0]? EDGES_X_ALL : EDGES_NONE) +
|
||||
(chamfaxes[1]? EDGES_Y_ALL : EDGES_NONE) +
|
||||
(chamfaxes[2]? EDGES_Z_ALL : EDGES_NONE)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,19 +272,9 @@ module chamfcube(
|
|||
// Examples:
|
||||
// rrect(size=[9,4,1], r=1, center=true);
|
||||
// rrect(size=[5,7,3], r=1, $fn=24);
|
||||
module rrect(size=[1,1,1], r=0.25, center=false)
|
||||
{
|
||||
w = size[0];
|
||||
l = size[1];
|
||||
h = size[2];
|
||||
rr = min(r, min(w/2-0.01, l/2-0.01));
|
||||
up(center? 0 : h/2) {
|
||||
linear_extrude(height=h, convexity=2, center=true) {
|
||||
offset(r=rr) {
|
||||
square([w-2*rr, l-2*rr], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
module rrect(size=[1,1,1], r=0.25, center=false) {
|
||||
echo("DEPRECATED: Use cuboid() instead of rrect()");
|
||||
cuboid(size=size, filler=r, edges=EDGES_Z_ALL, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,27 +286,145 @@ module rrect(size=[1,1,1], r=0.25, center=false)
|
|||
// Examples:
|
||||
// rcube(size=[9,4,1], r=0.333, center=true, $fn=24);
|
||||
// rcube(size=[5,7,3], r=1);
|
||||
module rcube(size=[1,1,1], r=0.25, center=false)
|
||||
{
|
||||
dd = min(2*r, min(size));
|
||||
$fn=quantup(segs(dd/2), 4);
|
||||
translate(center? [0,0,0] : size/2) {
|
||||
minkowski() {
|
||||
cube([max(0.01,size[0]-dd), max(0.01,size[1]-dd), max(0.01,size[2]-dd)], center=true);
|
||||
module rcube(size=[1,1,1], r=0.25, center=false) {
|
||||
echo("DEPRECATED: Use cuboid() instead of rcube()");
|
||||
cuboid(size=size, fillet=r, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
// Synthesize a sphere with vertices at the axis extremes.
|
||||
// This makes the result of the minkowski have the proper dimensions.
|
||||
rotate_extrude() {
|
||||
difference() {
|
||||
circle(dd/2);
|
||||
left(dd/2) square(dd, center=true);
|
||||
|
||||
|
||||
// Creates cylinders in various alignments and orientations,
|
||||
// with optional fillets and chamfers.
|
||||
// l = Length of cylinder along axis.
|
||||
// r = Radius of cylinder.
|
||||
// r1 = Radius of the negative (X-, Y-, Z-) end of cylinder.
|
||||
// r2 = Radius of the positive (X+, Y+, Z+) end of cylinder.
|
||||
// d = Diameter of cylinder.
|
||||
// d1 = Diameter of the negative (X-, Y-, Z-) end of cylinder.
|
||||
// d2 = Diameter of the positive (X+, Y+, Z+) end of cylinder.
|
||||
// chamfer = The size of the chamfers on the ends of the cylinder, inset from end. Default: none.
|
||||
// chamfer1 = The size of the chamfer on the axis-negative end of the cylinder, inset from end. Default: none.
|
||||
// chamfer2 = The size of the chamfer on the axis-positive end of the cylinder, inset from end. Default: none.
|
||||
// fillet = The radius of the fillets on the ends of the cylinder. Default: none.
|
||||
// fillet1 = The radius of the fillet on the axis-negative end of the cylinder.
|
||||
// fillet2 = The radius of the fillet on the axis-positive end of the cylinder.
|
||||
// circum = If true, cylinder should circumscribe the circle of the given size. Otherwise inscribes. Default: false
|
||||
// realign = If true, rotate the cylinder by half the angle of one face.
|
||||
// orient = Orientation of the cylinder. Use the ORIENT_ constants from constants.h. Default: vertical.
|
||||
// align = Alignment of the cylinder. Use the V_ constants from constants.h. Default: centered.
|
||||
// Examples:
|
||||
// cyl(l=100, r=25);
|
||||
// cyl(l=100, d=50, align=V_UP);
|
||||
// cyl(l=100, r=20, circum=true, realign=true);
|
||||
// cyl(l=40, d=50, orient=ORIENT_X, align=V_LEFT, chamfer=10);
|
||||
// cyl(l=100, d1=30, d2=75, orient=ORIENT_Y, fillet=10);
|
||||
// cyl(l=30, d2=100, d1=100, fillet1=10, fillet2=5, align=V_UP);
|
||||
module cyl(
|
||||
l=1,
|
||||
r=undef, r1=undef, r2=undef,
|
||||
d=undef, d1=undef, d2=undef,
|
||||
chamfer=undef, chamfer1=undef, chamfer2=undef,
|
||||
chamfang=undef, chamfang1=undef, chamfang2=undef,
|
||||
fillet=undef, fillet1=undef, fillet2=undef,
|
||||
circum=false, realign=false,
|
||||
orient=ORIENT_Z, align=V_ZERO
|
||||
) {
|
||||
r1 = get_radius(r1, r, d1, d, 1);
|
||||
r2 = get_radius(r2, r, d2, d, 1);
|
||||
sides = segs(max(r1,r2));
|
||||
sc = circum? 1/cos(180/sides) : 1;
|
||||
orient_and_align([r1*2,r1*2,l], orient, align) {
|
||||
zrot(realign? 180/sides : 0) {
|
||||
if (chamfer!=undef || chamfer1!=undef || chamfer2!=undef) {
|
||||
cham1 = (chamfer1!=undef)? chamfer1 : (chamfer2!=undef)? 0 : chamfer;
|
||||
cham2 = (chamfer2!=undef)? chamfer2 : (chamfer1!=undef)? 0 : chamfer;
|
||||
if (version_num()>20190000) {
|
||||
assert(cham1 <= r1, "Chamfer is smaller than the radius of the cylinder.");
|
||||
assert(cham1 <= r2, "Chamfer is smaller than the radius of the cylinder.");
|
||||
assert(cham1 <= l/2, "Chamfer is smaller than half the length of the cylinder.");
|
||||
assert(cham2 <= r1, "Chamfer is smaller than the radius of the cylinder.");
|
||||
assert(cham2 <= r2, "Chamfer is smaller than the radius of the cylinder.");
|
||||
assert(cham2 <= l/2, "Chamfer is smaller than half the length of the cylinder.");
|
||||
}
|
||||
chang1 = (chamfang1!=undef)? chamfang1 : (chamfang!=undef)? chamfang : undef;
|
||||
chang2 = (chamfang2!=undef)? chamfang2 : (chamfang!=undef)? chamfang : undef;
|
||||
vang = atan2(l, r1-r2)/2;
|
||||
hang1 = (chang1!=undef)? chang1 : 90-vang;
|
||||
hang2 = (chang2!=undef)? chang2 : vang;
|
||||
rr1 = sc * (r1 + (r2-r1)*cham1/l);
|
||||
rr2 = sc * (r2 + (r1-r2)*cham2/l);
|
||||
rr0 = rr1 - cham1 / tan(hang1);
|
||||
rr4 = rr2 - cham2 / tan(hang2);
|
||||
union() {
|
||||
if (cham2>0) {
|
||||
up(l/2-cham2) cylinder(h=cham2, r1=rr2, r2=max(0.001, rr4), center=false, $fn=sides);
|
||||
}
|
||||
up((cham1-cham2)/2) cylinder(h=max(0,l-cham1-cham2)+0.001, r1=rr1, r2=rr2, center=true, $fn=sides);
|
||||
if (cham1>0) {
|
||||
down(l/2-cham1) zflip() cylinder(h=cham1, r1=rr1, r2=max(0.001, rr0), center=false, $fn=sides);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (fillet!=undef || fillet1!=undef || fillet2!=undef) {
|
||||
fil1 = (fillet1!=undef)? fillet1 : (fillet2!=undef)? 0 : fillet;
|
||||
fil2 = (fillet2!=undef)? fillet2 : (fillet1!=undef)? 0 : fillet;
|
||||
if (version_num()>20190000) {
|
||||
assert(fil1 <= r1, "Fillet is smaller than the radius of the cylinder.");
|
||||
assert(fil1 <= r2, "Fillet is smaller than the radius of the cylinder.");
|
||||
assert(fil1 <= l/2, "Fillet is smaller than half the length of the cylinder.");
|
||||
assert(fil2 <= r1, "Fillet is smaller than the radius of the cylinder.");
|
||||
assert(fil2 <= r2, "Fillet is smaller than the radius of the cylinder.");
|
||||
assert(fil2 <= l/2, "Fillet is smaller than half the length of the cylinder.");
|
||||
}
|
||||
rr1 = sc * (r1+(r2-r1)*(fil1/l));
|
||||
rr2 = sc * (r2+(r1-r2)*(fil2/l));
|
||||
if (fil1==fil2) {
|
||||
if (r1==r2 && fil1 == r1) {
|
||||
hull() {
|
||||
zspread(l-2*fil1) {
|
||||
sphere(r=fil1*sc, $fn=sides);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
minkowski() {
|
||||
cylinder(h=max(0.001,l-fil1-fil2), r1=max(0.001,rr1-fil1), r2=max(0.001,rr2-fil2), center=true, $fn=sides);
|
||||
sphere(r=fil1*sc, $fn=sides);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fsegs1 = quantup(segs(fil1),4);
|
||||
fsegs2 = quantup(segs(fil2),4);
|
||||
rotate_extrude(convexity=2) {
|
||||
difference() {
|
||||
hull() {
|
||||
right(rr1-fil1) {
|
||||
difference() {
|
||||
fwd(l/2-fil1) circle(r=max(0.001,fil1), $fn=fsegs1);
|
||||
if (fil1>0) back(fil1) square(2*fil1, center=true);
|
||||
}
|
||||
}
|
||||
right(rr2-fil2) {
|
||||
difference() {
|
||||
back(l/2-fil2) circle(r=max(0.001,fil2), $fn=fsegs2);
|
||||
if (fil2>0) fwd(fil2) square(2*fil2, center=true);
|
||||
}
|
||||
}
|
||||
right(0.01/2) square([0.01, l], center=true);
|
||||
}
|
||||
left(max(rr1,rr2)/2) square([max(rr1, rr2), l+1], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cylinder(h=l, r1=r1*sc, r2=r2*sc, center=true, $fn=sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Creates a cylinder with its top face centered at the origin.
|
||||
// h = height of cylinder. (Default: 1.0)
|
||||
// r = radius of cylinder. (Default: 1.0)
|
||||
|
@ -327,32 +525,17 @@ module zcyl(l=undef, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, a
|
|||
// Example:
|
||||
// chamferred_cylinder(h=50, r=20, chamfer=5, angle=45, bottom=false, center=true);
|
||||
// chamferred_cylinder(h=50, r=20, chamfedge=10, angle=30, center=true);
|
||||
module chamferred_cylinder(h=1, r=1, d=undef, chamfer=0.25, chamfedge=undef, angle=45, center=false, top=true, bottom=true)
|
||||
module chamferred_cylinder(h=1, r=undef, d=undef, chamfer=0.25, chamfedge=undef, angle=45, center=false, top=true, bottom=true)
|
||||
{
|
||||
chamf = (chamfedge == undef)? chamfer * sqrt(2) : chamfedge;
|
||||
x = (chamfedge == undef)? chamfer : (chamfedge * sin(angle));
|
||||
y = (chamfedge == undef)? chamfer*sin(90-angle)/sin(angle) : (chamfedge * sin(90-angle));
|
||||
rad = (d == undef)? r : (d / 2.0);
|
||||
up(center? 0 : h/2) {
|
||||
rotate_extrude(angle=360, convexity=2) {
|
||||
polygon(
|
||||
points=[
|
||||
[0, h/2],
|
||||
[rad-x*(top?1:0), h/2],
|
||||
[rad, h/2-y*(top?1:0)],
|
||||
[rad, -h/2+y*(bottom?1:0)],
|
||||
[rad-x*(bottom?1:0), -h/2],
|
||||
[0, -h/2],
|
||||
[0, h/2],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
echo("DEPRECATED: You should use cyl() instead of chamf_cyl() or chamferred_cylinder().");
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
chamf = (chamfedge == undef)? chamfer : chamfedge * cos(angle);
|
||||
cyl(l=h, r=r, chamfer1=bottom? chamf : 0, chamfer2=top? chamf : 0, chamfang=angle, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
module chamf_cyl(h=1, r=1, d=undef, chamfer=0.25, chamfedge=undef, angle=45, center=false, top=true, bottom=true)
|
||||
module chamf_cyl(h=1, r=undef, d=undef, chamfer=0.25, chamfedge=undef, angle=45, center=false, top=true, bottom=true)
|
||||
chamferred_cylinder(h=h, r=r, d=d, chamfer=chamfer, chamfedge=chamfedge, angle=angle, center=center, top=top, bottom=bottom);
|
||||
//!chamf_cyl(h=20, d=20, chamfedge=10, angle=30, center=true, $fn=36);
|
||||
//!chamf_cyl(h=20, d=20, chamfedge=10, angle=60, center=true, $fn=36);
|
||||
|
||||
|
||||
// Creates a cylinder with filletted (rounded) ends.
|
||||
|
@ -364,40 +547,17 @@ module chamf_cyl(h=1, r=1, d=undef, chamfer=0.25, chamfedge=undef, angle=45, cen
|
|||
// Example:
|
||||
// rcylinder(h=50, r1=20, r2=30, fillet=5, center=true);
|
||||
// rcylinder(h=50, r=20, fillet=5, center=true);
|
||||
module rcylinder(h=1, r=1, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, fillet=0.25, center=false)
|
||||
{
|
||||
r1 = d1!=undef? d1/2 : (r1!=undef? r1 : (d!=undef? d/2 : r));
|
||||
r2 = d2!=undef? d2/2 : (r2!=undef? r2 : (d!=undef? d/2 : r));
|
||||
u = fillet/h;
|
||||
rr1 = (r1+(r2-r1)*u);
|
||||
rr2 = (r1+(r2-r1)*(1-u));
|
||||
yy = h/2 - fillet;
|
||||
up(center? 0 : h/2) {
|
||||
rotate_extrude(angle=360, convexity=2) {
|
||||
difference() {
|
||||
hull() {
|
||||
right(rr1-fillet) {
|
||||
difference() {
|
||||
fwd(yy) circle(r=fillet, $fn=quantup(segs(fillet), 4));
|
||||
back(fillet) square(2*fillet, center=true);
|
||||
}
|
||||
}
|
||||
right(rr2-fillet) {
|
||||
difference() {
|
||||
back(yy) circle(r=fillet, $fn=quantup(segs(fillet), 4));
|
||||
fwd(fillet) square(2*fillet, center=true);
|
||||
}
|
||||
}
|
||||
right(0.01/2) square([0.01, h], center=true);
|
||||
}
|
||||
left(max(rr1,rr2)/2) square([max(rr1, rr2), h+1], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
module rcylinder(h=1, r=1, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, fillet=0.25, center=false) {
|
||||
echo("DEPRECATED: use cyl() instead of rcylinder()");
|
||||
cyl(l=h, r=r, d=d, r1=r1, r2=r2, d1=d1, d2=d2, fillet=fillet, orient=V_UP, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
module filleted_cylinder(h=1, r=1, d=undef, fillet=0.25, center=false)
|
||||
rcylinder(h=h, r=r, d=d, fillet=fillet, center=center);
|
||||
|
||||
|
||||
module filleted_cylinder(h=1, r=undef, d=undef, r1=undef, r2=undef, d1=undef, d2=undef, fillet=0.25, center=false) {
|
||||
echo("DEPRECATED: use cyl() instead of filleted_cylinder()");
|
||||
cyl(l=h, r=r, d=d, r1=r1, r2=r2, d1=d1, d2=d2, fillet=fillet, orient=ORIENT_Z, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -412,9 +572,9 @@ module filleted_cylinder(h=1, r=1, d=undef, fillet=0.25, center=false)
|
|||
// pyramid(h=3, d=4, n=6, circum=true);
|
||||
module pyramid(n=4, h=1, l=1, r=undef, d=undef, circum=false)
|
||||
{
|
||||
cm = circum? 1/cos(180/n) : 1.0;
|
||||
radius = (r!=undef)? r*cm : ((d!=undef)? d*cm/2 : (l/(2*sin(180/n))));
|
||||
zrot(180/n) cylinder(r1=radius, r2=0, h=h, $fn=n, center=false);
|
||||
echo("DEPRECATED: use cyl() instead of pyramid()");
|
||||
radius = get_radius(r=r, d=d, dflt=l/2/sin(180/n));
|
||||
cyl(r1=radius, r2=0, l=h, circum=circum, $fn=n, realign=true, align=V_UP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -429,9 +589,9 @@ module pyramid(n=4, h=1, l=1, r=undef, d=undef, circum=false)
|
|||
// prism(n=8, h=3, d=4, circum=true);
|
||||
module prism(n=3, h=1, l=1, r=undef, d=undef, circum=false, center=false)
|
||||
{
|
||||
cm = circum? 1/cos(180/n) : 1.0;
|
||||
radius = (r!=undef)? r*cm : ((d!=undef)? d*cm/2 : (l/(2*sin(180/n))));
|
||||
zrot(180/n) cylinder(r=radius, h=h, center=center, $fn=n);
|
||||
echo("DEPRECATED: use cyl() instead of prism()");
|
||||
radius = get_radius(r=r, d=d, dflt=l/2/sin(180/n));
|
||||
cyl(r=radius, l=h, circum=circum, $fn=n, realign=true, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -503,23 +663,32 @@ module interior_fillet(l=1.0, r=1.0, ang=90, overlap=0.01) {
|
|||
// Deprecated. Renamed to prismoid.
|
||||
module trapezoid(size1=[1,1], size2=[1,1], h=1, center=false) {
|
||||
echo("DEPRECATED: trapezoid() has been renamed to prismoid().");
|
||||
prismoid(size=size, size2=size2, h=h, center=center);
|
||||
prismoid(size=size, size2=size2, h=h, align=center? V_ZERO : V_UP);
|
||||
}
|
||||
|
||||
|
||||
// Creates a rectangular prismoid/frustum shape.
|
||||
// size1 = [width, length] of the bottom of the prism.
|
||||
// size2 = [width, length] of the top of the prism.
|
||||
// Creates a rectangular prismoid shape.
|
||||
// size1 = [width, length] of the axis-negative end of the prism.
|
||||
// size2 = [width, length] of the axis-positive end of the prism.
|
||||
// h = Height of the prism.
|
||||
// center = vertically center the prism.
|
||||
// orient = Orientation of the prismoid. Use the ORIENT_ constants from constants.h. Default: ORIENT_Z.
|
||||
// align = Alignment of the prismoid by the axis-negative (size1) end. Use the V_ constants from constants.h. Default: V_UP.
|
||||
// center = vertically center the prism. DEPRECATED ARGUMENT. Use align instead.
|
||||
// Example:
|
||||
// prismoid(size1=[1,4], size2=[4,1], h=4, center=false);
|
||||
// prismoid(size1=[2,6], size2=[4,0], h=4, center=false);
|
||||
module prismoid(size1=[1,1], size2=[1,1], h=1, center=false)
|
||||
// prismoid(size1=[1,4], size2=[4,1], h=4, orient=ORIENT_X, align=V_UP+V_RIGHT+V_FWD);
|
||||
// prismoid(size1=[1,4], size2=[4,1], h=4);
|
||||
module prismoid(
|
||||
size1=[1,1], size2=[1,1], h=1,
|
||||
align=V_UP, orient=ORIENT_Z, center=undef)
|
||||
{
|
||||
if (center != undef) {
|
||||
echo("DEPRECATED ARGUMENT: in prismoid, use align instead of center");
|
||||
}
|
||||
algn = (center == undef)? align : (center? V_ZERO : V_UP);
|
||||
s1 = [max(size1[0], 0.001), max(size1[1], 0.001)];
|
||||
s2 = [max(size2[0], 0.001), max(size2[1], 0.001)];
|
||||
up(center? 0 : h/2) {
|
||||
orient_and_align([s1[0], s1[1], h], orient, algn) {
|
||||
polyhedron(
|
||||
points=[
|
||||
[+s2[0]/2, +s2[1]/2, +h/2],
|
||||
|
@ -551,7 +720,7 @@ module prismoid(size1=[1,1], size2=[1,1], h=1, center=false)
|
|||
}
|
||||
|
||||
|
||||
// Creates a rectangular prismoid/frustum shape
|
||||
// Creates a rectangular prismoid shape
|
||||
// with rounded vertical edges.
|
||||
// size1 = [width, length] of the bottom of the prism.
|
||||
// size2 = [width, length] of the top of the prism.
|
||||
|
@ -559,19 +728,24 @@ module prismoid(size1=[1,1], size2=[1,1], h=1, center=false)
|
|||
// r = radius of vertical edge fillets.
|
||||
// r1 = radius of vertical edge fillets at bottom.
|
||||
// r2 = radius of vertical edge fillets at top.
|
||||
// center = vertically center the prism.
|
||||
// orient = Orientation of the prismoid. Use the ORIENT_ constants from constants.h. Default: ORIENT_Z.
|
||||
// align = Alignment of the prismoid by the axis-negative (size1) end. Use the V_ constants from constants.h. Default: V_UP.
|
||||
// center = vertically center the prism. DEPRECATED ARGUMENT. Use align instead.
|
||||
// Example:
|
||||
// rounded_prismoid(size1=[40,40], size2=[0,0], h=40, r=5, center=false);
|
||||
// rounded_prismoid(size1=[20,60], size2=[40,30], h=40, r1=5, r2=10, center=false);
|
||||
// rounded_prismoid(size1=[40,60], size2=[35,55], h=40, r1=0, r2=10, center=true);
|
||||
module rounded_prismoid(size1, size2, h, r=undef, r1=undef, r2=undef, center=true)
|
||||
{
|
||||
module rounded_prismoid(
|
||||
size1, size2, h,
|
||||
r=undef, r1=undef, r2=undef,
|
||||
align=V_UP, orient=ORIENT_Z, center=undef
|
||||
) {
|
||||
eps = 0.001;
|
||||
maxrad1 = min(size1[0]/2, size1[1]/2);
|
||||
maxrad2 = min(size2[0]/2, size2[1]/2);
|
||||
rr1 = min(maxrad1, (r1!=undef)? r1 : r);
|
||||
rr2 = min(maxrad2, (r2!=undef)? r2 : r);
|
||||
down(center? h/2 : 0) {
|
||||
orient_and_align([size1[0], size1[1], h], orient, align) {
|
||||
hull() {
|
||||
linear_extrude(height=eps, center=false, convexity=2) {
|
||||
offset(r=rr1) {
|
||||
|
@ -602,7 +776,7 @@ module rounded_prismoid(size1, size2, h, r=undef, r1=undef, r2=undef, center=tru
|
|||
// teardrop2d(r=35, ang=45, cap_h=40);
|
||||
module teardrop2d(r=1, d=undef, ang=45, cap_h=undef)
|
||||
{
|
||||
r = (d!=undef)? (d/2.0) : r;
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
difference() {
|
||||
hull() {
|
||||
back(r*sin(ang)) {
|
||||
|
@ -630,9 +804,9 @@ module teardrop2d(r=1, d=undef, ang=45, cap_h=undef)
|
|||
// cap_h = if given, height above center where the shape will be truncated.
|
||||
// Example:
|
||||
// teardrop(r=30, h=10, ang=30);
|
||||
module teardrop(r=1, d=undef, h=1, ang=45, cap_h=undef)
|
||||
module teardrop(r=undef, d=undef, h=1, ang=45, cap_h=undef)
|
||||
{
|
||||
r = (d!=undef)? (d/2.0) : r;
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
xrot(90) {
|
||||
linear_extrude(height=h, center=true, steps=2) {
|
||||
teardrop2d(r=r, ang=ang, cap_h=cap_h);
|
||||
|
@ -675,21 +849,35 @@ module onion(h=1, r=1, d=undef, maxang=45)
|
|||
// id = Inner diameter of tube.
|
||||
// id1 = Inner diameter of bottom of tube.
|
||||
// id2 = Inner diameter of top of tube.
|
||||
// orient = Orientation of the tube. Use the ORIENT_ constants from constants.h. Default: vertical.
|
||||
// align = Alignment of the tube. Use the V_ constants from constants.h. Default: centered.
|
||||
// Example:
|
||||
// tube(h=3, r=4, wall=1, center=true);
|
||||
// tube(h=6, r=4, wall=2, $fn=6);
|
||||
// tube(h=3, r1=5, r2=7, wall=2, center=true);
|
||||
// tube(h=30, r1=50, r2=70, ir1=50, ir2=50, center=true);
|
||||
// tube(h=30, wall=5, r1=40, r2=50, center=false);
|
||||
module tube(h=1, wall=undef, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, ir=undef, id=undef, ir1=undef, ir2=undef, id1=undef, id2=undef, center=false)
|
||||
{
|
||||
r1 = first_defined([d1/2, d/2, id1/2+wall, id/2+wall, r1, r, ir1+wall, ir+wall]);
|
||||
r2 = first_defined([d2/2, d/2, id2/2+wall, id/2+wall, r2, r, ir2+wall, ir+wall]);
|
||||
ir1 = first_defined([id1/2, id/2, d1/2-wall, d/2-wall, ir1, ir, r1-wall, r-wall]);
|
||||
ir2 = first_defined([id2/2, id/2, d2/2-wall, d/2-wall, ir2, ir, r2-wall, r-wall]);
|
||||
if (ir1 > r1) echo("WARNING: r1 is smaller than ir1.");
|
||||
if (ir2 > r2) echo("WARNING: r2 is smaller than ir2.");
|
||||
up(center? 0 : h/2) {
|
||||
module tube(
|
||||
h=1, wall=undef,
|
||||
r=undef, r1=undef, r2=undef,
|
||||
d=undef, d1=undef, d2=undef,
|
||||
ir=undef, id=undef, ir1=undef,
|
||||
ir2=undef, id1=undef, id2=undef,
|
||||
center=undef, orient=ORIENT_Z, align=V_UP
|
||||
) {
|
||||
r1 = first_defined([r1, d1/2, r, d/2, ir1+wall, id1/2+wall, ir+wall, id/2+wall]);
|
||||
r2 = first_defined([r2, d2/2, r, d/2, ir2+wall, id2/2+wall, ir+wall, id/2+wall]);
|
||||
ir1 = first_defined([ir1, id1/2, ir, id/2, r1-wall, d1/2-wall, r-wall, d/2-wall]);
|
||||
ir2 = first_defined([ir2, id2/2, ir, id/2, r2-wall, d2/2-wall, r-wall, d/2-wall]);
|
||||
if (version_num()>20190000) {
|
||||
assert(ir1 <= r1, "Inner radius is larger than outer radius.");
|
||||
assert(ir2 <= r2, "Inner radius is larger than outer radius.");
|
||||
} else {
|
||||
if (ir1 > r1) echo("WARNING: r1 is smaller than ir1.");
|
||||
if (ir2 > r2) echo("WARNING: r2 is smaller than ir2.");
|
||||
}
|
||||
algn = (center == undef)? align : (center? V_ZERO : V_UP);
|
||||
orient_and_align([r1*2,r1*2,h], orient, algn) {
|
||||
difference() {
|
||||
cylinder(h=h, r1=r1, r2=r2, center=true);
|
||||
cylinder(h=h+0.05, r1=ir1, r2=ir2, center=true);
|
||||
|
@ -713,14 +901,18 @@ module tube(h=1, wall=undef, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=
|
|||
// torus(d=60, d2=15);
|
||||
// torus(od=60, ir=15);
|
||||
// torus(or=30, ir=20, $fa=1, $fs=1);
|
||||
module torus(or=1, ir=0.5, od=undef, id=undef, r=undef, r2=undef, d=undef, d2=undef)
|
||||
{
|
||||
ir = id!=undef? id/2 : ir;
|
||||
or = od!=undef? od/2 : or;
|
||||
r = d!=undef? d/2 : r!=undef? r : (ir+or)/2;
|
||||
r2 = d2!=undef? d2/2 : r2!=undef? r2 : (or-ir)/2;
|
||||
module torus(
|
||||
r=undef, d=undef,
|
||||
r2=undef, d2=undef,
|
||||
or=undef, od=undef,
|
||||
ir=undef, id=undef
|
||||
) {
|
||||
orr = get_radius(r=or, d=od, dflt=1.0);
|
||||
irr = get_radius(r=ir, d=id, dflt=0.5);
|
||||
majrad = get_radius(r=r, d=d, dflt=(orr+irr)/2);
|
||||
minrad = get_radius(r=r2, d=d2, dflt=(orr-irr)/2);
|
||||
rotate_extrude(convexity = 4) {
|
||||
right(r) circle(r2);
|
||||
right(majrad) circle(minrad);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,8 +931,8 @@ module torus(or=1, ir=0.5, od=undef, id=undef, r=undef, r2=undef, d=undef, d2=un
|
|||
// pie_slice(ang=45, h=30, r1=100, r2=80);
|
||||
module pie_slice(ang=30, h=1, r=10, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, center=false)
|
||||
{
|
||||
r1 = r1!=undef? r1 : (d1!=undef? d1/2 : (d!=undef? d/2 : r));
|
||||
r2 = r2!=undef? r2 : (d2!=undef? d2/2 : (d!=undef? d/2 : r));
|
||||
r1 = get_radius(r1, r, d1, d, 10);
|
||||
r2 = get_radius(r2, r, d2, d, 10);
|
||||
steps = ceil(segs(max(r1,r2))*ang/360);
|
||||
step = ang/steps;
|
||||
pts = concat(
|
||||
|
|
Loading…
Reference in a new issue