mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
commit
028cf9452d
11 changed files with 238 additions and 170 deletions
25
color.scad
25
color.scad
|
@ -15,7 +15,7 @@ use <builtins.scad>
|
||||||
|
|
||||||
// Module: recolor()
|
// Module: recolor()
|
||||||
// Usage:
|
// Usage:
|
||||||
// recolor([c]) {...}
|
// recolor([c]) children;
|
||||||
// Topics: Attachments
|
// Topics: Attachments
|
||||||
// See Also: color_this()
|
// See Also: color_this()
|
||||||
// Description:
|
// Description:
|
||||||
|
@ -34,6 +34,7 @@ use <builtins.scad>
|
||||||
// attach(TOP,BOT) cuboid([4,4,2]);
|
// attach(TOP,BOT) cuboid([4,4,2]);
|
||||||
module recolor(c="default")
|
module recolor(c="default")
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
$color=c;
|
$color=c;
|
||||||
children();
|
children();
|
||||||
}
|
}
|
||||||
|
@ -41,7 +42,7 @@ module recolor(c="default")
|
||||||
|
|
||||||
// Module: color_this()
|
// Module: color_this()
|
||||||
// Usage:
|
// Usage:
|
||||||
// color_this([c]) {...}
|
// color_this([c]) children;
|
||||||
// Topics: Attachments
|
// Topics: Attachments
|
||||||
// See Also: recolor()
|
// See Also: recolor()
|
||||||
// Description:
|
// Description:
|
||||||
|
@ -61,6 +62,7 @@ module recolor(c="default")
|
||||||
// attach(TOP,BOT) cuboid([4,4,2]);
|
// attach(TOP,BOT) cuboid([4,4,2]);
|
||||||
module color_this(c="default")
|
module color_this(c="default")
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
$save_color=default($color,"default");
|
$save_color=default($color,"default");
|
||||||
$color=c;
|
$color=c;
|
||||||
children();
|
children();
|
||||||
|
@ -69,7 +71,7 @@ module color_this(c="default")
|
||||||
|
|
||||||
// Module: rainbow()
|
// Module: rainbow()
|
||||||
// Usage:
|
// Usage:
|
||||||
// rainbow(list) ...
|
// rainbow(list,[stride],[maxhues],[shuffle],[seed]) children;
|
||||||
// Description:
|
// Description:
|
||||||
// Iterates the list, displaying children in different colors for each list item. The color
|
// Iterates the list, displaying children in different colors for each list item. The color
|
||||||
// is set using the color() module, so this module is not compatible with {{recolor()}} or
|
// is set using the color() module, so this module is not compatible with {{recolor()}} or
|
||||||
|
@ -91,6 +93,7 @@ module color_this(c="default")
|
||||||
// rainbow(rgn) stroke($item, closed=true);
|
// rainbow(rgn) stroke($item, closed=true);
|
||||||
module rainbow(list, stride=1, maxhues, shuffle=false, seed)
|
module rainbow(list, stride=1, maxhues, shuffle=false, seed)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
ll = len(list);
|
ll = len(list);
|
||||||
maxhues = first_defined([maxhues,ll]);
|
maxhues = first_defined([maxhues,ll]);
|
||||||
huestep = 360 / maxhues;
|
huestep = 360 / maxhues;
|
||||||
|
@ -107,7 +110,7 @@ module rainbow(list, stride=1, maxhues, shuffle=false, seed)
|
||||||
|
|
||||||
// Function&Module: hsl()
|
// Function&Module: hsl()
|
||||||
// Usage:
|
// Usage:
|
||||||
// hsl(h,[s],[l],[a]) ...
|
// hsl(h,[s],[l],[a]) children;
|
||||||
// rgb = hsl(h,[s],[l],[a]);
|
// rgb = hsl(h,[s],[l],[a]);
|
||||||
// Description:
|
// Description:
|
||||||
// When called as a function, returns the [R,G,B] color for the given hue `h`, saturation `s`, and lightness `l` from the HSL colorspace. If you supply
|
// When called as a function, returns the [R,G,B] color for the given hue `h`, saturation `s`, and lightness `l` from the HSL colorspace. If you supply
|
||||||
|
@ -133,12 +136,16 @@ function hsl(h,s=1,l=0.5,a) =
|
||||||
if (is_def(a)) a
|
if (is_def(a)) a
|
||||||
];
|
];
|
||||||
|
|
||||||
module hsl(h,s=1,l=0.5,a=1) color(hsl(h,s,l),a) children();
|
module hsl(h,s=1,l=0.5,a=1)
|
||||||
|
{
|
||||||
|
req_children($children);
|
||||||
|
color(hsl(h,s,l),a) children();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: hsv()
|
// Function&Module: hsv()
|
||||||
// Usage:
|
// Usage:
|
||||||
// hsv(h,[s],[v],[a]) ...
|
// hsv(h,[s],[v],[a]) children;
|
||||||
// rgb = hsv(h,[s],[v],[a]);
|
// rgb = hsv(h,[s],[v],[a]);
|
||||||
// Description:
|
// Description:
|
||||||
// When called as a function, returns the [R,G,B] color for the given hue `h`, saturation `s`, and value `v` from the HSV colorspace. If you supply
|
// When called as a function, returns the [R,G,B] color for the given hue `h`, saturation `s`, and value `v` from the HSV colorspace. If you supply
|
||||||
|
@ -175,7 +182,11 @@ function hsv(h,s=1,v=1,a) =
|
||||||
is_def(a) ? point4d(add_scalar(rgbprime,m),a)
|
is_def(a) ? point4d(add_scalar(rgbprime,m),a)
|
||||||
: add_scalar(rgbprime,m);
|
: add_scalar(rgbprime,m);
|
||||||
|
|
||||||
module hsv(h,s=1,v=1,a=1) color(hsv(h,s,v),a) children();
|
module hsv(h,s=1,v=1,a=1)
|
||||||
|
{
|
||||||
|
req_children($children);
|
||||||
|
color(hsv(h,s,v),a) children();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
// Translates copies of all children to each given translation offset.
|
// Translates copies of all children to each given translation offset.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// move_copies(a) ...
|
// move_copies(a) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// a = Array of XYZ offset vectors. Default `[[0,0,0]]`
|
// a = Array of XYZ offset vectors. Default `[[0,0,0]]`
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
// move_copies([[-25,-25,0], [25,-25,0], [0,0,50], [0,25,0]]) sphere(r=10);
|
// move_copies([[-25,-25,0], [25,-25,0], [0,0,50], [0,25,0]]) sphere(r=10);
|
||||||
module move_copies(a=[[0,0,0]])
|
module move_copies(a=[[0,0,0]])
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_list(a));
|
assert(is_list(a));
|
||||||
for ($idx = idx(a)) {
|
for ($idx = idx(a)) {
|
||||||
$pos = a[$idx];
|
$pos = a[$idx];
|
||||||
|
@ -46,15 +47,15 @@ module move_copies(a=[[0,0,0]])
|
||||||
// Function&Module: line_of()
|
// Function&Module: line_of()
|
||||||
//
|
//
|
||||||
// Usage: Spread `n` copies by a given spacing
|
// Usage: Spread `n` copies by a given spacing
|
||||||
// line_of(spacing, [n], [p1=]) ...
|
// line_of(spacing, [n], [p1=]) children;
|
||||||
// Usage: Spread copies every given spacing along the line
|
// Usage: Spread copies every given spacing along the line
|
||||||
// line_of(spacing, [l=], [p1=]) ...
|
// line_of(spacing, [l=], [p1=]) children;
|
||||||
// Usage: Spread `n` copies along the length of the line
|
// Usage: Spread `n` copies along the length of the line
|
||||||
// line_of([n=], [l=], [p1=]) ...
|
// line_of([n=], [l=], [p1=]) children;
|
||||||
// Usage: Spread `n` copies along the line from `p1` to `p2`
|
// Usage: Spread `n` copies along the line from `p1` to `p2`
|
||||||
// line_of([n=], [p1=], [p2=]) ...
|
// line_of([n=], [p1=], [p2=]) children;
|
||||||
// Usage: Spread copies every given spacing, centered along the line from `p1` to `p2`
|
// Usage: Spread copies every given spacing, centered along the line from `p1` to `p2`
|
||||||
// line_of([spacing], [p1=], [p2=]) ...
|
// line_of([spacing], [p1=], [p2=]) children;
|
||||||
// Usage: As a function
|
// Usage: As a function
|
||||||
// pts = line_of([spacing], [n], [p1=]);
|
// pts = line_of([spacing], [n], [p1=]);
|
||||||
// pts = line_of([spacing], [l=], [p1=]);
|
// pts = line_of([spacing], [l=], [p1=]);
|
||||||
|
@ -117,6 +118,7 @@ module move_copies(a=[[0,0,0]])
|
||||||
// move_copies(pts) circle(d=2);
|
// move_copies(pts) circle(d=2);
|
||||||
module line_of(spacing, n, l, p1, p2)
|
module line_of(spacing, n, l, p1, p2)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
pts = line_of(spacing=spacing, n=n, l=l, p1=p1, p2=p2);
|
pts = line_of(spacing=spacing, n=n, l=l, p1=p1, p2=p2);
|
||||||
for (i=idx(pts)) {
|
for (i=idx(pts)) {
|
||||||
$idx = i;
|
$idx = i;
|
||||||
|
@ -155,8 +157,8 @@ function line_of(spacing, n, l, p1, p2) =
|
||||||
// Spreads out `n` copies of the children along a line on the X axis.
|
// Spreads out `n` copies of the children along a line on the X axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// xcopies(spacing, [n], [sp]) ...
|
// xcopies(spacing, [n], [sp]) children;
|
||||||
// xcopies(l, [n], [sp]) ...
|
// xcopies(l, [n], [sp]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
|
@ -180,6 +182,7 @@ function line_of(spacing, n, l, p1, p2) =
|
||||||
// }
|
// }
|
||||||
module xcopies(spacing, n, l, sp)
|
module xcopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
sp = is_finite(sp)? [sp,0,0] : sp;
|
sp = is_finite(sp)? [sp,0,0] : sp;
|
||||||
line_of(
|
line_of(
|
||||||
l=u_mul(l,RIGHT),
|
l=u_mul(l,RIGHT),
|
||||||
|
@ -195,8 +198,8 @@ module xcopies(spacing, n, l, sp)
|
||||||
// Spreads out `n` copies of the children along a line on the Y axis.
|
// Spreads out `n` copies of the children along a line on the Y axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// ycopies(spacing, [n], [sp]) ...
|
// ycopies(spacing, [n], [sp]) children;
|
||||||
// ycopies(l, [n], [sp]) ...
|
// ycopies(l, [n], [sp]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
|
@ -220,6 +223,7 @@ module xcopies(spacing, n, l, sp)
|
||||||
// }
|
// }
|
||||||
module ycopies(spacing, n, l, sp)
|
module ycopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
sp = is_finite(sp)? [0,sp,0] : sp;
|
sp = is_finite(sp)? [0,sp,0] : sp;
|
||||||
line_of(
|
line_of(
|
||||||
l=u_mul(l,BACK),
|
l=u_mul(l,BACK),
|
||||||
|
@ -235,8 +239,8 @@ module ycopies(spacing, n, l, sp)
|
||||||
// Spreads out `n` copies of the children along a line on the Z axis.
|
// Spreads out `n` copies of the children along a line on the Z axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// zcopies(spacing, [n], [sp]) ...
|
// zcopies(spacing, [n], [sp]) children;
|
||||||
// zcopies(l, [n], [sp]) ...
|
// zcopies(l, [n], [sp]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
|
@ -274,6 +278,7 @@ module ycopies(spacing, n, l, sp)
|
||||||
// sphere(d=s);
|
// sphere(d=s);
|
||||||
module zcopies(spacing, n, l, sp)
|
module zcopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
sp = is_finite(sp)? [0,0,sp] : sp;
|
sp = is_finite(sp)? [0,0,sp] : sp;
|
||||||
line_of(
|
line_of(
|
||||||
l=u_mul(l,UP),
|
l=u_mul(l,UP),
|
||||||
|
@ -292,16 +297,16 @@ module zcopies(spacing, n, l, sp)
|
||||||
// Makes a square or hexagonal grid of copies of children, with an optional masking polygon or region.
|
// Makes a square or hexagonal grid of copies of children, with an optional masking polygon or region.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// grid2d(spacing, size, [stagger], [scale], [inside]) ...
|
// grid2d(spacing, size=, [stagger=], [scale=], [inside=]) children;
|
||||||
// grid2d(n, size, [stagger], [scale], [inside]) ...
|
// grid2d(n=, size=, [stagger=], [scale=], [inside=]) children;
|
||||||
// grid2d(spacing, n, [stagger], [scale], [inside]) ...
|
// grid2d(spacing, [n], [stagger=], [scale=], [inside=]) children;
|
||||||
// grid2d(spacing, inside, [stagger], [scale]) ...
|
// grid2d(n=, inside=, [stagger], [scale]) children;
|
||||||
// grid2d(n, inside, [stagger], [scale]) ...
|
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// size = The [X,Y] size to spread the copies over.
|
|
||||||
// spacing = Distance between copies in [X,Y] or scalar distance.
|
// spacing = Distance between copies in [X,Y] or scalar distance.
|
||||||
// n = How many columns and rows of copies to make. Can be given as `[COLS,ROWS]`, or just as a scalar that specifies both. If staggered, count both staggered and unstaggered columns and rows. Default: 2 (3 if staggered)
|
// n = How many columns and rows of copies to make. Can be given as `[COLS,ROWS]`, or just as a scalar that specifies both. If staggered, count both staggered and unstaggered columns and rows. Default: 2 (3 if staggered)
|
||||||
|
// size = The [X,Y] size to spread the copies over.
|
||||||
|
// ---
|
||||||
// stagger = If true, make a staggered (hexagonal) grid. If false, make square grid. If `"alt"`, makes alternate staggered pattern. Default: false
|
// stagger = If true, make a staggered (hexagonal) grid. If false, make square grid. If `"alt"`, makes alternate staggered pattern. Default: false
|
||||||
// inside = If given a list of polygon points, or a region, only creates copies whose center would be inside the polygon or region. Polygon can be concave and/or self crossing.
|
// inside = If given a list of polygon points, or a region, only creates copies whose center would be inside the polygon or region. Polygon can be concave and/or self crossing.
|
||||||
// nonzero = If inside is set to a polygon with self-crossings then use the nonzero method for deciding if points are in the polygon. Default: false
|
// nonzero = If inside is set to a polygon with self-crossings then use the nonzero method for deciding if points are in the polygon. Default: false
|
||||||
|
@ -343,7 +348,7 @@ module zcopies(spacing, n, l, sp)
|
||||||
// }
|
// }
|
||||||
module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero)
|
module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(in_list(stagger, [false, true, "alt"]));
|
assert(in_list(stagger, [false, true, "alt"]));
|
||||||
bounds = is_undef(inside)? undef :
|
bounds = is_undef(inside)? undef :
|
||||||
is_path(inside)? pointlist_bounds(inside) :
|
is_path(inside)? pointlist_bounds(inside) :
|
||||||
|
@ -424,16 +429,16 @@ module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero)
|
||||||
// Makes a 3D grid of duplicate children.
|
// Makes a 3D grid of duplicate children.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// grid3d(n, spacing) ...
|
// grid3d(spacing,n) children;
|
||||||
// grid3d(n=[Xn,Yn,Zn], spacing=[dX,dY,dZ]) ...
|
// grid3d(spacing=[dX,dY,dZ], n=[Xn,Yn,Zn]) children;
|
||||||
// grid3d([xa], [ya], [za]) ...
|
// grid3d([xa=], [ya=], [za=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// 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])
|
// 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])
|
// 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])
|
// za = array or range of Z-axis values to offset by. (Default: [0])
|
||||||
// n = Optional number of copies to have per axis.
|
|
||||||
// spacing = spacing of copies per axis. Use with `n`.
|
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
||||||
|
@ -450,8 +455,9 @@ module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero)
|
||||||
// grid3d(n=[3, 4], spacing=[80, 60]) sphere(r=10);
|
// grid3d(n=[3, 4], spacing=[80, 60]) sphere(r=10);
|
||||||
// Examples:
|
// Examples:
|
||||||
// grid3d(n=[10, 10, 10], spacing=50) color($idx/9) cube(50, center=true);
|
// grid3d(n=[10, 10, 10], spacing=50) color($idx/9) cube(50, center=true);
|
||||||
module grid3d(xa=[0], ya=[0], za=[0], n=undef, spacing=undef)
|
module grid3d(spacing, n, xa=[0], ya=[0], za=[0])
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
n = scalar_vec3(n, 1);
|
n = scalar_vec3(n, 1);
|
||||||
spacing = scalar_vec3(spacing, undef);
|
spacing = scalar_vec3(spacing, undef);
|
||||||
if (!is_undef(n) && !is_undef(spacing)) {
|
if (!is_undef(n) && !is_undef(spacing)) {
|
||||||
|
@ -492,14 +498,15 @@ module grid3d(xa=[0], ya=[0], za=[0], n=undef, spacing=undef)
|
||||||
// The first (unrotated) copy will be placed at the relative starting angle `sa`.
|
// The first (unrotated) copy will be placed at the relative starting angle `sa`.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// rot_copies(rots, [cp], [sa], [delta], [subrot]) ...
|
// rot_copies(rots, [cp=], [sa=], [delta=], [subrot=]) children;
|
||||||
// rot_copies(rots, v, [cp], [sa], [delta], [subrot]) ...
|
// rot_copies(rots, v, [cp=], [sa=], [delta=], [subrot=]) children;
|
||||||
// rot_copies(n, [v], [cp], [sa], [delta], [subrot]) ...
|
// rot_copies(n=, [v=], [cp=], [sa=], [delta=], [subrot=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// rots = A list of [X,Y,Z] rotation angles in degrees. If `v` is given, this will be a list of scalar angles in degrees to rotate around `v`.
|
// rots = A list of [X,Y,Z] rotation angles in degrees. If `v` is given, this will be a list of scalar angles in degrees to rotate around `v`.
|
||||||
// v = If given, this is the vector of the axis to rotate around.
|
// v = If given, this is the vector of the axis to rotate around.
|
||||||
// cp = Centerpoint to rotate around. Default: `[0,0,0]`
|
// cp = Centerpoint to rotate around. Default: `[0,0,0]`
|
||||||
|
// ---
|
||||||
// n = Optional number of evenly distributed copies, rotated around the axis.
|
// n = Optional number of evenly distributed copies, rotated around the axis.
|
||||||
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise. Default: 0
|
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise. Default: 0
|
||||||
// delta = [X,Y,Z] amount to move away from cp before rotating. Makes rings of copies. Default: `[0,0,0]`
|
// delta = [X,Y,Z] amount to move away from cp before rotating. Makes rings of copies. Default: `[0,0,0]`
|
||||||
|
@ -540,6 +547,7 @@ module grid3d(xa=[0], ya=[0], za=[0], n=undef, spacing=undef)
|
||||||
// color("red",0.333) yrot(90) cylinder(h=20, r1=5, r2=0);
|
// color("red",0.333) yrot(90) cylinder(h=20, r1=5, r2=0);
|
||||||
module rot_copies(rots=[], v=undef, cp=[0,0,0], n=undef, sa=0, offset=0, delta=[0,0,0], subrot=true)
|
module rot_copies(rots=[], v=undef, cp=[0,0,0], n=undef, sa=0, offset=0, delta=[0,0,0], subrot=true)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
sang = sa + offset;
|
sang = sa + offset;
|
||||||
angs = !is_undef(n)?
|
angs = !is_undef(n)?
|
||||||
(n<=0? [] : [for (i=[0:1:n-1]) i/n*360+sang]) :
|
(n<=0? [] : [for (i=[0:1:n-1]) i/n*360+sang]) :
|
||||||
|
@ -568,8 +576,8 @@ module rot_copies(rots=[], v=undef, cp=[0,0,0], n=undef, sa=0, offset=0, delta=[
|
||||||
// Module: xrot_copies()
|
// Module: xrot_copies()
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// xrot_copies(rots, [r], [cp], [sa], [subrot]) ...
|
// xrot_copies(rots, [cp], [r=], [sa=], [subrot=]) children;
|
||||||
// xrot_copies(n, [r], [cp], [sa], [subrot]) ...
|
// xrot_copies(n=, [cp=], [r=], [sa=], [subrot=]) children;
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Given an array of angles, rotates copies of the children to each of those angles around the X axis.
|
// Given an array of angles, rotates copies of the children to each of those angles around the X axis.
|
||||||
|
@ -582,6 +590,7 @@ module rot_copies(rots=[], v=undef, cp=[0,0,0], n=undef, sa=0, offset=0, delta=[
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
||||||
// cp = Centerpoint to rotate around.
|
// cp = Centerpoint to rotate around.
|
||||||
|
// --
|
||||||
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
||||||
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from Y+, when facing the origin from X+. First unrotated copy is placed at that angle.
|
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from Y+, when facing the origin from X+. First unrotated copy is placed at that angle.
|
||||||
// r = Radius to move children back (Y+), away from cp, before rotating. Makes rings of copies.
|
// r = Radius to move children back (Y+), away from cp, before rotating. Makes rings of copies.
|
||||||
|
@ -618,6 +627,7 @@ module rot_copies(rots=[], v=undef, cp=[0,0,0], n=undef, sa=0, offset=0, delta=[
|
||||||
// color("red",0.333) xrot(-90) cylinder(h=20, r1=5, r2=0, center=true);
|
// color("red",0.333) xrot(-90) cylinder(h=20, r1=5, r2=0, center=true);
|
||||||
module xrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
module xrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
rot_copies(rots=rots, v=RIGHT, cp=cp, n=n, sa=sa, delta=[0, r, 0], subrot=subrot) children();
|
rot_copies(rots=rots, v=RIGHT, cp=cp, n=n, sa=sa, delta=[0, r, 0], subrot=subrot) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,8 +635,8 @@ module xrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Module: yrot_copies()
|
// Module: yrot_copies()
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// yrot_copies(rots, [r], [cp], [sa], [subrot]) ...
|
// yrot_copies(rots, [cp], [r=], [sa=], [subrot=]) children;
|
||||||
// yrot_copies(n, [r], [cp], [sa], [subrot]) ...
|
// yrot_copies(n=, [cp=], [r=], [sa=], [subrot=]) children;
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Given an array of angles, rotates copies of the children to each of those angles around the Y axis.
|
// Given an array of angles, rotates copies of the children to each of those angles around the Y axis.
|
||||||
|
@ -639,6 +649,7 @@ module xrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
||||||
// cp = Centerpoint to rotate around.
|
// cp = Centerpoint to rotate around.
|
||||||
|
// ---
|
||||||
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
||||||
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from X-, when facing the origin from Y+.
|
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from X-, when facing the origin from Y+.
|
||||||
// r = Radius to move children left (X-), away from cp, before rotating. Makes rings of copies.
|
// r = Radius to move children left (X-), away from cp, before rotating. Makes rings of copies.
|
||||||
|
@ -675,6 +686,7 @@ module xrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// color("red",0.333) yrot(-90) cylinder(h=20, r1=5, r2=0, center=true);
|
// color("red",0.333) yrot(-90) cylinder(h=20, r1=5, r2=0, center=true);
|
||||||
module yrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
module yrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
rot_copies(rots=rots, v=BACK, cp=cp, n=n, sa=sa, delta=[-r, 0, 0], subrot=subrot) children();
|
rot_copies(rots=rots, v=BACK, cp=cp, n=n, sa=sa, delta=[-r, 0, 0], subrot=subrot) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,8 +694,8 @@ module yrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Module: zrot_copies()
|
// Module: zrot_copies()
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// zrot_copies(rots, [r], [cp], [sa], [subrot]) ...
|
// zrot_copies(rots, [cp], [r=], [sa=], [subrot=]) children;
|
||||||
// zrot_copies(n, [r], [cp], [sa], [subrot]) ...
|
// zrot_copies(n=, [cp=], [r=], [sa=], [subrot=]) children;
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Given an array of angles, rotates copies of the children to each of those angles around the Z axis.
|
// Given an array of angles, rotates copies of the children to each of those angles around the Z axis.
|
||||||
|
@ -696,6 +708,7 @@ module yrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
// rots = Optional array of rotation angles, in degrees, to make copies at.
|
||||||
// cp = Centerpoint to rotate around. Default: [0,0,0]
|
// cp = Centerpoint to rotate around. Default: [0,0,0]
|
||||||
|
// ---
|
||||||
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
// n = Optional number of evenly distributed copies to be rotated around the ring.
|
||||||
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from X+, when facing the origin from Z+. Default: 0
|
// sa = Starting angle, in degrees. For use with `n`. Angle is in degrees counter-clockwise from X+, when facing the origin from Z+. Default: 0
|
||||||
// r = Radius to move children right (X+), away from cp, before rotating. Makes rings of copies. Default: 0
|
// r = Radius to move children right (X+), away from cp, before rotating. Makes rings of copies. Default: 0
|
||||||
|
@ -742,12 +755,13 @@ module zrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Evenly distributes n duplicate children around an ovoid arc on the XY plane.
|
// Evenly distributes n duplicate children around an ovoid arc on the XY plane.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// arc_of(r|d, n, [sa], [ea], [rot]
|
// arc_of(n, r|d=, [sa=], [ea=], [rot=]) children;
|
||||||
// arc_of(rx|dx, ry|dy, n, [sa], [ea], [rot]
|
// arc_of(n, rx=|dx=, ry=|dy=, [sa=], [ea=], [rot=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// n = number of copies to distribute around the circle. (Default: 6)
|
// n = number of copies to distribute around the circle. (Default: 6)
|
||||||
// r = radius of circle (Default: 1)
|
// r = radius of circle (Default: 1)
|
||||||
|
// ---
|
||||||
// rx = radius of ellipse on X axis. Used instead of r.
|
// rx = radius of ellipse on X axis. Used instead of r.
|
||||||
// ry = radius of ellipse on Y axis. Used instead of r.
|
// ry = radius of ellipse on Y axis. Used instead of r.
|
||||||
// d = diameter of circle. (Default: 2)
|
// d = diameter of circle. (Default: 2)
|
||||||
|
@ -777,13 +791,19 @@ module zrot_copies(rots=[], cp=[0,0,0], n=undef, sa=0, r=0, subrot=true)
|
||||||
// Example:
|
// Example:
|
||||||
// #cube(size=[10,3,3],center=true);
|
// #cube(size=[10,3,3],center=true);
|
||||||
// arc_of(rx=20, ry=10, n=8) cube(size=[10,3,3],center=true);
|
// arc_of(rx=20, ry=10, n=8) cube(size=[10,3,3],center=true);
|
||||||
|
// Example(2D): Using `$idx` to alternate shapes
|
||||||
|
// arc_of(r=50, n=19, sa=0, ea=180)
|
||||||
|
// if ($idx % 2 == 0) rect(6);
|
||||||
|
// else circle(d=6);
|
||||||
module arc_of(
|
module arc_of(
|
||||||
n=6,
|
n=6,
|
||||||
r=undef, rx=undef, ry=undef,
|
r=undef,
|
||||||
|
rx=undef, ry=undef,
|
||||||
d=undef, dx=undef, dy=undef,
|
d=undef, dx=undef, dy=undef,
|
||||||
sa=0, ea=360,
|
sa=0, ea=360,
|
||||||
rot=true
|
rot=true
|
||||||
) {
|
) {
|
||||||
|
req_children($children);
|
||||||
rx = get_radius(r1=rx, r=r, d1=dx, d=d, dflt=1);
|
rx = get_radius(r1=rx, r=r, d1=dx, d=d, dflt=1);
|
||||||
ry = get_radius(r1=ry, r=r, d1=dy, d=d, dflt=1);
|
ry = get_radius(r1=ry, r=r, d1=dy, d=d, dflt=1);
|
||||||
sa = posmod(sa, 360);
|
sa = posmod(sa, 360);
|
||||||
|
@ -809,12 +829,13 @@ module arc_of(
|
||||||
// Spreads children semi-evenly over the surface of a sphere.
|
// Spreads children semi-evenly over the surface of a sphere.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// ovoid_spread(r|d, n, [cone_ang], [scale], [perp]) ...
|
// ovoid_spread(n, r|d=, [cone_ang=], [scale=], [perp=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// r = Radius of the sphere to distribute over
|
|
||||||
// d = Diameter of the sphere to distribute over
|
|
||||||
// n = How many copies to evenly spread over the surface.
|
// n = How many copies to evenly spread over the surface.
|
||||||
|
// r = Radius of the sphere to distribute over
|
||||||
|
// ---
|
||||||
|
// d = Diameter of the sphere to distribute over
|
||||||
// cone_ang = Angle of the cone, in degrees, to limit how much of the sphere gets covered. For full sphere coverage, use 180. Measured pre-scaling. Default: 180
|
// cone_ang = Angle of the cone, in degrees, to limit how much of the sphere gets covered. For full sphere coverage, use 180. Measured pre-scaling. Default: 180
|
||||||
// scale = The [X,Y,Z] scaling factors to reshape the sphere being covered.
|
// scale = The [X,Y,Z] scaling factors to reshape the sphere being covered.
|
||||||
// perp = If true, rotate children to be perpendicular to the sphere surface. Default: true
|
// perp = If true, rotate children to be perpendicular to the sphere surface. Default: true
|
||||||
|
@ -834,8 +855,9 @@ module arc_of(
|
||||||
// ovoid_spread(n=500, d=100, cone_ang=180)
|
// ovoid_spread(n=500, d=100, cone_ang=180)
|
||||||
// color(unit(point3d(v_abs($pos))))
|
// color(unit(point3d(v_abs($pos))))
|
||||||
// cylinder(d=8, h=10, center=false);
|
// cylinder(d=8, h=10, center=false);
|
||||||
module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=true)
|
module ovoid_spread(n=100, r=undef, d=undef, cone_ang=90, scale=[1,1,1], perp=true)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
r = get_radius(r=r, d=d, dflt=50);
|
r = get_radius(r=r, d=d, dflt=50);
|
||||||
cnt = ceil(n / (cone_ang/180));
|
cnt = ceil(n / (cone_ang/180));
|
||||||
|
|
||||||
|
@ -873,13 +895,15 @@ module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=tr
|
||||||
// If you specify `sp` then the copies will start at `sp`.
|
// If you specify `sp` then the copies will start at `sp`.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// path_spread(path), [n], [spacing], [sp], [rotate_children], [closed]) ...
|
// path_spread(path, [n], [spacing], [sp], [rotate_children], [closed]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// path = the path where children are placed
|
// path = path or 1-region where children are placed
|
||||||
// n = number of copies
|
// n = number of copies
|
||||||
// spacing = space between copies
|
// spacing = space between copies
|
||||||
// sp = if given, copies will start distance sp from the path start and spread beyond that point
|
// sp = if given, copies will start distance sp from the path start and spread beyond that point
|
||||||
|
// rotate_children = if true, rotate children to line up with curve normal. Default: true
|
||||||
|
// closed = If true treat path as a closed curve. Default: false
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
// `$pos` is set to the center of each copy
|
// `$pos` is set to the center of each copy
|
||||||
|
@ -947,8 +971,12 @@ module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=tr
|
||||||
// color("blue") cyl(h=3,r=.2, anchor=BOTTOM); // z-aligned cylinder
|
// color("blue") cyl(h=3,r=.2, anchor=BOTTOM); // z-aligned cylinder
|
||||||
// color("red") xcyl(h=10,r=.2, anchor=FRONT+LEFT); // x-aligned cylinder
|
// color("red") xcyl(h=10,r=.2, anchor=FRONT+LEFT); // x-aligned cylinder
|
||||||
// }
|
// }
|
||||||
module path_spread(path, n, spacing, sp=undef, rotate_children=true, closed=false)
|
module path_spread(path, n, spacing, sp=undef, rotate_children=true, closed)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
|
is_1reg = is_1region(path);
|
||||||
|
path = is_1reg ? path[0] : path;
|
||||||
|
closed = default(closed, is_1reg);
|
||||||
length = path_length(path,closed);
|
length = path_length(path,closed);
|
||||||
distances =
|
distances =
|
||||||
is_def(sp)? ( // Start point given
|
is_def(sp)? ( // Start point given
|
||||||
|
@ -1003,7 +1031,7 @@ module path_spread(path, n, spacing, sp=undef, rotate_children=true, closed=fals
|
||||||
// Makes a copy of the children, mirrored across the given plane.
|
// Makes a copy of the children, mirrored across the given plane.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// mirror_copy(v, [cp], [offset]) ...
|
// mirror_copy(v, [cp], [offset]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// v = The normal vector of the plane to mirror across.
|
// v = The normal vector of the plane to mirror across.
|
||||||
|
@ -1027,6 +1055,7 @@ module path_spread(path, n, spacing, sp=undef, rotate_children=true, closed=fals
|
||||||
// color("blue",0.25) translate([0,-5,-5]) rot(from=UP, to=BACK+UP) cube([15,15,0.01], center=true);
|
// color("blue",0.25) translate([0,-5,-5]) rot(from=UP, to=BACK+UP) cube([15,15,0.01], center=true);
|
||||||
module mirror_copy(v=[0,0,1], offset=0, cp)
|
module mirror_copy(v=[0,0,1], offset=0, cp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
cp = is_vector(v,4)? plane_normal(v) * v[3] :
|
cp = is_vector(v,4)? plane_normal(v) * v[3] :
|
||||||
is_vector(cp)? cp :
|
is_vector(cp)? cp :
|
||||||
is_num(cp)? cp*unit(v) :
|
is_num(cp)? cp*unit(v) :
|
||||||
|
@ -1057,7 +1086,7 @@ module mirror_copy(v=[0,0,1], offset=0, cp)
|
||||||
// Makes a copy of the children, mirrored across the X axis.
|
// Makes a copy of the children, mirrored across the X axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// xflip_copy([x], [offset]) ...
|
// xflip_copy([offset], [x]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// offset = Distance to offset children right, before copying.
|
// offset = Distance to offset children right, before copying.
|
||||||
|
@ -1080,6 +1109,7 @@ module mirror_copy(v=[0,0,1], offset=0, cp)
|
||||||
// color("blue",0.25) left(5) cube([0.01,15,15], center=true);
|
// color("blue",0.25) left(5) cube([0.01,15,15], center=true);
|
||||||
module xflip_copy(offset=0, x=0)
|
module xflip_copy(offset=0, x=0)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
mirror_copy(v=[1,0,0], offset=offset, cp=[x,0,0]) children();
|
mirror_copy(v=[1,0,0], offset=offset, cp=[x,0,0]) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,7 +1120,7 @@ module xflip_copy(offset=0, x=0)
|
||||||
// Makes a copy of the children, mirrored across the Y axis.
|
// Makes a copy of the children, mirrored across the Y axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// yflip_copy([y], [offset]) ...
|
// yflip_copy([offset], [y]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// offset = Distance to offset children back, before copying.
|
// offset = Distance to offset children back, before copying.
|
||||||
|
@ -1113,6 +1143,7 @@ module xflip_copy(offset=0, x=0)
|
||||||
// color("blue",0.25) fwd(5) cube([15,0.01,15], center=true);
|
// color("blue",0.25) fwd(5) cube([15,0.01,15], center=true);
|
||||||
module yflip_copy(offset=0, y=0)
|
module yflip_copy(offset=0, y=0)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
mirror_copy(v=[0,1,0], offset=offset, cp=[0,y,0]) children();
|
mirror_copy(v=[0,1,0], offset=offset, cp=[0,y,0]) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,7 +1154,7 @@ module yflip_copy(offset=0, y=0)
|
||||||
// Makes a copy of the children, mirrored across the Z axis.
|
// Makes a copy of the children, mirrored across the Z axis.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// zflip_copy([z], [offset]) ...
|
// zflip_copy([offset], [z]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// offset = Distance to offset children up, before copying.
|
// offset = Distance to offset children up, before copying.
|
||||||
|
@ -1146,6 +1177,7 @@ module yflip_copy(offset=0, y=0)
|
||||||
// color("blue",0.25) down(5) cube([15,15,0.01], center=true);
|
// color("blue",0.25) down(5) cube([15,15,0.01], center=true);
|
||||||
module zflip_copy(offset=0, z=0)
|
module zflip_copy(offset=0, z=0)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
mirror_copy(v=[0,0,1], offset=offset, cp=[0,0,z]) children();
|
mirror_copy(v=[0,0,1], offset=offset, cp=[0,0,z]) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,13 +1194,13 @@ module zflip_copy(offset=0, z=0)
|
||||||
// where you only really care about the spacing between them.
|
// where you only really care about the spacing between them.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// distribute(spacing, dir, [sizes]) ...
|
// distribute(spacing, sizes, dir) children;
|
||||||
// distribute(l, dir, [sizes]) ...
|
// distribute(l=, [sizes=], [dir=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = Spacing to add between each child. (Default: 10.0)
|
// spacing = Spacing to add between each child. (Default: 10.0)
|
||||||
// sizes = Array containing how much space each child will need.
|
// sizes = Array containing how much space each child will need.
|
||||||
// dir = Vector direction to distribute copies along.
|
// dir = Vector direction to distribute copies along. Default: RIGHT
|
||||||
// l = Length to distribute copies along.
|
// l = Length to distribute copies along.
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
|
@ -1183,6 +1215,7 @@ module zflip_copy(offset=0, z=0)
|
||||||
// }
|
// }
|
||||||
module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef)
|
module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
gaps = ($children < 2)? [0] :
|
gaps = ($children < 2)? [0] :
|
||||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||||
[for (i=[0:1:$children-2]) 0];
|
[for (i=[0:1:$children-2]) 0];
|
||||||
|
@ -1207,8 +1240,8 @@ module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef)
|
||||||
// where you only really care about the spacing between them.
|
// where you only really care about the spacing between them.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// xdistribute(spacing, [sizes]) ...
|
// xdistribute(spacing, [sizes]) children;
|
||||||
// xdistribute(l, [sizes]) ...
|
// xdistribute(l=, [sizes=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between each child. (Default: 10.0)
|
// spacing = spacing between each child. (Default: 10.0)
|
||||||
|
@ -1227,6 +1260,7 @@ module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef)
|
||||||
// }
|
// }
|
||||||
module xdistribute(spacing=10, sizes=undef, l=undef)
|
module xdistribute(spacing=10, sizes=undef, l=undef)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
dir = RIGHT;
|
dir = RIGHT;
|
||||||
gaps = ($children < 2)? [0] :
|
gaps = ($children < 2)? [0] :
|
||||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||||
|
@ -1252,8 +1286,8 @@ module xdistribute(spacing=10, sizes=undef, l=undef)
|
||||||
// where you only really care about the spacing between them.
|
// where you only really care about the spacing between them.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// ydistribute(spacing, [sizes])
|
// ydistribute(spacing, [sizes]) children;
|
||||||
// ydistribute(l, [sizes])
|
// ydistribute(l=, [sizes=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between each child. (Default: 10.0)
|
// spacing = spacing between each child. (Default: 10.0)
|
||||||
|
@ -1272,6 +1306,7 @@ module xdistribute(spacing=10, sizes=undef, l=undef)
|
||||||
// }
|
// }
|
||||||
module ydistribute(spacing=10, sizes=undef, l=undef)
|
module ydistribute(spacing=10, sizes=undef, l=undef)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
dir = BACK;
|
dir = BACK;
|
||||||
gaps = ($children < 2)? [0] :
|
gaps = ($children < 2)? [0] :
|
||||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||||
|
@ -1297,8 +1332,8 @@ module ydistribute(spacing=10, sizes=undef, l=undef)
|
||||||
// where you only really care about the spacing between them.
|
// where you only really care about the spacing between them.
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// zdistribute(spacing, [sizes])
|
// zdistribute(spacing, [sizes]) children;
|
||||||
// zdistribute(l, [sizes])
|
// zdistribute(l=, [sizes=]) children;
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// spacing = spacing between each child. (Default: 10.0)
|
// spacing = spacing between each child. (Default: 10.0)
|
||||||
|
@ -1317,6 +1352,7 @@ module ydistribute(spacing=10, sizes=undef, l=undef)
|
||||||
// }
|
// }
|
||||||
module zdistribute(spacing=10, sizes=undef, l=undef)
|
module zdistribute(spacing=10, sizes=undef, l=undef)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
dir = UP;
|
dir = UP;
|
||||||
gaps = ($children < 2)? [0] :
|
gaps = ($children < 2)? [0] :
|
||||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||||
|
|
|
@ -322,7 +322,7 @@ function _sum_preserving_round(data, index=0) =
|
||||||
// Function: subdivide_path()
|
// Function: subdivide_path()
|
||||||
// See Also: subdivide_and_slice(), resample_path(), jittered_poly()
|
// See Also: subdivide_and_slice(), resample_path(), jittered_poly()
|
||||||
// Usage:
|
// Usage:
|
||||||
// newpath = subdivide_path(path, [n|refine|maxlen], [method], [closed], [exact]);
|
// newpath = subdivide_path(path, n|refine=|maxlen=, [method=], [closed=], [exact=]);
|
||||||
// Description:
|
// Description:
|
||||||
// Takes a path as input (closed or open) and subdivides the path to produce a more
|
// Takes a path as input (closed or open) and subdivides the path to produce a more
|
||||||
// finely sampled path. You control the subdivision process by using the `maxlen` arg
|
// finely sampled path. You control the subdivision process by using the `maxlen` arg
|
||||||
|
@ -463,7 +463,7 @@ function subdivide_path(path, n, refine, maxlen, closed=true, exact, method) =
|
||||||
|
|
||||||
// Function: resample_path()
|
// Function: resample_path()
|
||||||
// Usage:
|
// Usage:
|
||||||
// newpath = resample_path(path, n|spacing, [closed]);
|
// newpath = resample_path(path, n|spacing=, [closed=]);
|
||||||
// Description:
|
// Description:
|
||||||
// Compute a uniform resampling of the input path. If you specify `n` then the output path will have n
|
// Compute a uniform resampling of the input path. If you specify `n` then the output path will have n
|
||||||
// points spaced uniformly (by linear interpolation along the input path segments). The only points of the
|
// points spaced uniformly (by linear interpolation along the input path segments). The only points of the
|
||||||
|
@ -553,7 +553,7 @@ function is_path_simple(path, closed, eps=EPSILON) =
|
||||||
|
|
||||||
// Function: path_closest_point()
|
// Function: path_closest_point()
|
||||||
// Usage:
|
// Usage:
|
||||||
// path_closest_point(path, pt);
|
// index_pt = path_closest_point(path, pt);
|
||||||
// Description:
|
// Description:
|
||||||
// Finds the closest path segment, and point on that segment to the given point.
|
// Finds the closest path segment, and point on that segment to the given point.
|
||||||
// Returns `[SEGNUM, POINT]`
|
// Returns `[SEGNUM, POINT]`
|
||||||
|
@ -828,7 +828,7 @@ function _path_cuts_dir(path, cuts, closed=false, eps=1e-2) =
|
||||||
// Topics: Paths
|
// Topics: Paths
|
||||||
// See Also: split_path_at_self_crossings()
|
// See Also: split_path_at_self_crossings()
|
||||||
// Usage:
|
// Usage:
|
||||||
// path_list = path_cut(path, cutdist, [closed=]);
|
// path_list = path_cut(path, cutdist, [closed]);
|
||||||
// Description:
|
// Description:
|
||||||
// Given a list of distances in `cutdist`, cut the path into
|
// Given a list of distances in `cutdist`, cut the path into
|
||||||
// subpaths at those lengths, returning a list of paths.
|
// subpaths at those lengths, returning a list of paths.
|
||||||
|
|
26
regions.scad
26
regions.scad
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
// Function: is_region()
|
// Function: is_region()
|
||||||
// Usage:
|
// Usage:
|
||||||
// is_region(x);
|
// bool = is_region(x);
|
||||||
// Description:
|
// Description:
|
||||||
// Returns true if the given item looks like a region. A region is a list of non-crossing simple polygons. This test just checks
|
// Returns true if the given item looks like a region. A region is a list of non-crossing simple polygons. This test just checks
|
||||||
// that the argument is a list whose first entry is a path.
|
// that the argument is a list whose first entry is a path.
|
||||||
|
@ -281,7 +281,7 @@ function force_region(poly) = is_path(poly) ? [poly] : poly;
|
||||||
|
|
||||||
// Module: region()
|
// Module: region()
|
||||||
// Usage:
|
// Usage:
|
||||||
// region(r, [anchor], [spin], [cp]) { ... };
|
// region(r, [anchor], [spin=], [cp=], [atype=]) [attachments];
|
||||||
// Description:
|
// Description:
|
||||||
// Creates the 2D polygons described by the given region or list of polygons. This module works on
|
// Creates the 2D polygons described by the given region or list of polygons. This module works on
|
||||||
// arbitrary lists of polygons that cross each other and hence do not define a valid region. The
|
// arbitrary lists of polygons that cross each other and hence do not define a valid region. The
|
||||||
|
@ -289,6 +289,7 @@ function force_region(poly) = is_path(poly) ? [poly] : poly;
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// r = region to create as geometry
|
// r = region to create as geometry
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
||||||
|
// ---
|
||||||
// spin = Rotate this many degrees after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// spin = Rotate this many degrees after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||||
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 2D point. Default: "centroid"
|
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 2D point. Default: "centroid"
|
||||||
// atype = Set to "hull" or "intersect" to select anchor type. Default: "hull"
|
// atype = Set to "hull" or "intersect" to select anchor type. Default: "hull"
|
||||||
|
@ -356,7 +357,7 @@ function _point_in_region(point, region, eps=EPSILON, i=0, cnt=0) =
|
||||||
|
|
||||||
// Function: region_area()
|
// Function: region_area()
|
||||||
// Usage:
|
// Usage:
|
||||||
// area=region_area(region);
|
// area = region_area(region);
|
||||||
// Description:
|
// Description:
|
||||||
// Computes the area of the specified valid region. (If the region is invalid and has self intersections
|
// Computes the area of the specified valid region. (If the region is invalid and has self intersections
|
||||||
// the result is meaningless.)
|
// the result is meaningless.)
|
||||||
|
@ -377,14 +378,13 @@ function _clockwise_region(r) = [for(p=r) clockwise_polygon(p)];
|
||||||
|
|
||||||
// Function: are_regions_equal()
|
// Function: are_regions_equal()
|
||||||
// Usage:
|
// Usage:
|
||||||
// b = are_regions_equal(region1, region2, [eps])
|
// b = are_regions_equal(region1, region2, [either_winding])
|
||||||
// Description:
|
// Description:
|
||||||
// Returns true if the components of region1 and region2 are the same polygons (in any order)
|
// Returns true if the components of region1 and region2 are the same polygons (in any order).
|
||||||
// within given epsilon tolerance.
|
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// region1 = first region
|
// region1 = first region
|
||||||
// region2 = second region
|
// region2 = second region
|
||||||
// eps = tolerance for comparison
|
// either_winding = if true then two shapes test equal if they wind in opposite directions. Default: false
|
||||||
function are_regions_equal(region1, region2, either_winding=false) =
|
function are_regions_equal(region1, region2, either_winding=false) =
|
||||||
let(
|
let(
|
||||||
region1=force_region(region1),
|
region1=force_region(region1),
|
||||||
|
@ -707,8 +707,8 @@ function _point_dist(path,pathseg_unit,pathseg_len,pt) =
|
||||||
|
|
||||||
// Function: offset()
|
// Function: offset()
|
||||||
// Usage:
|
// Usage:
|
||||||
// offsetpath = offset(path, [r|delta], [chamfer], [closed], [check_valid], [quality])
|
// offsetpath = offset(path, [r=|delta=], [chamfer=], [closed=], [check_valid=], [quality=])
|
||||||
// path_faces = offset(path, return_faces=true, [r|delta], [chamfer], [closed], [check_valid], [quality], [firstface_index], [flip_faces])
|
// path_faces = offset(path, return_faces=true, [r=|delta=], [chamfer=], [closed=], [check_valid=], [quality=], [firstface_index=], [flip_faces=])
|
||||||
// Description:
|
// Description:
|
||||||
// Takes a 2D input path, polygon or region and returns a path offset by the specified amount. As with the built-in
|
// Takes a 2D input path, polygon or region and returns a path offset by the specified amount. As with the built-in
|
||||||
// offset() module, you can use `r` to specify rounded offset and `delta` to specify offset with
|
// offset() module, you can use `r` to specify rounded offset and `delta` to specify offset with
|
||||||
|
@ -983,7 +983,7 @@ function _list_three(a,b,c) =
|
||||||
|
|
||||||
// Function&Module: union()
|
// Function&Module: union()
|
||||||
// Usage:
|
// Usage:
|
||||||
// union() {...}
|
// union() children;
|
||||||
// region = union(regions);
|
// region = union(regions);
|
||||||
// region = union(REGION1,REGION2);
|
// region = union(REGION1,REGION2);
|
||||||
// region = union(REGION1,REGION2,REGION3);
|
// region = union(REGION1,REGION2,REGION3);
|
||||||
|
@ -1013,7 +1013,7 @@ function union(regions=[],b=undef,c=undef,eps=EPSILON) =
|
||||||
|
|
||||||
// Function&Module: difference()
|
// Function&Module: difference()
|
||||||
// Usage:
|
// Usage:
|
||||||
// difference() {...}
|
// difference() children;
|
||||||
// region = difference(regions);
|
// region = difference(regions);
|
||||||
// region = difference(REGION1,REGION2);
|
// region = difference(REGION1,REGION2);
|
||||||
// region = difference(REGION1,REGION2,REGION3);
|
// region = difference(REGION1,REGION2,REGION3);
|
||||||
|
@ -1045,7 +1045,7 @@ function difference(regions=[],b=undef,c=undef,eps=EPSILON) =
|
||||||
|
|
||||||
// Function&Module: intersection()
|
// Function&Module: intersection()
|
||||||
// Usage:
|
// Usage:
|
||||||
// intersection() {...}
|
// intersection() children;
|
||||||
// region = intersection(regions);
|
// region = intersection(regions);
|
||||||
// region = intersection(REGION1,REGION2);
|
// region = intersection(REGION1,REGION2);
|
||||||
// region = intersection(REGION1,REGION2,REGION3);
|
// region = intersection(REGION1,REGION2,REGION3);
|
||||||
|
@ -1076,7 +1076,7 @@ function intersection(regions=[],b=undef,c=undef,eps=EPSILON) =
|
||||||
|
|
||||||
// Function&Module: exclusive_or()
|
// Function&Module: exclusive_or()
|
||||||
// Usage:
|
// Usage:
|
||||||
// exclusive_or() {...}
|
// exclusive_or() children;
|
||||||
// region = exclusive_or(regions);
|
// region = exclusive_or(regions);
|
||||||
// region = exclusive_or(REGION1,REGION2);
|
// region = exclusive_or(REGION1,REGION2);
|
||||||
// region = exclusive_or(REGION1,REGION2,REGION3);
|
// region = exclusive_or(REGION1,REGION2,REGION3);
|
||||||
|
|
|
@ -340,12 +340,13 @@ include <structs.scad>
|
||||||
// Example(2D): Two passes to apply chamfers first, and then round the unchamfered corners. Chamfers always add one point, so it's not hard to keep track of the vertices
|
// Example(2D): Two passes to apply chamfers first, and then round the unchamfered corners. Chamfers always add one point, so it's not hard to keep track of the vertices
|
||||||
// $fn=32;
|
// $fn=32;
|
||||||
// shape = square(10);
|
// shape = square(10);
|
||||||
// chamfered = round_corners(shape, method="chamfer", cut=[2,0,2,0]);
|
// chamfered = round_corners(shape, method="chamfer",
|
||||||
|
// cut=[2,0,2,0]);
|
||||||
// rounded = round_corners(chamfered,
|
// rounded = round_corners(chamfered,
|
||||||
// cut = [0, 0, // first original veretex, chamfered
|
// cut = [0, 0, // 1st original vertex, chamfered
|
||||||
// 1.5, // second original vertex
|
// 1.5, // 2nd original vertex
|
||||||
// 0, 0, // third original vertex, chamfered
|
// 0, 0, // 3rd original vertex, chamfered
|
||||||
// 2.5]); // last original vertex
|
// 2.5]); // 4th original vertex
|
||||||
// polygon(rounded);
|
// polygon(rounded);
|
||||||
// Example(2D): Another example of mixing chamfers and roundings with two passes
|
// Example(2D): Another example of mixing chamfers and roundings with two passes
|
||||||
// path = star(5, step=2, d=100);
|
// path = star(5, step=2, d=100);
|
||||||
|
@ -1706,7 +1707,7 @@ function os_mask(mask, out=false, extra,check_valid, quality, offset) =
|
||||||
|
|
||||||
// Module: convex_offset_extrude()
|
// Module: convex_offset_extrude()
|
||||||
// Usage: Basic usage. See below for full options
|
// Usage: Basic usage. See below for full options
|
||||||
// convex_offset_extrude(height, [bottom], [top], ...) {2D children};
|
// convex_offset_extrude(height, [bottom], [top], ...) 2D-children;
|
||||||
// Description:
|
// Description:
|
||||||
// Extrudes 2d children with layers formed from the convex hull of the offset of each child according to a sequence of offset values.
|
// Extrudes 2d children with layers formed from the convex hull of the offset of each child according to a sequence of offset values.
|
||||||
// Like `offset_sweep` this module can use built-in offset profiles to provide treatments such as roundovers or chamfers but unlike `offset_sweep()` it
|
// Like `offset_sweep` this module can use built-in offset profiles to provide treatments such as roundovers or chamfers but unlike `offset_sweep()` it
|
||||||
|
@ -1811,6 +1812,7 @@ module convex_offset_extrude(
|
||||||
joint=undef, k=0.75, angle=45,
|
joint=undef, k=0.75, angle=45,
|
||||||
convexity=10, thickness = 1/1024
|
convexity=10, thickness = 1/1024
|
||||||
) {
|
) {
|
||||||
|
req_children($children);
|
||||||
argspec = [
|
argspec = [
|
||||||
["for", ""],
|
["for", ""],
|
||||||
["r",r],
|
["r",r],
|
||||||
|
@ -2347,7 +2349,7 @@ function _circle_mask(r) =
|
||||||
// rot(-90) {
|
// rot(-90) {
|
||||||
// $fn=128;
|
// $fn=128;
|
||||||
// difference(){
|
// difference(){
|
||||||
// tube(or=r, wall=2, h=45);
|
// tube(or=r, wall=2, h=35, anchor=BOT);
|
||||||
// bent_cutout_mask(r-1, 2.1, back(5,p=square([18,18])));
|
// bent_cutout_mask(r-1, 2.1, back(5,p=square([18,18])));
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -2356,7 +2358,7 @@ function _circle_mask(r) =
|
||||||
// rot(-90) {
|
// rot(-90) {
|
||||||
// $fn=128;
|
// $fn=128;
|
||||||
// difference(){
|
// difference(){
|
||||||
// tube(or=r, wall=2, h=45);
|
// tube(or=r, wall=2, h=35, anchor=BOT);
|
||||||
// bent_cutout_mask(r-1, 2.1,
|
// bent_cutout_mask(r-1, 2.1,
|
||||||
// subdivide_path(back(5,p=square([18,18])),64,closed=true));
|
// subdivide_path(back(5,p=square([18,18])),64,closed=true));
|
||||||
// }
|
// }
|
||||||
|
@ -2366,7 +2368,7 @@ function _circle_mask(r) =
|
||||||
// rot(-90) {
|
// rot(-90) {
|
||||||
// $fn=128;
|
// $fn=128;
|
||||||
// difference(){
|
// difference(){
|
||||||
// tube(or=r, wall=2, h=45);
|
// tube(or=r, wall=2, h=35, anchor=BOT);
|
||||||
// bent_cutout_mask(r-1, 2.1,
|
// bent_cutout_mask(r-1, 2.1,
|
||||||
// apply(back(15),
|
// apply(back(15),
|
||||||
// subdivide_path(
|
// subdivide_path(
|
||||||
|
|
|
@ -2450,7 +2450,7 @@ function onion(r, ang=45, cap_h, d, anchor=CENTER, spin=0, orient=UP) =
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"baseline"`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"baseline"`
|
||||||
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// spin = Rotate this many degrees around the Z axis. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||||
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
// orient = Vector to rotate top towards. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||||
// See Also: attachable()
|
// See Also: path_text()
|
||||||
// Extra Anchors:
|
// Extra Anchors:
|
||||||
// "baseline" = Anchors at the baseline of the text, at the start of the string.
|
// "baseline" = Anchors at the baseline of the text, at the start of the string.
|
||||||
// str("baseline",VECTOR) = Anchors at the baseline of the text, modified by the X and Z components of the appended vector.
|
// str("baseline",VECTOR) = Anchors at the baseline of the text, modified by the X and Z components of the appended vector.
|
||||||
|
@ -2460,14 +2460,6 @@ 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));
|
||||||
// Example: Using line_of() distributor
|
|
||||||
// txt = "This is the string.";
|
|
||||||
// line_of(spacing=[10,-5],n=len(txt))
|
|
||||||
// text3d(txt[$idx], size=10, anchor=CENTER);
|
|
||||||
// Example: Using arc_of() distributor
|
|
||||||
// txt = "This is the string";
|
|
||||||
// arc_of(r=50, n=len(txt), sa=0, ea=180)
|
|
||||||
// text3d(select(txt,-1-$idx), size=10, anchor=str("baseline",CENTER), spin=-90);
|
|
||||||
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 =
|
||||||
|
|
|
@ -18,11 +18,10 @@ module test_move() {
|
||||||
for (val=vals) {
|
for (val=vals) {
|
||||||
assert_equal(move(val), [[1,0,0,val.x],[0,1,0,val.y],[0,0,1,val.z],[0,0,0,1]]);
|
assert_equal(move(val), [[1,0,0,val.x],[0,1,0,val.y],[0,0,1,val.z],[0,0,0,1]]);
|
||||||
assert_equal(move(val, p=[1,2,3]), [1,2,3]+val);
|
assert_equal(move(val, p=[1,2,3]), [1,2,3]+val);
|
||||||
assert_equal(move(x=val.x, y=val.y, z=val.z, p=[1,2,3]), [1,2,3]+val);
|
|
||||||
}
|
}
|
||||||
// Verify that module at least doesn't crash.
|
// Verify that module at least doesn't crash.
|
||||||
move(x=-5) move(y=-5) move(z=-5) move([-5,-5,-5]) union(){};
|
move([-5,-5,-5]) union(){};
|
||||||
move(x=5) move(y=5) move(z=5) move([5,5,5]) union(){};
|
move([5,5,5]) union(){};
|
||||||
sq = square(10);
|
sq = square(10);
|
||||||
assert_equal(move("centroid", sq), move(-centroid(sq),sq));
|
assert_equal(move("centroid", sq), move(-centroid(sq),sq));
|
||||||
assert_equal(move("mean", vals), move(-mean(vals), vals));
|
assert_equal(move("mean", vals), move(-mean(vals), vals));
|
||||||
|
|
117
transforms.scad
117
transforms.scad
|
@ -75,15 +75,12 @@ _NO_ARG = [true,[123232345],false];
|
||||||
// Aliases: translate()
|
// Aliases: translate()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// move([x=], [y=], [z=]) ...
|
// move(v) children;
|
||||||
// move(v) ...
|
|
||||||
// Usage: As a function to translate points, VNF, or Bezier patch
|
// Usage: As a function to translate points, VNF, or Bezier patch
|
||||||
// pts = move(v, p);
|
// pts = move(v, p);
|
||||||
// pts = move([x=], [y=], [z=], p=);
|
|
||||||
// pts = move(STRING, p);
|
// pts = move(STRING, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
// mat = move(v);
|
// mat = move(v);
|
||||||
// mat = move([x=], [y=], [z=]);
|
|
||||||
//
|
//
|
||||||
// Topics: Affine, Matrices, Transforms, Translation
|
// Topics: Affine, Matrices, Transforms, Translation
|
||||||
// See Also: left(), right(), fwd(), back(), down(), up(), spherical_to_xyz(), altaz_to_xyz(), cylindrical_to_xyz(), polar_to_xy()
|
// See Also: left(), right(), fwd(), back(), down(), up(), spherical_to_xyz(), altaz_to_xyz(), cylindrical_to_xyz(), polar_to_xy()
|
||||||
|
@ -97,28 +94,22 @@ _NO_ARG = [true,[123232345],false];
|
||||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the translated VNF.
|
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the translated VNF.
|
||||||
// * Called as a function with the `p` argument, returns the translated point or list of points.
|
// * Called as a function with the `p` argument, returns the translated point or list of points.
|
||||||
// * Called as a function with the `p` argument set to a VNF or a polygon and `v` set to "centroid", "mean" or "box", translates the argument to the centroid, mean, or bounding box center respectively.
|
// * Called as a function with the `p` argument set to a VNF or a polygon and `v` set to "centroid", "mean" or "box", translates the argument to the centroid, mean, or bounding box center respectively.
|
||||||
// * Called as a function without a `p` argument, with a 2D offset vector `v`, returns an affine2d translation matrix.
|
// * Called as a function without a `p` argument, returns a 4x4 translation matrix for operating on 3D data.
|
||||||
// * Called as a function without a `p` argument, with a 3D offset vector `v`, returns an affine3d translation matrix.
|
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// v = An [X,Y,Z] vector to translate by. For function form with `p` is a point list or VNF, can be "centroid", "mean" or "box".
|
// v = An [X,Y,Z] vector to translate by. For function form with `p` a point list or VNF, can be "centroid", "mean" or "box".
|
||||||
// p = Either a point, or a list of points to be translated when used as a function.
|
// p = Either a point, or a list of points to be translated when used as a function.
|
||||||
// ---
|
|
||||||
// x = X axis translation.
|
|
||||||
// y = Y axis translation.
|
|
||||||
// z = Z axis translation.
|
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// #sphere(d=10);
|
// #sphere(d=10);
|
||||||
// move([0,20,30]) sphere(d=10);
|
// move([0,20,30]) sphere(d=10);
|
||||||
//
|
//
|
||||||
// Example:
|
// Example: You can move a 3D object with a 2D vector. The Z component is treated at zero.
|
||||||
// #sphere(d=10);
|
// #sphere(d=10);
|
||||||
// move(y=20) sphere(d=10);
|
// move([-10,-5]) sphere(d=10);
|
||||||
//
|
//
|
||||||
// Example:
|
// Example(2D): Move to centroid
|
||||||
// #sphere(d=10);
|
// polygon(move("centroid", right_triangle([10,4])));
|
||||||
// move(x=-10, y=-5) sphere(d=10);
|
|
||||||
//
|
//
|
||||||
// Example(FlatSpin): Using Altitude-Azimuth Coordinates
|
// Example(FlatSpin): Using Altitude-Azimuth Coordinates
|
||||||
// #sphere(d=10);
|
// #sphere(d=10);
|
||||||
|
@ -135,19 +126,18 @@ _NO_ARG = [true,[123232345],false];
|
||||||
//
|
//
|
||||||
// Example(NORENDER):
|
// Example(NORENDER):
|
||||||
// pt1 = move([0,20,30], p=[15,23,42]); // Returns: [15, 43, 72]
|
// pt1 = move([0,20,30], p=[15,23,42]); // Returns: [15, 43, 72]
|
||||||
// pt2 = move(y=10, p=[15,23,42]); // Returns: [15, 33, 42]
|
// pt2 = move([0,3,1], p=[[1,2,3],[4,5,6]]); // Returns: [[1,5,4], [4,8,7]]
|
||||||
// pt3 = move([0,3,1], p=[[1,2,3],[4,5,6]]); // Returns: [[1,5,4], [4,8,7]]
|
|
||||||
// pt4 = move(y=11, p=[[1,2,3],[4,5,6]]); // Returns: [[1,13,3], [4,16,6]]
|
|
||||||
// mat2d = move([2,3]); // Returns: [[1,0,2],[0,1,3],[0,0,1]]
|
// mat2d = move([2,3]); // Returns: [[1,0,2],[0,1,3],[0,0,1]]
|
||||||
// mat3d = move([2,3,4]); // Returns: [[1,0,0,2],[0,1,0,3],[0,0,1,4],[0,0,0,1]]
|
// mat3d = move([2,3,4]); // Returns: [[1,0,0,2],[0,1,0,3],[0,0,1,4],[0,0,0,1]]
|
||||||
module move(v=[0,0,0], p, x=0, y=0, z=0) {
|
module move(v=[0,0,0], p) {
|
||||||
|
req_children($children);
|
||||||
assert(!is_string(v),"Module form of `move()` does not accept string `v` arguments");
|
assert(!is_string(v),"Module form of `move()` does not accept string `v` arguments");
|
||||||
assert(is_undef(p), "Module form `move()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `move()` does not accept p= argument.");
|
||||||
assert(is_vector(v) && (len(v)==3 || len(v)==2), "Invalid value for `v`")
|
assert(is_vector(v) && (len(v)==3 || len(v)==2), "Invalid value for `v`")
|
||||||
translate(point3d(v)+[x,y,z]) children();
|
translate(point3d(v)) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
function move(v=[0,0,0], p=_NO_ARG, x=0, y=0, z=0) =
|
function move(v=[0,0,0], p=_NO_ARG) =
|
||||||
is_string(v) ? (
|
is_string(v) ? (
|
||||||
assert(is_vnf(p) || is_path(p),"String movements only work with point lists and VNFs")
|
assert(is_vnf(p) || is_path(p),"String movements only work with point lists and VNFs")
|
||||||
let(
|
let(
|
||||||
|
@ -156,12 +146,12 @@ function move(v=[0,0,0], p=_NO_ARG, x=0, y=0, z=0) =
|
||||||
: v=="box" ? mean(pointlist_bounds(p))
|
: v=="box" ? mean(pointlist_bounds(p))
|
||||||
: assert(false,str("Unknown string movement ",v))
|
: assert(false,str("Unknown string movement ",v))
|
||||||
)
|
)
|
||||||
move(-center,p=p, x=x,y=y,z=z)
|
move(-center,p=p)
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
assert(is_vector(v) && (len(v)==3 || len(v)==2), "Invalid value for `v`")
|
assert(is_vector(v) && (len(v)==3 || len(v)==2), "Invalid value for `v`")
|
||||||
let(
|
let(
|
||||||
m = affine3d_translate(point3d(v)+[x,y,z])
|
m = affine3d_translate(point3d(v))
|
||||||
)
|
)
|
||||||
p==_NO_ARG ? m : apply(m, p);
|
p==_NO_ARG ? m : apply(m, p);
|
||||||
|
|
||||||
|
@ -171,7 +161,7 @@ function translate(v=[0,0,0], p=_NO_ARG) = move(v=v, p=p);
|
||||||
// Function&Module: left()
|
// Function&Module: left()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// left(x) ...
|
// left(x) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = left(x, p);
|
// pts = left(x, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -199,6 +189,7 @@ function translate(v=[0,0,0], p=_NO_ARG) = move(v=v, p=p);
|
||||||
// pt3 = left(3, p=[[1,2,3],[4,5,6]]); // Returns: [[-2,2,3], [1,5,6]]
|
// pt3 = left(3, p=[[1,2,3],[4,5,6]]); // Returns: [[-2,2,3], [1,5,6]]
|
||||||
// mat3d = left(4); // Returns: [[1,0,0,-4],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
|
// mat3d = left(4); // Returns: [[1,0,0,-4],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
|
||||||
module left(x=0, p) {
|
module left(x=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `left()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `left()` does not accept p= argument.");
|
||||||
assert(is_finite(x), "Invalid number")
|
assert(is_finite(x), "Invalid number")
|
||||||
translate([-x,0,0]) children();
|
translate([-x,0,0]) children();
|
||||||
|
@ -213,7 +204,7 @@ function left(x=0, p=_NO_ARG) =
|
||||||
// Aliases: xmove()
|
// Aliases: xmove()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// right(x) ...
|
// right(x) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = right(x, p);
|
// pts = right(x, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -241,6 +232,7 @@ function left(x=0, p=_NO_ARG) =
|
||||||
// pt3 = right(3, p=[[1,2,3],[4,5,6]]); // Returns: [[4,2,3], [7,5,6]]
|
// pt3 = right(3, p=[[1,2,3],[4,5,6]]); // Returns: [[4,2,3], [7,5,6]]
|
||||||
// mat3d = right(4); // Returns: [[1,0,0,4],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
|
// mat3d = right(4); // Returns: [[1,0,0,4],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
|
||||||
module right(x=0, p) {
|
module right(x=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `right()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `right()` does not accept p= argument.");
|
||||||
assert(is_finite(x), "Invalid number")
|
assert(is_finite(x), "Invalid number")
|
||||||
translate([x,0,0]) children();
|
translate([x,0,0]) children();
|
||||||
|
@ -251,6 +243,7 @@ function right(x=0, p=_NO_ARG) =
|
||||||
move([x,0,0],p=p);
|
move([x,0,0],p=p);
|
||||||
|
|
||||||
module xmove(x=0, p) {
|
module xmove(x=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `xmove()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `xmove()` does not accept p= argument.");
|
||||||
assert(is_finite(x), "Invalid number")
|
assert(is_finite(x), "Invalid number")
|
||||||
translate([x,0,0]) children();
|
translate([x,0,0]) children();
|
||||||
|
@ -264,7 +257,7 @@ function xmove(x=0, p=_NO_ARG) =
|
||||||
// Function&Module: fwd()
|
// Function&Module: fwd()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// fwd(y) ...
|
// fwd(y) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = fwd(y, p);
|
// pts = fwd(y, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -292,6 +285,7 @@ function xmove(x=0, p=_NO_ARG) =
|
||||||
// pt3 = fwd(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,-1,3], [4,2,6]]
|
// pt3 = fwd(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,-1,3], [4,2,6]]
|
||||||
// mat3d = fwd(4); // Returns: [[1,0,0,0],[0,1,0,-4],[0,0,1,0],[0,0,0,1]]
|
// mat3d = fwd(4); // Returns: [[1,0,0,0],[0,1,0,-4],[0,0,1,0],[0,0,0,1]]
|
||||||
module fwd(y=0, p) {
|
module fwd(y=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `fwd()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `fwd()` does not accept p= argument.");
|
||||||
assert(is_finite(y), "Invalid number")
|
assert(is_finite(y), "Invalid number")
|
||||||
translate([0,-y,0]) children();
|
translate([0,-y,0]) children();
|
||||||
|
@ -306,7 +300,7 @@ function fwd(y=0, p=_NO_ARG) =
|
||||||
// Aliases: ymove()
|
// Aliases: ymove()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// back(y) ...
|
// back(y) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = back(y, p);
|
// pts = back(y, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -334,6 +328,7 @@ function fwd(y=0, p=_NO_ARG) =
|
||||||
// pt3 = back(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,5,3], [4,8,6]]
|
// pt3 = back(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,5,3], [4,8,6]]
|
||||||
// mat3d = back(4); // Returns: [[1,0,0,0],[0,1,0,4],[0,0,1,0],[0,0,0,1]]
|
// mat3d = back(4); // Returns: [[1,0,0,0],[0,1,0,4],[0,0,1,0],[0,0,0,1]]
|
||||||
module back(y=0, p) {
|
module back(y=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `back()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `back()` does not accept p= argument.");
|
||||||
assert(is_finite(y), "Invalid number")
|
assert(is_finite(y), "Invalid number")
|
||||||
translate([0,y,0]) children();
|
translate([0,y,0]) children();
|
||||||
|
@ -344,6 +339,7 @@ function back(y=0,p=_NO_ARG) =
|
||||||
move([0,y,0],p=p);
|
move([0,y,0],p=p);
|
||||||
|
|
||||||
module ymove(y=0, p) {
|
module ymove(y=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `ymove()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `ymove()` does not accept p= argument.");
|
||||||
assert(is_finite(y), "Invalid number")
|
assert(is_finite(y), "Invalid number")
|
||||||
translate([0,y,0]) children();
|
translate([0,y,0]) children();
|
||||||
|
@ -357,7 +353,7 @@ function ymove(y=0,p=_NO_ARG) =
|
||||||
// Function&Module: down()
|
// Function&Module: down()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// down(z) ...
|
// down(z) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = down(z, p);
|
// pts = down(z, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -384,6 +380,7 @@ function ymove(y=0,p=_NO_ARG) =
|
||||||
// pt2 = down(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,2,0], [4,5,3]]
|
// pt2 = down(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,2,0], [4,5,3]]
|
||||||
// mat3d = down(4); // Returns: [[1,0,0,0],[0,1,0,0],[0,0,1,-4],[0,0,0,1]]
|
// mat3d = down(4); // Returns: [[1,0,0,0],[0,1,0,0],[0,0,1,-4],[0,0,0,1]]
|
||||||
module down(z=0, p) {
|
module down(z=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `down()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `down()` does not accept p= argument.");
|
||||||
translate([0,0,-z]) children();
|
translate([0,0,-z]) children();
|
||||||
}
|
}
|
||||||
|
@ -397,7 +394,7 @@ function down(z=0, p=_NO_ARG) =
|
||||||
// Aliases: zmove()
|
// Aliases: zmove()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// up(z) ...
|
// up(z) children;
|
||||||
// Usage: Translate Points
|
// Usage: Translate Points
|
||||||
// pts = up(z, p);
|
// pts = up(z, p);
|
||||||
// Usage: Get Translation Matrix
|
// Usage: Get Translation Matrix
|
||||||
|
@ -424,6 +421,7 @@ function down(z=0, p=_NO_ARG) =
|
||||||
// pt2 = up(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,2,6], [4,5,9]]
|
// pt2 = up(3, p=[[1,2,3],[4,5,6]]); // Returns: [[1,2,6], [4,5,9]]
|
||||||
// mat3d = up(4); // Returns: [[1,0,0,0],[0,1,0,0],[0,0,1,4],[0,0,0,1]]
|
// mat3d = up(4); // Returns: [[1,0,0,0],[0,1,0,0],[0,0,1,4],[0,0,0,1]]
|
||||||
module up(z=0, p) {
|
module up(z=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `up()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `up()` does not accept p= argument.");
|
||||||
assert(is_finite(z), "Invalid number");
|
assert(is_finite(z), "Invalid number");
|
||||||
translate([0,0,z]) children();
|
translate([0,0,z]) children();
|
||||||
|
@ -434,6 +432,7 @@ function up(z=0, p=_NO_ARG) =
|
||||||
move([0,0,z],p=p);
|
move([0,0,z],p=p);
|
||||||
|
|
||||||
module zmove(z=0, p) {
|
module zmove(z=0, p) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `zmove()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `zmove()` does not accept p= argument.");
|
||||||
assert(is_finite(z), "Invalid number");
|
assert(is_finite(z), "Invalid number");
|
||||||
translate([0,0,z]) children();
|
translate([0,0,z]) children();
|
||||||
|
@ -453,10 +452,10 @@ function zmove(z=0, p=_NO_ARG) =
|
||||||
// Function&Module: rot()
|
// Function&Module: rot()
|
||||||
//
|
//
|
||||||
// Usage: As a Module
|
// Usage: As a Module
|
||||||
// rot(a, [cp], [reverse]) {...}
|
// rot(a, [cp=], [reverse=]) children;
|
||||||
// rot([X,Y,Z], [cp], [reverse]) {...}
|
// rot([X,Y,Z], [cp=], [reverse=]) children;
|
||||||
// rot(a, v, [cp], [reverse]) {...}
|
// rot(a, v, [cp=], [reverse=]) children;
|
||||||
// rot(from, to, [a], [reverse]) {...}
|
// rot(from=, to=, [a=], [reverse=]) children;
|
||||||
// Usage: As a Function to transform data in `p`
|
// Usage: As a Function to transform data in `p`
|
||||||
// pts = rot(a, p=, [cp=], [reverse=]);
|
// pts = rot(a, p=, [cp=], [reverse=]);
|
||||||
// pts = rot([X,Y,Z], p=, [cp=], [reverse=]);
|
// pts = rot([X,Y,Z], p=, [cp=], [reverse=]);
|
||||||
|
@ -519,6 +518,7 @@ function zmove(z=0, p=_NO_ARG) =
|
||||||
// stroke(rot(30,p=path), closed=true);
|
// stroke(rot(30,p=path), closed=true);
|
||||||
module rot(a=0, v, cp, from, to, reverse=false)
|
module rot(a=0, v, cp, from, to, reverse=false)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
m = rot(a=a, v=v, cp=cp, from=from, to=to, reverse=reverse);
|
m = rot(a=a, v=v, cp=cp, from=from, to=to, reverse=reverse);
|
||||||
multmatrix(m) children();
|
multmatrix(m) children();
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ function rot(a=0, v, cp, from, to, reverse=false, p=_NO_ARG, _m) =
|
||||||
// Function&Module: xrot()
|
// Function&Module: xrot()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// xrot(a, [cp=]) ...
|
// xrot(a, [cp=]) children;
|
||||||
// Usage: As a function to rotate points
|
// Usage: As a function to rotate points
|
||||||
// rotated = xrot(a, p, [cp=]);
|
// rotated = xrot(a, p, [cp=]);
|
||||||
// Usage: As a function to return rotation matrix
|
// Usage: As a function to return rotation matrix
|
||||||
|
@ -585,6 +585,7 @@ function rot(a=0, v, cp, from, to, reverse=false, p=_NO_ARG, _m) =
|
||||||
// xrot(90) cylinder(h=50, r=10, center=true);
|
// xrot(90) cylinder(h=50, r=10, center=true);
|
||||||
module xrot(a=0, p, cp)
|
module xrot(a=0, p, cp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `xrot()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `xrot()` does not accept p= argument.");
|
||||||
if (a==0) {
|
if (a==0) {
|
||||||
children(); // May be slightly faster?
|
children(); // May be slightly faster?
|
||||||
|
@ -601,7 +602,7 @@ function xrot(a=0, p=_NO_ARG, cp) = rot([a,0,0], cp=cp, p=p);
|
||||||
// Function&Module: yrot()
|
// Function&Module: yrot()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// yrot(a, [cp=]) ...
|
// yrot(a, [cp=]) children;
|
||||||
// Usage: Rotate Points
|
// Usage: Rotate Points
|
||||||
// rotated = yrot(a, p, [cp=]);
|
// rotated = yrot(a, p, [cp=]);
|
||||||
// Usage: Get Rotation Matrix
|
// Usage: Get Rotation Matrix
|
||||||
|
@ -630,6 +631,7 @@ function xrot(a=0, p=_NO_ARG, cp) = rot([a,0,0], cp=cp, p=p);
|
||||||
// yrot(90) cylinder(h=50, r=10, center=true);
|
// yrot(90) cylinder(h=50, r=10, center=true);
|
||||||
module yrot(a=0, p, cp)
|
module yrot(a=0, p, cp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `yrot()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `yrot()` does not accept p= argument.");
|
||||||
if (a==0) {
|
if (a==0) {
|
||||||
children(); // May be slightly faster?
|
children(); // May be slightly faster?
|
||||||
|
@ -646,7 +648,7 @@ function yrot(a=0, p=_NO_ARG, cp) = rot([0,a,0], cp=cp, p=p);
|
||||||
// Function&Module: zrot()
|
// Function&Module: zrot()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// zrot(a, [cp=]) ...
|
// zrot(a, [cp=]) children;
|
||||||
// Usage: As Function to rotate points
|
// Usage: As Function to rotate points
|
||||||
// rotated = zrot(a, p, [cp=]);
|
// rotated = zrot(a, p, [cp=]);
|
||||||
// Usage: As Function to return rotation matrix
|
// Usage: As Function to return rotation matrix
|
||||||
|
@ -675,6 +677,7 @@ function yrot(a=0, p=_NO_ARG, cp) = rot([0,a,0], cp=cp, p=p);
|
||||||
// zrot(90) cube(size=[60,20,40], center=true);
|
// zrot(90) cube(size=[60,20,40], center=true);
|
||||||
module zrot(a=0, p, cp)
|
module zrot(a=0, p, cp)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `zrot()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `zrot()` does not accept p= argument.");
|
||||||
if (a==0) {
|
if (a==0) {
|
||||||
children(); // May be slightly faster?
|
children(); // May be slightly faster?
|
||||||
|
@ -696,8 +699,8 @@ function zrot(a=0, p=_NO_ARG, cp) = rot(a, cp=cp, p=p);
|
||||||
|
|
||||||
// Function&Module: scale()
|
// Function&Module: scale()
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// scale(SCALAR) ...
|
// scale(SCALAR) children;
|
||||||
// scale([X,Y,Z]) ...
|
// scale([X,Y,Z]) children;
|
||||||
// Usage: Scale Points
|
// Usage: Scale Points
|
||||||
// pts = scale(v, p, [cp=]);
|
// pts = scale(v, p, [cp=]);
|
||||||
// Usage: Get Scaling Matrix
|
// Usage: Get Scaling Matrix
|
||||||
|
@ -747,7 +750,7 @@ function scale(v=1, p=_NO_ARG, cp=[0,0,0]) =
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// xscale(x, [cp=]) ...
|
// xscale(x, [cp=]) children;
|
||||||
// Usage: Scale Points
|
// Usage: Scale Points
|
||||||
// scaled = xscale(x, p, [cp=]);
|
// scaled = xscale(x, p, [cp=]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
|
@ -780,6 +783,7 @@ function scale(v=1, p=_NO_ARG, cp=[0,0,0]) =
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(xscale(2,p=path),closed=true);
|
// stroke(xscale(2,p=path),closed=true);
|
||||||
module xscale(x=1, p, cp=0) {
|
module xscale(x=1, p, cp=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `xscale()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `xscale()` does not accept p= argument.");
|
||||||
cp = is_num(cp)? [cp,0,0] : cp;
|
cp = is_num(cp)? [cp,0,0] : cp;
|
||||||
if (cp == [0,0,0]) {
|
if (cp == [0,0,0]) {
|
||||||
|
@ -800,7 +804,7 @@ function xscale(x=1, p=_NO_ARG, cp=0) =
|
||||||
// Function&Module: yscale()
|
// Function&Module: yscale()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// yscale(y, [cp=]) ...
|
// yscale(y, [cp=]) children;
|
||||||
// Usage: Scale Points
|
// Usage: Scale Points
|
||||||
// scaled = yscale(y, p, [cp=]);
|
// scaled = yscale(y, p, [cp=]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
|
@ -833,6 +837,7 @@ function xscale(x=1, p=_NO_ARG, cp=0) =
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(yscale(2,p=path),closed=true);
|
// stroke(yscale(2,p=path),closed=true);
|
||||||
module yscale(y=1, p, cp=0) {
|
module yscale(y=1, p, cp=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `yscale()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `yscale()` does not accept p= argument.");
|
||||||
cp = is_num(cp)? [0,cp,0] : cp;
|
cp = is_num(cp)? [0,cp,0] : cp;
|
||||||
if (cp == [0,0,0]) {
|
if (cp == [0,0,0]) {
|
||||||
|
@ -853,7 +858,7 @@ function yscale(y=1, p=_NO_ARG, cp=0) =
|
||||||
// Function&Module: zscale()
|
// Function&Module: zscale()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// zscale(z, [cp=]) ...
|
// zscale(z, [cp=]) children;
|
||||||
// Usage: Scale Points
|
// Usage: Scale Points
|
||||||
// scaled = zscale(z, p, [cp=]);
|
// scaled = zscale(z, p, [cp=]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
|
@ -886,6 +891,7 @@ function yscale(y=1, p=_NO_ARG, cp=0) =
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(zscale(2,path),closed=true);
|
// stroke(zscale(2,path),closed=true);
|
||||||
module zscale(z=1, p, cp=0) {
|
module zscale(z=1, p, cp=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `zscale()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `zscale()` does not accept p= argument.");
|
||||||
cp = is_num(cp)? [0,0,cp] : cp;
|
cp = is_num(cp)? [0,0,cp] : cp;
|
||||||
if (cp == [0,0,0]) {
|
if (cp == [0,0,0]) {
|
||||||
|
@ -909,7 +915,7 @@ function zscale(z=1, p=_NO_ARG, cp=0) =
|
||||||
|
|
||||||
// Function&Module: mirror()
|
// Function&Module: mirror()
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// mirror(v) ...
|
// mirror(v) children;
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// pt = mirror(v, p);
|
// pt = mirror(v, p);
|
||||||
// Usage: Get Reflection/Mirror Matrix
|
// Usage: Get Reflection/Mirror Matrix
|
||||||
|
@ -979,11 +985,11 @@ function mirror(v, p=_NO_ARG) =
|
||||||
// Function&Module: xflip()
|
// Function&Module: xflip()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// xflip([x]) ...
|
// xflip([x=]) children;
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// pt = xflip(p, [x]);
|
// pt = xflip(p, [x]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
// pt = xflip([x]);
|
// mat = xflip([x=]);
|
||||||
//
|
//
|
||||||
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
||||||
// See Also: mirror(), yflip(), zflip()
|
// See Also: mirror(), yflip(), zflip()
|
||||||
|
@ -998,8 +1004,8 @@ function mirror(v, p=_NO_ARG) =
|
||||||
// * Called as a function without a `p` argument, returns the affine3d 4x4 mirror matrix.
|
// * Called as a function without a `p` argument, returns the affine3d 4x4 mirror matrix.
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// x = The X coordinate of the plane of reflection. Default: 0
|
|
||||||
// p = If given, the point, path, patch, or VNF to mirror. Function use only.
|
// p = If given, the point, path, patch, or VNF to mirror. Function use only.
|
||||||
|
// x = The X coordinate of the plane of reflection. Default: 0
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// xflip() yrot(90) cylinder(d1=10, d2=0, h=20);
|
// xflip() yrot(90) cylinder(d1=10, d2=0, h=20);
|
||||||
|
@ -1011,6 +1017,7 @@ function mirror(v, p=_NO_ARG) =
|
||||||
// color("blue", 0.25) left(5) cube([0.01,15,15], center=true);
|
// color("blue", 0.25) left(5) cube([0.01,15,15], center=true);
|
||||||
// color("red", 0.333) yrot(90) cylinder(d1=10, d2=0, h=20);
|
// color("red", 0.333) yrot(90) cylinder(d1=10, d2=0, h=20);
|
||||||
module xflip(p, x=0) {
|
module xflip(p, x=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `zflip()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `zflip()` does not accept p= argument.");
|
||||||
translate([x,0,0])
|
translate([x,0,0])
|
||||||
mirror([1,0,0])
|
mirror([1,0,0])
|
||||||
|
@ -1032,11 +1039,11 @@ function xflip(p=_NO_ARG, x=0) =
|
||||||
// Function&Module: yflip()
|
// Function&Module: yflip()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// yflip([y]) ...
|
// yflip([y=]) children;
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// pt = yflip(p, [y]);
|
// pt = yflip(p, [y]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
// pt = yflip([y]);
|
// mat = yflip([y=]);
|
||||||
//
|
//
|
||||||
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
||||||
// See Also: mirror(), xflip(), zflip()
|
// See Also: mirror(), xflip(), zflip()
|
||||||
|
@ -1064,6 +1071,7 @@ function xflip(p=_NO_ARG, x=0) =
|
||||||
// color("blue", 0.25) back(5) cube([15,0.01,15], center=true);
|
// color("blue", 0.25) back(5) cube([15,0.01,15], center=true);
|
||||||
// color("red", 0.333) xrot(90) cylinder(d1=10, d2=0, h=20);
|
// color("red", 0.333) xrot(90) cylinder(d1=10, d2=0, h=20);
|
||||||
module yflip(p, y=0) {
|
module yflip(p, y=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `yflip()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `yflip()` does not accept p= argument.");
|
||||||
translate([0,y,0])
|
translate([0,y,0])
|
||||||
mirror([0,1,0])
|
mirror([0,1,0])
|
||||||
|
@ -1085,11 +1093,11 @@ function yflip(p=_NO_ARG, y=0) =
|
||||||
// Function&Module: zflip()
|
// Function&Module: zflip()
|
||||||
//
|
//
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// zflip([z]) ...
|
// zflip([z=]) children;
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// pt = zflip(p, [z]);
|
// pt = zflip(p, [z]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
// pt = zflip([z]);
|
// mat = zflip([z=]);
|
||||||
//
|
//
|
||||||
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
||||||
// See Also: mirror(), xflip(), yflip()
|
// See Also: mirror(), xflip(), yflip()
|
||||||
|
@ -1117,6 +1125,7 @@ function yflip(p=_NO_ARG, y=0) =
|
||||||
// color("blue", 0.25) down(5) cube([15,15,0.01], center=true);
|
// color("blue", 0.25) down(5) cube([15,15,0.01], center=true);
|
||||||
// color("red", 0.333) cylinder(d1=10, d2=0, h=20);
|
// color("red", 0.333) cylinder(d1=10, d2=0, h=20);
|
||||||
module zflip(p, z=0) {
|
module zflip(p, z=0) {
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `zflip()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `zflip()` does not accept p= argument.");
|
||||||
translate([0,0,z])
|
translate([0,0,z])
|
||||||
mirror([0,0,1])
|
mirror([0,0,1])
|
||||||
|
@ -1137,7 +1146,7 @@ function zflip(p=_NO_ARG, z=0) =
|
||||||
|
|
||||||
// Function&Module: frame_map()
|
// Function&Module: frame_map()
|
||||||
// Usage: As module
|
// Usage: As module
|
||||||
// frame_map(v1, v2, v3, [reverse=]) { ... }
|
// frame_map(v1, v2, v3, [reverse=]) children;
|
||||||
// Usage: As function to remap points
|
// Usage: As function to remap points
|
||||||
// transformed = frame_map(v1, v2, v3, p=points, [reverse=]);
|
// transformed = frame_map(v1, v2, v3, p=points, [reverse=]);
|
||||||
// Usage: As function to return a transformation matrix:
|
// Usage: As function to return a transformation matrix:
|
||||||
|
@ -1216,6 +1225,7 @@ function frame_map(x,y,z, p=_NO_ARG, reverse=false) =
|
||||||
|
|
||||||
module frame_map(x,y,z,p,reverse=false)
|
module frame_map(x,y,z,p,reverse=false)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `frame_map()` does not accept p= argument.");
|
assert(is_undef(p), "Module form `frame_map()` does not accept p= argument.");
|
||||||
multmatrix(frame_map(x,y,z,reverse=reverse))
|
multmatrix(frame_map(x,y,z,reverse=reverse))
|
||||||
children();
|
children();
|
||||||
|
@ -1224,7 +1234,7 @@ module frame_map(x,y,z,p,reverse=false)
|
||||||
|
|
||||||
// Function&Module: skew()
|
// Function&Module: skew()
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// skew([sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]) ...
|
// skew([sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]) children;
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// pts = skew(p, [sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]);
|
// pts = skew(p, [sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]);
|
||||||
// Usage: Get Affine Matrix
|
// Usage: Get Affine Matrix
|
||||||
|
@ -1276,6 +1286,7 @@ module frame_map(x,y,z,p,reverse=false)
|
||||||
// stroke(pts,closed=true,dots=true,dots_color="blue");
|
// stroke(pts,closed=true,dots=true,dots_color="blue");
|
||||||
module skew(p, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0)
|
module skew(p, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0)
|
||||||
{
|
{
|
||||||
|
req_children($children);
|
||||||
assert(is_undef(p), "Module form `skew()` does not accept p= argument.")
|
assert(is_undef(p), "Module form `skew()` does not accept p= argument.")
|
||||||
multmatrix(
|
multmatrix(
|
||||||
affine3d_skew(sxy=sxy, sxz=sxz, syx=syx, syz=syz, szx=szx, szy=szy)
|
affine3d_skew(sxy=sxy, sxz=sxz, syx=syx, syz=syz, szx=szx, szy=szy)
|
||||||
|
@ -1299,7 +1310,7 @@ function skew(p=_NO_ARG, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0) =
|
||||||
|
|
||||||
/// Internal Function: is_2d_transform()
|
/// Internal Function: is_2d_transform()
|
||||||
/// Usage:
|
/// Usage:
|
||||||
/// x = is_2d_transform(t);
|
/// bool = is_2d_transform(t);
|
||||||
/// Topics: Affine, Matrices, Transforms, Type Checking
|
/// Topics: Affine, Matrices, Transforms, Type Checking
|
||||||
/// See Also: is_affine(), is_matrix()
|
/// See Also: is_affine(), is_matrix()
|
||||||
/// Description:
|
/// Description:
|
||||||
|
|
|
@ -50,21 +50,13 @@ include <BOSL2/std.scad>
|
||||||
right(30) sphere(d=20);
|
right(30) sphere(d=20);
|
||||||
```
|
```
|
||||||
|
|
||||||
There is also a more generic `move()` command that can work just like `translate()`, or you can
|
There is also a more generic `move()` command that can work just like `translate()`:
|
||||||
specify the motion on each axis more clearly:
|
|
||||||
```openscad
|
```openscad
|
||||||
include <BOSL2/std.scad>
|
include <BOSL2/std.scad>
|
||||||
#sphere(d=20);
|
#sphere(d=20);
|
||||||
move([30,-10]) sphere(d=20);
|
move([30,-10]) sphere(d=20);
|
||||||
```
|
```
|
||||||
|
|
||||||
```openscad
|
|
||||||
include <BOSL2/std.scad>
|
|
||||||
#sphere(d=20);
|
|
||||||
move(x=30,y=10) sphere(d=20);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Scaling
|
## Scaling
|
||||||
The `scale()` command is also fairly simple:
|
The `scale()` command is also fairly simple:
|
||||||
```openscad
|
```openscad
|
||||||
|
|
24
utility.scad
24
utility.scad
|
@ -731,7 +731,7 @@ function segs(r) =
|
||||||
// Usage:
|
// Usage:
|
||||||
// no_children($children);
|
// no_children($children);
|
||||||
// Topics: Error Checking
|
// Topics: Error Checking
|
||||||
// See Also: no_function(), no_module()
|
// See Also: no_function(), no_module(), req_children()
|
||||||
// Description:
|
// Description:
|
||||||
// Assert that the calling module does not support children. Prints an error message to this effect and fails if children are present,
|
// Assert that the calling module does not support children. Prints an error message to this effect and fails if children are present,
|
||||||
// as indicated by its argument.
|
// as indicated by its argument.
|
||||||
|
@ -749,6 +749,28 @@ module no_children(count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Module: req_children()
|
||||||
|
// Usage:
|
||||||
|
// req_children($children);
|
||||||
|
// Topics: Error Checking
|
||||||
|
// See Also: no_function(), no_module()
|
||||||
|
// Description:
|
||||||
|
// Assert that the calling module requires children. Prints an error message and fails if no
|
||||||
|
// children are present as indicated by its argument.
|
||||||
|
// Arguments:
|
||||||
|
// $children = number of children the module has.
|
||||||
|
// Example:
|
||||||
|
// module foo() {
|
||||||
|
// req_children($children);
|
||||||
|
// }
|
||||||
|
module req_children(count) {
|
||||||
|
assert($children==0, "Module no_children() does not support child modules");
|
||||||
|
if ($parent_modules>0) {
|
||||||
|
assert(count>0, str("Module ",parent_module(1),"() requires children"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Function: no_function()
|
// Function: no_function()
|
||||||
// Usage:
|
// Usage:
|
||||||
// dummy = no_function(name)
|
// dummy = no_function(name)
|
||||||
|
|
13
vnf.scad
13
vnf.scad
|
@ -27,7 +27,7 @@ EMPTY_VNF = [[],[]]; // The standard empty VNF with no vertices or faces.
|
||||||
|
|
||||||
// Function: vnf_vertex_array()
|
// Function: vnf_vertex_array()
|
||||||
// Usage:
|
// Usage:
|
||||||
// vnf = vnf_vertex_array(points, [caps], [cap1], [cap2], [style], [reverse], [col_wrap], [row_wrap]);
|
// vnf = vnf_vertex_array(points, [caps=], [cap1=], [cap2=], [style=], [reverse=], [col_wrap=], [row_wrap=]);
|
||||||
// Description:
|
// Description:
|
||||||
// Creates a VNF structure from a rectangular vertex list, by dividing the vertices into columns and rows,
|
// Creates a VNF structure from a rectangular vertex list, by dividing the vertices into columns and rows,
|
||||||
// adding faces to tile the surface. You can optionally have faces added to wrap the last column
|
// adding faces to tile the surface. You can optionally have faces added to wrap the last column
|
||||||
|
@ -662,7 +662,7 @@ function vnf_merge_points(vnf,eps=EPSILON) =
|
||||||
|
|
||||||
// Function: vnf_drop_unused_points()
|
// Function: vnf_drop_unused_points()
|
||||||
// Usage:
|
// Usage:
|
||||||
// clean_vnf=vnf_drop_unused_points(vnf);
|
// clean_vnf = vnf_drop_unused_points(vnf);
|
||||||
// Description:
|
// Description:
|
||||||
// Remove all unreferenced vertices from a VNF. Note that in most
|
// Remove all unreferenced vertices from a VNF. Note that in most
|
||||||
// cases unreferenced vertices cause no harm, and this function may
|
// cases unreferenced vertices cause no harm, and this function may
|
||||||
|
@ -1087,7 +1087,7 @@ function _triangulate_planar_convex_polygons(polys) =
|
||||||
|
|
||||||
// Function: vnf_bend()
|
// Function: vnf_bend()
|
||||||
// Usage:
|
// Usage:
|
||||||
// bentvnf = vnf_bend(vnf,r,d,[axis]);
|
// bentvnf = vnf_bend(vnf,r|d=,[axis=]);
|
||||||
// Description:
|
// Description:
|
||||||
// Bend a VNF around the X, Y or Z axis, splitting up faces as necessary. Returns the bent
|
// Bend a VNF around the X, Y or Z axis, splitting up faces as necessary. Returns the bent
|
||||||
// VNF. For bending around the Z axis the input VNF must not cross the Y=0 plane. For bending
|
// VNF. For bending around the Z axis the input VNF must not cross the Y=0 plane. For bending
|
||||||
|
@ -1292,7 +1292,7 @@ module _show_faces(vertices, faces, size=1) {
|
||||||
|
|
||||||
// Module: debug_vnf()
|
// Module: debug_vnf()
|
||||||
// Usage:
|
// Usage:
|
||||||
// debug_vnf(vnfs, [faces], [vertices], [opacity], [size], [convexity]);
|
// debug_vnf(vnfs, [faces=], [vertices=], [opacity=], [size=], [convexity=]);
|
||||||
// Description:
|
// Description:
|
||||||
// A drop-in module to replace `vnf_polyhedron()` to help debug vertices and faces.
|
// A drop-in module to replace `vnf_polyhedron()` to help debug vertices and faces.
|
||||||
// Draws all the vertices at their 3D position, numbered in blue by their
|
// Draws all the vertices at their 3D position, numbered in blue by their
|
||||||
|
@ -1332,7 +1332,7 @@ module debug_vnf(vnf, faces=true, vertices=true, opacity=0.5, size=1, convexity=
|
||||||
// Usage: As Function
|
// Usage: As Function
|
||||||
// fails = vnf_validate(vnf);
|
// fails = vnf_validate(vnf);
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// vnf_validate(vnf, [size]);
|
// vnf_validate(vnf, [size], [check_isects]);
|
||||||
// Description:
|
// Description:
|
||||||
// When called as a function, returns a list of non-manifold errors with the given VNF.
|
// When called as a function, returns a list of non-manifold errors with the given VNF.
|
||||||
// Each error has the format `[ERR_OR_WARN,CODE,MESG,POINTS,COLOR]`.
|
// Each error has the format `[ERR_OR_WARN,CODE,MESG,POINTS,COLOR]`.
|
||||||
|
@ -1358,6 +1358,8 @@ module debug_vnf(vnf, faces=true, vertices=true, opacity=0.5, size=1, convexity=
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// vnf = The VNF to validate.
|
// vnf = The VNF to validate.
|
||||||
// size = The width of the lines and diameter of points used to highlight edges and vertices. Module only. Default: 1
|
// size = The width of the lines and diameter of points used to highlight edges and vertices. Module only. Default: 1
|
||||||
|
// --
|
||||||
|
// show_warns = If true show warnings for non-triangular faces. Default: true
|
||||||
// check_isects = If true, performs slow checks for intersecting faces. Default: false
|
// check_isects = If true, performs slow checks for intersecting faces. Default: false
|
||||||
// Example: BIG_FACE Warnings; Faces with More Than 3 Vertices. CGAL often will fail to accept that a face is planar after a rotation, if it has more than 3 vertices.
|
// Example: BIG_FACE Warnings; Faces with More Than 3 Vertices. CGAL often will fail to accept that a face is planar after a rotation, if it has more than 3 vertices.
|
||||||
// vnf = skin([
|
// vnf = skin([
|
||||||
|
@ -1628,6 +1630,7 @@ function _edge_not_reported(edge, varr, reports) =
|
||||||
|
|
||||||
|
|
||||||
module vnf_validate(vnf, size=1, show_warns=true, check_isects=false) {
|
module vnf_validate(vnf, size=1, show_warns=true, check_isects=false) {
|
||||||
|
no_children($children);
|
||||||
faults = vnf_validate(
|
faults = vnf_validate(
|
||||||
vnf, show_warns=show_warns,
|
vnf, show_warns=show_warns,
|
||||||
check_isects=check_isects
|
check_isects=check_isects
|
||||||
|
|
Loading…
Reference in a new issue