implement tab hopping. toolpath goes up and over tab instead of interrupting cut.
fixes #207
This commit is contained in:
parent
5243873515
commit
eee5dd85a0
2 changed files with 48 additions and 16 deletions
2
notes.md
2
notes.md
|
|
@ -59,9 +59,7 @@
|
||||||
|
|
||||||
* `B` rapid moves should be max of terrain zmax and last cut layer height (roughing)
|
* `B` rapid moves should be max of terrain zmax and last cut layer height (roughing)
|
||||||
* `B` feed rate for next tool set before tool change (push/pop feed rates?)
|
* `B` feed rate for next tool set before tool change (push/pop feed rates?)
|
||||||
* `B` tab cuts cause loss of direction, parenting, depth, and it's hard to fix
|
|
||||||
* `B` tabs do not properly track widget mirror events
|
* `B` tabs do not properly track widget mirror events
|
||||||
* `B` tabs are not cut to exact height
|
|
||||||
* `B` contour does not honor clip to stock
|
* `B` contour does not honor clip to stock
|
||||||
|
|
||||||
* `F` add lathe step down to eliminate the need for roughing
|
* `F` add lathe step down to eliminate the need for roughing
|
||||||
|
|
|
||||||
|
|
@ -775,14 +775,33 @@ export async function holes(settings, widget, individual, rec, onProgress) {
|
||||||
return drills;
|
return drills;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cutTabs(tabs, offset, z, inter) {
|
function cutTabs(tabs, offset) {
|
||||||
tabs = tabs.filter(tab => z < tab.pos.z + tab.dim.z / 2).map(tab => tab.off).flat();
|
let out = [];
|
||||||
return cutPolys(tabs, offset, z, false);
|
for (let tab of tabs) {
|
||||||
|
tab.top = tab.pos.z + tab.dim.z / 2;
|
||||||
|
}
|
||||||
|
for (let poly of offset) {
|
||||||
|
let polyZ = poly.getZ();
|
||||||
|
let cut = tabs.filter(tab => tab.top >= polyZ);
|
||||||
|
let lo = poly.cut(cut.map(tab => tab.off).flat(), false);
|
||||||
|
let hi = [];
|
||||||
|
for (let tab of cut) {
|
||||||
|
hi.appendAll(POLY.setZ(poly.cut(tab.off, true), tab.top));
|
||||||
|
}
|
||||||
|
if (hi.length) {
|
||||||
|
let heal = healPolys([ ...lo, ...hi ], false);
|
||||||
|
POLY.setWinding(heal, poly.isClockwise());
|
||||||
|
out.push(...heal);
|
||||||
|
} else {
|
||||||
|
out.push(poly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cutPolys(polys, offset, z, inter) {
|
function cutPolys(polys, offset) {
|
||||||
let noff = [];
|
let noff = [];
|
||||||
offset.forEach(op => noff.appendAll(op.cut(POLY.union(polys, 0, true), inter)));
|
offset.forEach(op => noff.appendAll(op.cut(POLY.union(polys, 0, true))));
|
||||||
return healPolys(noff);
|
return healPolys(noff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -799,7 +818,17 @@ function contourPolys(widget, polys) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function healPolys(noff) {
|
function dedup(arr, same) {
|
||||||
|
const out = [];
|
||||||
|
let prev;
|
||||||
|
for (const x of arr) {
|
||||||
|
if (!prev || !same(prev, x)) out.push(x);
|
||||||
|
prev = x;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function healPolys(noff, sameZ = true) {
|
||||||
for (let p of noff) {
|
for (let p of noff) {
|
||||||
if (p.appearsClosed()) {
|
if (p.appearsClosed()) {
|
||||||
p.points.pop();
|
p.points.pop();
|
||||||
|
|
@ -818,29 +847,29 @@ function healPolys(noff) {
|
||||||
let s2 = ntmp[j];
|
let s2 = ntmp[j];
|
||||||
if (!s2) continue;
|
if (!s2) continue;
|
||||||
// require polys at same Z to heal
|
// require polys at same Z to heal
|
||||||
if (Math.abs(s1.getZ() - s2.getZ()) > 0.01) {
|
if (sameZ && Math.abs(s1.getZ() - s2.getZ()) > 0.01) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(s1.open && s2.open)) continue;
|
if (!(s1.open && s2.open)) continue;
|
||||||
if (s1.last().isMergable2D(s2.first())) {
|
if (s1.last().isMergable2D(s2.first())) {
|
||||||
s1.addPoints(s2.points.slice(1));
|
s1.addPoints(s2.points);
|
||||||
ntmp[j] = null;
|
ntmp[j] = null;
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
if (s2.last().isMergable2D(s1.first())) {
|
if (s2.last().isMergable2D(s1.first())) {
|
||||||
s2.addPoints(s1.points.slice(1));
|
s2.addPoints(s1.points);
|
||||||
ntmp[i] = null;
|
ntmp[i] = null;
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
if (s1.first().isMergable2D(s2.first())) {
|
if (s1.first().isMergable2D(s2.first())) {
|
||||||
s1.reverse();
|
s1.reverse();
|
||||||
s1.addPoints(s2.points.slice(1));
|
s1.addPoints(s2.points);
|
||||||
ntmp[j] = null;
|
ntmp[j] = null;
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
if (s1.last().isMergable2D(s2.last())) {
|
if (s1.last().isMergable2D(s2.last())) {
|
||||||
s2.reverse();
|
s2.reverse();
|
||||||
s1.addPoints(s2.points.slice(1));
|
s1.addPoints(s2.points);
|
||||||
ntmp[j] = null;
|
ntmp[j] = null;
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
|
|
@ -854,9 +883,14 @@ function healPolys(noff) {
|
||||||
}
|
}
|
||||||
// close poly if head meets tail
|
// close poly if head meets tail
|
||||||
for (let poly of noff) {
|
for (let poly of noff) {
|
||||||
if (poly.open && poly.first().isMergable2D(poly.last())) {
|
poly.points = dedup(poly.points, (a,b) => a.isMergable3D(b));
|
||||||
poly.points.pop();
|
if (poly.open) {
|
||||||
poly.open = false;
|
if (poly.first().isMergable3D(poly.last())) {
|
||||||
|
poly.points.pop();
|
||||||
|
poly.open = false;
|
||||||
|
} else if (poly.first().isMergable2D(poly.last())) {
|
||||||
|
poly.open = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue