mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-07 11:56:30 +02:00
improved size error handling, round3d docs & default size change
This commit is contained in:
@@ -448,7 +448,7 @@ function zcopies(spacing, n, l, sp, p=_NO_ARG) =
|
|||||||
// When called as a module, copies `children()` at one or more evenly spaced positions along a line.
|
// When called as a module, copies `children()` at one or more evenly spaced positions along a line.
|
||||||
// By default, the line will be centered at the origin, unless the starting point `p1` is given.
|
// By default, the line will be centered at the origin, unless the starting point `p1` is given.
|
||||||
// The line will be pointed towards `RIGHT` (X+) unless otherwise given as a vector in `l`,
|
// The line will be pointed towards `RIGHT` (X+) unless otherwise given as a vector in `l`,
|
||||||
// `spacing`, or `p1`/`p2`. The psotion of the copies is specified in one of several ways:
|
// `spacing`, or `p1`/`p2`. The position of the copies is specified in one of several ways:
|
||||||
// .
|
// .
|
||||||
// If You Know... | Then Use Something Like...
|
// If You Know... | Then Use Something Like...
|
||||||
// -------------------------------- | --------------------------------
|
// -------------------------------- | --------------------------------
|
||||||
@@ -520,6 +520,7 @@ module line_copies(spacing, n, l, p1, p2)
|
|||||||
|
|
||||||
function line_copies(spacing, n, l, p1, p2, p=_NO_ARG) =
|
function line_copies(spacing, n, l, p1, p2, p=_NO_ARG) =
|
||||||
assert(is_undef(spacing) || is_finite(spacing) || is_vector(spacing))
|
assert(is_undef(spacing) || is_finite(spacing) || is_vector(spacing))
|
||||||
|
assert(!is_list(spacing) || len(spacing)==2 || len(spacing)==3, "Vector `spacing` must have length 2 or 3")
|
||||||
assert(is_undef(n) || is_finite(n))
|
assert(is_undef(n) || is_finite(n))
|
||||||
assert(is_undef(l) || is_finite(l) || is_vector(l))
|
assert(is_undef(l) || is_finite(l) || is_vector(l))
|
||||||
assert(is_undef(p1) || is_vector(p1))
|
assert(is_undef(p1) || is_vector(p1))
|
||||||
@@ -527,9 +528,11 @@ function line_copies(spacing, n, l, p1, p2, p=_NO_ARG) =
|
|||||||
assert(is_undef(p2) || is_def(p1), "If p2 is given must also give p1")
|
assert(is_undef(p2) || is_def(p1), "If p2 is given must also give p1")
|
||||||
assert(is_undef(p2) || is_undef(l), "Cannot give both p2 and l")
|
assert(is_undef(p2) || is_undef(l), "Cannot give both p2 and l")
|
||||||
assert(is_undef(n) || num_defined([l,spacing,p2])==1,"If n is given then must give exactly one of 'l', 'spacing', or the 'p1'/'p2' pair")
|
assert(is_undef(n) || num_defined([l,spacing,p2])==1,"If n is given then must give exactly one of 'l', 'spacing', or the 'p1'/'p2' pair")
|
||||||
assert(is_def(n) || num_defined([l,spacing,p2])>=1,"If n is given then must give at least one of 'l', 'spacing', or the 'p1'/'p2' pair")
|
assert(is_def(n) || num_defined([l,spacing,p2])>=1,"If n is not given then must give at least one of 'l', 'spacing', or the 'p1'/'p2' pair")
|
||||||
|
assert(!(is_vector(spacing) && is_vector(l)), "Cannot give vector 'spacing' and vector 'l' value.")
|
||||||
|
assert(!(is_vector(spacing) && is_def(p2)), "Cannot combine vector 'spacing' with the 'p1'/'p2' pair")
|
||||||
let(
|
let(
|
||||||
ll = is_def(l)? scalar_vec3(l, 0)
|
ll = is_def(l)? scalar_vec3(l)
|
||||||
: is_def(spacing) && is_def(n)? (n-1) * scalar_vec3(spacing, 0)
|
: is_def(spacing) && is_def(n)? (n-1) * scalar_vec3(spacing, 0)
|
||||||
: is_def(p1) && is_def(p2)? point3d(p2-p1)
|
: is_def(p1) && is_def(p2)? point3d(p2-p1)
|
||||||
: undef,
|
: undef,
|
||||||
@@ -538,7 +541,7 @@ function line_copies(spacing, n, l, p1, p2, p=_NO_ARG) =
|
|||||||
: 2,
|
: 2,
|
||||||
spc = cnt<=1? [0,0,0]
|
spc = cnt<=1? [0,0,0]
|
||||||
: is_undef(spacing) && is_def(ll)? ll/(cnt-1)
|
: is_undef(spacing) && is_def(ll)? ll/(cnt-1)
|
||||||
: is_num(spacing) && is_def(ll)? (ll/(cnt-1))
|
: is_num(spacing) && is_def(ll)? ll/(cnt-1)
|
||||||
: scalar_vec3(spacing, 0)
|
: scalar_vec3(spacing, 0)
|
||||||
)
|
)
|
||||||
assert(!is_undef(cnt), "Need two of `spacing`, 'l', 'n', or `p1`/`p2` arguments in `line_copies()`.")
|
assert(!is_undef(cnt), "Need two of `spacing`, 'l', 'n', or `p1`/`p2` arguments in `line_copies()`.")
|
||||||
@@ -546,7 +549,6 @@ function line_copies(spacing, n, l, p1, p2, p=_NO_ARG) =
|
|||||||
[for (i=[0:1:cnt-1]) translate(i * spc + spos, p=p)];
|
[for (i=[0:1:cnt-1]) translate(i * spc + spos, p=p)];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: grid_copies()
|
// Function&Module: grid_copies()
|
||||||
// Synopsis: Places copies of children in an [X,Y] grid.
|
// Synopsis: Places copies of children in an [X,Y] grid.
|
||||||
// SynTags: MatList, Trans
|
// SynTags: MatList, Trans
|
||||||
|
@@ -1907,8 +1907,8 @@ function _merge_segments(insegs,outsegs, eps, i=1) =
|
|||||||
// the input polygon. For 3d polygons, the triangle windings will induce a normal
|
// the input polygon. For 3d polygons, the triangle windings will induce a normal
|
||||||
// vector with the same direction of the polygon normal.
|
// vector with the same direction of the polygon normal.
|
||||||
// .
|
// .
|
||||||
// The function produce correct triangulations for some non-twisted non-simple polygons.
|
// The function produces correct triangulations for some non-twisted non-simple polygons.
|
||||||
// A polygon is non-twisted iff it is simple or it has a partition in
|
// A polygon is non-twisted if it is simple or it has a partition in
|
||||||
// simple polygons with the same winding such that the intersection of any two partitions is
|
// simple polygons with the same winding such that the intersection of any two partitions is
|
||||||
// made of full edges and/or vertices of both partitions. These polygons may have "touching" vertices
|
// made of full edges and/or vertices of both partitions. These polygons may have "touching" vertices
|
||||||
// (two vertices having the same coordinates, but distinct adjacencies) and "contact" edges
|
// (two vertices having the same coordinates, but distinct adjacencies) and "contact" edges
|
||||||
@@ -1972,7 +1972,11 @@ function polygon_triangulate(poly, ind, error=true, eps=EPSILON) =
|
|||||||
len(ind) == 3
|
len(ind) == 3
|
||||||
? _degenerate_tri([poly[ind[0]], poly[ind[1]], poly[ind[2]]], eps) ? [] :
|
? _degenerate_tri([poly[ind[0]], poly[ind[1]], poly[ind[2]]], eps) ? [] :
|
||||||
// non zero area
|
// non zero area
|
||||||
let( degen = norm(scalar_vec3(cross(poly[ind[1]]-poly[ind[0]], poly[ind[2]]-poly[ind[0]]))) < 2*eps )
|
let(
|
||||||
|
cp = cross(poly[ind[1]]-poly[ind[0]], poly[ind[2]]-poly[ind[0]]),
|
||||||
|
degen = is_num(cp) ? abs(cp) < 2*eps
|
||||||
|
: norm(cp) < 2*eps
|
||||||
|
)
|
||||||
assert( ! error || ! degen, "The polygon vertices are collinear.")
|
assert( ! error || ! degen, "The polygon vertices are collinear.")
|
||||||
degen ? undef : [ind]
|
degen ? undef : [ind]
|
||||||
: len(poly[ind[0]]) == 3
|
: len(poly[ind[0]]) == 3
|
||||||
|
@@ -358,7 +358,6 @@ function sinh(x) =
|
|||||||
assert(is_finite(x), "The input must be a finite number.")
|
assert(is_finite(x), "The input must be a finite number.")
|
||||||
(exp(x)-exp(-x))/2;
|
(exp(x)-exp(-x))/2;
|
||||||
|
|
||||||
|
|
||||||
// Function: cosh()
|
// Function: cosh()
|
||||||
// Synopsis: Returns the hyperbolic cosine of the given value.
|
// Synopsis: Returns the hyperbolic cosine of the given value.
|
||||||
// Topics: Math, Trigonometry
|
// Topics: Math, Trigonometry
|
||||||
@@ -378,10 +377,11 @@ function cosh(x) =
|
|||||||
// Usage:
|
// Usage:
|
||||||
// a = tanh(x);
|
// a = tanh(x);
|
||||||
// Description: Takes a value `x`, and returns the hyperbolic tangent of it.
|
// Description: Takes a value `x`, and returns the hyperbolic tangent of it.
|
||||||
|
|
||||||
function tanh(x) =
|
function tanh(x) =
|
||||||
assert(is_finite(x), "The input must be a finite number.")
|
assert(is_finite(x), "The input must be a finite number.")
|
||||||
sinh(x)/cosh(x);
|
let (e = exp(2*x) + 1)
|
||||||
|
e == INF ? 1 : (e-2)/e;
|
||||||
|
|
||||||
// Function: asinh()
|
// Function: asinh()
|
||||||
// Synopsis: Returns the hyperbolic arc-sine of the given value.
|
// Synopsis: Returns the hyperbolic arc-sine of the given value.
|
||||||
|
@@ -488,7 +488,7 @@ module chain_hull()
|
|||||||
// Synopsis: Removes diff shapes from base shape surface.
|
// Synopsis: Removes diff shapes from base shape surface.
|
||||||
// SynTags: Geom
|
// SynTags: Geom
|
||||||
// Topics: Miscellaneous
|
// Topics: Miscellaneous
|
||||||
// See Also: offset3d()
|
// See Also: offset3d(), round3d()
|
||||||
// Usage:
|
// Usage:
|
||||||
// minkowski_difference() { BASE; DIFF1; DIFF2; ... }
|
// minkowski_difference() { BASE; DIFF1; DIFF2; ... }
|
||||||
// Description:
|
// Description:
|
||||||
@@ -536,14 +536,15 @@ module minkowski_difference(planar=false) {
|
|||||||
// Usage:
|
// Usage:
|
||||||
// offset3d(r, [size], [convexity]) CHILDREN;
|
// offset3d(r, [size], [convexity]) CHILDREN;
|
||||||
// Description:
|
// Description:
|
||||||
// Expands or contracts the surface of a 3D object by a given amount. This is very, very slow.
|
// Expands or contracts the surface of a 3D object by a given amount. The children must
|
||||||
|
// fit in a centered cube of the specified size. This is very, very slow.
|
||||||
// No really, this is unbearably slow. It uses `minkowski()`. Use this as a last resort.
|
// No really, this is unbearably slow. It uses `minkowski()`. Use this as a last resort.
|
||||||
// This is so slow that no example images will be rendered.
|
// This is so slow that no example images will be rendered.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// r = Radius to expand object by. Negative numbers contract the object.
|
// r = Radius to expand object by. Negative numbers contract the object.
|
||||||
// size = Maximum size of object to be contracted, given as a scalar. Default: 100
|
// size = Scalar size of a centered cube containing the children. Default: 1000
|
||||||
// convexity = Max number of times a line could intersect the walls of the object. Default: 10
|
// convexity = Max number of times a line could intersect the walls of the object. Default: 10
|
||||||
module offset3d(r, size=100, convexity=10) {
|
module offset3d(r, size=1000, convexity=10) {
|
||||||
req_children($children);
|
req_children($children);
|
||||||
n = quant(max(8,segs(abs(r))),4);
|
n = quant(max(8,segs(abs(r))),4);
|
||||||
attachable(){
|
attachable(){
|
||||||
@@ -589,14 +590,16 @@ module offset3d(r, size=100, convexity=10) {
|
|||||||
// Rounds arbitrary 3D objects. Giving `r` rounds all concave and convex corners. Giving just `ir`
|
// Rounds arbitrary 3D objects. Giving `r` rounds all concave and convex corners. Giving just `ir`
|
||||||
// rounds just concave corners. Giving just `or` rounds convex corners. Giving both `ir` and `or`
|
// rounds just concave corners. Giving just `or` rounds convex corners. Giving both `ir` and `or`
|
||||||
// can let you round to different radii for concave and convex corners. The 3D object must not have
|
// can let you round to different radii for concave and convex corners. The 3D object must not have
|
||||||
// any parts narrower than twice the `or` radius. Such parts will disappear. This is an *extremely*
|
// any parts narrower than twice the `or` radius. Such parts will disappear. The children must fit
|
||||||
|
// inside a cube of the specified size. This is an *extremely*
|
||||||
// slow operation. I cannot emphasize enough just how slow it is. It uses `minkowski()` multiple times.
|
// slow operation. I cannot emphasize enough just how slow it is. It uses `minkowski()` multiple times.
|
||||||
// Use this as a last resort. This is so slow that no example images will be rendered.
|
// Use this as a last resort. This is so slow that no example images will be rendered.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// r = Radius to round all concave and convex corners to.
|
// r = Radius to round all concave and convex corners to.
|
||||||
// or = Radius to round only outside (convex) corners to. Use instead of `r`.
|
// or = Radius to round only outside (convex) corners to. Use instead of `r`.
|
||||||
// ir = Radius to round only inside (concave) corners to. Use instead of `r`.
|
// ir = Radius to round only inside (concave) corners to. Use instead of `r`.
|
||||||
module round3d(r, or, ir, size=100)
|
// size = size of centered cube that contains the children. Default: 1000
|
||||||
|
module round3d(r, or, ir, size=1000)
|
||||||
{
|
{
|
||||||
req_children($children);
|
req_children($children);
|
||||||
or = get_radius(r1=or, r=r, dflt=0);
|
or = get_radius(r1=or, r=r, dflt=0);
|
||||||
|
@@ -58,8 +58,8 @@ use <builtins.scad>
|
|||||||
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]);
|
||||||
size = scalar_vec3(size);
|
size = force_list(size,3); // Native cube prints a warning and gives a unit cube when parameters are bogus
|
||||||
attachable(anchor,spin,orient, size=size) {
|
attachable(anchor,spin,orient, size=is_vector(size,3)?size:[1,1,1]) {
|
||||||
_cube(size, center=true);
|
_cube(size, center=true);
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
@@ -67,18 +67,17 @@ module cube(size=1, center, anchor, spin=0, orient=UP)
|
|||||||
|
|
||||||
function cube(size=1, center, anchor, spin=0, orient=UP) =
|
function cube(size=1, center, anchor, spin=0, orient=UP) =
|
||||||
let(
|
let(
|
||||||
siz = scalar_vec3(size)
|
size = force_list(size,3)
|
||||||
)
|
)
|
||||||
assert(all_positive(siz), "All size components must be positive.")
|
assert(is_vector(size,3), "\nSize parameter cannot be converted to a 3-vector")
|
||||||
|
assert(all_positive(size), "\nAll size components must be positive.")
|
||||||
let(
|
let(
|
||||||
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]),
|
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]),
|
||||||
unscaled = [
|
unscaled = [
|
||||||
[-1,-1,-1],[1,-1,-1],[1,1,-1],[-1,1,-1],
|
[-1,-1,-1],[1,-1,-1],[1,1,-1],[-1,1,-1],
|
||||||
[-1,-1, 1],[1,-1, 1],[1,1, 1],[-1,1, 1],
|
[-1,-1, 1],[1,-1, 1],[1,1, 1],[-1,1, 1],
|
||||||
]/2,
|
]/2,
|
||||||
verts = is_num(size)? unscaled * size :
|
verts = [for (p=unscaled) v_mul(p,size)],
|
||||||
is_vector(size,3)? [for (p=unscaled) v_mul(p,size)] :
|
|
||||||
assert(is_num(size) || is_vector(size,3)),
|
|
||||||
faces = [
|
faces = [
|
||||||
[0,1,2], [0,2,3], //BOTTOM
|
[0,1,2], [0,2,3], //BOTTOM
|
||||||
[0,4,5], [0,5,1], //FRONT
|
[0,4,5], [0,5,1], //FRONT
|
||||||
@@ -87,7 +86,7 @@ function cube(size=1, center, anchor, spin=0, orient=UP) =
|
|||||||
[3,7,4], [3,4,0], //LEFT
|
[3,7,4], [3,4,0], //LEFT
|
||||||
[6,4,7], [6,5,4] //TOP
|
[6,4,7], [6,5,4] //TOP
|
||||||
]
|
]
|
||||||
) [reorient(anchor,spin,orient, size=siz, p=verts), faces];
|
) [reorient(anchor,spin,orient, size=size, p=verts), faces];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -333,13 +332,13 @@ module cuboid(
|
|||||||
}
|
}
|
||||||
sizecheck = assert(num_defined([size,p1,p2])!=3, "\nCannot give size if p2 is given (did you forget braces on the size argument?)")
|
sizecheck = assert(num_defined([size,p1,p2])!=3, "\nCannot give size if p2 is given (did you forget braces on the size argument?)")
|
||||||
assert(is_def(p1) || is_undef(p2), "If p2 is given you must also give p1");
|
assert(is_def(p1) || is_undef(p2), "If p2 is given you must also give p1");
|
||||||
size = scalar_vec3(default(size,[1,1,1]));
|
size = default(force_list(size,3),[1,1,1]);
|
||||||
edges = _edges(edges, except=first_defined([except_edges,except]));
|
edges = _edges(edges, except=first_defined([except_edges,except]));
|
||||||
teardrop = is_bool(teardrop)&&teardrop? 45 : teardrop;
|
teardrop = is_bool(teardrop)&&teardrop? 45 : teardrop;
|
||||||
chamfer = approx(chamfer,0) ? undef : chamfer;
|
chamfer = approx(chamfer,0) ? undef : chamfer;
|
||||||
rounding = approx(rounding,0) ? undef : rounding;
|
rounding = approx(rounding,0) ? undef : rounding;
|
||||||
checks =
|
checks =
|
||||||
assert(is_vector(size,3))
|
assert(is_vector(size,3),"Size must be a scalar or 3-vector")
|
||||||
assert(all_nonnegative(size), "All components of size= must be >=0")
|
assert(all_nonnegative(size), "All components of size= must be >=0")
|
||||||
assert(is_undef(chamfer) || is_finite(chamfer),"chamfer must be a finite value")
|
assert(is_undef(chamfer) || is_finite(chamfer),"chamfer must be a finite value")
|
||||||
assert(is_undef(rounding) || is_finite(rounding),"rounding must be a finite value")
|
assert(is_undef(rounding) || is_finite(rounding),"rounding must be a finite value")
|
||||||
@@ -804,7 +803,7 @@ function prismoid(
|
|||||||
// When called as a module, creates an octahedron with axis-aligned points.
|
// When called as a module, creates an octahedron with axis-aligned points.
|
||||||
// When called as a function, creates a [VNF](vnf.scad) of an octahedron with axis-aligned points.
|
// When called as a function, creates a [VNF](vnf.scad) of an octahedron with axis-aligned points.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// size = Width of the octahedron, tip to tip.
|
// size = Width of the octahedron, tip to tip. Can be a 3-vector. Default: [1,1,1]
|
||||||
// ---
|
// ---
|
||||||
// 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`
|
||||||
@@ -813,6 +812,8 @@ function prismoid(
|
|||||||
// octahedron(size=40);
|
// octahedron(size=40);
|
||||||
// Example: Anchors
|
// Example: Anchors
|
||||||
// octahedron(size=40) show_anchors();
|
// octahedron(size=40) show_anchors();
|
||||||
|
// Example:
|
||||||
|
// octahedron([10,15,25]);
|
||||||
|
|
||||||
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);
|
||||||
@@ -824,8 +825,8 @@ module octahedron(size=1, anchor=CENTER, spin=0, orient=UP) {
|
|||||||
|
|
||||||
function octahedron(size=1, anchor=CENTER, spin=0, orient=UP) =
|
function octahedron(size=1, anchor=CENTER, spin=0, orient=UP) =
|
||||||
let(
|
let(
|
||||||
size = scalar_vec3(size),
|
s = force_list(size,3)/2,
|
||||||
s = size/2,
|
dummy=assert(is_vector(s,3) && all_positive(s), "\nsize must be a positive scalar or 3-vector"),
|
||||||
vnf = [
|
vnf = [
|
||||||
[ [0,0,s.z], [s.x,0,0], [0,s.y,0], [-s.x,0,0], [0,-s.y,0], [0,0,-s.z] ],
|
[ [0,0,s.z], [s.x,0,0], [0,s.y,0], [-s.x,0,0], [0,-s.y,0], [0,0,-s.z] ],
|
||||||
[ [0,2,1], [0,3,2], [0,4,3], [0,1,4], [5,1,2], [5,2,3], [5,3,4], [5,4,1] ]
|
[ [0,2,1], [0,3,2], [0,4,3], [0,1,4], [5,1,2], [5,2,3], [5,3,4], [5,4,1] ]
|
||||||
@@ -1482,7 +1483,7 @@ function rect_tube(
|
|||||||
// direction of the sloped edge.
|
// direction of the sloped edge.
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// size = [width, thickness, height]
|
// size = [width, thickness, height]. Default: [1,1,1]
|
||||||
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`.
|
// center = If given, overrides `anchor`. A true value sets `anchor=CENTER`, false sets `anchor=UP`.
|
||||||
// ---
|
// ---
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `FRONT+LEFT+BOTTOM`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `FRONT+LEFT+BOTTOM`
|
||||||
@@ -1509,7 +1510,8 @@ function rect_tube(
|
|||||||
|
|
||||||
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 = force_list(size,3);
|
||||||
|
check=assert(is_vector(size,3) && all_positive(size), "\nsize must be a positive scalar or 3-vector");
|
||||||
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]);
|
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]);
|
||||||
vnf = wedge(size, anchor="origin");
|
vnf = wedge(size, anchor="origin");
|
||||||
spindir = unit([0,-size.y,size.z]);
|
spindir = unit([0,-size.y,size.z]);
|
||||||
@@ -1533,7 +1535,8 @@ module wedge(size=[1, 1, 1], center, anchor, spin=0, orient=UP)
|
|||||||
|
|
||||||
function wedge(size=[1,1,1], center, anchor, spin=0, orient=UP) =
|
function wedge(size=[1,1,1], center, anchor, spin=0, orient=UP) =
|
||||||
let(
|
let(
|
||||||
size = scalar_vec3(size),
|
size = force_list(size,3),
|
||||||
|
check=assert(is_vector(size,3) && all_positive(size), "\nsize must be a positive scalar or 3-vector"),
|
||||||
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]),
|
anchor = get_anchor(anchor, center, -[1,1,1], -[1,1,1]),
|
||||||
pts = [
|
pts = [
|
||||||
[ 1,1,-1], [ 1,-1,-1], [ 1,-1,1],
|
[ 1,1,-1], [ 1,-1,-1], [ 1,-1,1],
|
||||||
|
17
utility.scad
17
utility.scad
@@ -748,8 +748,9 @@ function get_radius(r1, r2, r, d1, d2, d, dflt) =
|
|||||||
// same way that OpenSCAD expands short vectors in some contexts, e.g. cube(10) or rotate([45,90]).
|
// same way that OpenSCAD expands short vectors in some contexts, e.g. cube(10) or rotate([45,90]).
|
||||||
// If `v` is a scalar, and `dflt==undef`, returns `[v, v, v]`.
|
// If `v` is a scalar, and `dflt==undef`, returns `[v, v, v]`.
|
||||||
// If `v` is a scalar, and `dflt!=undef`, returns `[v, dflt, dflt]`.
|
// If `v` is a scalar, and `dflt!=undef`, returns `[v, dflt, dflt]`.
|
||||||
// If `v` is a vector and dflt is defined, returns the first 3 items, with any missing values replaced by `dflt`.
|
// if `v` is a list of length 3 or more then reutnrs `v`
|
||||||
// If `v` is a vector and dflt is undef, returns the first 3 items, with any missing values replaced by 0.
|
// If `v` is a list and dflt is defined, returns a length 3 list by padding with `dflt`
|
||||||
|
// If `v` is a list and dflt is undef, returns a length 3 list by padding with 0.
|
||||||
// If `v` is `undef`, returns `undef`.
|
// If `v` is `undef`, returns `undef`.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// v = Value to return vector from.
|
// v = Value to return vector from.
|
||||||
@@ -761,10 +762,14 @@ function get_radius(r1, r2, r, d1, d2, d, dflt) =
|
|||||||
// vec = scalar_vec3([10,10],1); // Returns: [10,10,1]
|
// vec = scalar_vec3([10,10],1); // Returns: [10,10,1]
|
||||||
// vec = scalar_vec3([10,10]); // Returns: [10,10,0]
|
// vec = scalar_vec3([10,10]); // Returns: [10,10,0]
|
||||||
// vec = scalar_vec3([10]); // Returns: [10,0,0]
|
// vec = scalar_vec3([10]); // Returns: [10,0,0]
|
||||||
function scalar_vec3(v, dflt) =
|
function scalar_vec3(v, dflt) =
|
||||||
is_undef(v)? undef :
|
is_undef(v)? undef
|
||||||
is_list(v)? [for (i=[0:2]) default(v[i], default(dflt, 0))] :
|
:
|
||||||
!is_undef(dflt)? [v,dflt,dflt] : [v,v,v];
|
is_list(v)? len(v)>=3 ? v
|
||||||
|
: [for (i=[0:2]) default(v[i], default(dflt, 0))]
|
||||||
|
:
|
||||||
|
!is_undef(dflt) ? [v,dflt,dflt]
|
||||||
|
: [v,v,v];
|
||||||
|
|
||||||
// Function: segs()
|
// Function: segs()
|
||||||
// Synopsis: Returns the number of sides for a circle given `$fn`, `$fa`, and `$fs`.
|
// Synopsis: Returns the number of sides for a circle given `$fn`, `$fa`, and `$fs`.
|
||||||
|
@@ -193,8 +193,9 @@ module sparse_cuboid(size, dir=RIGHT, strut=5, maxang=30, max_bridge=20,
|
|||||||
teardrop=false,
|
teardrop=false,
|
||||||
anchor=CENTER, spin=0, orient=UP)
|
anchor=CENTER, spin=0, orient=UP)
|
||||||
{
|
{
|
||||||
size = scalar_vec3(size);
|
size = force_list(size,3);
|
||||||
dummy1=assert(in_list(dir,["X","Y","Z"]) || is_vector(dir,3), "dir must be a 3-vector or one of \"X\", \"Y\", or \"Z\"");
|
dummy1= assert(is_vector(size,3) && all_positive(size), "size must be a positive number or 3-vector")
|
||||||
|
assert(in_list(dir,["X","Y","Z"]) || is_vector(dir,3), "dir must be a 3-vector or one of \"X\", \"Y\", or \"Z\"");
|
||||||
count = len([for(d=dir) if (d!=0) d]);
|
count = len([for(d=dir) if (d!=0) d]);
|
||||||
dummy2=assert(is_string(dir) || (count==1 && len(dir)<=3), "vector valued dir must have exactly one non-zero component");
|
dummy2=assert(is_string(dir) || (count==1 && len(dir)<=3), "vector valued dir must have exactly one non-zero component");
|
||||||
dir = is_string(dir) ? dir
|
dir = is_string(dir) ? dir
|
||||||
|
Reference in New Issue
Block a user