checkpoint raft work

This commit is contained in:
Stewart Allen 2018-01-14 18:43:43 -05:00
commit 8b1a1fb014
4 changed files with 126 additions and 84 deletions

View file

@ -169,25 +169,123 @@ var gs_kiri_fdm = exports;
var widgets = print.widgets, var widgets = print.widgets,
settings = print.settings, settings = print.settings,
device = settings.device, device = settings.device,
nozzle = device.nozzleSize,
process = settings.process, process = settings.process,
mode = settings.mode, mode = settings.mode,
output = print.output, output = print.output,
printPoint = newPoint(0,0,0), printPoint = newPoint(0,0,0),
firstLayerHeight = process.firstSliceHeight,
maxLayers = 0, maxLayers = 0,
layer = 0, layer = 0,
zoff = 0,
mesh, mesh,
meshIndex, meshIndex,
lastIndex, lastIndex,
layerout,
closest, closest,
mindist, mindist,
minidx, minidx,
find, find,
found, found,
mslices, mslices,
slices, layerout = [],
slices = [],
sliceEntry; sliceEntry;
// create brim, skirt, raft if specificed in FDM mode (code shared by laser)
if (process.outputBrimCount || process.outputRaft) {
var brims = [];
// compute first brim
widgets.forEach(function(widget) {
var tops = [];
// collect top outer polygons
widget.slices[0].tops.forEach(function(top) {
tops.push(top.poly.clone());
});
// nest and offset tops
POLY.nest(tops).forEach(function(poly) {
poly.offset(-process.outputBrimOffset + nozzle / 2).forEach(function(brim) {
brim.move(widget.mesh.position);
brims.push(brim);
});
});
});
// merge brims
brims = POLY.union(brims);
// if brim is offset, the expand and shrink to cause brims to merge
if (process.outputBrimOffset && brims.length) {
var extra = process.sliceSupportExtra + 2;
brims = POLY.expand(brims, extra, 0, null, 1);
brims = POLY.expand(brims, -extra, 0, null, 1);
}
// if raft is specified
if (process.outputRaft) {
var offset = newPoint(0,0,0),
height = nozzle;
var raft = function(height, angle, spacing, speed, extrude) {
var slice = kiri.newSlice(zoff + height / 2);
brims.forEach(function(brim) {
var t = slice.addTop(brim);
t.traces = [ brim ];
t.inner = POLY.expand(t.traces, -nozzle * 0.5, 0, null, 1);
t.fill_lines = POLY.fillArea(t.inner, angle, spacing, []);
})
offset.z = slice.z;
printPoint = print.slicePrintPath(slice, printPoint, offset, layerout, {
speed: speed,
mult: extrude,
});
layerout.height = height;
output.append(layerout);
layerout = [];
zoff += height;
};
raft(nozzle/1, process.sliceFillAngle + 90, nozzle * 3.5, process.firstLayerRate / 3, 3.5);
raft(nozzle/1, process.sliceFillAngle + 90, nozzle * 3.5, process.firstLayerRate / 3, 3.5);
raft(nozzle/3, process.sliceFillAngle + 22.5, nozzle * 0.5, process.firstLayerRate / 1, 0.5);
raft(nozzle/3, process.sliceFillAngle + 22.5, nozzle * 0.5, process.firstLayerRate / 1, 0.5);
// raise first layer off raft slightly to lessen adhesion
firstLayerHeight += nozzle / 6;
}
// raft excludes brims
else
// if using brim vs raft
if (process.outputBrimCount) {
var polys = [],
preout = [];
// expand brims
brims.forEach(function(brim) {
POLY.trace2count(brim, polys, -nozzle, process.outputBrimCount, 0);
});
// output brim points
printPoint = print.poly2polyEmit(polys, printPoint, function(poly, index, count, startPoint) {
return print.polyPrintPath(poly, startPoint, preout, {
rate: process.firstLayerRate,
onfirst: function(point) {
if (preout.length && point.distTo2D(startPoint) > 2) {
// retract between brims
preout.last().retract = true;
}
}
});
});
print.addPrintPoints(preout, layerout, null);
if (preout.length) {
preout.last().retract = true;
}
}
}
// find max layers (for updates) // find max layers (for updates)
widgets.forEach(function(widget) { widgets.forEach(function(widget) {
maxLayers = Math.max(maxLayers, widget.slices.length); maxLayers = Math.max(maxLayers, widget.slices.length);
@ -195,9 +293,6 @@ var gs_kiri_fdm = exports;
// for each layer until no layers are found // for each layer until no layers are found
for (;;) { for (;;) {
slices = [];
layerout = [];
// create list of mesh slice arrays with their platform offsets // create list of mesh slice arrays with their platform offsets
for (meshIndex = 0; meshIndex < widgets.length; meshIndex++) { for (meshIndex = 0; meshIndex < widgets.length; meshIndex++) {
mesh = widgets[meshIndex].mesh; mesh = widgets[meshIndex].mesh;
@ -210,68 +305,6 @@ var gs_kiri_fdm = exports;
if (slices.length === 0) break; if (slices.length === 0) break;
// create brim, if specificed in FDM mode (code shared by laser)
if (layer === 0 && (process.outputBrimCount || process.outputRaft)) {
var brims = [],
polys = [],
preout = [];
// compute first brim
widgets.forEach(function(widget) {
var tops = [];
// collect top outer polygons
widget.slices[0].tops.forEach(function(top) {
tops.push(top.poly.clone());
});
// nest and offset tops
POLY.nest(tops).forEach(function(poly) {
poly.offset(-process.outputBrimOffset + device.nozzleSize/2).forEach(function(brim) {
brim.move(widget.mesh.position);
brims.push(brim);
});
});
});
// merge brims
brims = POLY.union(brims);
// if brim is offset, the expand and shrink to cause brims to merge
if (process.outputBrimOffset && brims.length) {
var extra = process.sliceSupportExtra + 2;
brims = POLY.expand(brims, extra, 0, null, 1);
brims = POLY.expand(brims, -extra, 0, null, 1);
}
// if raft is specified
if (process.outputRaft) {
console.log("output raft coming soon");
}
// if using brim vs raft
if (process.outputBrimCount) {
// expand brims
brims.forEach(function(brim) {
POLY.trace2count(brim, polys, -device.nozzleSize, process.outputBrimCount, 0);
});
// output brim points
printPoint = print.poly2polyEmit(polys, printPoint, function(poly, index, count, startPoint) {
return print.polyPrintPath(poly, startPoint, preout, {
rate: process.firstLayerRate,
onfirst: function(point) {
if (preout.length && point.distTo2D(startPoint) > 2) {
// retract between brims
preout.last().retract = true;
}
}
});
});
}
print.addPrintPoints(preout, layerout, null);
preout.last().retract = true;
}
// iterate over layer slices, find closest widget, print, eliminate // iterate over layer slices, find closest widget, print, eliminate
for (;;) { for (;;) {
found = 0; found = 0;
@ -290,21 +323,28 @@ var gs_kiri_fdm = exports;
} }
if (!closest) break; if (!closest) break;
slices[minidx] = null; slices[minidx] = null;
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
printPoint = print.slicePrintPath( printPoint = print.slicePrintPath(
closest.slice, closest.slice,
printPoint.sub(closest.offset), printPoint.sub(closest.offset),
closest.offset, closest.offset,
layerout, layerout,
// wipe after last layer or between widgets {
(found > 1 && slices.length > 1) || (found === 1 && layer == maxLayers-1) // wipe after last layer or between widgets
wipeAfter: (found > 1 && slices.length > 1) || (found === 1 && layer == maxLayers-1)
}
); );
lastIndex = minidx; lastIndex = minidx;
} }
layerout.height = layer === 0 ? firstLayerHeight : process.sliceHeight;
if (layerout.length) output.append(layerout); if (layerout.length) output.append(layerout);
layer++; layer++;
update(layer / maxLayers); update(layer / maxLayers);
slices = [];
layerout = [];
} }
}; };
@ -331,8 +371,7 @@ var gs_kiri_fdm = exports;
retracted = 0, retracted = 0,
pos = {x:0, y:0, z:0, f:0}, pos = {x:0, y:0, z:0, f:0},
last = null, last = null,
zinc = process.sliceHeight, zpos = 0,
zpos = process.firstSliceHeight,
offset = process.outputOriginCenter ? null : { offset = process.outputOriginCenter ? null : {
x: device.bedWidth/2, x: device.bedWidth/2,
y: device.bedDepth/2 y: device.bedDepth/2
@ -476,7 +515,7 @@ var gs_kiri_fdm = exports;
append(constReplace(line, { append(constReplace(line, {
progress: progress, progress: progress,
layer: layer, layer: layer,
height: zinc.toFixed(3)})); height: path.height.toFixed(3)}));
}); });
} else { } else {
append("; --- layer "+layer+" ---"); append("; --- layer "+layer+" ---");
@ -488,8 +527,8 @@ var gs_kiri_fdm = exports;
} }
// move Z to layer height // move Z to layer height
zpos += path.height;
moveTo({z:zpos}, seekMMM); moveTo({z:zpos}, seekMMM);
zpos += zinc;
// iterate through layer outputs // iterate through layer outputs
for (pidx=0; pidx<path.length; pidx++) { for (pidx=0; pidx<path.length; pidx++) {

View file

@ -472,11 +472,12 @@ var gs_kiri_print = exports;
* @param {Point} startPoint start as close as possible to startPoint * @param {Point} startPoint start as close as possible to startPoint
* @param {THREE.Vector3} offset * @param {THREE.Vector3} offset
* @param {Point[]} output points * @param {Point[]} output points
* @param {Boolean} wipeAfter so we can wipe at the end * @param {Object} [options] object
* @return {Point} last output point * @return {Point} last output point
*/ */
PRO.slicePrintPath = function(slice, startPoint, offset, output, wipeAfter) { PRO.slicePrintPath = function(slice, startPoint, offset, output, options) {
var i, var i,
opt = options || {},
preout = [], preout = [],
scope = this, scope = this,
settings = this.settings, settings = this.settings,
@ -485,14 +486,14 @@ var gs_kiri_print = exports;
firstLayer = slice.index === 0, firstLayer = slice.index === 0,
minSeek = nozzle * 1.5, minSeek = nozzle * 1.5,
thinWall = nozzle * 1.75, thinWall = nozzle * 1.75,
fillMult = process.outputFillMult, fillMult = opt.mult || process.outputFillMult,
shellMult = process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0), shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0),
sparseMult = process.outputSparseMult, sparseMult = process.outputSparseMult,
wipeDistance = process.outputWipeDistance, wipeDistance = process.outputWipeDistance,
wipeSpeed = process.outputWipeSpeed || 20, wipeSpeed = process.outputWipeSpeed || 20,
finishFactor = process.outputFinishFactor || 0, finishFactor = process.outputFinishFactor || 0,
firstSpeed = process.firstLayerRate, finishSpeed = opt.speed || process.outputFinishrate,
printSpeed = firstLayer ? firstSpeed : process.outputFeedrate, printSpeed = opt.speed || (firstLayer ? process.firstLayerRate : process.outputFeedrate),
moveSpeed = process.outputSeekrate, moveSpeed = process.outputSeekrate,
outerFirst = process.outputOuterFirst, outerFirst = process.outputOuterFirst,
origin = startPoint.add(offset), origin = startPoint.add(offset),
@ -536,7 +537,7 @@ var gs_kiri_print = exports;
} 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, {
rate: finishShell ? process.outputFinishrate : printSpeed, rate: finishShell ? finishSpeed : printSpeed,
accel: finishShell, accel: finishShell,
shorten: finishShell && !firstLayer ? nozzle * finishFactor : 0, shorten: finishShell && !firstLayer ? nozzle * finishFactor : 0,
extrude: shellMult, extrude: shellMult,
@ -744,7 +745,7 @@ var gs_kiri_print = exports;
}); });
// perform last wipe on top layer at end of run // perform last wipe on top layer at end of run
if (wipeAfter && wipe) { if (opt.wipeAfter && wipe) {
outputWipe(wipe); outputWipe(wipe);
} }

