mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Merge pull request #473 from revarbat/revarbat_dev
Fixes for worm_gear()
This commit is contained in:
commit
10a667c86b
3 changed files with 125 additions and 72 deletions
11
arrays.scad
11
arrays.scad
|
@ -489,12 +489,19 @@ function deduplicate_indexed(list, indices, closed=false, eps=EPSILON) =
|
|||
indices==[]? [] :
|
||||
assert(is_vector(indices), "Indices must be a list of numbers.")
|
||||
let(
|
||||
ll = len(list),
|
||||
l = len(indices),
|
||||
end = l-(closed?0:1)
|
||||
) [
|
||||
for (i = [0:1:l-1]) let(
|
||||
a = list[indices[i]],
|
||||
b = list[indices[(i+1)%l]],
|
||||
idx1 = indices[i],
|
||||
idx2 = indices[(i+1)%l],
|
||||
a = assert(idx1>=0,"Bad index.")
|
||||
assert(idx1<len(list),"Bad index in indices.")
|
||||
list[idx1],
|
||||
b = assert(idx2>=0,"Bad index.")
|
||||
assert(idx2<len(list),"Bad index in indices.")
|
||||
list[idx2],
|
||||
eq = (a == b)? true :
|
||||
(a*0 != b*0) || (eps==0)? false :
|
||||
is_num(a) || is_vector(a) ? approx(a, b, eps=eps)
|
||||
|
|
|
@ -1420,7 +1420,7 @@ function worm_gear(
|
|||
tp = [0,r1,0] - spherical_to_xyz(r2, 90, 90+zang),
|
||||
zang2 = u * helical
|
||||
) [
|
||||
for (i = [0:1:teeth]) each
|
||||
for (i = [0:1:teeth-1]) each
|
||||
apply(
|
||||
zrot(-i*360/teeth+zang2) *
|
||||
move(tp) *
|
||||
|
@ -1435,7 +1435,7 @@ function worm_gear(
|
|||
face_pts = len(tooth_profile),
|
||||
gear_pts = face_pts * teeth,
|
||||
top_faces =[
|
||||
for (i=[0:1:teeth-1], j=[0:1:(face_pts/2)-1]) each [
|
||||
for (i=[0:1:teeth-1], j=[0:1:(face_pts/2)-2]) each [
|
||||
[i*face_pts+j, (i+1)*face_pts-j-1, (i+1)*face_pts-j-2],
|
||||
[i*face_pts+j, (i+1)*face_pts-j-2, i*face_pts+j+1]
|
||||
],
|
||||
|
|
182
vnf.scad
182
vnf.scad
|
@ -291,26 +291,27 @@ function vnf_vertex_array(
|
|||
cap1 = first_defined([cap1,caps,false]),
|
||||
cap2 = first_defined([cap2,caps,false]),
|
||||
colcnt = cols - (col_wrap?0:1),
|
||||
rowcnt = rows - (row_wrap?0:1)
|
||||
rowcnt = rows - (row_wrap?0:1),
|
||||
verts = [
|
||||
each pts,
|
||||
if (style=="quincunx") (
|
||||
for (r = [0:1:rowcnt-1]) (
|
||||
for (c = [0:1:colcnt-1]) (
|
||||
let(
|
||||
i1 = ((r+0)%rows)*cols + ((c+0)%cols),
|
||||
i2 = ((r+1)%rows)*cols + ((c+0)%cols),
|
||||
i3 = ((r+1)%rows)*cols + ((c+1)%cols),
|
||||
i4 = ((r+0)%rows)*cols + ((c+1)%cols)
|
||||
) mean([pts[i1], pts[i2], pts[i3], pts[i4]])
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
rows<=1 || cols<=1 ? vnf :
|
||||
vnf_merge(cleanup=true, [
|
||||
vnf, [
|
||||
concat(
|
||||
pts,
|
||||
style!="quincunx"? [] : [
|
||||
for (r = [0:1:rowcnt-1]) (
|
||||
for (c = [0:1:colcnt-1]) (
|
||||
let(
|
||||
i1 = ((r+0)%rows)*cols + ((c+0)%cols),
|
||||
i2 = ((r+1)%rows)*cols + ((c+0)%cols),
|
||||
i3 = ((r+1)%rows)*cols + ((c+1)%cols),
|
||||
i4 = ((r+0)%rows)*cols + ((c+1)%cols)
|
||||
) mean([pts[i1], pts[i2], pts[i3], pts[i4]])
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
verts,
|
||||
concat(
|
||||
[
|
||||
for (r = [0:1:rowcnt-1]) (
|
||||
|
@ -337,8 +338,9 @@ function vnf_vertex_array(
|
|||
) fsets[test?0:1] : (
|
||||
[[i1,i3,i2],[i1,i4,i3]]
|
||||
),
|
||||
rfaces = reverse? [for (face=faces) reverse(face)] : faces
|
||||
) rfaces
|
||||
rfaces = reverse? [for (face=faces) reverse(face)] : faces,
|
||||
ffaces = [for (face=rfaces) if(len(deduplicate_indexed(verts,face,closed=true))>=3) face]
|
||||
) faces
|
||||
)
|
||||
)
|
||||
],
|
||||
|
@ -618,14 +620,15 @@ function vnf_bend(vnf,r,d,axis="Z") =
|
|||
// Currently checks for these problems:
|
||||
// Type | Color | Code | Message
|
||||
// ------- | -------- | ------------ | ---------------------------------
|
||||
// WARNING | Yellow | BIG_FACE | Face has more than 3 vertices, and may confuse CGAL
|
||||
// WARNING | Brown | NULL_FACE | Face has zero area
|
||||
// ERROR | Cyan | NONPLANAR | Face vertices are not coplanar
|
||||
// ERROR | Orange | OVRPOP_EDGE | Too many faces attached at edge
|
||||
// ERROR | Violet | REVERSAL | Faces reverse across edge
|
||||
// ERROR | Red | T_JUNCTION | Vertex is mid-edge on another Face
|
||||
// ERROR | Blue | FACE_ISECT | Faces intersect
|
||||
// ERROR | Magenta | HOLE_EDGE | Edge bounds Hole
|
||||
// WARNING | Yellow | BIG_FACE | Face has more than 3 vertices, and may confuse CGAL.
|
||||
// WARNING | Brown | NULL_FACE | Face has zero area.
|
||||
// ERROR | Cyan | NONPLANAR | Face vertices are not coplanar.
|
||||
// ERROR | Brown | DUP_FACE | Multiple instances of the same face.
|
||||
// ERROR | Orange | MULTCONN | Multiply Connected Geometry. Too many faces attached at Edge.
|
||||
// ERROR | Violet | REVERSAL | Faces reverse across edge.
|
||||
// ERROR | Red | T_JUNCTION | Vertex is mid-edge on another Face.
|
||||
// ERROR | Blue | FACE_ISECT | Faces intersect.
|
||||
// ERROR | Magenta | HOLE_EDGE | Edge bounds Hole.
|
||||
// .
|
||||
// Still to implement:
|
||||
// - Overlapping coplanar faces.
|
||||
|
@ -649,7 +652,7 @@ function vnf_bend(vnf,r,d,axis="Z") =
|
|||
// [a, b, e], [a, c, b], [a, d, c], [a, e, d], [b, c, d, e]
|
||||
// ]);
|
||||
// vnf_validate(vnf);
|
||||
// Example: OVRPOP_EDGE Errors; More Than Two Faces Attached to the Same Edge. This confuses CGAL, and can lead to failed renders.
|
||||
// Example: MULTCONN Errors; More Than Two Faces Attached to the Same Edge. This confuses CGAL, and can lead to failed renders.
|
||||
// vnf = vnf_triangulate(linear_sweep(union(square(50), square(50,anchor=BACK+RIGHT)), height=50));
|
||||
// vnf_validate(vnf);
|
||||
// Example: REVERSAL Errors; Faces Reversed Across Edge
|
||||
|
@ -700,61 +703,95 @@ function vnf_validate(vnf, show_warns=true, check_isects=false) =
|
|||
for (face=faces, edge=pair(face,true))
|
||||
edge[0]<edge[1]? edge : [edge[1],edge[0]]
|
||||
]),
|
||||
dfaces = [
|
||||
for (face=faces) let(
|
||||
face=deduplicate_indexed(varr,face,closed=true)
|
||||
) if(len(face)>=3)
|
||||
face
|
||||
],
|
||||
face_areas = [
|
||||
for (face = faces)
|
||||
len(face) < 3? 0 :
|
||||
polygon_area([for (k=face) varr[k]])
|
||||
],
|
||||
edgecnts = unique_count(edges),
|
||||
uniq_edges = edgecnts[0],
|
||||
issues = []
|
||||
)
|
||||
let(
|
||||
big_faces = !show_warns? [] : [
|
||||
for (face = faces)
|
||||
if (len(face) > 3)
|
||||
_vnf_validate_err("BIG_FACE", [for (i=face) varr[i]])
|
||||
],
|
||||
null_faces = !show_warns? [] : [
|
||||
for (face = faces) let(
|
||||
face = deduplicate(face,closed=true)
|
||||
)
|
||||
if (len(face)>=3) let(
|
||||
faceverts = [for (k=face) varr[k]],
|
||||
area = polygon_area(faceverts)
|
||||
for (i = idx(faces)) let(
|
||||
face = faces[i],
|
||||
area = face_areas[i],
|
||||
faceverts = [for (k=face) varr[k]]
|
||||
)
|
||||
if (is_num(area) && abs(area) < EPSILON)
|
||||
_vnf_validate_err("NULL_FACE", faceverts)
|
||||
],
|
||||
nonplanars = unique([
|
||||
for (face = faces) let(
|
||||
faceverts = [for (k=face) varr[k]],
|
||||
area = polygon_area(faceverts)
|
||||
)
|
||||
if (is_num(area) && abs(area) > EPSILON)
|
||||
if (!coplanar(faceverts))
|
||||
_vnf_validate_err("NONPLANAR", faceverts)
|
||||
]),
|
||||
overpop_edges = unique([
|
||||
for (i=idx(uniq_edges))
|
||||
issues = concat(big_faces, null_faces)
|
||||
)
|
||||
let(
|
||||
repeated_faces = [
|
||||
for (i=idx(dfaces), j=idx(dfaces))
|
||||
if (i!=j) let(
|
||||
face1 = dfaces[i],
|
||||
face2 = dfaces[j]
|
||||
) if (min(face1) == min(face2)) let(
|
||||
min1 = min_index(face1),
|
||||
min2 = min_index(face2)
|
||||
) if (min1 == min2) let(
|
||||
sface1 = list_rotate(face1,min1),
|
||||
sface2 = list_rotate(face2,min2)
|
||||
) if (sface1 == sface2)
|
||||
_vnf_validate_err("DUP_FACE", [for (i=sface1) varr[i]])
|
||||
],
|
||||
issues = concat(issues, repeated_faces)
|
||||
) issues? issues :
|
||||
let(
|
||||
multconn_edges = unique([
|
||||
for (i = idx(uniq_edges))
|
||||
if (edgecnts[1][i]>2)
|
||||
_vnf_validate_err("OVRPOP_EDGE", [for (i=uniq_edges[i]) varr[i]])
|
||||
_vnf_validate_err("MULTCONN", [for (i=uniq_edges[i]) varr[i]])
|
||||
]),
|
||||
issues = concat(issues, multconn_edges)
|
||||
) issues? issues :
|
||||
let(
|
||||
reversals = unique([
|
||||
for(i = idx(faces), j = idx(faces)) if(i != j)
|
||||
if(len(deduplicate(faces[i],closed=true))>=3)
|
||||
if(len(deduplicate(faces[j],closed=true))>=3)
|
||||
for(i = idx(dfaces), j = idx(dfaces)) if(i != j)
|
||||
for(edge1 = pair(faces[i],true))
|
||||
for(edge2 = pair(faces[j],true))
|
||||
if(edge1 == edge2) // Valid adjacent faces will never have the same vertex ordering.
|
||||
if(_edge_not_reported(edge1, varr, overpop_edges))
|
||||
if(_edge_not_reported(edge1, varr, multconn_edges))
|
||||
_vnf_validate_err("REVERSAL", [for (i=edge1) varr[i]])
|
||||
]),
|
||||
issues = concat(issues, reversals)
|
||||
) issues? issues :
|
||||
let(
|
||||
t_juncts = unique([
|
||||
for (v=idx(varr), edge=uniq_edges)
|
||||
if (v!=edge[0] && v!=edge[1]) let(
|
||||
a = varr[edge[0]],
|
||||
b = varr[v],
|
||||
c = varr[edge[1]]
|
||||
for (v=idx(varr), edge=uniq_edges) let(
|
||||
ia = edge[0],
|
||||
ib = v,
|
||||
ic = edge[1]
|
||||
)
|
||||
if (a != b && b != c && a != c) let(
|
||||
if (ia!=ib && ib!=ic && ia!=ic) let(
|
||||
a = varr[ia],
|
||||
b = varr[ib],
|
||||
c = varr[ic]
|
||||
)
|
||||
if (!approx(a,b) && !approx(b,c) && !approx(a,c)) let(
|
||||
pt = segment_closest_point([a,c],b)
|
||||
)
|
||||
if (pt == b)
|
||||
if (approx(pt,b))
|
||||
_vnf_validate_err("T_JUNCTION", [b])
|
||||
]),
|
||||
issues = concat(issues, t_juncts)
|
||||
) issues? issues :
|
||||
let(
|
||||
isect_faces = !check_isects? [] : unique([
|
||||
for (i = [0:1:len(faces)-2])
|
||||
for (j = [i+1:1:len(faces)-1]) let(
|
||||
|
@ -787,30 +824,39 @@ function vnf_validate(vnf, show_warns=true, check_isects=false) =
|
|||
if (seg[0] != seg[1])
|
||||
_vnf_validate_err("FACE_ISECT", seg)
|
||||
]),
|
||||
issues = concat(issues, isect_faces)
|
||||
) issues? issues :
|
||||
let(
|
||||
hole_edges = unique([
|
||||
for (i=idx(uniq_edges))
|
||||
if (edgecnts[1][i]<2)
|
||||
if (_pts_not_reported(uniq_edges[i], varr, t_juncts))
|
||||
if (_pts_not_reported(uniq_edges[i], varr, isect_faces))
|
||||
_vnf_validate_err("HOLE_EDGE", [for (i=uniq_edges[i]) varr[i]])
|
||||
])
|
||||
) concat(
|
||||
big_faces,
|
||||
null_faces,
|
||||
nonplanars,
|
||||
overpop_edges,
|
||||
reversals,
|
||||
t_juncts,
|
||||
isect_faces,
|
||||
hole_edges
|
||||
);
|
||||
]),
|
||||
issues = concat(issues, hole_edges)
|
||||
) issues? issues :
|
||||
let(
|
||||
nonplanars = unique([
|
||||
for (i = idx(faces)) let(
|
||||
face = faces[i],
|
||||
area = face_areas[i],
|
||||
faceverts = [for (k=face) varr[k]]
|
||||
)
|
||||
if (is_num(area) && abs(area) > EPSILON)
|
||||
if (!coplanar(faceverts))
|
||||
_vnf_validate_err("NONPLANAR", faceverts)
|
||||
]),
|
||||
issues = concat(issues, nonplanars)
|
||||
) issues;
|
||||
|
||||
|
||||
_vnf_validate_errs = [
|
||||
["BIG_FACE", "WARNING", "cyan", "Face has more than 3 vertices, and may confuse CGAL"],
|
||||
["NULL_FACE", "WARNING", "blue", "Face has zero area."],
|
||||
["NONPLANAR", "ERROR", "yellow", "Face vertices are not coplanar"],
|
||||
["OVRPOP_EDGE", "ERROR", "orange", "Too many faces attached at Edge"],
|
||||
["DUP_FACE", "ERROR", "brown", "Multiple instances of the same face."],
|
||||
["MULTCONN", "ERROR", "orange", "Multiply Connected Geometry. Too many faces attached at Edge"],
|
||||
["REVERSAL", "ERROR", "violet", "Faces Reverse Across Edge"],
|
||||
["T_JUNCTION", "ERROR", "magenta", "Vertex is mid-edge on another Face"],
|
||||
["FACE_ISECT", "ERROR", "brown", "Faces intersect"],
|
||||
|
|
Loading…
Reference in a new issue