From 26d16a3187aea326e8fa5677c41c676e67e4c747 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Wed, 15 May 2019 21:07:27 -0700 Subject: [PATCH] Split compat.scad out into errors.scad and common.scad --- README.md | 2 + common.scad | 99 +++++++++++++++++++++++++++++++++++ compat.scad => errors.scad | 104 ++----------------------------------- polyhedra.scad | 4 +- scripts/run_tests.sh | 8 +++ std.scad | 3 +- tests/test_vectors.scad | 4 +- vectors.scad | 9 ++++ 8 files changed, 127 insertions(+), 106 deletions(-) create mode 100644 common.scad rename compat.scad => errors.scad (59%) create mode 100755 scripts/run_tests.sh diff --git a/README.md b/README.md index a84ad25..7a2b2b9 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ The library files are as follows: ### Various Math - [`constants.scad`](https://github.com/revarbat/BOSL2/wiki/constants.scad): Useful constants for vectors, edges, etc. + - [`errors.scad`](https://github.com/revarbat/BOSL2/wiki/errors.scad): Stuff for reporting errors and warnings. + - [`common.scad`](https://github.com/revarbat/BOSL2/wiki/common.scad): Common argument processing helpers and functions. - [`math.scad`](https://github.com/revarbat/BOSL2/wiki/math.scad): Useful helper functions. - [`arrays.scad`](https://github.com/revarbat/BOSL2/wiki/arrays.scad): List and Array helper functions. - [`vectors.scad`](https://github.com/revarbat/BOSL2/wiki/vectors.scad): Vector math functions. diff --git a/common.scad b/common.scad new file mode 100644 index 0000000..7c5fa0c --- /dev/null +++ b/common.scad @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////// +// LibFile: common.scad +// Common functions used in argument processing. +// To use, include this line at the top of your file: +// ``` +// use +// ``` +////////////////////////////////////////////////////////////////////// + + +// Section: Handling `undef`s. + + +// Function: is_def() +// Usage: +// is_def(v) +// Description: +// Returns true if `v` is not `undef`. False if `v==undef`. +function is_def(v) = !is_undef(v); + + +// Function: default() +// Description: +// Returns the value given as `v` if it is not `undef`. +// Otherwise, returns the value of `dflt`. +// Arguments: +// v = Value to pass through if not `undef`. +// dflt = Value to return if `v` *is* `undef`. +function default(v,dflt=undef) = is_undef(v)? dflt : v; + + +// Function: first_defined() +// Description: +// Returns the first item in the list that is not `undef`. +// If all items are `undef`, or list is empty, returns `undef`. +function first_defined(v,_i=0) = _i=len(v)? _cnt : num_defined(v,_i+1,_cnt+(is_undef(v[_i])? 0 : 1)); + + +// Function: any_defined() +// Description: +// Returns true if any item in the given array is not `undef`. +function any_defined(v) = first_defined(v) != undef; + + +// Function: all_defined() +// Description: +// Returns true if all items in the given array are not `undef`. +function all_defined(v,_i=0) = _i= len(v)); + + +// Section: Argument Helpers + + +// Function: get_radius() +// Usage: +// get_radius([r1], [r], [d1], [d], [dflt]); +// Description: +// Given various radii and diameters, returns the most specific radius. +// If a diameter is most specific, returns half its value, giving the radius. +// If no radii or diameters are defined, returns the value of dflt. +// Value specificity order is r1, d1, r, d, then dflt +// Arguments: +// r1 = Most specific radius. +// d1 = Most specific diameter. +// r = Most general radius. +// d = Most general diameter. +// dflt = Value to return if all other values given are `undef`. +function get_radius(r1=undef, r=undef, d1=undef, d=undef, dflt=undef) = ( + !is_undef(r1)? r1 : + !is_undef(d1)? d1/2 : + !is_undef(r)? r : + !is_undef(d)? d/2 : + dflt +); + + +// Function: scalar_vec3() +// Usage: +// scalar_vec3(v, [dflt]); +// Description: +// If `v` is a scalar, and `dflt==undef`, returns `[v, v, v]`. +// If `v` is a scalar, and `dflt!=undef`, returns `[v, dflt, dflt]`. +// If `v` is a vector, returns the first 3 items, with any missing values replaced by `dflt`. +// If `v` is `undef`, returns `undef`. +// Arguments: +// v = Value to return vector from. +// dflt = Default value to set empty vector parts from. +function scalar_vec3(v, dflt=undef) = + is_undef(v)? undef : + is_list(v)? [for (i=[0:2]) default(v[i], default(dflt, 0))] : + !is_undef(dflt)? [v,dflt,dflt] : [v,v,v]; + + +// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/compat.scad b/errors.scad similarity index 59% rename from compat.scad rename to errors.scad index 5a23140..5138b6c 100644 --- a/compat.scad +++ b/errors.scad @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////// -// LibFile: compat.scad -// Backwards Compatability library +// LibFile: errors.scad +// Functions and modules to facilitate error reporting. // To use, include this line at the top of your file: // ``` // use @@ -8,106 +8,8 @@ ////////////////////////////////////////////////////////////////////// -// Section: Functions - -// Function: default() -// Description: -// Returns the value given as `v` if it is not `undef`. -// Otherwise, returns the value of `dflt`. -// Arguments: -// v = Value to pass through if not `undef`. -// dflt = Value to return if `v` *is* `undef`. -function default(v,dflt=undef) = is_undef(v)? dflt : v; - - -// Function: is_def() -// Usage: -// is_def(v) -// Description: -// Returns true if `v` is not `undef`. False if `v==undef`. -function is_def(v) = !is_undef(v); - - -// Function: is_vector() -// Usage: -// is_vector(v) -// Description: -// Returns true if the given value is a list, and at least the first item is a number. -function is_vector(v) = is_list(v) && is_num(v[0]); - - -// Function: get_radius() -// Description: -// Given various radii and diameters, returns the most specific radius. -// If a diameter is most specific, returns half its value, giving the radius. -// If no radii or diameters are defined, returns the value of dflt. -// Value specificity order is r1, d1, r, d, then dflt -// Arguments: -// r1 = Most specific radius. -// d1 = Most specific Diameter. -// r = Most general radius. -// d = Most general diameter. -// dflt = Value to return if all other values given are `undef`. -function get_radius(r1=undef, r=undef, d1=undef, d=undef, dflt=undef) = ( - !is_undef(r1)? r1 : - !is_undef(d1)? d1/2 : - !is_undef(r)? r : - !is_undef(d)? d/2 : - dflt -); - - - -// Function: remove_undefs() -// Description: Removes all `undef`s from a list. -function remove_undefs(v) = [for (x = v) if (!is_undef(x)) x]; - - -// Function: first_defined() -// Description: -// Returns the first item in the list that is not `undef`. -// If all items are `undef`, or list is empty, returns `undef`. -function first_defined(v) = remove_undefs(v)[0]; - - -// Function: num_defined() -// Description: Counts how many items in list `v` are not `undef`. -function num_defined(v) = sum([for (x = v) is_undef(x)? 0 : 1]); - - -// Function: any_defined() -// Description: -// Returns true if any item in the given array is not `undef`. -function any_defined(v) = num_defined(v)>0; - - -// Function: all_defined() -// Description: -// Returns true if all items in the given array are not `undef`. -function all_defined(v) = num_defined(v)==len(v); - - -// Function: scalar_vec3() -// Usage: -// scalar_vec3(v, [dflt]); -// Description: -// If `v` is a scalar, and `dflt==undef`, returns `[v, v, v]`. -// If `v` is a scalar, and `dflt!=undef`, returns `[v, dflt, dflt]`. -// If `v` is a vector, returns the first 3 items, with any missing values replaced by `dflt`. -// If `v` is `undef`, returns `undef`. -// Arguments: -// v = Value to return vector from. -// dflt = Default value to set empty vector parts from. -function scalar_vec3(v, dflt=undef) = - is_undef(v)? undef : - is_list(v)? [for (i=[0:2]) default(v[i], default(dflt, 0))] : - !is_undef(dflt)? [v,dflt,dflt] : [v,v,v]; - - - - -// Section: Modules +// Section: Warnings and Errors // Function&Module: assert_in_list() diff --git a/polyhedra.scad b/polyhedra.scad index 5924369..3fa173f 100644 --- a/polyhedra.scad +++ b/polyhedra.scad @@ -597,7 +597,7 @@ function regular_polyhedron_info( longside=undef, h=undef // special parameters for trapezohedron ) = let( anchor = !is_undef(center) ? [0,0,0] : anchor, - argcount = len(remove_undefs([ir,mr,or,r,d])) + argcount = num_defined([ir,mr,or,r,d]) ) assert(argcount<=1, "You must specify only one of 'ir', 'mr', 'or', 'r', and 'd'") let( @@ -725,7 +725,7 @@ function trapezohedron(faces, r, side, longside, h) = assert(faces%2==0, "Number of faces must be even") let( N = faces/2, - parmcount = len(remove_undefs([r,side,longside,h])) + parmcount = num_defined([r,side,longside,h]) ) assert(parmcount==2,"Must define exactly two of 'r', 'side', 'longside', and 'height'") let( diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh new file mode 100755 index 0000000..bfd4101 --- /dev/null +++ b/scripts/run_tests.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +OPENSCAD=/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD + +for testscript in tests/test_*.scad ; do + ${OPENSCAD} -o .off --hardwarnings --check-parameters true --check-parameter-ranges true $testscript +done + diff --git a/std.scad b/std.scad index bdab568..5834bcf 100644 --- a/std.scad +++ b/std.scad @@ -10,7 +10,8 @@ include include -include +include +include include include include diff --git a/tests/test_vectors.scad b/tests/test_vectors.scad index 49d8546..1edc7bf 100644 --- a/tests/test_vectors.scad +++ b/tests/test_vectors.scad @@ -53,8 +53,8 @@ module test_vector_angle() { } assert(abs(vector_angle([10,10,0],[10,0,0])-45) < EPSILON); assert(abs(vector_angle([[10,10,0],[10,0,0]])-45) < EPSILON); - assert(abs(vector_angle([11,11,1],[1,1,1],[11,-11,1])-90) < EPSILON); - assert(abs(vector_angle([[11,11,1],[1,1,1],[11,-11,1]])-90) < EPSILON); + assert(abs(vector_angle([11,11,1],[1,1,1],[11,-9,1])-90) < EPSILON); + assert(abs(vector_angle([[11,11,1],[1,1,1],[11,-9,1]])-90) < EPSILON); } test_vector_angle(); diff --git a/vectors.scad b/vectors.scad index d2895cf..fd02a0a 100644 --- a/vectors.scad +++ b/vectors.scad @@ -10,6 +10,15 @@ // Section: Vector Manipulation + +// Function: is_vector() +// Usage: +// is_vector(v) +// Description: +// Returns true if the given value is a list, and at least the first item is a number. +function is_vector(v) = is_list(v) && is_num(v[0]); + + // Function: vmul() // Description: // Element-wise vector multiplication. Multiplies each element of vector `v1` by