add adaptive layer heights
This commit is contained in:
parent
6c90b4fff0
commit
4d49d0a7af
5 changed files with 69 additions and 26 deletions
|
|
@ -41,16 +41,15 @@ var gs_kiri_fdm = exports;
|
||||||
*/
|
*/
|
||||||
FDM.slice = function(settings, widget, onupdate, ondone) {
|
FDM.slice = function(settings, widget, onupdate, ondone) {
|
||||||
var spro = settings.process,
|
var spro = settings.process,
|
||||||
spri = settings.device,
|
sdev = settings.device,
|
||||||
sout = settings.process,
|
|
||||||
update_start = time(),
|
update_start = time(),
|
||||||
minSolid = spro.sliceSolidMinArea,
|
minSolid = spro.sliceSolidMinArea,
|
||||||
solidLayers = spro.sliceSolidLayers,
|
solidLayers = spro.sliceSolidLayers,
|
||||||
doSolidLayers = solidLayers && !spro.sliceVase,
|
doSolidLayers = solidLayers && !spro.sliceVase,
|
||||||
firstOffset = spri.nozzleSize / 2,
|
firstOffset = sdev.nozzleSize / 2,
|
||||||
shellOffset = spri.nozzleSize * spro.sliceShellSpacing,
|
shellOffset = sdev.nozzleSize * spro.sliceShellSpacing,
|
||||||
fillOffset = shellOffset * settings.synth.fillOffsetMult,
|
fillOffset = shellOffset * settings.synth.fillOffsetMult,
|
||||||
fillSpacing = spri.nozzleSize * spro.sliceFillSpacing,
|
fillSpacing = sdev.nozzleSize * spro.sliceFillSpacing,
|
||||||
sliceFillAngle = spro.sliceFillAngle,
|
sliceFillAngle = spro.sliceFillAngle,
|
||||||
view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null;
|
view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null;
|
||||||
|
|
||||||
|
|
@ -66,8 +65,9 @@ var gs_kiri_fdm = exports;
|
||||||
|
|
||||||
SLICER.sliceWidget(widget, {
|
SLICER.sliceWidget(widget, {
|
||||||
height: spro.sliceHeight,
|
height: spro.sliceHeight,
|
||||||
view:view,
|
minHeight: spro.sliceMinHeight,
|
||||||
firstHeight: sout.firstSliceHeight
|
firstHeight: spro.firstSliceHeight,
|
||||||
|
view: view
|
||||||
}, onSliceDone, onSliceUpdate);
|
}, onSliceDone, onSliceUpdate);
|
||||||
|
|
||||||
function onSliceUpdate(update) {
|
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);
|
slice.doSupport(spro.sliceSupportOffset, spro.sliceSupportSpan, spro.sliceSupportExtra, supportMinArea, spro.sliceSupportSize, spro.sliceSupportOffset, spro.sliceSupportGap);
|
||||||
}, "support");
|
}, "support");
|
||||||
forSlices(0.7, 0.8, function(slice) {
|
forSlices(0.7, 0.8, function(slice) {
|
||||||
slice.doSupportFill(spri.nozzleSize, spro.sliceSupportDensity, supportMinArea);
|
slice.doSupportFill(sdev.nozzleSize, spro.sliceSupportDensity, supportMinArea);
|
||||||
}, "support");
|
}, "support");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,12 +102,15 @@ var gs_kiri_slicer = exports;
|
||||||
var zMin = options.zmin || Math.floor(bounds.min.z),
|
var zMin = options.zmin || Math.floor(bounds.min.z),
|
||||||
zMax = options.zmax || Math.ceil(bounds.max.z),
|
zMax = options.zmax || Math.ceil(bounds.max.z),
|
||||||
zInc = options.height,
|
zInc = options.height,
|
||||||
|
zIncMin = options.minHeight,
|
||||||
|
zIncFirst = options.firstHeight || zInc,
|
||||||
zOff = true ? zInc / 2 : 0,
|
zOff = true ? zInc / 2 : 0,
|
||||||
|
zHeights = [], // heights for zIndexes in adaptive mode
|
||||||
zIndexes = [], // auto-detected z slicing offsets (laser/cam)
|
zIndexes = [], // auto-detected z slicing offsets (laser/cam)
|
||||||
|
zOrdered = [], // ordered list of Z vertices
|
||||||
zList = {}, // list of z indices for auto slicing (laser)
|
zList = {}, // list of z indices for auto slicing (laser)
|
||||||
zFlat = {}, // area of z offset flat areas (cam)
|
zFlat = {}, // area of z offset flat areas (cam)
|
||||||
zScale, // bucket span in z units
|
zScale, // bucket span in z units
|
||||||
zPos,
|
|
||||||
timeStart = time(),
|
timeStart = time(),
|
||||||
slices = [],
|
slices = [],
|
||||||
zSum = 0.0,
|
zSum = 0.0,
|
||||||
|
|
@ -129,7 +132,7 @@ var gs_kiri_slicer = exports;
|
||||||
p3 = points[i++];
|
p3 = points[i++];
|
||||||
zSum += (Math.abs(p1.z - p2.z) + Math.abs(p2.z - p3.z) + Math.abs(p3.z - p1.z));
|
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
|
// laser auto-detect z slice points
|
||||||
if (zInc === 0) {
|
if (zInc === 0 || zIncMin) {
|
||||||
countZ(p1.z);
|
countZ(p1.z);
|
||||||
countZ(p2.z);
|
countZ(p2.z);
|
||||||
countZ(p3.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) {
|
if (zInc === 0) {
|
||||||
// find unique z-index offsets for slicing
|
// find unique z-index offsets for slicing
|
||||||
var key, zl = [];
|
var zl = zOrdered
|
||||||
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++) {
|
for (i = 0; i < zl.length - 1; i++) {
|
||||||
zIndexes.push((zl[i] + zl[i+1]) / 2);
|
zIndexes.push((zl[i] + zl[i+1]) / 2);
|
||||||
}
|
}
|
||||||
zIndexes.sort(function(a,b) { return a - b});
|
|
||||||
} else if (options.cam) {
|
} else if (options.cam) {
|
||||||
// re-divide slice height so that top and
|
// re-divide slice height so that top and
|
||||||
// bottom slices fall exactly on those faces
|
// bottom slices fall exactly on those faces
|
||||||
|
|
@ -202,6 +208,40 @@ var gs_kiri_slicer = exports;
|
||||||
zIndexes.sort(function(a,b) {
|
zIndexes.sort(function(a,b) {
|
||||||
return b-a;
|
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 {
|
} else {
|
||||||
// FDM is the simplest case. Just offset and slice at
|
// FDM is the simplest case. Just offset and slice at
|
||||||
// predicable offsets.
|
// predicable offsets.
|
||||||
|
|
@ -216,8 +256,8 @@ var gs_kiri_slicer = exports;
|
||||||
|
|
||||||
// create a Slice for each z offset in the zIndexes array
|
// create a Slice for each z offset in the zIndexes array
|
||||||
for (var i = 0; i < zIndexes.length; i++) {
|
for (var i = 0; i < zIndexes.length; i++) {
|
||||||
zPos = zIndexes[i];
|
// mark the slice height
|
||||||
sliceZ(zPos);
|
sliceZ(zIndexes[i], zHeights[i]);
|
||||||
// kill slicing if onupdate() returns 42
|
// kill slicing if onupdate() returns 42
|
||||||
if (onupdate(i / zIndexes.length) === 42) {
|
if (onupdate(i / zIndexes.length) === 42) {
|
||||||
return ondone(null);
|
return ondone(null);
|
||||||
|
|
@ -319,8 +359,9 @@ var gs_kiri_slicer = exports;
|
||||||
* add to slices array
|
* add to slices array
|
||||||
*
|
*
|
||||||
* @param {number} z
|
* @param {number} z
|
||||||
|
* @param {number} [height] optional real height (fdm)
|
||||||
*/
|
*/
|
||||||
function sliceZ(z) {
|
function sliceZ(z, height) {
|
||||||
z = UTIL.round(z,5);
|
z = UTIL.round(z,5);
|
||||||
|
|
||||||
// avoid slicing directly on flat faces as it greatly increases
|
// 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)
|
// allow empty slices in CAM swap mode (for topos w/ gaps)
|
||||||
if (lines.length == 0 && !(options.swapX || options.swapY)) return;
|
if (lines.length == 0 && !(options.swapX || options.swapY)) return;
|
||||||
|
|
||||||
|
slice.height = height || z;
|
||||||
slice.index = slices.length;
|
slice.index = slices.length;
|
||||||
slice.lines = removeDuplicateLines(lines);
|
slice.lines = removeDuplicateLines(lines);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ self.kiri.license = exports.LICENSE;
|
||||||
outputShortDistance: 1,
|
outputShortDistance: 1,
|
||||||
outputShortFactor: 1,
|
outputShortFactor: 1,
|
||||||
outputFinishFactor: 1,
|
outputFinishFactor: 1,
|
||||||
|
sliceMinHeight: 1,
|
||||||
outputCooling: 1,
|
outputCooling: 1,
|
||||||
// detectThinWalls: 1,
|
// detectThinWalls: 1,
|
||||||
antiBacklash: 1,
|
antiBacklash: 1,
|
||||||
|
|
@ -308,6 +309,7 @@ self.kiri.license = exports.LICENSE;
|
||||||
outputShortDistance: 0.0,
|
outputShortDistance: 0.0,
|
||||||
outputShortFactor: 0.2,
|
outputShortFactor: 0.2,
|
||||||
outputFinishFactor: 0,
|
outputFinishFactor: 0,
|
||||||
|
sliceMinHeight: 0,
|
||||||
detectThinWalls: false,
|
detectThinWalls: false,
|
||||||
antiBacklash: 2,
|
antiBacklash: 2,
|
||||||
zHopDistance: 0,
|
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}),
|
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}),
|
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}),
|
||||||
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}),
|
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})
|
//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}),
|
gcodeVars: UC.newGroup("gcode", null, {modes:FDM}),
|
||||||
|
|
|
||||||
|
|
@ -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.1.7"
|
VERSION:"1.1.8"
|
||||||
};
|
};
|
||||||
if (!module) var module = {};
|
if (!module) var module = {};
|
||||||
module.exports = exports;
|
module.exports = exports;
|
||||||
|
|
|
||||||
2
notes.md
2
notes.md
|
|
@ -59,8 +59,6 @@
|
||||||
|
|
||||||
# FDM todo
|
# FDM todo
|
||||||
|
|
||||||
* adaptive layer heights
|
|
||||||
* preview doesn't show proper z offsets
|
|
||||||
* trim support offset from layer below
|
* trim support offset from layer below
|
||||||
* feather sharp tips by reducing extrusion in area of overlap
|
* feather sharp tips by reducing extrusion in area of overlap
|
||||||
* add option to reduce poly speed to match shortest/slowest segment
|
* add option to reduce poly speed to match shortest/slowest segment
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue