mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09: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==[]? [] :
|
indices==[]? [] :
|
||||||
assert(is_vector(indices), "Indices must be a list of numbers.")
|
assert(is_vector(indices), "Indices must be a list of numbers.")
|
||||||
let(
|
let(
|
||||||
|
ll = len(list),
|
||||||
l = len(indices),
|
l = len(indices),
|
||||||
end = l-(closed?0:1)
|
end = l-(closed?0:1)
|
||||||
) [
|
) [
|
||||||
for (i = [0:1:l-1]) let(
|
for (i = [0:1:l-1]) let(
|
||||||
a = list[indices[i]],
|
idx1 = indices[i],
|
||||||
b = list[indices[(i+1)%l]],
|
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 :
|
eq = (a == b)? true :
|
||||||
(a*0 != b*0) || (eps==0)? false :
|
(a*0 != b*0) || (eps==0)? false :
|
||||||
is_num(a) || is_vector(a) ? approx(a, b, eps=eps)
|
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),
|
tp = [0,r1,0] - spherical_to_xyz(r2, 90, 90+zang),
|
||||||
zang2 = u * helical
|
zang2 = u * helical
|
||||||
) [
|
) [
|
||||||
for (i = [0:1:teeth]) each
|
for (i = [0:1:teeth-1]) each
|
||||||
apply(
|
apply(
|
||||||
zrot(-i*360/teeth+zang2) *
|
zrot(-i*360/teeth+zang2) *
|
||||||
move(tp) *
|
move(tp) *
|
||||||
|
@ -1435,7 +1435,7 @@ function worm_gear(
|
||||||
face_pts = len(tooth_profile),
|
face_pts = len(tooth_profile),
|
||||||
gear_pts = face_pts * teeth,
|
gear_pts = face_pts * teeth,
|
||||||
top_faces =[
|
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-1, (i+1)*face_pts-j-2],
|
||||||
[i*face_pts+j, (i+1)*face_pts-j-2, i*face_pts+j+1]
|
[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]),
|
cap1 = first_defined([cap1,caps,false]),
|
||||||
cap2 = first_defined([cap2,caps,false]),
|
cap2 = first_defined([cap2,caps,false]),
|
||||||
colcnt = cols - (col_wrap?0:1),
|
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 :
|
rows<=1 || cols<=1 ? vnf :
|
||||||
vnf_merge(cleanup=true, [
|
vnf_merge(cleanup=true, [
|
||||||
vnf, [
|
vnf, [
|
||||||
concat(
|
verts,
|
||||||
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]])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
concat(
|
concat(
|
||||||
[
|
[
|
||||||
for (r = [0:1:rowcnt-1]) (
|
for (r = [0:1:rowcnt-1]) (
|
||||||
|
@ -337,8 +338,9 @@ function vnf_vertex_array(
|
||||||
) fsets[test?0:1] : (
|
) fsets[test?0:1] : (
|
||||||
[[i1,i3,i2],[i1,i4,i3]]
|
[[i1,i3,i2],[i1,i4,i3]]
|
||||||
),
|
),
|
||||||
rfaces = reverse? [for (face=faces) reverse(face)] : faces
|
rfaces = reverse? [for (face=faces) reverse(face)] : faces,
|
||||||
) rfaces
|
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:
|
// Currently checks for these problems:
|
||||||
// Type | Color | Code | Message
|
// Type | Color | Code | Message
|
||||||
// ------- | -------- | ------------ | ---------------------------------
|
// ------- | -------- | ------------ | ---------------------------------
|
||||||
// WARNING | Yellow | BIG_FACE | Face has more than 3 vertices, and may confuse CGAL
|
// WARNING | Yellow | BIG_FACE | Face has more than 3 vertices, and may confuse CGAL.
|
||||||
// WARNING | Brown | NULL_FACE | Face has zero area
|
// WARNING | Brown | NULL_FACE | Face has zero area.
|
||||||
// ERROR | Cyan | NONPLANAR | Face vertices are not coplanar
|
// ERROR | Cyan | NONPLANAR | Face vertices are not coplanar.
|
||||||
// ERROR | Orange | OVRPOP_EDGE | Too many faces attached at edge
|
// ERROR | Brown | DUP_FACE | Multiple instances of the same face.
|
||||||
// ERROR | Violet | REVERSAL | Faces reverse across edge
|
// ERROR | Orange | MULTCONN | Multiply Connected Geometry. Too many faces attached at Edge.
|
||||||
// ERROR | Red | T_JUNCTION | Vertex is mid-edge on another Face
|
// ERROR | Violet | REVERSAL | Faces reverse across edge.
|
||||||
// ERROR | Blue | FACE_ISECT | Faces intersect
|
// ERROR | Red | T_JUNCTION | Vertex is mid-edge on another Face.
|
||||||
// ERROR | Magenta | HOLE_EDGE | Edge bounds Hole
|
// ERROR | Blue | FACE_ISECT | Faces intersect.
|
||||||
|
// ERROR | Magenta | HOLE_EDGE | Edge bounds Hole.
|
||||||
// .
|
// .
|
||||||
// Still to implement:
|
// Still to implement:
|
||||||
// - Overlapping coplanar faces.
|
// - 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]
|
// [a, b, e], [a, c, b], [a, d, c], [a, e, d], [b, c, d, e]
|
||||||
// ]);
|
// ]);
|
||||||
// vnf_validate(vnf);
|
// 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 = vnf_triangulate(linear_sweep(union(square(50), square(50,anchor=BACK+RIGHT)), height=50));
|
||||||
// vnf_validate(vnf);
|
// vnf_validate(vnf);
|
||||||
// Example: REVERSAL Errors; Faces Reversed Across Edge
|
// 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))
|
for (face=faces, edge=pair(face,true))
|
||||||
edge[0]<edge[1]? edge : [edge[1],edge[0]]
|
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),
|
edgecnts = unique_count(edges),
|
||||||
uniq_edges = edgecnts[0],
|
uniq_edges = edgecnts[0],
|
||||||
|
issues = []
|
||||||
|
)
|
||||||
|
let(
|
||||||
big_faces = !show_warns? [] : [
|
big_faces = !show_warns? [] : [
|
||||||
for (face = faces)
|
for (face = faces)
|
||||||
if (len(face) > 3)
|
if (len(face) > 3)
|
||||||
_vnf_validate_err("BIG_FACE", [for (i=face) varr[i]])
|
_vnf_validate_err("BIG_FACE", [for (i=face) varr[i]])
|
||||||
],
|
],
|
||||||
null_faces = !show_warns? [] : [
|
null_faces = !show_warns? [] : [
|
||||||
for (face = faces) let(
|
for (i = idx(faces)) let(
|
||||||
face = deduplicate(face,closed=true)
|
face = faces[i],
|
||||||
)
|
area = face_areas[i],
|
||||||
if (len(face)>=3) let(
|
faceverts = [for (k=face) varr[k]]
|
||||||
faceverts = [for (k=face) varr[k]],
|
|
||||||
area = polygon_area(faceverts)
|
|
||||||
)
|
)
|
||||||
if (is_num(area) && abs(area) < EPSILON)
|
if (is_num(area) && abs(area) < EPSILON)
|
||||||
_vnf_validate_err("NULL_FACE", faceverts)
|
_vnf_validate_err("NULL_FACE", faceverts)
|
||||||
],
|
],
|
||||||
nonplanars = unique([
|
issues = concat(big_faces, null_faces)
|
||||||
for (face = faces) let(
|
)
|
||||||
faceverts = [for (k=face) varr[k]],
|
let(
|
||||||
area = polygon_area(faceverts)
|
repeated_faces = [
|
||||||
)
|
for (i=idx(dfaces), j=idx(dfaces))
|
||||||
if (is_num(area) && abs(area) > EPSILON)
|
if (i!=j) let(
|
||||||
if (!coplanar(faceverts))
|
face1 = dfaces[i],
|
||||||
_vnf_validate_err("NONPLANAR", faceverts)
|
face2 = dfaces[j]
|
||||||
]),
|
) if (min(face1) == min(face2)) let(
|
||||||
overpop_edges = unique([
|
min1 = min_index(face1),
|
||||||
for (i=idx(uniq_edges))
|
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)
|
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([
|
reversals = unique([
|
||||||
for(i = idx(faces), j = idx(faces)) if(i != j)
|
for(i = idx(dfaces), j = idx(dfaces)) if(i != j)
|
||||||
if(len(deduplicate(faces[i],closed=true))>=3)
|
|
||||||
if(len(deduplicate(faces[j],closed=true))>=3)
|
|
||||||
for(edge1 = pair(faces[i],true))
|
for(edge1 = pair(faces[i],true))
|
||||||
for(edge2 = pair(faces[j],true))
|
for(edge2 = pair(faces[j],true))
|
||||||
if(edge1 == edge2) // Valid adjacent faces will never have the same vertex ordering.
|
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]])
|
_vnf_validate_err("REVERSAL", [for (i=edge1) varr[i]])
|
||||||
]),
|
]),
|
||||||
|
issues = concat(issues, reversals)
|
||||||
|
) issues? issues :
|
||||||
|
let(
|
||||||
t_juncts = unique([
|
t_juncts = unique([
|
||||||
for (v=idx(varr), edge=uniq_edges)
|
for (v=idx(varr), edge=uniq_edges) let(
|
||||||
if (v!=edge[0] && v!=edge[1]) let(
|
ia = edge[0],
|
||||||
a = varr[edge[0]],
|
ib = v,
|
||||||
b = varr[v],
|
ic = edge[1]
|
||||||
c = varr[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)
|
pt = segment_closest_point([a,c],b)
|
||||||
)
|
)
|
||||||
if (pt == b)
|
if (approx(pt,b))
|
||||||
_vnf_validate_err("T_JUNCTION", [b])
|
_vnf_validate_err("T_JUNCTION", [b])
|
||||||
]),
|
]),
|
||||||
|
issues = concat(issues, t_juncts)
|
||||||
|
) issues? issues :
|
||||||
|
let(
|
||||||
isect_faces = !check_isects? [] : unique([
|
isect_faces = !check_isects? [] : unique([
|
||||||
for (i = [0:1:len(faces)-2])
|
for (i = [0:1:len(faces)-2])
|
||||||
for (j = [i+1:1:len(faces)-1]) let(
|
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])
|
if (seg[0] != seg[1])
|
||||||
_vnf_validate_err("FACE_ISECT", seg)
|
_vnf_validate_err("FACE_ISECT", seg)
|
||||||
]),
|
]),
|
||||||
|
issues = concat(issues, isect_faces)
|
||||||
|
) issues? issues :
|
||||||
|
let(
|
||||||
hole_edges = unique([
|
hole_edges = unique([
|
||||||
for (i=idx(uniq_edges))
|
for (i=idx(uniq_edges))
|
||||||
if (edgecnts[1][i]<2)
|
if (edgecnts[1][i]<2)
|
||||||
if (_pts_not_reported(uniq_edges[i], varr, t_juncts))
|
if (_pts_not_reported(uniq_edges[i], varr, t_juncts))
|
||||||
if (_pts_not_reported(uniq_edges[i], varr, isect_faces))
|
if (_pts_not_reported(uniq_edges[i], varr, isect_faces))
|
||||||
_vnf_validate_err("HOLE_EDGE", [for (i=uniq_edges[i]) varr[i]])
|
_vnf_validate_err("HOLE_EDGE", [for (i=uniq_edges[i]) varr[i]])
|
||||||
])
|
]),
|
||||||
) concat(
|
issues = concat(issues, hole_edges)
|
||||||
big_faces,
|
) issues? issues :
|
||||||
null_faces,
|
let(
|
||||||
nonplanars,
|
nonplanars = unique([
|
||||||
overpop_edges,
|
for (i = idx(faces)) let(
|
||||||
reversals,
|
face = faces[i],
|
||||||
t_juncts,
|
area = face_areas[i],
|
||||||
isect_faces,
|
faceverts = [for (k=face) varr[k]]
|
||||||
hole_edges
|
)
|
||||||
);
|
if (is_num(area) && abs(area) > EPSILON)
|
||||||
|
if (!coplanar(faceverts))
|
||||||
|
_vnf_validate_err("NONPLANAR", faceverts)
|
||||||
|
]),
|
||||||
|
issues = concat(issues, nonplanars)
|
||||||
|
) issues;
|
||||||
|
|
||||||
|
|
||||||
_vnf_validate_errs = [
|
_vnf_validate_errs = [
|
||||||
["BIG_FACE", "WARNING", "cyan", "Face has more than 3 vertices, and may confuse CGAL"],
|
["BIG_FACE", "WARNING", "cyan", "Face has more than 3 vertices, and may confuse CGAL"],
|
||||||
["NULL_FACE", "WARNING", "blue", "Face has zero area."],
|
["NULL_FACE", "WARNING", "blue", "Face has zero area."],
|
||||||
["NONPLANAR", "ERROR", "yellow", "Face vertices are not coplanar"],
|
["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"],
|
["REVERSAL", "ERROR", "violet", "Faces Reverse Across Edge"],
|
||||||
["T_JUNCTION", "ERROR", "magenta", "Vertex is mid-edge on another Face"],
|
["T_JUNCTION", "ERROR", "magenta", "Vertex is mid-edge on another Face"],
|
||||||
["FACE_ISECT", "ERROR", "brown", "Faces intersect"],
|
["FACE_ISECT", "ERROR", "brown", "Faces intersect"],
|
||||||
|
|
Loading…
Reference in a new issue