mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
_UNDEF definition didn't work; moving to constants.scad fixed this.
Fixed vnf.scad so that "convex" is efficient and handles degenerate case in vnf_vertex_array Fixed skin to correctly handle multi-section "distance" skins.
This commit is contained in:
parent
f2914f0efb
commit
75b974906d
4 changed files with 70 additions and 24 deletions
|
@ -6,6 +6,7 @@
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Section: Type handling helpers.
|
// Section: Type handling helpers.
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,7 +323,8 @@ function first_defined(v,recursive=false,_i=0) =
|
||||||
// Examples:
|
// Examples:
|
||||||
// length = one_defined([length,L,l], ["length","L","l"]);
|
// length = one_defined([length,L,l], ["length","L","l"]);
|
||||||
// length = one_defined([length,L,l], "length,L,l", dflt=1);
|
// 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(
|
let(
|
||||||
checkargs = is_list(names)? assert(len(vals) == len(names)) :
|
checkargs = is_list(names)? assert(len(vals) == len(names)) :
|
||||||
is_string(names)? let(
|
is_string(names)? let(
|
||||||
|
@ -533,10 +535,6 @@ function get_radius(r1, r2, r, d1, d2, d, dflt) =
|
||||||
// echo(f(undef, arg1="given1", undef));
|
// echo(f(undef, arg1="given1", undef));
|
||||||
// // ["given1", undef, 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
|
/* Note: however tempting it might be, it is *not* possible to accept
|
||||||
* named argument as a list [named1, named2, ...] (without default
|
* named argument as a list [named1, named2, ...] (without default
|
||||||
* values), because the values [named1, named2...] themselves might be
|
* values), because the values [named1, named2...] themselves might be
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
// include <BOSL2/std.scad>
|
// include <BOSL2/std.scad>
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 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
|
// Section: General Constants
|
||||||
|
|
||||||
|
|
59
skin.scad
59
skin.scad
|
@ -5,7 +5,6 @@
|
||||||
// - https://github.com/openscad/list-comprehension-demos/blob/master/skin.scad
|
// - https://github.com/openscad/list-comprehension-demos/blob/master/skin.scad
|
||||||
// Includes:
|
// Includes:
|
||||||
// include <BOSL2/std.scad>
|
// include <BOSL2/std.scad>
|
||||||
// include <BOSL2/skin.scad>
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,7 +464,7 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
||||||
: reindex_polygon(resampled[i-1],resampled[i])],
|
: reindex_polygon(resampled[i-1],resampled[i])],
|
||||||
sliced = slice_profiles(fixedprof, slices, closed)
|
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
|
: // There are duplicators, so use approach where each pair is treated separately
|
||||||
[for(i=[0:profcount-1])
|
[for(i=[0:profcount-1])
|
||||||
let(
|
let(
|
||||||
|
@ -482,9 +481,59 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
||||||
". Method ",method[i]," requires equal values"))
|
". Method ",method[i]," requires equal values"))
|
||||||
refine[i] * len(pair[0])
|
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<j,
|
||||||
|
p1 = voff + (i%plen),
|
||||||
|
p2 = voff + (j%plen) + plen,
|
||||||
|
p3 = voff + (side? (i+1)%plen : (j+1)%plen + plen),
|
||||||
|
face = [p1, p3, p2],
|
||||||
|
i = i + (side? 1 : 0),
|
||||||
|
j = j + (side? 0 : 1),
|
||||||
|
first = false,
|
||||||
|
finished = finishing,
|
||||||
|
finishing = 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([
|
vnf_vertex_array([
|
||||||
each proflist,
|
each proflist,
|
||||||
if (closed) proflist[0]
|
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,
|
module path_sweep2d(profile, path, closed=false, caps, quality=1, style="min_edge", convexity=10,
|
||||||
|
|
24
vnf.scad
24
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]) && !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(!(any([caps,cap1,cap2]) && row_wrap), "Cannot combine caps with row_wrap")
|
||||||
assert(in_list(style,["default","alt","quincunx", "convex","min_edge"]))
|
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(
|
let(
|
||||||
pts = flatten(points),
|
pts = flatten(points),
|
||||||
pcnt = len(pts),
|
pcnt = len(pts),
|
||||||
|
@ -346,22 +346,18 @@ function vnf_vertex_array(
|
||||||
let(
|
let(
|
||||||
d42=norm(pts[i4]-pts[i2]),
|
d42=norm(pts[i4]-pts[i2]),
|
||||||
d13=norm(pts[i1]-pts[i3]),
|
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]]
|
: [[i1,i3,i2],[i1,i4,i3]]
|
||||||
)
|
)
|
||||||
shortface
|
shortedge
|
||||||
: style=="convex"? // This style bombs on degenerate faces
|
: style=="convex"?
|
||||||
let(
|
let( // Find normal for 3 of the points. Is the other point above or below?
|
||||||
fsets = [
|
n = (reverse?-1:1)*cross(pts[i2]-pts[i1],pts[i3]-pts[i1]),
|
||||||
[[i1,i4,i2],[i2,i4,i3]],
|
convexfaces = n==0 ? [[i1,i4,i3]]
|
||||||
[[i1,i3,i2],[i1,i4,i3]]
|
: n*pts[i4] > n*pts[i1] ? [[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]<dists[1]
|
|
||||||
)
|
)
|
||||||
fsets[test?0:1]
|
convexfaces
|
||||||
: [[i1,i3,i2],[i1,i4,i3]],
|
: [[i1,i3,i2],[i1,i4,i3]],
|
||||||
// remove degenerate faces
|
// remove degenerate faces
|
||||||
culled_faces= [for(face=faces)
|
culled_faces= [for(face=faces)
|
||||||
|
|
Loading…
Reference in a new issue