diff --git a/common.scad b/common.scad index e24c744..990c0aa 100644 --- a/common.scad +++ b/common.scad @@ -6,6 +6,7 @@ ////////////////////////////////////////////////////////////////////// + // Section: Type handling helpers. @@ -322,7 +323,8 @@ function first_defined(v,recursive=false,_i=0) = // Examples: // length = one_defined([length,L,l], ["length","L","l"]); // length = one_defined([length,L,l], "length,L,l", dflt=1); -function one_defined(vals, names, dflt=_UNDEF) = + +function one_defined(vals, names, dflt=_UNDEF) = let( checkargs = is_list(names)? assert(len(vals) == len(names)) : is_string(names)? let( @@ -533,10 +535,6 @@ function get_radius(r1, r2, r, d1, d2, d, dflt) = // echo(f(undef, arg1="given1", undef)); // // ["given1", undef, undef] -// a value that the user should never enter randomly; -// result of `dd if=/dev/random bs=32 count=1 |base64` : -_UNDEF="LRG+HX7dy89RyHvDlAKvb9Y04OTuaikpx205CTh8BSI"; - /* Note: however tempting it might be, it is *not* possible to accept * named argument as a list [named1, named2, ...] (without default * values), because the values [named1, named2...] themselves might be diff --git a/constants.scad b/constants.scad index cc6daf1..8815aa9 100644 --- a/constants.scad +++ b/constants.scad @@ -5,6 +5,9 @@ // include ////////////////////////////////////////////////////////////////////// +// a value that the user should never enter randomly; +// result of `dd if=/dev/random bs=32 count=1 |base64` : +_UNDEF="LRG+HX7dy89RyHvDlAKvb9Y04OTuaikpx205CTh8BSI"; // Section: General Constants diff --git a/skin.scad b/skin.scad index 8bc6f03..8b197f9 100644 --- a/skin.scad +++ b/skin.scad @@ -5,7 +5,6 @@ // - https://github.com/openscad/list-comprehension-demos/blob/master/skin.scad // Includes: // include -// include ////////////////////////////////////////////////////////////////////// @@ -465,7 +464,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close : reindex_polygon(resampled[i-1],resampled[i])], sliced = slice_profiles(fixedprof, slices, closed) ) - !closed ? sliced : concat(sliced,[sliced[0]]) + [!closed ? sliced : concat(sliced,[sliced[0]])] : // There are duplicators, so use approach where each pair is treated separately [for(i=[0:profcount-1]) let( @@ -482,9 +481,59 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close ". Method ",method[i]," requires equal values")) refine[i] * len(pair[0]) ) - each subdivide_and_slice(pair,slices[i], nsamples, method=sampling)] + subdivide_and_slice(pair,slices[i], nsamples, method=sampling)] ) - vnf_vertex_array(full_list, cap1=fullcaps[0], cap2=fullcaps[1], col_wrap=true, style=style); + vnf_merge(cleanup=false, + [for(i=idx(full_list)) + vnf_vertex_array(full_list[i], cap1=i==0 && fullcaps[0], cap2=i==len(full_list)-1 && fullcaps[1], + col_wrap=true, style=style)]); + +function _skin_core(profiles, caps) = + let( + vertices = flatten(profiles), + plen = len(profiles[0]), + faces = [ + for(pidx=idx(profiles,e=-2)) + let( + prof1 = profiles[pidx], + prof2 = profiles[pidx+1], + voff = pidx*plen, + faces = [ + for( + first = true, + finishing = false, + finished = false, + i=0, j=0, side=false; + + !finished; + + side = + let( + p1a = prof1[i%plen], + p1b = prof1[(i+1)%plen], + p2a = prof2[j%plen], + p2b = prof2[(j+1)%plen], + dist1 = norm(p1a-p2b), + dist2 = norm(p1b-p2a) + ) (i==j) ? dist1>dist2 : i=plen && j>=plen + ) if (!first) face + ] + ) each faces, + if (caps[0]) count(plen,reverse=true), + if (caps[1]) count(plen,plen*(len(profiles)-1)) + ] + ) [vertices, faces]; + + @@ -1419,7 +1468,7 @@ function path_sweep2d(shape, path, closed=false, caps, quality=1, style="min_edg vnf_vertex_array([ each proflist, if (closed) proflist[0] - ],cap1=fullcaps[0],cap1=fullcaps[1],col_wrap=true,style=style); + ],cap1=fullcaps[0],cap2=fullcaps[1],col_wrap=true,style=style); module path_sweep2d(profile, path, closed=false, caps, quality=1, style="min_edge", convexity=10, diff --git a/vnf.scad b/vnf.scad index 452743e..8d4f123 100644 --- a/vnf.scad +++ b/vnf.scad @@ -298,7 +298,7 @@ function vnf_vertex_array( assert(!(any([caps,cap1,cap2]) && !col_wrap), "col_wrap must be true if caps are requested") assert(!(any([caps,cap1,cap2]) && row_wrap), "Cannot combine caps with row_wrap") assert(in_list(style,["default","alt","quincunx", "convex","min_edge"])) - assert(is_consistent(points), "Non-rectangular or invalid point array") + assert(is_consistent(points), "Non-rectangular or invalid point array") let( pts = flatten(points), pcnt = len(pts), @@ -346,22 +346,18 @@ function vnf_vertex_array( let( d42=norm(pts[i4]-pts[i2]), d13=norm(pts[i1]-pts[i3]), - shortface = d42<=d13 ? [[i1,i4,i2],[i2,i4,i3]] + shortedge = d42<=d13 ? [[i1,i4,i2],[i2,i4,i3]] : [[i1,i3,i2],[i1,i4,i3]] ) - shortface - : style=="convex"? // This style bombs on degenerate faces - let( - fsets = [ - [[i1,i4,i2],[i2,i4,i3]], - [[i1,i3,i2],[i1,i4,i3]] - ], - cps = [for (fset=fsets) [for (f=fset) mean(select(pts,f))]], - ns = cps + [for (fset=fsets) [for (f=fset) polygon_normal(select(pts,f))]], - dists = [for (i=idx(fsets)) norm(cps[i][1]-cps[i][0]) - norm(ns[i][1]-ns[i][0])], - test = reverse? dists[0]>dists[1] : dists[0] n*pts[i1] ? [[i1,i4,i2],[i2,i4,i3]] + : [[i1,i3,i2],[i1,i4,i3]] ) - fsets[test?0:1] + convexfaces : [[i1,i3,i2],[i1,i4,i3]], // remove degenerate faces culled_faces= [for(face=faces)