mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 00:09:41 +00:00
Hid textured_*() functions/modules. Integrated textures into cyl(), linear_sweep(), and rotate_sweep()
This commit is contained in:
parent
f96826d9ac
commit
60a565381a
3 changed files with 728 additions and 429 deletions
339
shapes3d.scad
339
shapes3d.scad
|
@ -52,6 +52,7 @@ use <builtins.scad>
|
|||
// Example: Called as Function
|
||||
// vnf = cube([20,40,50]);
|
||||
// vnf_polyhedron(vnf);
|
||||
|
||||
module cube(size=1, center, anchor, spin=0, orient=UP)
|
||||
{
|
||||
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]);
|
||||
|
@ -177,6 +178,7 @@ function cube(size=1, center, anchor, spin=0, orient=UP) =
|
|||
// cuboid([4,2,1], rounding=2, edges=[FWD+RIGHT,BACK+LEFT]);
|
||||
// Example: Standard Connectors
|
||||
// cuboid(40) show_anchors();
|
||||
|
||||
module cuboid(
|
||||
size=[1,1,1],
|
||||
p1, p2,
|
||||
|
@ -633,6 +635,7 @@ function cuboid(
|
|||
// Example(Spin,VPD=160,VPT=[0,0,10]): Standard Connectors
|
||||
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5])
|
||||
// show_anchors();
|
||||
|
||||
module prismoid(
|
||||
size1, size2, h, shift=[0,0],
|
||||
rounding=0, rounding1, rounding2,
|
||||
|
@ -775,6 +778,7 @@ function prismoid(
|
|||
// octahedron(size=40);
|
||||
// Example: Anchors
|
||||
// octahedron(size=40) show_anchors();
|
||||
|
||||
module octahedron(size=1, anchor=CENTER, spin=0, orient=UP) {
|
||||
vnf = octahedron(size=size);
|
||||
attachable(anchor,spin,orient, vnf=vnf, extent=true) {
|
||||
|
@ -900,6 +904,7 @@ function octahedron(size=1, anchor=CENTER, spin=0, orient=UP) =
|
|||
// rounding1=[5,0,10,0], irounding1=[3,0,8,0],
|
||||
// rounding2=[0,5,0,10], irounding2=[0,3,0,8]
|
||||
// );
|
||||
|
||||
module rect_tube(
|
||||
h, size, isize, center, shift=[0,0],
|
||||
wall, size1, size2, isize1, isize2,
|
||||
|
@ -1014,6 +1019,7 @@ function rect_tube(
|
|||
// wedge([20, 40, 15]);
|
||||
// Example: Standard Connectors
|
||||
// wedge([20, 40, 15]) show_anchors();
|
||||
|
||||
module wedge(size=[1, 1, 1], center, anchor, spin=0, orient=UP)
|
||||
{
|
||||
size = scalar_vec3(size);
|
||||
|
@ -1095,6 +1101,7 @@ function wedge(size=[1,1,1], center, anchor, spin=0, orient=UP) =
|
|||
// cylinder(h=30, d=25) show_anchors();
|
||||
// cylinder(h=30, d1=25, d2=10) show_anchors();
|
||||
// }
|
||||
|
||||
module cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
||||
{
|
||||
anchor = get_anchor(anchor, center, BOTTOM, BOTTOM);
|
||||
|
@ -1128,13 +1135,7 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
|
||||
|
||||
|
||||
// Module: cyl()
|
||||
//
|
||||
// Description:
|
||||
// Creates cylinders in various anchorings and orientations, with optional rounding and chamfers.
|
||||
// You can use `h` and `l` interchangably, and all variants allow specifying size by either `r`|`d`,
|
||||
// or `r1`|`d1` and `r2`|`d2`. Note: the chamfers and rounding cannot be cumulatively longer than
|
||||
// the cylinder's length.
|
||||
// Function&Module: cyl()
|
||||
//
|
||||
// Usage: Normal Cylinders
|
||||
// cyl(l|h, r, [center], [circum=], [realign=]) [ATTACHMENTS];
|
||||
|
@ -1154,6 +1155,14 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
// cyl(l|h, r|d, rounding2=, ...);
|
||||
// cyl(l|h, r|d, rounding1=, rounding2=, ...);
|
||||
//
|
||||
// Topics: Cylinders, Textures, Rounding, Chamfers
|
||||
//
|
||||
// Description:
|
||||
// Creates cylinders in various anchorings and orientations, with optional rounding and chamfers.
|
||||
// You can use `h` and `l` interchangably, and all variants allow specifying size by either `r`|`d`,
|
||||
// or `r1`|`d1` and `r2`|`d2`. Note: the chamfers and rounding cannot be cumulatively longer than
|
||||
// the cylinder's length.
|
||||
//
|
||||
// Arguments:
|
||||
// l / h = Length of cylinder along oriented axis. Default: 1
|
||||
// r = Radius of cylinder. Default: 1
|
||||
|
@ -1165,6 +1174,7 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
// d1 = Diameter of the negative (X-, Y-, Z-) end of cylinder.
|
||||
// d2 = Diameter of the positive (X+, Y+, Z+) end of cylinder.
|
||||
// circum = If true, cylinder should circumscribe the circle of the given size. Otherwise inscribes. Default: `false`
|
||||
// shift = [X,Y] amount to shift the center of the top end with respect to the center of the bottom end.
|
||||
// chamfer = The size of the chamfers on the ends of the cylinder. Default: none.
|
||||
// chamfer1 = The size of the chamfer on the bottom end of the cylinder. Default: none.
|
||||
// chamfer2 = The size of the chamfer on the top end of the cylinder. Default: none.
|
||||
|
@ -1176,10 +1186,20 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
// rounding1 = The radius of the rounding on the bottom end of the cylinder.
|
||||
// rounding2 = The radius of the rounding on the top end of the cylinder.
|
||||
// realign = If true, rotate the cylinder by half the angle of one face.
|
||||
// texture = A texture name string, or a rectangular array of scalar height values (0.0 to 1.0), or a VNF tile that defines the texture to apply to vertical surfaces. See {{texture()}} for what named textures are supported.
|
||||
// tex_size = An optional 2D target size for the textures. Actual texture sizes will be scaled somewhat to evenly fit the available surface. Default: `[5,5]`
|
||||
// tex_counts = If given instead of tex_size, gives the tile repetition counts for textures over the surface length and height.
|
||||
// tex_inset = If numeric, lowers the texture into the surface by that amount, before the tex_scale multiplier is applied. If `true`, insets by exactly `1`. Default: `false`
|
||||
// tex_rot = If true, rotates the texture 90º.
|
||||
// tex_scale = Scaling multiplier for the texture depth.
|
||||
// tex_samples = Minimum number of "bend points" to have in VNF texture tiles. Default: 8
|
||||
// tex_style = {{vnf_vertex_array()}} style used to triangulate heightfield textures. Default: "min_edge"
|
||||
// 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`
|
||||
//
|
||||
// See Also: texture(), rotate_sweep()
|
||||
//
|
||||
// Example: By Radius
|
||||
// xdistribute(30) {
|
||||
// cyl(l=40, r=10);
|
||||
|
@ -1230,6 +1250,156 @@ function cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
|||
// cyl(l=30, d1=25, d2=10) show_anchors();
|
||||
// }
|
||||
//
|
||||
// Example: Texturing with heightfield diamonds
|
||||
// cyl(h=40, r=20, texture="diamonds", tex_size=[5,5]);
|
||||
//
|
||||
// Example: Texturing with heightfield pyramids
|
||||
// cyl(h=40, r1=20, r2=15,
|
||||
// texture="pyramids", tex_size=[5,5],
|
||||
// tex_style="convex");
|
||||
//
|
||||
// Example: Texturing with heightfield truncated pyramids
|
||||
// cyl(h=40, r1=20, r2=15, chamfer=5,
|
||||
// texture="trunc_pyramids",
|
||||
// tex_size=[5,5], tex_style="convex");
|
||||
//
|
||||
// Example: Texturing with VNF tile "vnf_dots"
|
||||
// cyl(h=40, r1=20, r2=15, rounding=9,
|
||||
// texture="vnf_dots", tex_size=[5,5],
|
||||
// samples=6);
|
||||
//
|
||||
// Example: Texturing with VNF tile "vnf_bricks"
|
||||
// cyl(h=50, r1=25, r2=20, shift=[0,10], rounding1=-10,
|
||||
// texture="vnf_bricks", tex_size=[10,10],
|
||||
// tex_scale=0.5, tex_style="concave");
|
||||
//
|
||||
// Example: No Texture Taper
|
||||
// cyl(d1=25, d2=20, h=30, rounding=5,
|
||||
// texture="trunc_ribs", tex_size=[5,1]);
|
||||
//
|
||||
// Example: Taper Texure at Extreme Ends
|
||||
// cyl(d1=25, d2=20, h=30, rounding=5,
|
||||
// texture="trunc_ribs", taper=0,
|
||||
// tex_size=[5,1]);
|
||||
//
|
||||
// Example: Taper Texture over First and Last 10%
|
||||
// cyl(d1=25, d2=20, h=30, rounding=5,
|
||||
// texture="trunc_ribs", taper=10,
|
||||
// tex_size=[5,1]);
|
||||
|
||||
function cyl(
|
||||
h, r, center,
|
||||
l, r1, r2,
|
||||
d, d1, d2,
|
||||
length, height,
|
||||
chamfer, chamfer1, chamfer2,
|
||||
chamfang, chamfang1, chamfang2,
|
||||
rounding, rounding1, rounding2,
|
||||
circum=false, realign=false,
|
||||
from_end=false, shift=[0,0],
|
||||
texture, tex_size=[5,5], tex_counts,
|
||||
tex_inset=false, tex_rot=false,
|
||||
tex_scale=1, tex_samples,
|
||||
tex_taper, tex_style="min_edge",
|
||||
anchor, spin=0, orient=UP
|
||||
) =
|
||||
let(
|
||||
l = first_defined([l, h, length, height, 1]),
|
||||
_r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1),
|
||||
_r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1),
|
||||
sides = segs(max(_r1,_r2)),
|
||||
sc = circum? 1/cos(180/sides) : 1,
|
||||
r1 = _r1 * sc,
|
||||
r2 = _r2 * sc,
|
||||
phi = atan2(l, r2-r1),
|
||||
anchor = get_anchor(anchor,center,BOT,CENTER)
|
||||
)
|
||||
assert(is_finite(l), "l/h/length/height must be a finite number.")
|
||||
assert(is_finite(r1), "r/r1/d/d1 must be a finite number.")
|
||||
assert(is_finite(r2), "r2 or d2 must be a finite number.")
|
||||
assert(is_vector(shift,2), "shift must be a 2D vector.")
|
||||
let(
|
||||
vnf = texture != undef? _textured_cylinder(
|
||||
l=l, r1=r1, r2=r2,
|
||||
texture=texture, tex_size=tex_size,
|
||||
counts=tex_counts, tex_scale=tex_scale,
|
||||
inset=tex_inset, rot=tex_rot,
|
||||
style=tex_style, taper=tex_taper,
|
||||
chamfer=chamfer,
|
||||
chamfer1=chamfer1,
|
||||
chamfer2=chamfer2,
|
||||
rounding=rounding,
|
||||
rounding1=rounding1,
|
||||
rounding2=rounding2,
|
||||
samples=tex_samples
|
||||
) :
|
||||
!any_defined([chamfer, chamfer1, chamfer2, rounding, rounding1, rounding2])?
|
||||
cylinder(h=l, r1=r1, r2=r2, center=true, $fn=sides) :
|
||||
let(
|
||||
vang = atan2(l, r1-r2)/2,
|
||||
chang = default(chamfang, 45),
|
||||
chang1 = 90-first_defined([chamfang1, chamfang, vang]),
|
||||
chang2 = 90-first_defined([chamfang2, chamfang, 90-vang]),
|
||||
checks1 =
|
||||
assert(is_finite(chang) && chang>0 && chang<90, "chamfang must be a number between 0 and 90 (exclusive) if given.")
|
||||
assert(is_finite(chang1) && chang1>0 && chang1<90, "chamfang1 must be a number between 0 and 90 (exclusive) if given.")
|
||||
assert(is_finite(chang2) && chang2>0 && chang2<90, "chamfang2 must be a number between 0 and 90 (exclusive) if given.")
|
||||
undef,
|
||||
chamf = default(chamfer, 0) * (from_end? 1 : tan(chang1)),
|
||||
chamf1 = first_defined([chamfer1, chamfer, 0]) * (from_end? 1 : tan(chang1)),
|
||||
chamf2 = first_defined([chamfer2, chamfer, 0]) * (from_end? 1 : tan(chang2)),
|
||||
round = default(rounding, 0),
|
||||
round1 = first_defined([rounding1, rounding, 0]),
|
||||
round2 = first_defined([rounding2, rounding, 0]),
|
||||
dy1 = abs(first_defined([chamf1, round1, 0])),
|
||||
dy2 = abs(first_defined([chamf2, round2, 0])),
|
||||
checks2 =
|
||||
assert(is_finite(chamf), "chamfer must be a finite number if given.")
|
||||
assert(is_finite(chamf1), "chamfer1 must be a finite number if given.")
|
||||
assert(is_finite(chamf2), "chamfer2 must be a finite number if given.")
|
||||
assert(is_finite(round), "rounding must be a finite number if given.")
|
||||
assert(is_finite(round1), "rounding1 must be a finite number if given.")
|
||||
assert(is_finite(round2), "rounding2 must be a finite number if given.")
|
||||
assert(chamf <= r1, "chamfer is larger than the r1 radius of the cylinder.")
|
||||
assert(chamf <= r2, "chamfer is larger than the r2 radius of the cylinder.")
|
||||
assert(chamf1 <= r1, "chamfer1 is larger than the r1 radius of the cylinder.")
|
||||
assert(chamf2 <= r2, "chamfer2 is larger than the r2 radius of the cylinder.")
|
||||
assert(round <= r1, "rounding is larger than the r1 radius of the cylinder.")
|
||||
assert(round <= r2, "rounding is larger than the r2 radius of the cylinder.")
|
||||
assert(round1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.")
|
||||
assert(round2 <= r2, "rounding2 is larger than the r1 radius of the cylinder.")
|
||||
assert(dy1+dy2 <= l, "Sum of fillets and chamfer sizes must be less than the length of the cylinder.")
|
||||
undef,
|
||||
path = [
|
||||
[0,-l/2],
|
||||
if (is_finite(chamf1) && !approx(chamf1,0))
|
||||
let(
|
||||
p1 = [r1-chamf1/tan(chang1),-l/2],
|
||||
p2 = lerp([r1,-l/2],[r2,l/2],abs(chamf1)/l)
|
||||
) each [p1,p2]
|
||||
else if (is_finite(round1) && !approx(round1,0))
|
||||
each arc(r=abs(round1), corner=[[(round1>0?0:1e6),-l/2],[r1,-l/2],[r2,l/2]])
|
||||
else [r1,-l/2],
|
||||
if (is_finite(chamf2) && !approx(chamf2,0))
|
||||
let(
|
||||
p1 = lerp([r2,l/2],[r1,-l/2],abs(chamf2)/l),
|
||||
p2 = [r2-chamf2/tan(chang2),l/2]
|
||||
) each [p1,p2]
|
||||
else if (is_finite(round2) && !approx(round2,0))
|
||||
each arc(r=abs(round2), corner=[[r1,-l/2],[r2,l/2],[(round2>0?0:1e6),l/2]])
|
||||
else [r2,l/2],
|
||||
[0,l/2]
|
||||
]
|
||||
) rotate_sweep(path),
|
||||
skmat = down(l/2) *
|
||||
skew(sxz=shift.x/l, syz=shift.y/l) *
|
||||
up(l/2) *
|
||||
zrot(realign? 180/sides : 0),
|
||||
ovnf = apply(skmat, vnf)
|
||||
)
|
||||
reorient(anchor,spin,orient, r1=r1, r2=r2, l=l, shift=shift, p=ovnf);
|
||||
|
||||
|
||||
module cyl(
|
||||
h, r, center,
|
||||
l, r1, r2,
|
||||
|
@ -1237,7 +1407,12 @@ module cyl(
|
|||
chamfer, chamfer1, chamfer2,
|
||||
chamfang, chamfang1, chamfang2,
|
||||
rounding, rounding1, rounding2,
|
||||
circum=false, realign=false, from_end=false,
|
||||
circum=false, realign=false,
|
||||
from_end=false, shift=[0,0],
|
||||
texture, tex_size=[5,5], tex_counts,
|
||||
tex_inset=false, tex_rot=false,
|
||||
tex_scale=1, tex_samples,
|
||||
tex_taper, tex_style="min_edge",
|
||||
anchor, spin=0, orient=UP
|
||||
) {
|
||||
l = first_defined([l, h, 1]);
|
||||
|
@ -1245,86 +1420,76 @@ module cyl(
|
|||
_r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1);
|
||||
sides = segs(max(_r1,_r2));
|
||||
sc = circum? 1/cos(180/sides) : 1;
|
||||
r1=_r1*sc;
|
||||
r2=_r2*sc;
|
||||
r1 = _r1 * sc;
|
||||
r2 = _r2 * sc;
|
||||
phi = atan2(l, r2-r1);
|
||||
anchor = get_anchor(anchor,center,BOT,CENTER);
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=l) {
|
||||
skmat = down(l/2) * skew(sxz=shift.x/l, syz=shift.y/l) * up(l/2);
|
||||
attachable(anchor,spin,orient, r1=r1, r2=r2, l=l, shift=shift) {
|
||||
multmatrix(skmat)
|
||||
zrot(realign? 180/sides : 0) {
|
||||
if (!any_defined([chamfer, chamfer1, chamfer2, rounding, rounding1, rounding2])) {
|
||||
if (texture != undef) {
|
||||
_textured_cylinder(
|
||||
l=l, r1=r1, r2=r2,
|
||||
texture=texture, tex_size=tex_size,
|
||||
counts=tex_counts, tex_scale=tex_scale,
|
||||
inset=tex_inset, rot=tex_rot,
|
||||
style=tex_style, taper=tex_taper,
|
||||
chamfer=chamfer,
|
||||
chamfer1=chamfer1,
|
||||
chamfer2=chamfer2,
|
||||
rounding=rounding,
|
||||
rounding1=rounding1,
|
||||
rounding2=rounding2,
|
||||
convexity=10, samples=tex_samples
|
||||
);
|
||||
} else if (!any_defined([chamfer, chamfer1, chamfer2, rounding, rounding1, rounding2])) {
|
||||
cylinder(h=l, r1=r1, r2=r2, center=true, $fn=sides);
|
||||
} else {
|
||||
vang = atan2(l, r1-r2)/2;
|
||||
chang1 = 90-first_defined([chamfang1, chamfang, vang]);
|
||||
chang1 = 90-first_defined([chamfang1, chamfang, vang,]);
|
||||
chang2 = 90-first_defined([chamfang2, chamfang, 90-vang]);
|
||||
cham1 = u_mul(first_defined([chamfer1, chamfer]) , (from_end? 1 : tan(chang1)));
|
||||
cham2 = u_mul(first_defined([chamfer2, chamfer]) , (from_end? 1 : tan(chang2)));
|
||||
fil1 = first_defined([rounding1, rounding]);
|
||||
fil2 = first_defined([rounding2, rounding]);
|
||||
if (chamfer != undef) {
|
||||
checks =
|
||||
assert(chamfer <= r1, "chamfer is larger than the r1 radius of the cylinder.")
|
||||
assert(chamfer <= r2, "chamfer is larger than the r2 radius of the cylinder.");
|
||||
}
|
||||
if (cham1 != undef) {
|
||||
check = assert(cham1 <= r1, "chamfer1 is larger than the r1 radius of the cylinder.");
|
||||
}
|
||||
if (cham2 != undef) {
|
||||
check = assert(cham2 <= r2, "chamfer2 is larger than the r2 radius of the cylinder.");
|
||||
}
|
||||
if (rounding != undef) {
|
||||
checks =
|
||||
assert(rounding <= r1, "rounding is larger than the r1 radius of the cylinder.")
|
||||
assert(rounding <= r2, "rounding is larger than the r2 radius of the cylinder.");
|
||||
}
|
||||
if (fil1 != undef) {
|
||||
check = assert(fil1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.");
|
||||
}
|
||||
if (fil2 != undef) {
|
||||
check = assert(fil2 <= r2, "rounding2 is larger than the r1 radius of the cylinder.");
|
||||
}
|
||||
dy1 = abs(first_defined([cham1, fil1, 0]));
|
||||
dy2 = abs(first_defined([cham2, fil2, 0]));
|
||||
check = assert(dy1+dy2 <= l, "Sum of fillets and chamfer sizes must be less than the length of the cylinder.");
|
||||
|
||||
path = concat(
|
||||
[[0,l/2]],
|
||||
|
||||
!is_undef(cham2)? (
|
||||
chamf = default(chamfer, 0) * (from_end? 1 : tan(chang1));
|
||||
chamf1 = first_defined([chamfer1, chamfer, 0]) * (from_end? 1 : tan(chang1));
|
||||
chamf2 = first_defined([chamfer2, chamfer, 0]) * (from_end? 1 : tan(chang2));
|
||||
round = default(rounding, 0);
|
||||
round1 = first_defined([rounding1, rounding, 0]);
|
||||
round2 = first_defined([rounding2, rounding, 0]);
|
||||
dy1 = abs(first_defined([chamf1, round1, 0]));
|
||||
dy2 = abs(first_defined([chamf2, round2, 0]));
|
||||
checks =
|
||||
assert(chamf <= r1, "chamfer is larger than the r1 radius of the cylinder.")
|
||||
assert(chamf <= r2, "chamfer is larger than the r2 radius of the cylinder.")
|
||||
assert(chamf1 <= r1, "chamfer1 is larger than the r1 radius of the cylinder.")
|
||||
assert(chamf2 <= r2, "chamfer2 is larger than the r2 radius of the cylinder.")
|
||||
assert(round <= r1, "rounding is larger than the r1 radius of the cylinder.")
|
||||
assert(round <= r2, "rounding is larger than the r2 radius of the cylinder.")
|
||||
assert(round1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.")
|
||||
assert(round2 <= r2, "rounding2 is larger than the r1 radius of the cylinder.")
|
||||
assert(dy1+dy2 <= l, "Sum of fillets and chamfer sizes must be less than the length of the cylinder.")
|
||||
undef;
|
||||
path = [
|
||||
[0,-l/2],
|
||||
if (is_finite(chamf1) && !approx(chamf1,0))
|
||||
let(
|
||||
p1 = [r2-cham2/tan(chang2),l/2],
|
||||
p2 = lerp([r2,l/2],[r1,-l/2],abs(cham2)/l)
|
||||
) [p1,p2]
|
||||
) : !is_undef(fil2)? (
|
||||
p1 = [r1-chamf1/tan(chang1),-l/2],
|
||||
p2 = lerp([r1,-l/2],[r2,l/2],abs(chamf1)/l)
|
||||
) each [p1,p2]
|
||||
else if (is_finite(round1) && !approx(round1,0))
|
||||
each arc(r=abs(round1), corner=[[(round1>0?0:1e6),-l/2],[r1,-l/2],[r2,l/2]])
|
||||
else [r1,-l/2],
|
||||
if (is_finite(chamf2) && !approx(chamf2,0))
|
||||
let(
|
||||
cn = circle_2tangents(abs(fil2), [r2-fil2,l/2], [r2,l/2], [r1,-l/2]),
|
||||
ang = fil2<0? phi : phi-180,
|
||||
steps = ceil(abs(ang)/360*segs(abs(fil2))),
|
||||
step = ang/steps,
|
||||
pts = [for (i=[0:1:steps]) let(a=90+i*step) cn[0]+abs(fil2)*[cos(a),sin(a)]]
|
||||
) pts
|
||||
) : [[r2,l/2]],
|
||||
p1 = lerp([r2,l/2],[r1,-l/2],abs(chamf2)/l),
|
||||
p2 = [r2-chamf2/tan(chang2),l/2]
|
||||
) each [p1,p2]
|
||||
else if (is_finite(round2) && !approx(round2,0))
|
||||
each arc(r=abs(round2), corner=[[r1,-l/2],[r2,l/2],[(round2>0?0:1e6),l/2]])
|
||||
else [r2,l/2],
|
||||
[0,l/2]
|
||||
];
|
||||
|
||||
!is_undef(cham1)? (
|
||||
let(
|
||||
p1 = lerp([r1,-l/2],[r2,l/2],abs(cham1)/l),
|
||||
p2 = [r1-cham1/tan(chang1),-l/2]
|
||||
) [p1,p2]
|
||||
) : !is_undef(fil1)? (
|
||||
let(
|
||||
cn = circle_2tangents(abs(fil1), [r1-fil1,-l/2], [r1,-l/2], [r2,l/2]),
|
||||
ang = fil1<0? 180-phi : -phi,
|
||||
steps = ceil(abs(ang)/360*segs(abs(fil1))),
|
||||
step = ang/steps,
|
||||
pts = [for (i=[0:1:steps]) let(a=(fil1<0?180:0)+(phi-90)+i*step) cn[0]+abs(fil1)*[cos(a),sin(a)]]
|
||||
) pts
|
||||
) : [[r1,-l/2]],
|
||||
|
||||
[[0,-l/2]]
|
||||
);
|
||||
rotate_extrude(convexity=2) {
|
||||
polygon(path);
|
||||
}
|
||||
rotate_extrude(convexity=2) polygon(path);
|
||||
}
|
||||
}
|
||||
children();
|
||||
|
@ -1378,6 +1543,7 @@ module cyl(
|
|||
// xcyl(l=35, d=20);
|
||||
// xcyl(l=35, d1=30, d2=10);
|
||||
// }
|
||||
|
||||
module xcyl(
|
||||
h, r, d, r1, r2, d1, d2, l,
|
||||
chamfer, chamfer1, chamfer2,
|
||||
|
@ -1448,6 +1614,7 @@ module xcyl(
|
|||
// ycyl(l=35, d=20);
|
||||
// ycyl(l=35, d1=30, d2=10);
|
||||
// }
|
||||
|
||||
module ycyl(
|
||||
h, r, d, r1, r2, d1, d2, l,
|
||||
chamfer, chamfer1, chamfer2,
|
||||
|
@ -1519,6 +1686,7 @@ module ycyl(
|
|||
// zcyl(l=35, d=20);
|
||||
// zcyl(l=35, d1=30, d2=10);
|
||||
// }
|
||||
|
||||
module zcyl(
|
||||
h, r, d, r1, r2, d1, d2, l,
|
||||
chamfer, chamfer1, chamfer2,
|
||||
|
@ -1596,6 +1764,7 @@ module zcyl(
|
|||
// tube(h=30, or1=40, or2=30, ir1=20, ir2=30);
|
||||
// Example: Standard Connectors
|
||||
// tube(h=30, or=40, wall=5) show_anchors();
|
||||
|
||||
module tube(
|
||||
h, or, ir, center,
|
||||
od, id, wall,
|
||||
|
@ -1673,6 +1842,7 @@ module tube(
|
|||
// Example: Generating a VNF
|
||||
// vnf = pie_slice(ang=150, l=20, r1=30, r2=50);
|
||||
// vnf_polyhedron(vnf);
|
||||
|
||||
module pie_slice(
|
||||
h, r, ang=30, center,
|
||||
r1, r2, d, d1, d2, l,
|
||||
|
@ -1696,7 +1866,6 @@ module pie_slice(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function pie_slice(
|
||||
h, r, ang=30, center,
|
||||
r1, r2, d, d1, d2, l,
|
||||
|
@ -1774,6 +1943,7 @@ function pie_slice(
|
|||
// Example: Called as Function
|
||||
// vnf = sphere(d=100, style="icosa");
|
||||
// vnf_polyhedron(vnf);
|
||||
|
||||
module sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
if (!circum && style=="orig" && is_num(r)) {
|
||||
|
@ -1789,7 +1959,6 @@ module sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=UP
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=UP) =
|
||||
spheroid(r=r, d=d, circum=circum, style=style, anchor=anchor, spin=spin, orient=orient);
|
||||
|
||||
|
@ -1884,6 +2053,7 @@ function sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=
|
|||
// Example: The dual of "icosa" features hexagons and always 12 pentagons:
|
||||
// color("green")spheroid(r=10.01, $fn=256);
|
||||
// spheroid(r=10, style="icosa", circum=true, $fn=16);
|
||||
|
||||
module spheroid(r, style="aligned", d, circum=false, dual=false, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
|
@ -2194,6 +2364,7 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
|
|||
// vnf_polyhedron(torus(d_min=15, od=60), convexity=4);
|
||||
// Example: Standard Connectors
|
||||
// torus(od=60, id=30) show_anchors();
|
||||
|
||||
module torus(
|
||||
r_maj, r_min, center,
|
||||
d_maj, d_min,
|
||||
|
@ -2314,6 +2485,7 @@ function torus(
|
|||
// 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)
|
||||
{
|
||||
r1 = get_radius(r=r, r1=r1, d=d, d1=d1, dflt=1);
|
||||
|
@ -2432,6 +2604,7 @@ function teardrop(h, r, ang=45, cap_h, r1, r2, d, d1, d2, cap_h1, cap_h2, l, anc
|
|||
// }
|
||||
// Example: Standard Connectors
|
||||
// onion(d=30, ang=30, cap_h=20) show_anchors();
|
||||
|
||||
module onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
|
@ -2527,6 +2700,7 @@ function onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP) =
|
|||
// text3d("Foobar", h=2, anchor=CENTER);
|
||||
// text3d("Foobar", h=2, anchor=str("baseline",CENTER));
|
||||
// text3d("Foobar", h=2, anchor=str("baseline",BOTTOM+RIGHT));
|
||||
|
||||
module text3d(text, h=1, size=10, font="Helvetica", halign, valign, spacing=1.0, direction="ltr", language="em", script="latin", anchor="baseline[-1,0,-1]", spin=0, orient=UP) {
|
||||
no_children($children);
|
||||
dummy1 =
|
||||
|
@ -2721,6 +2895,7 @@ function _cut_interp(pathcut, path, data) =
|
|||
// color("red")stroke(path, width=.3);
|
||||
// kern = [1,1.2,1,1,.3,-.2,1,0,.8,1,1.1,1];
|
||||
// path_text(path, "Example text", font="Courier", size=5, lettersize = 5/1.2, kern=kern, normal=UP);
|
||||
|
||||
module path_text(path, text, font, size, thickness, lettersize, offset=0, reverse=false, normal, top, center=false, textmetrics=false, kern=0)
|
||||
{
|
||||
no_children($children);
|
||||
|
@ -2849,6 +3024,7 @@ module path_text(path, text, font, size, thickness, lettersize, offset=0, revers
|
|||
// position(BOT+FRONT)
|
||||
// interior_fillet(l=50, r=10, spin=180, orient=RIGHT);
|
||||
// }
|
||||
|
||||
module interior_fillet(l=1.0, r, ang=90, overlap=0.01, d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
steps = ceil(segs(r)*(180-ang)/360);
|
||||
|
@ -2923,6 +3099,7 @@ module interior_fillet(l=1.0, r, ang=90, overlap=0.01, d, anchor=CENTER, spin=0,
|
|||
// size=[100,100], bottom=-20, data=fn,
|
||||
// xrange=[-180:2:180], yrange=[-180:2:180]
|
||||
// );
|
||||
|
||||
module heightfield(data, size=[100,100], bottom=-20, maxz=100, xrange=[-1:0.04:1], yrange=[-1:0.04:1], style="default", convexity=10, anchor=CENTER, spin=0, orient=UP)
|
||||
{
|
||||
size = is_num(size)? [size,size] : point2d(size);
|
||||
|
@ -3057,6 +3234,7 @@ function heightfield(data, size=[100,100], bottom=-20, maxz=100, xrange=[-1:0.04
|
|||
// l=100, r=30, base=5, data=fn,
|
||||
// xrange=[-180:2:180], yrange=[-180:2:180]
|
||||
// );
|
||||
|
||||
function cylindrical_heightfield(
|
||||
data, l, r, base=1,
|
||||
transpose=false, aspect=1,
|
||||
|
@ -3176,6 +3354,7 @@ module cylindrical_heightfield(
|
|||
// Example(2D,Big): Metric vs Imperial
|
||||
// ruler(12,width=50,inch=true,labels=true,maxscale=0);
|
||||
// fwd(50)ruler(300,width=50,labels=true);
|
||||
|
||||
module ruler(length=100, width, thickness=1, depth=3, labels=false, pipscale=1/3, maxscale,
|
||||
colors=["black","white"], alpha=1.0, unit=1, inch=false, anchor=LEFT+BACK+TOP, spin=0, orient=UP)
|
||||
{
|
||||
|
|
5
vnf.scad
5
vnf.scad
|
@ -886,6 +886,11 @@ function _slice_3dpolygons(polys, dir, cuts) =
|
|||
// 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`
|
||||
// atype = Select "hull" or "intersect" anchor type. Default: "hull"
|
||||
// Anchor Types:
|
||||
// "hull" = Anchors to the virtual convex hull of the shape.
|
||||
// "intersect" = Anchors to the surface of the shape.
|
||||
// Extra Anchors:
|
||||
// "origin" = Anchor at the origin, oriented UP.
|
||||
module vnf_polyhedron(vnf, convexity=2, extent=true, cp="centroid", anchor="origin", spin=0, orient=UP, atype="hull") {
|
||||
vnf = is_vnf_list(vnf)? vnf_join(vnf) : vnf;
|
||||
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
|
||||
|
|
Loading…
Reference in a new issue