move path utilities out of print

This commit is contained in:
Stewart Allen 2022-02-17 00:36:17 -05:00
commit 36d3f6b0b6
4 changed files with 118 additions and 109 deletions

2
app.js
View file

@ -361,7 +361,6 @@ const script = {
"kiri/stack",
"kiri/stacks",
"kiri/widget",
"kiri/print",
"kiri/codec",
"kiri/conf",
"kiri/main",
@ -384,6 +383,7 @@ const script = {
"add/three",
"add/class",
"geo/base",
"geo/path",
"geo/wasm",
"geo/point",
"geo/points",

111
src/geo/path.js Normal file
View file

@ -0,0 +1,111 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
const base = self.base;
if (base.path) return;
const { util, config, newPoint } = base;
const { sqr, numOrDefault } = util;
const DEG2RAD = Math.PI / 180;
/**
* emit each element in an array based on
* the next closest endpoint.
*/
function tip2tipEmit(array, startPoint, emitter) {
let mindist, dist, found, count = 0;
for (;;) {
found = null;
mindist = Infinity;
array.forEach(function(el) {
if (el.delete) return;
dist = startPoint.distTo2D(el.first);
if (dist < mindist) {
found = {el:el, first:el.first, last:el.last};
mindist = dist;
}
dist = startPoint.distTo2D(el.last);
if (dist < mindist) {
found = {el:el, first:el.last, last:el.first};
mindist = dist;
}
});
if (found) {
found.el.delete = true;
startPoint = found.last;
emitter(found.el, found.first, ++count);
} else {
break;
}
}
return startPoint;
}
/**
* like tip2tipEmit but accepts an array of polygons and the next closest
* point can be anywhere in the adjacent polygon. should be re-written
* to be more like outputOrderClosest() and have the option to account for
* depth in determining distance
*/
function poly2polyEmit(array, startPoint, emitter, opt = {}) {
let marker = opt.mark || 'delete';
let mindist, dist, found, count = 0;
for (;;) {
found = null;
mindist = Infinity;
for (let poly of array) {
if (poly[marker]) {
continue;
}
if (poly.isOpen()) {
const d2f = startPoint.distTo2D(poly.first());
const d2l = startPoint.distTo2D(poly.last());
if (d2f > mindist && d2l > mindist) {
continue;
}
if (d2l < mindist && d2l < d2f && opt.swapdir !== false) {
poly.reverse();
found = {poly:poly, index:0, point:poly.first()};
mindist = d2l;
} else if (d2f < mindist) {
found = {poly:poly, index:0, point:poly.first()};
mindist = d2f;
}
continue;
}
let area = poly.open ? 1 : poly.area();
poly.forEachPoint(function(point, index) {
dist = opt.weight ?
startPoint.distTo3D(point) * area * area :
startPoint.distTo2D(point);
if (dist < mindist) {
found = {poly:poly, index:index, point:point};
mindist = dist;
}
});
}
if (!found || opt.term) {
break;
}
found.poly[marker] = true;
startPoint = emitter(found.poly, found.index, ++count, startPoint) || found.point;
}
// undo delete marks
if (opt.perm !== true) {
array.forEach(function(poly) { poly[marker] = false });
}
return startPoint;
}
base.path = {
poly2polyEmit,
tip2tipEmit
};
})();

View file

