improve retraction

This commit is contained in:
Stewart Allen 2018-01-15 22:17:56 -05:00
commit 531fdd28d3
4 changed files with 35 additions and 41 deletions

View file

@ -262,6 +262,9 @@ var gs_kiri_fdm = exports;
// raise first layer off raft slightly to lessen adhesion // raise first layer off raft slightly to lessen adhesion
firstLayerHeight += 0.2; firstLayerHeight += 0.2;
// retract after last raft layer
output.last().last().retract = true;
} }
// raft excludes brims // raft excludes brims
else else
@ -332,6 +335,10 @@ var gs_kiri_fdm = exports;
found++; found++;
} }
if (!closest) break; if (!closest) break;
// retract between widgets
if (layerout.length && minidx !== lastIndex) {
layerout.last().retract = true;
}
slices[minidx] = null; slices[minidx] = null;
closest.offset.z = zoff; closest.offset.z = zoff;
// output seek to start point between mesh slices if previous data // output seek to start point between mesh slices if previous data
@ -340,12 +347,7 @@ var gs_kiri_fdm = exports;
printPoint.sub(closest.offset), printPoint.sub(closest.offset),
closest.offset, closest.offset,
layerout, layerout,
{ { first: closest.slice.index === 0 }
// wipe after last layer or between widgets
wipeAfter: (found > 1 && slices.length > 1) || (found === 1 && layer == maxLayers-1),
// only use first layer settings in the absence of a raft
first: closest.slice.index === 0
}
); );
lastIndex = minidx; lastIndex = minidx;
} }
@ -354,6 +356,10 @@ var gs_kiri_fdm = exports;
if (layerout.length) output.append(layerout); if (layerout.length) output.append(layerout);
layer++; layer++;
update(layer / maxLayers); update(layer / maxLayers);
// retract after last layer
if (layer === maxLayers) {
layerout.last().retract = true;
}
slices = []; slices = [];
layerout = []; layerout = [];

View file