View file

@ -2401,7 +2401,6 @@ self.kiri.license = exports.LICENSE;
firstLayerRate: UC.newInput("print speed", {title:"print move max speed\nmillimeters / minute", convert:UC.toFloat, modes:FDM}), firstLayerRate: UC.newInput("print speed", {title:"print move max speed\nmillimeters / minute", convert:UC.toFloat, modes:FDM}),
outputBrimCount: UC.newInput("skirt count", {title:"number of skirts", convert:UC.toInt, modes:FDM}), outputBrimCount: UC.newInput("skirt count", {title:"number of skirts", convert:UC.toInt, modes:FDM}),
outputBrimOffset: UC.newInput("skirt offset", {title:"millimeters", convert:UC.toFloat, modes:FDM}), outputBrimOffset: UC.newInput("skirt offset", {title:"millimeters", convert:UC.toFloat, modes:FDM}),
outputRaft: UC.newBoolean("raft", onBooleanClick, {title:"create a raft under the\nmodel for better adhesion", modes:FDM}),
advanced: UC.newGroup("advanced", null, {modes:FDM}), advanced: UC.newGroup("advanced", null, {modes:FDM}),
// outputRetractOver: UC.newInput("retract over", {title:"move threshold that\ntriggers retraction\n0 to disable", convert:UC.toFloat, modes:FDM}), // outputRetractOver: UC.newInput("retract over", {title:"move threshold that\ntriggers retraction\n0 to disable", convert:UC.toFloat, modes:FDM}),
@ -2415,7 +2414,10 @@ 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", onBooleanClick, {title: "thin wall detection\nexperimental", 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.85" VERSION:"1.0.86"
}; };
if (!module) var module = {}; if (!module) var module = {};
module.exports = exports; module.exports = exports;