fix climb vs conventional for 95% of cases with normal endmills
This commit is contained in:
parent
d955c69077
commit
01485dc38e
4 changed files with 93 additions and 71 deletions
|
|
@ -437,7 +437,7 @@ var gs_kiri_conf = exports;
|
|||
camStockZ: 0,
|
||||
camStockOffset: true,
|
||||
|
||||
outputClockwise: true,
|
||||
outputClockwise: false,
|
||||
|
||||
// --- shared FDM/Laser/CAM ---
|
||||
|
||||
|
|
|
|||
|
|
@ -832,7 +832,6 @@ var gs_kiri_cam = exports;
|
|||
function slice(settings, widget, onupdate, ondone) {
|
||||
let conf = settings,
|
||||
proc = conf.process,
|
||||
outp = conf.process,
|
||||
sliceAll = widget.slices = [],
|
||||
unitsName = settings.controller.units,
|
||||
units = unitsName === 'in' ? 25.4 : 1,
|
||||
|
|
@ -847,9 +846,9 @@ var gs_kiri_cam = exports;
|
|||
procFacing = proc.roughingOn && proc.camZTopOffset,
|
||||
procDrill = proc.drillingOn && proc.drillDown && proc.drillDownSpeed,
|
||||
sliceDepth = MAX(0.1, MIN(proc.roughingDown, proc.finishingDown) / 3) * units,
|
||||
// pocketOnly = outp.camPocketOnly,
|
||||
pocketOnlyRough = outp.camPocketOnlyRough,
|
||||
pocketOnlyFinish = outp.camPocketOnlyFinish,
|
||||
// pocketOnly = proc.camPocketOnly,
|
||||
pocketOnlyRough = proc.camPocketOnlyRough,
|
||||
pocketOnlyFinish = proc.camPocketOnlyFinish,
|
||||
// addTabs = proc.camTabsOn && !pocketOnly,
|
||||
addTabsRough = procRough && proc.camTabsOn && !pocketOnlyRough,
|
||||
addTabsFinish = procFinish && proc.camTabsOn && !pocketOnlyFinish,
|
||||
|
|
@ -857,7 +856,7 @@ var gs_kiri_cam = exports;
|
|||
tabHeight = proc.camTabsHeight * units,
|
||||
mesh = widget.mesh,
|
||||
bounds = widget.getBoundingBox(),
|
||||
zMin = MAX(bounds.min.z, outp.camZBottom) * units,
|
||||
zMin = MAX(bounds.min.z, proc.camZBottom) * units,
|
||||
shellRough,
|
||||
shellFinish,
|
||||
facePolys;
|
||||
|
|
@ -952,7 +951,7 @@ var gs_kiri_cam = exports;
|
|||
// hollow area from top of stock to top of part
|
||||
if (procFacing) {
|
||||
let ztop = bounds.max.z,
|
||||
zpos = ztop + (outp.camZTopOffset * units),
|
||||
zpos = ztop + (proc.camZTopOffset * units),
|
||||
zstep = proc.roughingDown * units;
|
||||
|
||||
while (zpos >= ztop) {
|
||||
|
|
@ -1029,7 +1028,7 @@ var gs_kiri_cam = exports;
|
|||
}
|
||||
|
||||
// horizontal slices for rough/finish
|
||||
doSlicing(widget, {height: sliceDepth, cam:true, zmin:outp.camZBottom}, camSlicesDone, function(update) {
|
||||
doSlicing(widget, {height: sliceDepth, cam:true, zmin:proc.camZBottom}, camSlicesDone, function(update) {
|
||||
onupdate(0.0 + update * 0.25, "slicing");
|
||||
});
|
||||
|
||||
|
|
@ -1370,7 +1369,7 @@ var gs_kiri_cam = exports;
|
|||
}
|
||||
});
|
||||
// set winding specified in output
|
||||
POLY.setWinding(polys, process.outputClockwise, true);
|
||||
POLY.setWinding(polys, process.outputClockwise, false);
|
||||
printPoint = poly2polyEmit(polys, printPoint, function(poly, index, count) {
|
||||
poly.forEachPoint(function(point, pidx, points, offset) {
|
||||
camOut(point.clone(), offset !== 0);
|
||||
|
|
@ -1381,6 +1380,7 @@ var gs_kiri_cam = exports;
|
|||
break;
|
||||
case modes.ROUGH:
|
||||
case modes.FINISH:
|
||||
let dir = process.outputClockwise;
|
||||
if (slice.camMode === modes.ROUGH) {
|
||||
setTool(process.roughingTool, process.roughingSpeed, process.roughingPlunge);
|
||||
spindle = Math.min(spindleMax, process.roughingSpindle);
|
||||
|
|
@ -1389,19 +1389,26 @@ var gs_kiri_cam = exports;
|
|||
setTool(process.finishingTool, process.finishingSpeed, process.finishingPlunge);
|
||||
spindle = Math.min(spindleMax, process.finishingSpindle);
|
||||
depthData.finishDiam = toolDiam;
|
||||
if (!process.camPocketOnlyFinish) {
|
||||
dir = !dir;
|
||||
}
|
||||
}
|
||||
// todo find closest next trace/trace-point
|
||||
slice.tops.forEach(function(top) {
|
||||
if (!top.poly) return;
|
||||
if (!top.traces) return;
|
||||
let polys = [];
|
||||
let polys = [], t = [], c = [];
|
||||
POLY.flatten(top.traces, top.inner || []).forEach(function (poly) {
|
||||
let child = poly.parent;
|
||||
if (depthFirst) poly = poly.clone(true);
|
||||
if (child) c.push(poly); else t.push(poly);
|
||||
poly.layer = depthData.layer;
|
||||
polys.push(poly);
|
||||
});
|
||||
// set winding specified in output
|
||||
POLY.setWinding(polys, process.outputClockwise, true);
|
||||
// set cut direction on outer polys
|
||||
POLY.setWinding(t, dir);
|
||||
// set cut direction on inner polys
|
||||
POLY.setWinding(c, !dir);
|
||||
if (depthFirst) {
|
||||
(slice.camMode === modes.ROUGH ? depthData.rough : depthData.finish).append(polys);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ var gs_kiri_init = exports;
|
|||
camZClearance: UC.newInput("z clearance", {title:"travel offset from z top\nin workspace units", convert:UC.toFloat, bound:UC.bound(0.01,100), modes:CAM}),
|
||||
// camPocketOnly: UC.newBoolean("pocket only", onBooleanClick, {title:"constrain to\npart boundaries", modes:CAM}),
|
||||
camDepthFirst: UC.newBoolean("depth first", onBooleanClick, {title:"optimize pocket cuts\nwith depth priority", modes:CAM}),
|
||||
outputClockwise: UC.newBoolean("clockwise", onBooleanClick, {title:"waterline milling direction", modes:CAM}),
|
||||
outputClockwise: UC.newBoolean("conventional", onBooleanClick, {title:"milling direction\nuncheck for 'climb'", modes:CAM}),
|
||||
|
||||
camStock: UC.newGroup("stock", null, {modes:CAM}),
|
||||
camStockX: UC.newInput("width", {title:"width (x) in workspace units\n0 defaults to part size", convert:UC.toFloat, bound:UC.bound(0,9999), modes:CAM}),
|
||||
|
|
|
|||
131
js/kiri-print.js
131
js/kiri-print.js
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var gs_kiri_print = exports;
|
||||
let gs_kiri_print = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
|
||||
var KIRI = self.kiri,
|
||||
let KIRI = self.kiri,
|
||||
DRIVERS = KIRI.driver,
|
||||
LASER = DRIVERS.LASER,
|
||||
CAM = DRIVERS.CAM,
|
||||
FDM = DRIVERS.FDM,
|
||||
LASER = DRIVERS.LASER,
|
||||
BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
DBUG = BASE.debug,
|
||||
|
|
@ -92,7 +92,7 @@ var gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.parseGCode = function(gcode, offset) {
|
||||
var lines = gcode
|
||||
let lines = gcode
|
||||
.toUpperCase()
|
||||
.replace("X", " X")
|
||||
.replace("Y", " Y")
|
||||
|
|
@ -102,7 +102,7 @@ var gs_kiri_print = exports;
|
|||
.replace(" ", " ")
|
||||
.split("\n");
|
||||
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
output = scope.output = [],
|
||||
bounds = scope.bounds = {
|
||||
max: { x:-Infinity, y:-Infinity, z:-Infinity},
|
||||
|
|
@ -185,7 +185,7 @@ var gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.setup = function(remote, onupdate, ondone) {
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
settings = scope.settings,
|
||||
mode = settings.mode;
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ var gs_kiri_print = exports;
|
|||
} else {
|
||||
|
||||
// executed from kiri-worker.js
|
||||
var driver = KIRI.driver[mode];
|
||||
let driver = KIRI.driver[mode];
|
||||
if (driver) driver.printSetup(scope, onupdate);
|
||||
else console.log({missing_print_driver: mode});
|
||||
ondone();
|
||||
|
|
@ -216,7 +216,7 @@ var gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.exportGCode = function(remote, ondone, online) {
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
settings = scope.settings,
|
||||
mode = settings.mode;
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ var gs_kiri_print = exports;
|
|||
} else {
|
||||
|
||||
// executed from kiri-worker.js
|
||||
var driver = KIRI.driver[mode];
|
||||
let driver = KIRI.driver[mode];
|
||||
if (driver && driver.printExport) {
|
||||
ondone(driver.printExport(scope, online));
|
||||
} else {
|
||||
|
|
@ -263,7 +263,7 @@ var gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.encodeOutput = function() {
|
||||
var newout = [], newlayer;
|
||||
let newout = [], newlayer;
|
||||
|
||||
this.output.forEach(function(layerout) {
|
||||
newlayer = [];
|
||||
|
|
@ -286,7 +286,7 @@ var gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.render = function() {
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
mode = scope.settings.mode;
|
||||
|
||||
switch (mode) {
|
||||
|
|
@ -306,13 +306,13 @@ var gs_kiri_print = exports;
|
|||
|
||||
// hsv values all = 0 to 1
|
||||
function hsv2rgb(hsv) {
|
||||
var seg = Math.floor(hsv.h * 6);
|
||||
var rem = hsv.h - (seg * (1/6));
|
||||
var out = {};
|
||||
let seg = Math.floor(hsv.h * 6);
|
||||
let rem = hsv.h - (seg * (1/6));
|
||||
let out = {};
|
||||
|
||||
var p = hsv.v * (1.0 - (hsv.s) );
|
||||
var q = hsv.v * (1.0 - (hsv.s * rem) );
|
||||
var t = hsv.v * (1.0 - (hsv.s * (1.0 - rem)));
|
||||
let p = hsv.v * (1.0 - (hsv.s) );
|
||||
let q = hsv.v * (1.0 - (hsv.s * rem) );
|
||||
let t = hsv.v * (1.0 - (hsv.s * (1.0 - rem)));
|
||||
|
||||
switch (seg) {
|
||||
case 0:
|
||||
|
|
@ -351,31 +351,46 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
PRO.renderMoves = function(showMoves, moveColor) {
|
||||
var scope = this, last, emits, moves;
|
||||
let debug = KIRI.api.const.LOCAL;
|
||||
let scope = this, last, emits, moves;
|
||||
// render layered output
|
||||
scope.lines = 0;
|
||||
scope.output.forEach(function(layerout) {
|
||||
var move = [], print = {}, z;
|
||||
let move = [], print = {}, z;
|
||||
layerout.forEach(function(out, index) {
|
||||
let point = out.point;
|
||||
if (last) {
|
||||
if (UTIL.distSq(last, out.point) < 0.001 && out.point.z === last.z) {
|
||||
if (UTIL.distSq(last, point) < 0.001 && point.z === last.z) {
|
||||
return;
|
||||
}
|
||||
if (out.emit > 0) {
|
||||
var spd = out.speed || 4000;
|
||||
var arr = print[spd] || [];
|
||||
let spd = out.speed || 4000;
|
||||
let arr = print[spd] || [];
|
||||
print[spd] = arr;
|
||||
arr.push(last);
|
||||
arr.push(out.point);
|
||||
arr.push(point);
|
||||
if (debug && showMoves) {
|
||||
let rs = BASE.newSlope(
|
||||
{x: point.x, y: point.y},
|
||||
{x: last.x, y: last.y}
|
||||
);
|
||||
let ao1 = BASE.newSlopeFromAngle(rs.angle + 25);
|
||||
let ao2 = BASE.newSlopeFromAngle(rs.angle - 25);
|
||||
let sp = BASE.newPoint(point.x, point.y, point.z);
|
||||
move.push(sp);
|
||||
move.push(sp.projectOnSlope(ao1, 0.5));
|
||||
move.push(sp);
|
||||
move.push(sp.projectOnSlope(ao2, 0.5));
|
||||
}
|
||||
} else {
|
||||
move.push(last);
|
||||
move.push(out.point);
|
||||
move.push(point);
|
||||
}
|
||||
} else {
|
||||
if (out.emit) DBUG.log("first point is emit");
|
||||
z = out.point.z;
|
||||
z = point.z;
|
||||
}
|
||||
last = out.point;
|
||||
last = point;
|
||||
});
|
||||
emits = KIRI.newLayer(scope.group);
|
||||
scope.printView.push(emits);
|
||||
|
|
@ -385,9 +400,9 @@ var gs_kiri_print = exports;
|
|||
scope.movesView.push(moves);
|
||||
moves.render();
|
||||
}
|
||||
for (var speed in print) {
|
||||
var sint = Math.min(6000, parseInt(speed));
|
||||
var rgb = hsv2rgb({h:sint/6000, s:1, v:0.6});
|
||||
for (let speed in print) {
|
||||
let sint = Math.min(6000, parseInt(speed));
|
||||
let rgb = hsv2rgb({h:sint/6000, s:1, v:0.6});
|
||||
emits.lines(print[speed],
|
||||
((rgb.r * 0xff) << 16) |
|
||||
((rgb.g * 0xff) << 8) |
|
||||
|
|
@ -448,10 +463,10 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function segmentOutput(output, p1, p2, s1, s2, steps, mult) {
|
||||
var sd = (s2 - s1) / (steps + 1);
|
||||
var dd = p1.distTo2D(p2) / steps;
|
||||
var dist = dd;
|
||||
var spd = s1;
|
||||
let sd = (s2 - s1) / (steps + 1);
|
||||
let dd = p1.distTo2D(p2) / steps;
|
||||
let dist = dd;
|
||||
let spd = s1;
|
||||
while (steps-- > 0) {
|
||||
spd += sd;
|
||||
p1 = p1.offsetPointTo(p2, dd);
|
||||
|
|
@ -469,10 +484,10 @@ var gs_kiri_print = exports;
|
|||
* @param {Function} [onfirst] optional fn to call on first point
|
||||
* @return {Point} last output point
|
||||
*/
|
||||
PRO.polyPrintPath = function(poly, startPoint, output, options) {
|
||||
PRO.polyPrintPath = function(poly, startPoint, output, opt) {
|
||||
poly.setClockwise();
|
||||
|
||||
var options = options || {},
|
||||
let options = opt || {},
|
||||
process = this.settings.process,
|
||||
shortDist = process.outputShortDistance,
|
||||
shellMult = pref(options.extrude, process.outputShellMult),
|
||||
|
|
@ -500,11 +515,11 @@ var gs_kiri_print = exports;
|
|||
addOutput(output, point, 0, moveSpeed);
|
||||
first = false;
|
||||
} else {
|
||||
var seglen = last.distTo2D(point);
|
||||
let seglen = last.distTo2D(point);
|
||||
if (coastDist && shellMult && perimeter - seglen <= coastDist) {
|
||||
var delta = perimeter - coastDist;
|
||||
var offset = seglen - delta;
|
||||
var offPoint = last.offsetPointFrom(point, offset)
|
||||
let delta = perimeter - coastDist;
|
||||
let offset = seglen - delta;
|
||||
let offPoint = last.offsetPointFrom(point, offset)
|
||||
addOutput(output, offPoint, shellMult, printSpeed);
|
||||
shellMult = 0;
|
||||
}
|
||||
|
|
@ -528,7 +543,7 @@ var gs_kiri_print = exports;
|
|||
* @return {Point} last output point
|
||||
*/
|
||||
PRO.slicePrintPath = function(slice, startPoint, offset, output, options) {
|
||||
var i,
|
||||
let i,
|
||||
opt = options || {},
|
||||
preout = [],
|
||||
scope = this,
|
||||
|
|
@ -567,7 +582,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function intersectsTop(p1, p2) {
|
||||
var int = false;
|
||||
let int = false;
|
||||
POLY.flatten(slice.gatherTopPolys([])).forEach(function(poly) {
|
||||
if (!int) poly.forEachSegment(function(s1, s2) {
|
||||
if (UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT)) {
|
||||
|
|
@ -586,7 +601,7 @@ var gs_kiri_print = exports;
|
|||
outputTraces(next, extrude);
|
||||
}, null);
|
||||
} else {
|
||||
var finishShell = poly.depth === 0 && !firstLayer;
|
||||
let finishShell = poly.depth === 0 && !firstLayer;
|
||||
startPoint = scope.polyPrintPath(poly, startPoint, preout, {
|
||||
rate: finishShell ? finishSpeed : printSpeed,
|
||||
accel: finishShell,
|
||||
|
|
@ -607,12 +622,12 @@ var gs_kiri_print = exports;
|
|||
*/
|
||||
function outputSparse(polys, extrude, speed) {
|
||||
if (!polys) return;
|
||||
var proxy = polys.map(function(poly) {
|
||||
let proxy = polys.map(function(poly) {
|
||||
return {poly: poly, first: poly.first(), last: poly.last()};
|
||||
});
|
||||
var lp = startPoint;
|
||||
let lp = startPoint;
|
||||
startPoint = tip2tipEmit(proxy, startPoint, function(el, point, count) {
|
||||
var poly = el.poly;
|
||||
let poly = el.poly;
|
||||
if (poly.last() === point) {
|
||||
poly.reverse();
|
||||
}
|
||||
|
|
@ -629,7 +644,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function outputFills(lines, options) {
|
||||
var p, p1, p2, dist, len, found, group, mindist, t1, t2,
|
||||
let p, p1, p2, dist, len, found, group, mindist, t1, t2,
|
||||
marked = 0,
|
||||
start = 0,
|
||||
skip = false,
|
||||
|
|
@ -744,7 +759,7 @@ var gs_kiri_print = exports;
|
|||
return fn(array[0]);
|
||||
}
|
||||
array = array.slice();
|
||||
var closest, find, next, order, poly, lastDepth = 0;
|
||||
let closest, find, next, order, poly, lastDepth = 0;
|
||||
for (;;) {
|
||||
order = [];
|
||||
closest = null;
|
||||
|
|
@ -771,8 +786,8 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
}
|
||||
|
||||
var all = [].appendAll(slice.supports || []).appendAll(slice.tops || []);
|
||||
var lastTop = null;
|
||||
let all = [].appendAll(slice.supports || []).appendAll(slice.tops || []);
|
||||
let lastTop = null;
|
||||
outputOrderClosest(all || [], function(next) {
|
||||
if (next instanceof Polygon) {
|
||||
// support polygon
|
||||
|
|
@ -784,7 +799,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
} else {
|
||||
// top object
|
||||
var bounds = POLY.flatten(next.gatherOuter([]));
|
||||
let bounds = POLY.flatten(next.gatherOuter([]));
|
||||
|
||||
let dir = -1; // 1 == inside out, -1 == outside-in
|
||||
|
||||
|
|
@ -853,7 +868,7 @@ var gs_kiri_print = exports;
|
|||
* the next closest endpoint.
|
||||
*/
|
||||
function tip2tipEmit(array, startPoint, emitter) {
|
||||
var mindist, dist, found, count = 0;
|
||||
let mindist, dist, found, count = 0;
|
||||
for (;;) {
|
||||
found = null;
|
||||
mindist = Infinity;
|
||||
|
|
@ -889,7 +904,7 @@ var gs_kiri_print = exports;
|
|||
* depth in determining distance
|
||||
*/
|
||||
function poly2polyEmit(array, startPoint, emitter, mark) {
|
||||
var mindist, dist, found, count = 0, marker = mark || 'delete';
|
||||
let mindist, dist, found, count = 0, marker = mark || 'delete';
|
||||
for (;;) {
|
||||
found = null;
|
||||
mindist = Infinity;
|
||||
|
|
@ -943,7 +958,7 @@ var gs_kiri_print = exports;
|
|||
* used for CAM depth first layer output
|
||||
*/
|
||||
function poly2polyDepthFirstEmit(array, startPoint, emitter, offset) {
|
||||
var layers = [],
|
||||
let layers = [],
|
||||
pools;
|
||||
|
||||
array.forEach(function(layerPolys, layerIndex) {
|
||||
|
|
@ -968,7 +983,7 @@ var gs_kiri_print = exports;
|
|||
poly.poolsDown = [];
|
||||
} else {
|
||||
// otherwise walk up the parent tree to find a pool to join
|
||||
var search = poly.parent;
|
||||
let search = poly.parent;
|
||||
// walk up until pool found
|
||||
while (search && !search.pool) {
|
||||
search = search.parent;
|
||||
|
|
@ -993,7 +1008,7 @@ var gs_kiri_print = exports;
|
|||
|
||||
if (layerIndex > 0)
|
||||
pools.forEach(function(pool) {
|
||||
for (var i=0; i<poolsAbove.length; i++) {
|
||||
for (let i=0; i<poolsAbove.length; i++) {
|
||||
const above = poolsAbove[i];
|
||||
// can only add open polys to open polys
|
||||
if (above.isOpen() && pool.isClosed()) {
|
||||
|
|
@ -1059,7 +1074,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function polygonMinOffset(poly1, poly2, offset) {
|
||||
var mindist = Infinity;
|
||||
let mindist = Infinity;
|
||||
poly1.forEachPoint(function(p) {
|
||||
const nextdist = p.distToPolySegments(poly2, offset);
|
||||
mindist = Math.min(mindist, nextdist);
|
||||
|
|
@ -1082,7 +1097,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function constOp(tok, consts, opch, op) {
|
||||
var pos, v1, v2;
|
||||
let pos, v1, v2;
|
||||
if ((pos = tok.indexOf(opch)) > 0) {
|
||||
v1 = consts[tok.substring(0,pos)] || 0;
|
||||
v2 = parseInt(tok.substring(pos+1)) || 0;
|
||||
|
|
@ -1093,7 +1108,7 @@ var gs_kiri_print = exports;
|
|||
}
|
||||
|
||||
function constReplace(str, consts, start) {
|
||||
var cs = str.indexOf("{", start || 0),
|
||||
let cs = str.indexOf("{", start || 0),
|
||||
ce = str.indexOf("}", cs),
|
||||
tok, nutok, nustr;
|
||||
if (cs >=0 && ce > cs) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue