add adaptive layer heights

This commit is contained in:
Stewart Allen 2018-03-06 20:57:26 -05:00
commit 4d49d0a7af
5 changed files with 69 additions and 26 deletions

View file

@ -41,16 +41,15 @@ var gs_kiri_fdm = exports;
*/
FDM.slice = function(settings, widget, onupdate, ondone) {
var spro = settings.process,
spri = settings.device,
sout = settings.process,
sdev = settings.device,
update_start = time(),
minSolid = spro.sliceSolidMinArea,
solidLayers = spro.sliceSolidLayers,
doSolidLayers = solidLayers && !spro.sliceVase,
firstOffset = spri.nozzleSize / 2,
shellOffset = spri.nozzleSize * spro.sliceShellSpacing,
firstOffset = sdev.nozzleSize / 2,
shellOffset = sdev.nozzleSize * spro.sliceShellSpacing,
fillOffset = shellOffset * settings.synth.fillOffsetMult,
fillSpacing = spri.nozzleSize * spro.sliceFillSpacing,
fillSpacing = sdev.nozzleSize * spro.sliceFillSpacing,
sliceFillAngle = spro.sliceFillAngle,
view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null;
@ -66,8 +65,9 @@ var gs_kiri_fdm = exports;
SLICER.sliceWidget(widget, {
height: spro.sliceHeight,
view:view,
firstHeight: sout.firstSliceHeight
minHeight: spro.sliceMinHeight,
firstHeight: spro.firstSliceHeight,
view: view
}, onSliceDone, onSliceUpdate);
function onSliceUpdate(update) {
@ -142,7 +142,7 @@ var gs_kiri_fdm = exports;
slice.doSupport(spro.sliceSupportOffset, spro.sliceSupportSpan, spro.sliceSupportExtra, supportMinArea, spro.sliceSupportSize, spro.sliceSupportOffset, spro.sliceSupportGap);
}, "support");
forSlices(0.7, 0.8, function(slice) {
slice.doSupportFill(spri.nozzleSize, spro.sliceSupportDensity, supportMinArea);
slice.doSupportFill(sdev.nozzleSize, spro.sliceSupportDensity, supportMinArea);
}, "support");
}

View file

@ -102,12 +102,15 @@ var gs_kiri_slicer = exports;
var zMin = options.zmin || Math.floor(bounds.min.z),
zMax = options.zmax || Math.ceil(bounds.max.z),
zInc = options.height,
zIncMin = options.minHeight,
zIncFirst = options.firstHeight || zInc,
zOff = true ? zInc / 2 : 0,
zHeights = [], // heights for zIndexes in adaptive mode
zIndexes = [], // auto-detected z slicing offsets (laser/cam)
zOrdered = [], // ordered list of Z vertices
zList = {}, // list of z indices for auto slicing (laser)
zFlat = {}, // area of z offset flat areas (cam)
zScale, // bucket span in z units
zPos,
timeStart = time(),
slices = [],
zSum = 0.0,
@ -129,7 +132,7 @@ var gs_kiri_slicer = exports;
p3 = points[i++];
zSum += (Math.abs(p1.z - p2.z) + Math.abs(p2.z - p3.z) + Math.abs(p3.z - p1.z));
// laser auto-detect z slice points
if (zInc === 0) {
if (zInc === 0 || zIncMin) {
countZ(p1.z);
countZ(p2.z);
countZ(p3.z);
@ -172,19 +175,22 @@ var gs_kiri_slicer = exports;
}
}
// create zIndexes array (0 = auto-detect)
// we need Z ordered list for laser auto or adaptive fdm slicing
if (zInc === 0 || zIncMin) {
for (var key in zList) {
if (!zList.hasOwnProperty(key)) continue;
zOrdered.push(parseFloat(key));
}
zOrdered.sort(function(a,b) { return a - b});
}
// use Z indices in auto slice mode for laser
if (zInc === 0) {
// find unique z-index offsets for slicing
var key, zl = [];
for (key in zList) {
if (!zList.hasOwnProperty(key)) continue;
zl.push(parseFloat(key));
}
zl.sort(function(a,b) { return a - b});
for (i = 0; i < zl.length-1; i++) {
var zl = zOrdered
for (i = 0; i < zl.length - 1; i++) {
zIndexes.push((zl[i] + zl[i+1]) / 2);
}
zIndexes.sort(function(a,b) { return a - b});
} else if (options.cam) {
// re-divide slice height so that top and
// bottom slices fall exactly on those faces
@ -202,6 +208,40 @@ var gs_kiri_slicer = exports;
zIndexes.sort(function(a,b) {
return b-a;
});
} else if (zIncMin) {
var zPos = zMin + zIncFirst,
zOI = 0,
zDelta,
zDivMin,
zDivMax,
zStep,
nextZ;
// first slice is fixed
zHeights.push(zPos);
zIndexes.push(zIncFirst / 2);
while (zPos < zMax && zOI < zOrdered.length) {
nextZ = zOrdered[zOI++];
if (zPos >= nextZ) continue;
zDelta = nextZ - zPos;
if (zDelta < zIncMin) continue;
zDivMin = Math.floor(zDelta / zIncMin);
zDivMax = Math.floor(zDelta / zInc);
if (zDivMax) {
zStep = zDelta / (zDivMax + 1);
} else {
zStep = zDelta;
}
while (zPos < nextZ) {
zHeights.push(zPos + zStep);
zIndexes.push(zPos + zStep / 2);
zPos += zStep;
}
}
} else {
// FDM is the simplest case. Just offset and slice at
// predicable offsets.
@ -216,8 +256,8 @@ var gs_kiri_slicer = exports;
// create a Slice for each z offset in the zIndexes array
for (var i = 0; i < zIndexes.length; i++) {
zPos = zIndexes[i];
sliceZ(zPos);
// mark the slice height
sliceZ(zIndexes[i], zHeights[i]);
// kill slicing if onupdate() returns 42
if (onupdate(i / zIndexes.length) === 42) {
return ondone(null);
@ -319,8 +359,9 @@ var gs_kiri_slicer = exports;
* add to slices array
*
* @param {number} z
* @param {number} [height] optional real height (fdm)
*/
function sliceZ(z) {
function sliceZ(z, height) {
z = UTIL.round(z,5);
// avoid slicing directly on flat faces as it greatly increases
@ -378,6 +419,7 @@ var gs_kiri_slicer = exports;
// allow empty slices in CAM swap mode (for topos w/ gaps)
if (lines.length == 0 && !(options.swapX || options.swapY)) return;
slice.height = height || z;
slice.index = slices.length;
slice.lines = removeDuplicateLines(lines);

View file

@ -97,6 +97,7 @@ self.kiri.license = exports.LICENSE;
outputShortDistance: 1,
outputShortFactor: 1,
outputFinishFactor: 1,
sliceMinHeight: 1,
outputCooling: 1,
// detectThinWalls: 1,
antiBacklash: 1,
@ -308,6 +309,7 @@ self.kiri.license = exports.LICENSE;
outputShortDistance: 0.0,
outputShortFactor: 0.2,
outputFinishFactor: 0,
sliceMinHeight: 0,
detectThinWalls: false,
antiBacklash: 2,
zHopDistance: 0,
@ -2511,8 +2513,9 @@ self.kiri.license = exports.LICENSE;
outputShortDistance: UC.newInput("short segment", {title:"segment length cutoff\nfor short segments\nin millimeters", bound:UC.bound(0,200), 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}),
antiBacklash: UC.newInput("anti-backlash", {title: "use micro-movements to cancel\nbacklash during fills\nin millimeters", bound:UC.bound(0,3), convert:UC.toInt, modes:FDM}),
sliceMinHeight: UC.newInput("min layer", {title: "enables adaptive slicing with\nthis as the min layer height\nin millimeters\n0 to disable", bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM}),
zHopDistance: UC.newInput("z hop dist", {title: "amount to raise z\non retraction moves\nin millimeters\n0 to disable", bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM}),
antiBacklash: UC.newInput("anti-backlash", {title: "use micro-movements to cancel\nbacklash during fills\nin millimeters", bound:UC.bound(0,3), convert:UC.toInt, modes:FDM}),
//detectThinWalls: UC.newBoolean("thin wall fill", onBooleanClick, {title: "detect and fill thin openings\nbetween shells walls", modes:FDM})
gcodeVars: UC.newGroup("gcode", null, {modes:FDM}),

View file

@ -1,7 +1,7 @@
var exports = {
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.",
VERSION:"1.1.7"
VERSION:"1.1.8"
};
if (!module) var module = {};
module.exports = exports;

View file

@ -59,8 +59,6 @@
# FDM todo
* adaptive layer heights
* preview doesn't show proper z offsets
* trim support offset from layer below
* feather sharp tips by reducing extrusion in area of overlap
* add option to reduce poly speed to match shortest/slowest segment