diff --git a/distributors.scad b/distributors.scad index 92c1775..80089e2 100644 --- a/distributors.scad +++ b/distributors.scad @@ -34,6 +34,7 @@ // move_copies([[-25,-25,0], [25,-25,0], [0,0,50], [0,25,0]]) sphere(r=10); module move_copies(a=[[0,0,0]]) { + req_children($children); assert(is_list(a)); for ($idx = idx(a)) { $pos = a[$idx]; @@ -117,6 +118,7 @@ module move_copies(a=[[0,0,0]]) // move_copies(pts) circle(d=2); module line_of(spacing, n, l, p1, p2) { + req_children($children); pts = line_of(spacing=spacing, n=n, l=l, p1=p1, p2=p2); for (i=idx(pts)) { $idx = i; @@ -180,6 +182,7 @@ function line_of(spacing, n, l, p1, p2) = // } module xcopies(spacing, n, l, sp) { + req_children($children); sp = is_finite(sp)? [sp,0,0] : sp; line_of( l=u_mul(l,RIGHT), @@ -220,6 +223,7 @@ module xcopies(spacing, n, l, sp) // } module ycopies(spacing, n, l, sp) { + req_children($children); sp = is_finite(sp)? [0,sp,0] : sp; line_of( l=u_mul(l,BACK), @@ -274,6 +278,7 @@ module ycopies(spacing, n, l, sp) // sphere(d=s); module zcopies(spacing, n, l, sp) { + req_children($children); sp = is_finite(sp)? [0,0,sp] : sp; line_of( l=u_mul(l,UP), @@ -343,7 +348,7 @@ module zcopies(spacing, n, l, sp) // } module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero) { - + req_children($children); assert(in_list(stagger, [false, true, "alt"])); bounds = is_undef(inside)? undef : is_path(inside)? pointlist_bounds(inside) : @@ -452,6 +457,7 @@ module grid2d(spacing, n, size, stagger=false, inside=undef, nonzero) // grid3d(n=[10, 10, 10], spacing=50) color($idx/9) cube(50, center=true); module grid3d(spacing, n, xa=[0], ya=[0], za=[0]) { + req_children($children); n = scalar_vec3(n, 1); spacing = scalar_vec3(spacing, undef); if (!is_undef(n) && !is_undef(spacing)) { @@ -541,6 +547,7 @@ module grid3d(spacing, n, xa=[0], ya=[0], za=[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) { + req_children($children); sang = sa + offset; angs = !is_undef(n)? (n<=0? [] : [for (i=[0:1:n-1]) i/n*360+sang]) : @@ -620,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); 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(); } @@ -678,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); 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(); } @@ -794,6 +803,7 @@ module arc_of( sa=0, ea=360, rot=true ) { + req_children($children); 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); sa = posmod(sa, 360); @@ -847,6 +857,7 @@ module arc_of( // cylinder(d=8, h=10, center=false); 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); cnt = ceil(n / (cone_ang/180)); @@ -962,6 +973,7 @@ module ovoid_spread(n=100, r=undef, d=undef, cone_ang=90, scale=[1,1,1], perp=tr // } 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); @@ -1043,6 +1055,7 @@ module path_spread(path, n, spacing, sp=undef, rotate_children=true, closed) // 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) { + req_children($children); cp = is_vector(v,4)? plane_normal(v) * v[3] : is_vector(cp)? cp : is_num(cp)? cp*unit(v) : @@ -1096,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); module xflip_copy(offset=0, x=0) { + req_children($children); mirror_copy(v=[1,0,0], offset=offset, cp=[x,0,0]) children(); } @@ -1129,6 +1143,7 @@ module xflip_copy(offset=0, x=0) // color("blue",0.25) fwd(5) cube([15,0.01,15], center=true); module yflip_copy(offset=0, y=0) { + req_children($children); mirror_copy(v=[0,1,0], offset=offset, cp=[0,y,0]) children(); } @@ -1162,6 +1177,7 @@ module yflip_copy(offset=0, y=0) // color("blue",0.25) down(5) cube([15,15,0.01], center=true); module zflip_copy(offset=0, z=0) { + req_children($children); mirror_copy(v=[0,0,1], offset=offset, cp=[0,0,z]) children(); } @@ -1199,6 +1215,7 @@ module zflip_copy(offset=0, z=0) // } module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef) { + req_children($children); gaps = ($children < 2)? [0] : !is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] : [for (i=[0:1:$children-2]) 0]; @@ -1243,6 +1260,7 @@ module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef) // } module xdistribute(spacing=10, sizes=undef, l=undef) { + req_children($children); dir = RIGHT; gaps = ($children < 2)? [0] : !is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] : @@ -1288,6 +1306,7 @@ module xdistribute(spacing=10, sizes=undef, l=undef) // } module ydistribute(spacing=10, sizes=undef, l=undef) { + req_children($children); dir = BACK; gaps = ($children < 2)? [0] : !is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] : @@ -1333,6 +1352,7 @@ module ydistribute(spacing=10, sizes=undef, l=undef) // } module zdistribute(spacing=10, sizes=undef, l=undef) { + req_children($children); dir = UP; gaps = ($children < 2)? [0] : !is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] : diff --git a/paths.scad b/paths.scad index dff9991..35884c7 100644 --- a/paths.scad +++ b/paths.scad @@ -322,7 +322,7 @@ function _sum_preserving_round(data, index=0) = // Function: subdivide_path() // See Also: subdivide_and_slice(), resample_path(), jittered_poly() // Usage: -// newpath = subdivide_path(path, [n|refine|maxlen], [method], [closed], [exact]); +// newpath = subdivide_path(path, n|refine=|maxlen=, [method=], [closed=], [exact=]); // Description: // 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 @@ -463,7 +463,7 @@ function subdivide_path(path, n, refine, maxlen, closed=true, exact, method) = // Function: resample_path() // Usage: -// newpath = resample_path(path, n|spacing, [closed]); +// newpath = resample_path(path, n|spacing=, [closed=]); // Description: // 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 @@ -553,7 +553,7 @@ function is_path_simple(path, closed, eps=EPSILON) = // Function: path_closest_point() // Usage: -// path_closest_point(path, pt); +// index_pt = path_closest_point(path, pt); // Description: // Finds the closest path segment, and point on that segment to the given point. // Returns `[SEGNUM, POINT]` @@ -828,7 +828,7 @@ function _path_cuts_dir(path, cuts, closed=false, eps=1e-2) = // Topics: Paths // See Also: split_path_at_self_crossings() // Usage: -// path_list = path_cut(path, cutdist, [closed=]); +// path_list = path_cut(path, cutdist, [closed]); // Description: // Given a list of distances in `cutdist`, cut the path into // subpaths at those lengths, returning a list of paths. diff --git a/rounding.scad b/rounding.scad index 42341bf..871e611 100644 --- a/rounding.scad +++ b/rounding.scad @@ -1707,7 +1707,7 @@ function os_mask(mask, out=false, extra,check_valid, quality, offset) = // Module: convex_offset_extrude() // 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: // 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 @@ -1812,6 +1812,7 @@ module convex_offset_extrude( joint=undef, k=0.75, angle=45, convexity=10, thickness = 1/1024 ) { + req_children($children); argspec = [ ["for", ""], ["r",r], diff --git a/utility.scad b/utility.scad index 978f538..5a92dfb 100644 --- a/utility.scad +++ b/utility.scad @@ -731,7 +731,7 @@ function segs(r) = // Usage: // no_children($children); // Topics: Error Checking -// See Also: no_function(), no_module() +// See Also: no_function(), no_module(), req_children() // Description: // 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. @@ -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() // Usage: // dummy = no_function(name)