mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +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
|
// Example: Called as Function
|
||||||
// vnf = cube([20,40,50]);
|
// vnf = cube([20,40,50]);
|
||||||
// vnf_polyhedron(vnf);
|
// vnf_polyhedron(vnf);
|
||||||
|
|
||||||
module cube(size=1, center, anchor, spin=0, orient=UP)
|
module cube(size=1, center, anchor, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]);
|
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]);
|
// cuboid([4,2,1], rounding=2, edges=[FWD+RIGHT,BACK+LEFT]);
|
||||||
// Example: Standard Connectors
|
// Example: Standard Connectors
|
||||||
// cuboid(40) show_anchors();
|
// cuboid(40) show_anchors();
|
||||||
|
|
||||||
module cuboid(
|
module cuboid(
|
||||||
size=[1,1,1],
|
size=[1,1,1],
|
||||||
p1, p2,
|
p1, p2,
|
||||||
|
@ -633,6 +635,7 @@ function cuboid(
|
||||||
// Example(Spin,VPD=160,VPT=[0,0,10]): Standard Connectors
|
// Example(Spin,VPD=160,VPT=[0,0,10]): Standard Connectors
|
||||||
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5])
|
// prismoid(size1=[50,30], size2=[20,20], h=20, shift=[15,5])
|
||||||
// show_anchors();
|
// show_anchors();
|
||||||
|
|
||||||
module prismoid(
|
module prismoid(
|
||||||
size1, size2, h, shift=[0,0],
|
size1, size2, h, shift=[0,0],
|
||||||
rounding=0, rounding1, rounding2,
|
rounding=0, rounding1, rounding2,
|
||||||
|
@ -775,6 +778,7 @@ function prismoid(
|
||||||
// octahedron(size=40);
|
// octahedron(size=40);
|
||||||
// Example: Anchors
|
// Example: Anchors
|
||||||
// octahedron(size=40) show_anchors();
|
// octahedron(size=40) show_anchors();
|
||||||
|
|
||||||
module octahedron(size=1, anchor=CENTER, spin=0, orient=UP) {
|
module octahedron(size=1, anchor=CENTER, spin=0, orient=UP) {
|
||||||
vnf = octahedron(size=size);
|
vnf = octahedron(size=size);
|
||||||
attachable(anchor,spin,orient, vnf=vnf, extent=true) {
|
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],
|
// rounding1=[5,0,10,0], irounding1=[3,0,8,0],
|
||||||
// rounding2=[0,5,0,10], irounding2=[0,3,0,8]
|
// rounding2=[0,5,0,10], irounding2=[0,3,0,8]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
module rect_tube(
|
module rect_tube(
|
||||||
h, size, isize, center, shift=[0,0],
|
h, size, isize, center, shift=[0,0],
|
||||||
wall, size1, size2, isize1, isize2,
|
wall, size1, size2, isize1, isize2,
|
||||||
|
@ -1014,6 +1019,7 @@ function rect_tube(
|
||||||
// wedge([20, 40, 15]);
|
// wedge([20, 40, 15]);
|
||||||
// Example: Standard Connectors
|
// Example: Standard Connectors
|
||||||
// wedge([20, 40, 15]) show_anchors();
|
// wedge([20, 40, 15]) show_anchors();
|
||||||
|
|
||||||
module wedge(size=[1, 1, 1], center, anchor, spin=0, orient=UP)
|
module wedge(size=[1, 1, 1], center, anchor, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
size = scalar_vec3(size);
|
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, d=25) show_anchors();
|
||||||
// cylinder(h=30, d1=25, d2=10) 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)
|
module cylinder(h, r1, r2, center, l, r, d, d1, d2, anchor, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
anchor = get_anchor(anchor, center, BOTTOM, BOTTOM);
|
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()
|
// Function&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.
|
|
||||||
//
|
//
|
||||||
// Usage: Normal Cylinders
|
// Usage: Normal Cylinders
|
||||||
// cyl(l|h, r, [center], [circum=], [realign=]) [ATTACHMENTS];
|
// 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, rounding2=, ...);
|
||||||
// cyl(l|h, r|d, rounding1=, 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:
|
// Arguments:
|
||||||
// l / h = Length of cylinder along oriented axis. Default: 1
|
// l / h = Length of cylinder along oriented axis. Default: 1
|
||||||
// r = Radius of cylinder. 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.
|
// d1 = Diameter of the negative (X-, Y-, Z-) end of cylinder.
|
||||||
// d2 = Diameter of the positive (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`
|
// 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.
|
// 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.
|
// 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.
|
// 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.
|
// 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.
|
// 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.
|
// 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`
|
// 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`
|
// 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`
|
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||||
//
|
//
|
||||||
|
// See Also: texture(), rotate_sweep()
|
||||||
|
//
|
||||||
// Example: By Radius
|
// Example: By Radius
|
||||||
// xdistribute(30) {
|
// xdistribute(30) {
|
||||||
// cyl(l=40, r=10);
|
// 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();
|
// 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(
|
module cyl(
|
||||||
h, r, center,
|
h, r, center,
|
||||||
l, r1, r2,
|
l, r1, r2,
|
||||||
|
@ -1237,7 +1407,12 @@ module cyl(
|
||||||
chamfer, chamfer1, chamfer2,
|
chamfer, chamfer1, chamfer2,
|
||||||
chamfang, chamfang1, chamfang2,
|
chamfang, chamfang1, chamfang2,
|
||||||
rounding, rounding1, rounding2,
|
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
|
anchor, spin=0, orient=UP
|
||||||
) {
|
) {
|
||||||
l = first_defined([l, h, 1]);
|
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);
|
_r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1);
|
||||||
sides = segs(max(_r1,_r2));
|
sides = segs(max(_r1,_r2));
|
||||||
sc = circum? 1/cos(180/sides) : 1;
|
sc = circum? 1/cos(180/sides) : 1;
|
||||||
r1=_r1*sc;
|
r1 = _r1 * sc;
|
||||||
r2=_r2*sc;
|
r2 = _r2 * sc;
|
||||||
phi = atan2(l, r2-r1);
|
phi = atan2(l, r2-r1);
|
||||||
anchor = get_anchor(anchor,center,BOT,CENTER);
|
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) {
|
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);
|
cylinder(h=l, r1=r1, r2=r2, center=true, $fn=sides);
|
||||||
} else {
|
} else {
|
||||||
vang = atan2(l, r1-r2)/2;
|
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]);
|
chang2 = 90-first_defined([chamfang2, chamfang, 90-vang]);
|
||||||
cham1 = u_mul(first_defined([chamfer1, chamfer]) , (from_end? 1 : tan(chang1)));
|
chamf = default(chamfer, 0) * (from_end? 1 : tan(chang1));
|
||||||
cham2 = u_mul(first_defined([chamfer2, chamfer]) , (from_end? 1 : tan(chang2)));
|
chamf1 = first_defined([chamfer1, chamfer, 0]) * (from_end? 1 : tan(chang1));
|
||||||
fil1 = first_defined([rounding1, rounding]);
|
chamf2 = first_defined([chamfer2, chamfer, 0]) * (from_end? 1 : tan(chang2));
|
||||||
fil2 = first_defined([rounding2, rounding]);
|
round = default(rounding, 0);
|
||||||
if (chamfer != undef) {
|
round1 = first_defined([rounding1, rounding, 0]);
|
||||||
checks =
|
round2 = first_defined([rounding2, rounding, 0]);
|
||||||
assert(chamfer <= r1, "chamfer is larger than the r1 radius of the cylinder.")
|
dy1 = abs(first_defined([chamf1, round1, 0]));
|
||||||
assert(chamfer <= r2, "chamfer is larger than the r2 radius of the cylinder.");
|
dy2 = abs(first_defined([chamf2, round2, 0]));
|
||||||
}
|
checks =
|
||||||
if (cham1 != undef) {
|
assert(chamf <= r1, "chamfer is larger than the r1 radius of the cylinder.")
|
||||||
check = assert(cham1 <= r1, "chamfer1 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.")
|
||||||
if (cham2 != undef) {
|
assert(chamf2 <= r2, "chamfer2 is larger than the r2 radius of the cylinder.")
|
||||||
check = assert(cham2 <= 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.")
|
||||||
if (rounding != undef) {
|
assert(round1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.")
|
||||||
checks =
|
assert(round2 <= r2, "rounding2 is larger than the r1 radius of the cylinder.")
|
||||||
assert(rounding <= r1, "rounding 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.")
|
||||||
assert(rounding <= r2, "rounding is larger than the r2 radius of the cylinder.");
|
undef;
|
||||||
}
|
path = [
|
||||||
if (fil1 != undef) {
|
[0,-l/2],
|
||||||
check = assert(fil1 <= r1, "rounding1 is larger than the r1 radius of the cylinder.");
|
if (is_finite(chamf1) && !approx(chamf1,0))
|
||||||
}
|
|
||||||
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)? (
|
|
||||||
let(
|
let(
|
||||||
p1 = [r2-cham2/tan(chang2),l/2],
|
p1 = [r1-chamf1/tan(chang1),-l/2],
|
||||||
p2 = lerp([r2,l/2],[r1,-l/2],abs(cham2)/l)
|
p2 = lerp([r1,-l/2],[r2,l/2],abs(chamf1)/l)
|
||||||
) [p1,p2]
|
) each [p1,p2]
|
||||||
) : !is_undef(fil2)? (
|
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(
|
let(
|
||||||
cn = circle_2tangents(abs(fil2), [r2-fil2,l/2], [r2,l/2], [r1,-l/2]),
|
p1 = lerp([r2,l/2],[r1,-l/2],abs(chamf2)/l),
|
||||||
ang = fil2<0? phi : phi-180,
|
p2 = [r2-chamf2/tan(chang2),l/2]
|
||||||
steps = ceil(abs(ang)/360*segs(abs(fil2))),
|
) each [p1,p2]
|
||||||
step = ang/steps,
|
else if (is_finite(round2) && !approx(round2,0))
|
||||||
pts = [for (i=[0:1:steps]) let(a=90+i*step) cn[0]+abs(fil2)*[cos(a),sin(a)]]
|
each arc(r=abs(round2), corner=[[r1,-l/2],[r2,l/2],[(round2>0?0:1e6),l/2]])
|
||||||
) pts
|
else [r2,l/2],
|
||||||
) : [[r2,l/2]],
|
[0,l/2]
|
||||||
|
];
|
||||||
|
|
||||||
!is_undef(cham1)? (
|
rotate_extrude(convexity=2) polygon(path);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
children();
|
children();
|
||||||
|
@ -1378,6 +1543,7 @@ module cyl(
|
||||||
// xcyl(l=35, d=20);
|
// xcyl(l=35, d=20);
|
||||||
// xcyl(l=35, d1=30, d2=10);
|
// xcyl(l=35, d1=30, d2=10);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
module xcyl(
|
module xcyl(
|
||||||
h, r, d, r1, r2, d1, d2, l,
|
h, r, d, r1, r2, d1, d2, l,
|
||||||
chamfer, chamfer1, chamfer2,
|
chamfer, chamfer1, chamfer2,
|
||||||
|
@ -1448,6 +1614,7 @@ module xcyl(
|
||||||
// ycyl(l=35, d=20);
|
// ycyl(l=35, d=20);
|
||||||
// ycyl(l=35, d1=30, d2=10);
|
// ycyl(l=35, d1=30, d2=10);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
module ycyl(
|
module ycyl(
|
||||||
h, r, d, r1, r2, d1, d2, l,
|
h, r, d, r1, r2, d1, d2, l,
|
||||||
chamfer, chamfer1, chamfer2,
|
chamfer, chamfer1, chamfer2,
|
||||||
|
@ -1519,6 +1686,7 @@ module ycyl(
|
||||||
// zcyl(l=35, d=20);
|
// zcyl(l=35, d=20);
|
||||||
// zcyl(l=35, d1=30, d2=10);
|
// zcyl(l=35, d1=30, d2=10);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
module zcyl(
|
module zcyl(
|
||||||
h, r, d, r1, r2, d1, d2, l,
|
h, r, d, r1, r2, d1, d2, l,
|
||||||
chamfer, chamfer1, chamfer2,
|
chamfer, chamfer1, chamfer2,
|
||||||
|
@ -1596,6 +1764,7 @@ module zcyl(
|
||||||
// tube(h=30, or1=40, or2=30, ir1=20, ir2=30);
|
// tube(h=30, or1=40, or2=30, ir1=20, ir2=30);
|
||||||
// Example: Standard Connectors
|
// Example: Standard Connectors
|
||||||
// tube(h=30, or=40, wall=5) show_anchors();
|
// tube(h=30, or=40, wall=5) show_anchors();
|
||||||
|
|
||||||
module tube(
|
module tube(
|
||||||
h, or, ir, center,
|
h, or, ir, center,
|
||||||
od, id, wall,
|
od, id, wall,
|
||||||
|
@ -1673,6 +1842,7 @@ module tube(
|
||||||
// Example: Generating a VNF
|
// Example: Generating a VNF
|
||||||
// vnf = pie_slice(ang=150, l=20, r1=30, r2=50);
|
// vnf = pie_slice(ang=150, l=20, r1=30, r2=50);
|
||||||
// vnf_polyhedron(vnf);
|
// vnf_polyhedron(vnf);
|
||||||
|
|
||||||
module pie_slice(
|
module pie_slice(
|
||||||
h, r, ang=30, center,
|
h, r, ang=30, center,
|
||||||
r1, r2, d, d1, d2, l,
|
r1, r2, d, d1, d2, l,
|
||||||
|
@ -1696,7 +1866,6 @@ module pie_slice(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function pie_slice(
|
function pie_slice(
|
||||||
h, r, ang=30, center,
|
h, r, ang=30, center,
|
||||||
r1, r2, d, d1, d2, l,
|
r1, r2, d, d1, d2, l,
|
||||||
|
@ -1774,6 +1943,7 @@ function pie_slice(
|
||||||
// Example: Called as Function
|
// Example: Called as Function
|
||||||
// vnf = sphere(d=100, style="icosa");
|
// vnf = sphere(d=100, style="icosa");
|
||||||
// vnf_polyhedron(vnf);
|
// vnf_polyhedron(vnf);
|
||||||
|
|
||||||
module sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=UP) {
|
module sphere(r, d, circum=false, style="orig", anchor=CENTER, spin=0, orient=UP) {
|
||||||
r = get_radius(r=r, d=d, dflt=1);
|
r = get_radius(r=r, d=d, dflt=1);
|
||||||
if (!circum && style=="orig" && is_num(r)) {
|
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) =
|
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);
|
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:
|
// Example: The dual of "icosa" features hexagons and always 12 pentagons:
|
||||||
// color("green")spheroid(r=10.01, $fn=256);
|
// color("green")spheroid(r=10.01, $fn=256);
|
||||||
// spheroid(r=10, style="icosa", circum=true, $fn=16);
|
// 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)
|
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);
|
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);
|
// vnf_polyhedron(torus(d_min=15, od=60), convexity=4);
|
||||||
// Example: Standard Connectors
|
// Example: Standard Connectors
|
||||||
// torus(od=60, id=30) show_anchors();
|
// torus(od=60, id=30) show_anchors();
|
||||||
|
|
||||||
module torus(
|
module torus(
|
||||||
r_maj, r_min, center,
|
r_maj, r_min, center,
|
||||||
d_maj, d_min,
|
d_maj, d_min,
|
||||||
|
@ -2314,6 +2485,7 @@ function torus(
|
||||||
// Example(Spin,VPD=150,Med): Named Conical Connectors
|
// Example(Spin,VPD=150,Med): Named Conical Connectors
|
||||||
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
// teardrop(d1=20, d2=30, h=20, cap_h1=11, cap_h2=16)
|
||||||
// show_anchors(std=false);
|
// 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)
|
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);
|
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
|
// Example: Standard Connectors
|
||||||
// onion(d=30, ang=30, cap_h=20) show_anchors();
|
// onion(d=30, ang=30, cap_h=20) show_anchors();
|
||||||
|
|
||||||
module onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP)
|
module onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
r = get_radius(r=r, d=d, dflt=1);
|
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=CENTER);
|
||||||
// text3d("Foobar", h=2, anchor=str("baseline",CENTER));
|
// text3d("Foobar", h=2, anchor=str("baseline",CENTER));
|
||||||
// text3d("Foobar", h=2, anchor=str("baseline",BOTTOM+RIGHT));
|
// 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) {
|
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);
|
no_children($children);
|
||||||
dummy1 =
|
dummy1 =
|
||||||
|
@ -2721,6 +2895,7 @@ function _cut_interp(pathcut, path, data) =
|
||||||
// color("red")stroke(path, width=.3);
|
// color("red")stroke(path, width=.3);
|
||||||
// kern = [1,1.2,1,1,.3,-.2,1,0,.8,1,1.1,1];
|
// 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);
|
// 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)
|
module path_text(path, text, font, size, thickness, lettersize, offset=0, reverse=false, normal, top, center=false, textmetrics=false, kern=0)
|
||||||
{
|
{
|
||||||
no_children($children);
|
no_children($children);
|
||||||
|
@ -2849,6 +3024,7 @@ module path_text(path, text, font, size, thickness, lettersize, offset=0, revers
|
||||||
// position(BOT+FRONT)
|
// position(BOT+FRONT)
|
||||||
// interior_fillet(l=50, r=10, spin=180, orient=RIGHT);
|
// 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) {
|
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);
|
r = get_radius(r=r, d=d, dflt=1);
|
||||||
steps = ceil(segs(r)*(180-ang)/360);
|
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,
|
// size=[100,100], bottom=-20, data=fn,
|
||||||
// xrange=[-180:2:180], yrange=[-180:2:180]
|
// 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)
|
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);
|
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,
|
// l=100, r=30, base=5, data=fn,
|
||||||
// xrange=[-180:2:180], yrange=[-180:2:180]
|
// xrange=[-180:2:180], yrange=[-180:2:180]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
function cylindrical_heightfield(
|
function cylindrical_heightfield(
|
||||||
data, l, r, base=1,
|
data, l, r, base=1,
|
||||||
transpose=false, aspect=1,
|
transpose=false, aspect=1,
|
||||||
|
@ -3176,6 +3354,7 @@ module cylindrical_heightfield(
|
||||||
// Example(2D,Big): Metric vs Imperial
|
// Example(2D,Big): Metric vs Imperial
|
||||||
// ruler(12,width=50,inch=true,labels=true,maxscale=0);
|
// ruler(12,width=50,inch=true,labels=true,maxscale=0);
|
||||||
// fwd(50)ruler(300,width=50,labels=true);
|
// fwd(50)ruler(300,width=50,labels=true);
|
||||||
|
|
||||||
module ruler(length=100, width, thickness=1, depth=3, labels=false, pipscale=1/3, maxscale,
|
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)
|
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`
|
// 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`
|
// 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"
|
// 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") {
|
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;
|
vnf = is_vnf_list(vnf)? vnf_join(vnf) : vnf;
|
||||||
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
|
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
|
||||||
|
|
Loading…
Reference in a new issue