diff --git a/src/geo/polygon.js b/src/geo/polygon.js index 73197f9f..f76af961 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -1800,7 +1800,7 @@ class Polygon { * print paths. * * @param {Point} target - * @return {Object} {point:point, distance:distance} + * @return {Object} {distance, point, index: point_index} */ findClosestPointTo(target) { let dist, diff --git a/src/kiri-mode/cam/ops.js b/src/kiri-mode/cam/ops.js index f2f44e64..d3fe08cb 100644 --- a/src/kiri-mode/cam/ops.js +++ b/src/kiri-mode/cam/ops.js @@ -1383,7 +1383,7 @@ class OpPocket extends CamOp { prepare(ops, progress) { let { op, state, pockets } = this; - let { setTool, setSpindle, setTolerance, sliceOutput } = ops; + let { setTool, setSpindle, setTolerance, sliceOutput, getPrintPoint } = ops; let { process } = state.settings; setTool(op.tool, op.rate); @@ -1393,13 +1393,37 @@ class OpPocket extends CamOp { setTolerance(this.topo.tolerance); } - for (let sliceOut of pockets) { - sliceOutput(sliceOut, { - cutdir: process.camConventional, - depthFirst: process.camDepthFirst && !state.isIndexed, - easeDown: op.down && process.easeDown ? op.down : 0, - progress: (n,m) => progress(n/m, "pocket") - }); + // eliminate empty pockets + pockets = pockets.filter(p => p.length); + + // pockets is an [ array of an [ array of slices ] ] + // each top level array is a pocket containing a [ z layer array of slices ] + // follow each pocket to the next closest one from previous exit + for (;;) { + let printPoint = getPrintPoint(); + let min = { + dist: Infinity, + pocket: undefined + }; + for (let pocket of pockets.filter(p => !p.used)) { + let poly = pocket[0].camLines.slice().sort((a,b) => b.area() - a.area())[0]; + let find = poly.findClosestPointTo(printPoint); + if (find.distance < min.dist) { + min.pocket = pocket; + min.dist = find.distance; + } + } + if (min.pocket) { + min.pocket.used = true; + sliceOutput(min.pocket, { + cutdir: process.camConventional, + depthFirst: process.camDepthFirst && !state.isIndexed, + easeDown: op.down && process.easeDown ? op.down : 0, + progress: (n,m) => progress(n/m, "pocket") + }); + } else { + break; + } } } } diff --git a/src/kiri-mode/cam/prepare.js b/src/kiri-mode/cam/prepare.js index f113dddb..86389347 100644 --- a/src/kiri-mode/cam/prepare.js +++ b/src/kiri-mode/cam/prepare.js @@ -437,6 +437,12 @@ function prepEach(widget, settings, print, firstPoint, update) { ); } + /** + * output an array of slices that form a pocket + * + * @param {Slice[]} top-down Z stack of slices + * @param {*} opts + */ function sliceOutput(sliceOut, opts = {}) { const { cutdir, depthFirst, easeDown, progress } = opts; @@ -518,6 +524,7 @@ function prepEach(widget, settings, print, firstPoint, update) { setTolerance, setPrintPoint, setLasering, + getPrintPoint() { return printPoint }, printPoint, newLayer, addGCode,