@ -7,10 +7,10 @@
let KIRI = self.kiri,
BASE = self.base,
POLY = BASE.polygons,
UTIL = BASE.util,
PATH = BASE.path,
CAM = KIRI.driver.CAM,
PRO = CAM.process,
newPoint = BASE.newPoint;
{ newPoint } = BASE,
{ tip2tipEmit, poly2polyEmit } = PATH;
/**
* DRIVER PRINT CONTRACT
@ -103,8 +103,6 @@
spindle = 0,
spindleMax = device.spindleMax,
addOutput = print.addOutput,
tip2tipEmit = print.tip2tipEmit,
poly2polyEmit = print.poly2polyEmit,
maxToolDiam = widget.maxToolDiam,
terrain = widget.terrain ? widget.terrain.map(data => {
return {

View file

@ -7,19 +7,15 @@
if (self.kiri.newPrint) return;
const KIRI = self.kiri,
DRIVERS = KIRI.driver,
LASER = DRIVERS.LASER,
CAM = DRIVERS.CAM,
FDM = DRIVERS.FDM,
BASE = self.base,
PATH = BASE.path,
UTIL = BASE.util,
POLY = BASE.polygons,
SQRT = Math.sqrt,
SQR = UTIL.sqr,
PI = Math.PI,
PRO = Print.prototype,
Polygon = BASE.Polygon,
newPoint = BASE.newPoint;
newPoint = BASE.newPoint,
{ tip2tipEmit } = PATH;
let lastPoint = null,
lastEmit = null,
@ -58,8 +54,6 @@
PRO.addOutput = addOutput;
PRO.extrudePerMM = extrudePerMM;
PRO.constReplace = constReplace;
PRO.poly2polyEmit = poly2polyEmit;
PRO.tip2tipEmit = tip2tipEmit;
PRO.addPrintPoints = addPrintPoints;
PRO.parseSVG = function(code, offset) {
@ -1185,100 +1179,6 @@
output.appendAll(input);
}
/**
* emit each element in an array based on
* the next closest endpoint.
*/
function tip2tipEmit(array, startPoint, emitter) {
let mindist, dist, found, count = 0;
for (;;) {
found = null;
mindist = Infinity;
array.forEach(function(el) {
if (el.delete) return;
dist = startPoint.distTo2D(el.first);
if (dist < mindist) {
found = {el:el, first:el.first, last:el.last};
mindist = dist;
}
dist = startPoint.distTo2D(el.last);
if (dist < mindist) {
found = {el:el, first:el.last, last:el.first};
mindist = dist;
}
});
if (found) {
found.el.delete = true;
startPoint = found.last;
emitter(found.el, found.first, ++count);
} else {
break;
}
}
return startPoint;
}
BASE.util.poly2polyEmit = poly2polyEmit;
/**
* like tip2tipEmit but accepts an array of polygons and the next closest
* point can be anywhere in the adjacent polygon. should be re-written
* to be more like outputOrderClosest() and have the option to account for
* depth in determining distance
*/
function poly2polyEmit(array, startPoint, emitter, opt = {}) {
let marker = opt.mark || 'delete';
let mindist, dist, found, count = 0;
for (;;) {
found = null;
mindist = Infinity;
for (let poly of array) {
if (poly[marker]) {
continue;
}
if (poly.isOpen()) {
const d2f = startPoint.distTo2D(poly.first());
const d2l = startPoint.distTo2D(poly.last());
if (d2f > mindist && d2l > mindist) {
continue;
}
if (d2l < mindist && d2l < d2f && opt.swapdir !== false) {
poly.reverse();
found = {poly:poly, index:0, point:poly.first()};
mindist = d2l;
} else if (d2f < mindist) {
found = {poly:poly, index:0, point:poly.first()};
mindist = d2f;
}
continue;
}
let area = poly.open ? 1 : poly.area();
poly.forEachPoint(function(point, index) {
dist = opt.weight ?
startPoint.distTo3D(point) * area * area :
startPoint.distTo2D(point);
if (dist < mindist) {
found = {poly:poly, index:index, point:point};
mindist = dist;
}
});
}
if (!found || opt.term) {
break;
}
found.poly[marker] = true;
startPoint = emitter(found.poly, found.index, ++count, startPoint) || found.point;
}
// undo delete marks
if (opt.perm !== true) {
array.forEach(function(poly) { poly[marker] = false });
}
return startPoint;
}
/**
* calculate mm of filament required for a given extrusion length and layer height.
*