mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-01-16 13:50:23 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
de67e5be43
@ -159,9 +159,10 @@ function line_of(spacing, n, l, p1, p2) =
|
||||
// Usage:
|
||||
// xcopies(spacing, [n], [sp]) children;
|
||||
// xcopies(l, [n], [sp]) children;
|
||||
// xcopies(LIST) children;
|
||||
//
|
||||
// Arguments:
|
||||
// spacing = spacing between copies. (Default: 1.0)
|
||||
// spacing = Given a scalar, specifies a uniform spacing between copies. Given a list of scalars, each one gives a specific position along the line. (Default: 1.0)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// l = Length to spread copies over.
|
||||
// sp = If given as a point, copies will be spread on a line to the right of starting position `sp`. If given as a scalar, copies will be spread on a line to the right of starting position `[sp,0,0]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||
@ -180,15 +181,26 @@ function line_of(spacing, n, l, p1, p2) =
|
||||
// cube(size=[1,3,1],center=true);
|
||||
// cube(size=[3,1,1],center=true);
|
||||
// }
|
||||
// Example:
|
||||
// xcopies([1,2,3,5,7]) sphere(d=1);
|
||||
module xcopies(spacing, n, l, sp)
|
||||
{
|
||||
req_children($children);
|
||||
sp = is_finite(sp)? [sp,0,0] : sp;
|
||||
line_of(
|
||||
l=u_mul(l,RIGHT),
|
||||
spacing=u_mul(spacing,RIGHT),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
dir = RIGHT;
|
||||
sp = is_finite(sp)? (sp*dir) : sp;
|
||||
if (is_vector(spacing)) {
|
||||
translate(default(sp,[0,0,0])) {
|
||||
for (x = spacing) {
|
||||
translate(x*dir) children();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
line_of(
|
||||
l=u_mul(l,dir),
|
||||
spacing=u_mul(spacing,dir),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -200,9 +212,10 @@ module xcopies(spacing, n, l, sp)
|
||||
// Usage:
|
||||
// ycopies(spacing, [n], [sp]) children;
|
||||
// ycopies(l, [n], [sp]) children;
|
||||
// ycopies(LIST) children;
|
||||
//
|
||||
// Arguments:
|
||||
// spacing = spacing between copies. (Default: 1.0)
|
||||
// spacing = Given a scalar, specifies a uniform spacing between copies. Given a list of scalars, each one gives a specific position along the line. (Default: 1.0)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// l = Length to spread copies over.
|
||||
// sp = If given as a point, copies will be spread on a line back from starting position `sp`. If given as a scalar, copies will be spread on a line back from starting position `[0,sp,0]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||
@ -221,15 +234,26 @@ module xcopies(spacing, n, l, sp)
|
||||
// cube(size=[1,3,1],center=true);
|
||||
// cube(size=[3,1,1],center=true);
|
||||
// }
|
||||
// Example:
|
||||
// ycopies([1,2,3,5,7]) sphere(d=1);
|
||||
module ycopies(spacing, n, l, sp)
|
||||
{
|
||||
req_children($children);
|
||||
sp = is_finite(sp)? [0,sp,0] : sp;
|
||||
line_of(
|
||||
l=u_mul(l,BACK),
|
||||
spacing=u_mul(spacing,BACK),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
dir = BACK;
|
||||
sp = is_finite(sp)? (sp*dir) : sp;
|
||||
if (is_vector(spacing)) {
|
||||
translate(default(sp,[0,0,0])) {
|
||||
for (x = spacing) {
|
||||
translate(x*dir) children();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
line_of(
|
||||
l=u_mul(l,dir),
|
||||
spacing=u_mul(spacing,dir),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -241,9 +265,10 @@ module ycopies(spacing, n, l, sp)
|
||||
// Usage:
|
||||
// zcopies(spacing, [n], [sp]) children;
|
||||
// zcopies(l, [n], [sp]) children;
|
||||
// zcopies(LIST) children;
|
||||
//
|
||||
// Arguments:
|
||||
// spacing = spacing between copies. (Default: 1.0)
|
||||
// spacing = Given a scalar, specifies a uniform spacing between copies. Given a list of scalars, each one gives a specific position along the line. (Default: 1.0)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// l = Length to spread copies over.
|
||||
// sp = If given as a point, copies will be spread on a line up from starting position `sp`. If given as a scalar, copies will be spread on a line up from starting position `[0,0,sp]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||
@ -276,15 +301,26 @@ module ycopies(spacing, n, l, sp)
|
||||
// back(($idx%2)*xyr*cos(60))
|
||||
// grid2d(s,n=[12,7],stagger=($idx%2)? "alt" : true)
|
||||
// sphere(d=s);
|
||||
// Example:
|
||||
// zcopies([1,2,3,5,7]) sphere(d=1);
|
||||
module zcopies(spacing, n, l, sp)
|
||||
{
|
||||
req_children($children);
|
||||
sp = is_finite(sp)? [0,0,sp] : sp;
|
||||
line_of(
|
||||
l=u_mul(l,UP),
|
||||
spacing=u_mul(spacing,UP),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
dir = UP;
|
||||
sp = is_finite(sp)? (sp*dir) : sp;
|
||||
if (is_vector(spacing)) {
|
||||
translate(default(sp,[0,0,0])) {
|
||||
for (x = spacing) {
|
||||
translate(x*dir) children();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
line_of(
|
||||
l=u_mul(l,dir),
|
||||
spacing=u_mul(spacing,dir),
|
||||
n=n, p1=sp
|
||||
) children();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -422,64 +458,6 @@ module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Module: grid3d()
|
||||
//
|
||||
// Description:
|
||||
// Makes a 3D grid of duplicate children.
|
||||
//
|
||||
// Usage:
|
||||
// grid3d(spacing,n) children;
|
||||
// grid3d(spacing=[dX,dY,dZ], n=[Xn,Yn,Zn]) children;
|
||||
// grid3d([xa=], [ya=], [za=]) children;
|
||||
//
|
||||
// Arguments:
|
||||
// spacing = spacing of copies per axis. Use with `n`.
|
||||
// n = Optional number of copies to have per axis.
|
||||
// xa = array or range of X-axis values to offset by. (Default: [0])
|
||||
// ya = array or range of Y-axis values to offset by. (Default: [0])
|
||||
// za = array or range of Z-axis values to offset by. (Default: [0])
|
||||
//
|
||||
// Side Effects:
|
||||
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
||||
// `$idx` is set to the [Xidx,Yidx,Zidx] index values of each child copy, when using `count` and `n`.
|
||||
//
|
||||
// Examples(FlatSpin,VPD=222):
|
||||
// grid3d(xa=[0:25:50],ya=[0,40],za=[-20:40:20]) sphere(r=5);
|
||||
// Examples(FlatSpin,VPD=800):
|
||||
// grid3d(n=[3, 4, 2], spacing=[60, 50, 40]) sphere(r=10);
|
||||
// Examples:
|
||||
// grid3d(ya=[-60:40:60],za=[0,70]) sphere(r=10);
|
||||
// grid3d(n=3, spacing=30) sphere(r=10);
|
||||
// grid3d(n=[3, 1, 2], spacing=30) sphere(r=10);
|
||||
// grid3d(n=[3, 4], spacing=[80, 60]) sphere(r=10);
|
||||
// Examples:
|
||||
// grid3d(n=[10, 10, 10], spacing=50) color($idx/9) cube(50, center=true);
|
||||
module grid3d(spacing, n, xa=[0], ya=[0], za=[0])
|
||||
{
|
||||
req_children($children);
|
||||
n = scalar_vec3(n, 1);
|
||||
spacing = scalar_vec3(spacing, undef);
|
||||
if (!is_undef(n) && !is_undef(spacing)) {
|
||||
for (xi = [0:1:n.x-1]) {
|
||||
for (yi = [0:1:n.y-1]) {
|
||||
for (zi = [0:1:n.z-1]) {
|
||||
$idx = [xi,yi,zi];
|
||||
$pos = v_mul(spacing, $idx - (n-[1,1,1])/2);
|
||||
translate($pos) children();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (xoff = xa, yoff = ya, zoff = za) {
|
||||
$pos = [xoff, yoff, zoff];
|
||||
translate($pos) children();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Section: Rotating copies of all children
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -215,43 +215,48 @@ module cuboid(
|
||||
cnt = sum(e);
|
||||
r = first_defined([chamfer, rounding]);
|
||||
dummy=assert(is_finite(r) && !approx(r,0));
|
||||
c = [min(r,size.x/2), min(r,size.y/2), min(r,size.z/2)];
|
||||
c = [r,r,r];
|
||||
m = 0.01;
|
||||
c2 = v_mul(corner,c/2);
|
||||
c3 = v_mul(corner,c-[1,1,1]*m/2);
|
||||
$fn = is_finite(chamfer)? 4 : quantup(segs(r),4);
|
||||
translate(v_mul(corner, size/2-c)) {
|
||||
if (cnt == 0 || approx(r,0)) {
|
||||
translate(c2) cube(c, center=true);
|
||||
} else if (cnt == 1) {
|
||||
if (e.x) right(c2.x) xtcyl(l=c.x, r=r);
|
||||
if (e.y) back (c2.y) ytcyl(l=c.y, r=r);
|
||||
if (e.z) up (c2.z) zcyl(l=c.z, r=r);
|
||||
} else if (cnt == 2) {
|
||||
if (!e.x) {
|
||||
intersection() {
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
}
|
||||
} else if (!e.y) {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
intersection() {
|
||||
if (cnt == 0 || approx(r,0)) {
|
||||
translate(c3) cube(m, center=true);
|
||||
} else if (cnt == 1) {
|
||||
if (e.x) right(c3.x) xtcyl(l=m, r=r);
|
||||
if (e.y) back (c3.y) ytcyl(l=m, r=r);
|
||||
if (e.z) up (c3.z) zcyl(l=m, r=r);
|
||||
} else if (cnt == 2) {
|
||||
if (!e.x) {
|
||||
intersection() {
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
}
|
||||
} else if (!e.y) {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
}
|
||||
} else {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (trimcorners) {
|
||||
tsphere(r=r);
|
||||
} else {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
if (trimcorners) {
|
||||
tsphere(r=r);
|
||||
} else {
|
||||
intersection() {
|
||||
xtcyl(l=c.x*2, r=r);
|
||||
ytcyl(l=c.y*2, r=r);
|
||||
zcyl(l=c.z*2, r=r);
|
||||
}
|
||||
}
|
||||
}
|
||||
translate(c2) cube(c, center=true); // Trim to just the octant.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,15 +286,22 @@ module cuboid(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_finite(chamfer)) {
|
||||
if (any(edges[0])) assert(chamfer <= size.y/2 && chamfer <=size.z/2, "chamfer must be smaller than half the cube length or height.");
|
||||
if (any(edges[1])) assert(chamfer <= size.x/2 && chamfer <=size.z/2, "chamfer must be smaller than half the cube width or height.");
|
||||
if (any(edges[2])) assert(chamfer <= size.x/2 && chamfer <=size.y/2, "chamfer must be smaller than half the cube width or length.");
|
||||
}
|
||||
if (is_finite(rounding)) {
|
||||
if (any(edges[0])) assert(rounding <= size.y/2 && rounding<=size.z/2, "rounding radius must be smaller than half the cube length or height.");
|
||||
if (any(edges[1])) assert(rounding <= size.x/2 && rounding<=size.z/2, "rounding radius must be smaller than half the cube width or height.");
|
||||
if (any(edges[2])) assert(rounding <= size.x/2 && rounding<=size.y/2, "rounding radius must be smaller than half the cube width or length.");
|
||||
rr = max(default(chamfer,0), default(rounding,0));
|
||||
if (rr>0) {
|
||||
rv = [for (i=[0:2])
|
||||
[for (j=[0:3])
|
||||
(edges[i][j]>0?rr:0) * v_abs(EDGE_OFFSETS[i][j])
|
||||
]
|
||||
];
|
||||
grays = pair([0,1,3,2],wrap=true); // gray code ordering.
|
||||
minx = max([for (i=[1,2], j=grays) rv[i][j[0]].x + rv[i][j[1]].x]);
|
||||
miny = max([for (i=[0,2], j=grays) rv[i][j[0]].y + rv[i][j[1]].y]);
|
||||
minz = max([for (i=[0,1], j=grays) rv[i][j[0]].z + rv[i][j[1]].z]);
|
||||
check =
|
||||
assert(minx <= size.x, "Rounding or chamfering too large for cuboid size in the X axis.")
|
||||
assert(miny <= size.y, "Rounding or chamfering too large for cuboid size in the Y axis.")
|
||||
assert(minz <= size.z, "Rounding or chamfering too large for cuboid size in the Z axis.")
|
||||
;
|
||||
}
|
||||
majrots = [[0,90,0], [90,0,0], [0,0,0]];
|
||||
attachable(anchor,spin,orient, size=size) {
|
||||
@ -1500,7 +1512,7 @@ module zcyl(
|
||||
// ---
|
||||
// od = Outer diameter of tube.
|
||||
// id = Inner diameter of tube.
|
||||
// wall = horizontal thickness of tube wall. Default 0.5
|
||||
// wall = horizontal thickness of tube wall. Default 1
|
||||
// or1 = Outer radius of bottom of tube. Default: value of r)
|
||||
// or2 = Outer radius of top of tube. Default: value of r)
|
||||
// od1 = Outer diameter of bottom of tube.
|
||||
@ -1540,14 +1552,16 @@ module tube(
|
||||
orr2 = get_radius(r1=or2, r=or, d1=od2, d=od, dflt=undef);
|
||||
irr1 = get_radius(r1=ir1, r=ir, d1=id1, d=id, dflt=undef);
|
||||
irr2 = get_radius(r1=ir2, r=ir, d1=id2, d=id, dflt=undef);
|
||||
wall = default(wall, 1);
|
||||
r1 = default(orr1, u_add(irr1,wall));
|
||||
r2 = default(orr2, u_add(irr2,wall));
|
||||
ir1 = default(irr1, u_sub(orr1,wall));
|
||||
ir2 = default(irr2, u_sub(orr2,wall));
|
||||
assert(all_defined([r1, r2, ir1, ir2]), "Must specify two of inner radius/diam, outer radius/diam, and wall width.");
|
||||
assert(ir1 <= r1, "Inner radius is larger than outer radius.");
|
||||
assert(ir2 <= r2, "Inner radius is larger than outer radius.");
|
||||
sides = segs(max(r1,r2));
|
||||
anchor = get_anchor(anchor, center, BOT, BOT);
|
||||
anchor = get_anchor(anchor, center, BOT, CENTER);
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
|
||||
zrot(realign? 180/sides : 0) {
|
||||
difference() {
|
||||
@ -2247,7 +2261,7 @@ function torus(
|
||||
// Example: Standard Conical Connectors
|
||||
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
||||
// show_anchors(custom=false);
|
||||
// Example(Spin,VPD=275): Named Conical Connectors
|
||||
// Example(Spin,VPD=150,Med): Named Conical Connectors
|
||||
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
||||
// show_anchors(std=false);
|
||||
module teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, anchor=CENTER, spin=0, orient=UP)
|
||||
@ -2310,7 +2324,6 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, anc
|
||||
profile2 = teardrop2d(r=r2, ang=ang, cap_h=cap_h2, $fn=sides),
|
||||
tip_y1 = max(column(profile1,1)),
|
||||
tip_y2 = max(column(profile2,1)),
|
||||
feef=echo(tip_y1=tip_y1, tip_y2=tip_y2),
|
||||
_cap_h1 = min(default(cap_h1, tip_y1), tip_y1),
|
||||
_cap_h2 = min(default(cap_h2, tip_y2), tip_y2),
|
||||
capvec = unit([0, _cap_h1-_cap_h2, l]),
|
||||
|
Loading…
x
Reference in New Issue
Block a user