From 737baed34c8cb635843c053c3bab299016a30063 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sun, 14 Mar 2021 12:08:20 -0400 Subject: [PATCH] further type checking fixes --- common.scad | 49 +++++++++++++++++------------------------- skin.scad | 4 ++-- tests/test_common.scad | 17 ++++++--------- turtle3d.scad | 4 ++-- vectors.scad | 3 +-- 5 files changed, 32 insertions(+), 45 deletions(-) diff --git a/common.scad b/common.scad index 44f1513..ab24380 100644 --- a/common.scad +++ b/common.scad @@ -185,49 +185,40 @@ function valid_range(x) = : ( x[1]<0 && x[0]>=x[2] ) ); -// Function: is_list_of() -// Usage: -// bool = is_list_of(list, pattern); -// Topics: Type Checking -// See Also: typeof(), is_type(), is_str(), is_def(), is_int(), is_range() -// Description: -// Tests whether the input is a list whose entries are all numeric lists that have the same -// list shape as the pattern. -// Example: -// is_list_of([3,4,5], 0); // Returns true -// is_list_of([3,4,undef], 0); // Returns false -// is_list_of([[3,4],[4,5]], [1,1]); // Returns true -// is_list_of([[3,"a"],[4,true]], [1,undef]); // Returns true -// is_list_of([[3,4], 6, [4,5]], [1,1]); // Returns false -// is_list_of([[1,[3,4]], [4,[5,6]]], [1,[2,3]]); // Returns true -// is_list_of([[1,[3,INF]], [4,[5,6]]], [1,[2,3]]); // Returns false -// is_list_of([], [1,[2,3]]); // Returns true -function is_list_of(list,pattern) = - let(pattern = 0*pattern) - is_list(list) && - []==[for(entry=0*list) if (entry != pattern) entry]; - - // Function: is_consistent() // Usage: -// bool = is_consistent(list); +// bool = is_consistent(list, ); // Topics: Type Checking // See Also: typeof(), is_type(), is_str(), is_def(), is_int(), is_range(), is_homogeneous() // Description: // Tests whether input is a list of entries which all have the same list structure -// and are filled with finite numerical data. It returns `true`for the empty list. +// and are filled with finite numerical data. You can optionally specify a required +// list structure with the pattern argument. It returns `true` for the empty list. +// Arguments: +// list = list to check +// pattern = optional pattern required to match // Example: // is_consistent([3,4,5]); // Returns true // is_consistent([[3,4],[4,5],[6,7]]); // Returns true // is_consistent([[3,4,5],[3,4]]); // Returns false // is_consistent([[3,[3,4,[5]]], [5,[2,9,[9]]]]); // Returns true // is_consistent([[3,[3,4,[5]]], [5,[2,9,9]]]); // Returns false -function is_consistent(list) = - /*is_list(list) &&*/ is_list_of(list, _list_pattern(list[0])); - +// is_consistent([3,4,5], 0); // Returns true +// is_consistent([3,4,undef], 0); // Returns false +// is_consistent([[3,4],[4,5]], [1,1]); // Returns true +// is_consistent([[3,"a"],[4,true]], [1,undef]); // Returns true +// is_consistent([[3,4], 6, [4,5]], [1,1]); // Returns false +// is_consistent([[1,[3,4]], [4,[5,6]]], [1,[2,3]]); // Returns true +// is_consistent([[1,[3,INF]], [4,[5,6]]], [1,[2,3]]); // Returns false +// is_consistent([], [1,[2,3]]); // Returns true +function is_consistent(list, pattern) = + is_list(list) + && (len(list)==0 + || (let(pattern = is_undef(pattern) ? _list_pattern(list[0]): _list_pattern(pattern) ) + []==[for(entry=0*list) if (entry != pattern) entry])); //Internal function -//Creates a list with the same structure of `list` with each of its elements substituted by 0. +//Creates a list with the same structure of `list` with each of its elements replaced by 0. function _list_pattern(list) = is_list(list) ? [for(entry=list) is_list(entry) ? _list_pattern(entry) : 0] diff --git a/skin.scad b/skin.scad index 79cd244..40237fb 100644 --- a/skin.scad +++ b/skin.scad @@ -236,7 +236,7 @@ // interior = regular_ngon(n=len(base), d=60); // right_half() // skin([ sub_base, base, base, sub_base, interior], z=[0,2,height, height, 2], slices=0, refine=1, method="reindex"); -// Example: Connecting a pentagon and circle with the "tangent" method produces triangular faces. +// Example: Connecting a pentagon and circle with the "tangent" method produces large triangular faces and cone shaped corners. // skin([pentagon(4), circle($fn=80,r=2)], z=[0,3], slices=10, method="tangent"); // Example: rounding corners of a square. Note that `$fn` makes the number of points constant, and avoiding the `rounding=0` case keeps everything simple. In this case, the connections between profiles are linear, so there is no benefit to setting `slices` bigger than zero. // shapes = [for(i=[.01:.045:2])zrot(-i*180/2,cp=[-8,0,0],p=xrot(90,p=path3d(regular_ngon(n=4, side=4, rounding=i, $fn=64))))]; @@ -921,7 +921,7 @@ function associate_vertices(polygons, split, curpoly=0) = // sweep(shape, concat(outside,inside)); function sweep(shape, transforms, closed=false, caps) = - assert(is_list_of(transforms, ident(4)), "Input transforms must be a list of numeric 4x4 matrices in sweep") + assert(is_consistent(transforms, ident(4)), "Input transforms must be a list of numeric 4x4 matrices in sweep") assert(is_path(shape,2) || is_region(shape), "Input shape must be a 2d path or a region.") let( caps = is_def(caps) ? caps : diff --git a/tests/test_common.scad b/tests/test_common.scad index 3568440..3d150d7 100644 --- a/tests/test_common.scad +++ b/tests/test_common.scad @@ -217,16 +217,6 @@ module test_valid_range() { } test_valid_range(); -module test_is_list_of() { - assert(is_list_of([3,4,5], 0)); - assert(!is_list_of([3,4,undef], 0)); - assert(is_list_of([[3,4],[4,5]], [1,1])); - assert(!is_list_of([[3,4], 6, [4,5]], [1,1])); - assert(is_list_of([[1,[3,4]], [4,[5,6]]], [1,[2,3]])); - assert(!is_list_of([[1,[3,INF]], [4,[5,6]]], [1,[2,3]])); -} -test_is_list_of(); - module test_is_consistent() { assert(is_consistent([])); assert(is_consistent([[],[]])); @@ -238,6 +228,13 @@ module test_is_consistent() { assert(!is_consistent([[3,4,5],[3,4]])); assert(is_consistent([[3,[3,4,[5]]], [5,[2,9,[9]]]])); assert(!is_consistent([[3,[3,4,[5]]], [5,[2,9,9]]])); + + assert(is_consistent([3,4,5], 0)); + assert(!is_consistent([3,4,undef], 0)); + assert(is_consistent([[3,4],[4,5]], [1,1])); + assert(!is_consistent([[3,4], 6, [4,5]], [1,1])); + assert(is_consistent([[1,[3,4]], [4,[5,6]]], [1,[2,3]])); + assert(!is_consistent([[1,[3,INF]], [4,[5,6]]], [1,[2,3]])); } test_is_consistent(); diff --git a/turtle3d.scad b/turtle3d.scad index 8b510b0..8f9176d 100644 --- a/turtle3d.scad +++ b/turtle3d.scad @@ -421,8 +421,8 @@ turtle state: sequence of transformations ("path") so far function _turtle3d_state_valid(state) = is_list(state) - && is_list_of(state[0],ident(4)) - && is_list_of(state[1],ident(4)) + && is_consistent(state[0],ident(4)) + && is_consistent(state[1],ident(4)) && is_num(state[2]) && is_num(state[3]) && is_num(state[4]); diff --git a/vectors.scad b/vectors.scad index 8a6ca60..f8bc2f5 100644 --- a/vectors.scad +++ b/vectors.scad @@ -36,8 +36,7 @@ // is_vector([1,1,1],all_nonzero=false); // Returns true // is_vector([],zero=false); // Returns false function is_vector(v, length, zero, all_nonzero=false, eps=EPSILON) = - is_list_of(v,1) // is_list(v) && is_num(v[0]) && is_num(0*(v*v)) - && len(v)>0 + is_list(v) && len(v)>0 && []==[for(vi=v) if(!is_num(vi)) 0] && (is_undef(length) || len(v)==length) && (is_undef(zero) || ((norm(v) >= eps) == !zero)) && (!all_nonzero || all_nonzero(v)) ;