@ -232,12 +232,13 @@ var gs_kiri_print = exports;
newout.push(newlayer); newout.push(newlayer);
layerout.forEach(function(out) { layerout.forEach(function(out) {
if (out.point) { if (out.point) {
// used for presentation only. can drop non-essential // used for renderMoves client side. can drop non-essential
// data to speed up worker -> browser transfer // data to speed up worker -> browser transfer. perhaps a
// more compact encoding (arrays, etc)
newlayer.push({ newlayer.push({
emit: out.emit, emit: out.emit,
speed: out.speed * 60, speed: out.speed * 60,
// retract: out.retract, retract: out.retract,
point: {x: out.point.x, y: out.point.y, z: out.point.z} point: {x: out.point.x, y: out.point.y, z: out.point.z}
}); });
} }
@ -481,8 +482,10 @@ var gs_kiri_print = exports;
process = settings.process, process = settings.process,
nozzle = settings.device.nozzleSize, nozzle = settings.device.nozzleSize,
firstLayer = opt.first || false, firstLayer = opt.first || false,
minSeek = nozzle * 1.5, minSeek = nozzle * (opt.minSeek || 1.5),
thinWall = nozzle * 1.75, thinWall = nozzle * (opt.thinWall || 1.75),
retractDist = opt.retractOver || 2,
retractDistSparse = opt.retractOverSparse || 5,
fillMult = opt.mult || process.outputFillMult, fillMult = opt.mult || process.outputFillMult,
shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0), shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0),
sparseMult = process.outputSparseMult, sparseMult = process.outputSparseMult,
@ -525,12 +528,12 @@ var gs_kiri_print = exports;
startPoint = preout[preout.length - 1].point; startPoint = preout[preout.length - 1].point;
} }
function outputTraces(poly, bounds, newTop) { function outputTraces(poly, bounds) {
if (!poly) return; if (!poly) return;
if (Array.isArray(poly)) { if (Array.isArray(poly)) {
outputOrderClosest(poly, function(next) { outputOrderClosest(poly, function(next) {
outputTraces(next, bounds); outputTraces(next, bounds);
}, null, newTop); }, null);
} else { } else {
var finishShell = poly.depth === 0 && !firstLayer; var finishShell = poly.depth === 0 && !firstLayer;
startPoint = scope.polyPrintPath(poly, startPoint, preout, { startPoint = scope.polyPrintPath(poly, startPoint, preout, {
@ -539,8 +542,8 @@ var gs_kiri_print = exports;
shorten: finishShell && !firstLayer ? nozzle * finishFactor : 0, shorten: finishShell && !firstLayer ? nozzle * finishFactor : 0,
extrude: shellMult, extrude: shellMult,
onfirst: function(firstPoint) { onfirst: function(firstPoint) {
if (startPoint.distTo2D(firstPoint) > 2) retract(); if (startPoint.distTo2D(firstPoint) > retractDist) retract();
checkBisect(startPoint, firstPoint, bounds); // checkBisect(startPoint, firstPoint, bounds);
} }
}); });
} }
@ -591,7 +594,8 @@ var gs_kiri_print = exports;
var poly = el.poly; var poly = el.poly;
if (poly.last() === point) poly.reverse(); if (poly.last() === point) poly.reverse();
poly.forEachPoint(function(p, i) { poly.forEachPoint(function(p, i) {
if (i === 0 && lp) checkBisect(lp, p, bounds); // if (i === 0 && lp) checkBisect(lp, p, bounds);
if (i === 0 && lp && lp.distTo2D(p) > retractDistSparse) retract();
addOutput(preout, p, i === 0 ? 0 : sparseMult, printSpeed); addOutput(preout, p, i === 0 ? 0 : sparseMult, printSpeed);
lp = p; lp = p;
}); });
@ -638,11 +642,13 @@ var gs_kiri_print = exports;
addOutput(preout, p2, fillMult * (find.d / thinWall), printSpeed); addOutput(preout, p2, fillMult * (find.d / thinWall), printSpeed);
lastout = 1; lastout = 1;
} else { } else {
if (dist > retractDist) retract();
// check for intersection with bounds and if found // check for intersection with bounds and if found
// follow the shortest path around that bounding poly // follow the shortest path around that bounding poly
if (bounds && startPoint && dist > minSeek) { // if (bounds && startPoint && dist > minSeek) {
checkBisect(startPoint, p1, bounds); // checkBisect(startPoint, p1, bounds);
} // }
// bridge ends of fill when they're close together // bridge ends of fill when they're close together
if (dist < thinWall) { if (dist < thinWall) {
@ -708,7 +714,6 @@ var gs_kiri_print = exports;
} }
var all = [].appendAll(slice.supports || []).appendAll(slice.tops || []); var all = [].appendAll(slice.supports || []).appendAll(slice.tops || []);
var wipe = null;
var lastTop = null; var lastTop = null;
outputOrderClosest(all || [], function(next) { outputOrderClosest(all || [], function(next) {
if (next instanceof Polygon) { if (next instanceof Polygon) {
@ -720,32 +725,17 @@ var gs_kiri_print = exports;
outputFills(next.fills, next.inner); outputFills(next.fills, next.inner);
} }
} else { } else {
// when skipping between tops, first perform a wipe
if (lastTop && wipe) {
outputWipe(wipe);
wipe = null;
}
// top object // top object
var bounds = POLY.flatten(next.gatherOuter([])); var bounds = POLY.flatten(next.gatherOuter([]));
outputTraces([].appendAll(next.traces).appendAll(next.innerTraces() || []), bounds, !lastTop); outputTraces([].appendAll(next.traces).appendAll(next.innerTraces() || []), bounds);
outputFills(next.fill_lines, bounds); outputFills(next.fill_lines, bounds);
outputSparse(next.fill_sparse, bounds); outputSparse(next.fill_sparse, bounds);
if (next.inner) {
wipe = next.inner.last();
} else {
wipe = next.traces.last();
}
lastTop = next; lastTop = next;
} }
}, function(obj) { }, function(obj) {
return obj instanceof Polygon ? obj : obj.poly; return obj instanceof Polygon ? obj : obj.poly;
}); });
// perform last wipe on top layer at end of run
if (opt.wipeAfter && wipe) {
outputWipe(wipe);
}
// offset print points // offset print points
for (i=0; i<preout.length; i++) { for (i=0; i<preout.length; i++) {
preout[i].point = preout[i].point.add(offset); preout[i].point = preout[i].point.add(offset);

View file

@ -2368,6 +2368,7 @@ self.kiri.license = exports.LICENSE;
outputFillMult: UC.newInput("solid factor", {title:"extrusion multiplier\n0.0 - 2.0", convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}), outputFillMult: UC.newInput("solid factor", {title:"extrusion multiplier\n0.0 - 2.0", convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
outputSparseMult: UC.newInput("infill factor", {title:"extrusion multiplier\n0.0 - 2.0", convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}), outputSparseMult: UC.newInput("infill factor", {title:"extrusion multiplier\n0.0 - 2.0", convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
outputCooling: UC.newBoolean("cooling", onBooleanClick, {title: "enable cooling fan\nafter first layer", modes:FDM}), outputCooling: UC.newBoolean("cooling", onBooleanClick, {title: "enable cooling fan\nafter first layer", modes:FDM}),
outputRaft: UC.newBoolean("raft layer", onBooleanClick, {title:"create a raft under the\nmodel for better adhesion\nuses skirt offset and\ndisables skirt output", modes:FDM}),
// cam // cam
camTolerance: UC.newInput("tolerance", {title:"surface precision\nin millimeters", convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:CAM}), camTolerance: UC.newInput("tolerance", {title:"surface precision\nin millimeters", convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:CAM}),
@ -2414,10 +2415,7 @@ self.kiri.license = exports.LICENSE;
outputShortFactor: UC.newInput("short factor", {title:"max speed reduction factor\nfor short segments\nas % of print speed", bound:UC.bound(0.05,1), convert:UC.toFloat, modes:FDM}), outputShortFactor: UC.newInput("short factor", {title:"max speed reduction factor\nfor short segments\nas % of print speed", bound:UC.bound(0.05,1), convert:UC.toFloat, modes:FDM}),
outputFinishFactor: UC.newInput("finish factor", {title:"% of nozzle diameter to\nshorten finish path by\nvalues of 0-1", bound:UC.bound(0.0,1), convert:UC.toFloat, modes:FDM}), outputFinishFactor: UC.newInput("finish factor", {title:"% of nozzle diameter to\nshorten finish path by\nvalues of 0-1", bound:UC.bound(0.0,1), convert:UC.toFloat, modes:FDM}),
outputOuterFirst: UC.newBoolean("outer first", onBooleanClick, {title: "output outermost shell first", modes:FDM}), outputOuterFirst: UC.newBoolean("outer first", onBooleanClick, {title: "output outermost shell first", modes:FDM}),
detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM})
experimental: UC.newGroup("experimental", null, {modes:FDM}),
detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM}),
outputRaft: UC.newBoolean("raft layer", onBooleanClick, {title:"create a raft under the\nmodel for better adhesion\nuses skirt offset and\ndisables skirt output", modes:FDM})
}); });
function toolUpdate(a,b,c) { function toolUpdate(a,b,c) {

View file

@ -1,7 +1,7 @@
var exports = { var exports = {
COPYRIGHT:"Copyright (C) 2014-2017 Stewart Allen <stewart@neuron.com> - All Rights Reserved", COPYRIGHT:"Copyright (C) 2014-2017 Stewart Allen <stewart@neuron.com> - All Rights Reserved",
LICENSE:"Unauthorized copying, modification and re-distribution are strictly prohibited without prior written consent.", LICENSE:"Unauthorized copying, modification and re-distribution are strictly prohibited without prior written consent.",
VERSION:"1.0.86" VERSION:"1.0.87"
}; };
if (!module) var module = {}; if (!module) var module = {};
module.exports = exports; module.exports = exports;