diff --git a/js/geo-point.js b/js/geo-point.js index 8b69e45b..c561beea 100644 --- a/js/geo-point.js +++ b/js/geo-point.js @@ -227,9 +227,8 @@ var gs_base_point = exports; }; /** - * return a point along the line this from point to p2 - * but offset by a distance. positive distances are - * closer to this point. + * return a point along the line this from point to p2 offset + * by a distance. positive distances are closer to this point. * * @param p2 * @param dist @@ -244,6 +243,23 @@ var gs_base_point = exports; return newPoint(p2.x - ox, p2.y - oy, p2.z, KEYS.NONE); }; + /** + * return a point along the line this from point to p2 offset + * by a distance. positive distances are farther from this point. + * + * @param p2 + * @param dist + */ + PRO.offsetPointTo = function(p2, dist) { + var p1 = this, + dx = p2.x - p1.x, + dy = p2.y - p1.y, + ls = dist / Math.sqrt(dx * dx + dy * dy), + ox = dx * ls, + oy = dy * ls; + return newPoint(p1.x + ox, p1.y + oy, p2.z, KEYS.NONE); + }; + /** * @param {Point} p2 * @param {number} offset @@ -263,7 +279,6 @@ var gs_base_point = exports; return BASE.newLine(np1, np2, KEYS.NONE); }; - /** * checks if a point is inside of a polygon * does not check children/holes diff --git a/js/kiri-driver-fdm.js b/js/kiri-driver-fdm.js index 686fdbf0..8e5c85e8 100644 --- a/js/kiri-driver-fdm.js +++ b/js/kiri-driver-fdm.js @@ -218,7 +218,9 @@ var gs_kiri_fdm = exports; }); printPoint = print.poly2polyEmit(polys, printPoint, function(poly, index, count, startPoint) { - return print.polyPrintPath(poly, startPoint, preout); + return print.polyPrintPath(poly, startPoint, preout, { + rate: process.firstLayerSpeed * process.outputFeedrate + }); }); print.addPrintPoints(preout, layerout, startPoint); @@ -260,7 +262,6 @@ var gs_kiri_fdm = exports; process = settings.process, fan_power = device.gcodeFan, trackProgress = device.gcodeTrack, - layer1speed = process.firstLayerSpeed, time = 0, layer = 0, output = [], @@ -291,12 +292,7 @@ var gs_kiri_fdm = exports; bottom: offset ? 0 : -device.bedDepth/2, z_max: device.maxHeight }, - shortDist = process.outputShortDistance, - shortFact = process.outputShortFactor, - glideBridgeDist = device.nozzleSize * 2, - maxPrintMMM = process.outputFeedrate * 60, seekMMM = process.outputSeekrate * 60, - retOver = process.outputRetractOver, retDist = process.outputRetractDist, retSpeed = process.outputRetractSpeed * 60, // ratio of nozzle area to filament area times @@ -304,7 +300,7 @@ var gs_kiri_fdm = exports; emitPerMM = print.extrudePerMM(device.nozzleSize, device.filamentSize, process.sliceHeight), emitPerMMLayer1 = print.extrudePerMM(device.nozzleSize, device.filamentSize, process.sliceHeight * process.firstLayerHeight), constReplace = print.constReplace, - pidx, path, out, lastp, laste, dist, printMMM, shortMMM, + pidx, path, out, speedMMM, emitMM, lastp, laste, dist, appendAll = function(arr) { arr.forEach(function(line) { append(line) }); }, @@ -399,24 +395,27 @@ var gs_kiri_fdm = exports; layers.forEach(function(outs) { allout.appendAll(outs) }); allout.forEachPair(function (o1, o2) { totaldistance += o1.point.distTo2D(o2.point); - },1); + }, 1); while (layer < layers.length) { - append("; --- layer "+layer+" ---"); - // second layer fan on - if (layer === 1 && fan_power) append(constReplace(fan_power,consts)); - shortMMM = shortFact * maxPrintMMM; - printMMM = maxPrintMMM; - // first layer 50% underspeed - if (layer === 0) { - printMMM *= layer1speed; - shortMMM *= layer1speed; - } path = layers[layer]; - moveTo({z:zpos}, seekMMM); + + append("; --- layer "+layer+" ---"); + + // second layer fan on + if (layer === 1 && fan_power) { + append(constReplace(fan_power,consts)); + } + + // move up to next layer + if (layer > 0) moveTo({z:zpos}, seekMMM); zpos += zinc; + + // iterate through layer outputs for (pidx=0; pidx 0 && dist < shortDist) { - outMMM = shortMMM + ((outMMM - shortMMM) * (dist / shortDist)); - } else { - // approximate compensation for acceleration & deceleration - time += (shortDist * 2) / outMMM / 10 * 60; - } - // print time - time += (dist / outMMM) * 60; - moveTo({x:x, y:y, e:emitMM}, outMMM); + emitMM = (layer === 0 ? emitPerMMLayer1 : emitPerMM) * out.emit * dist; + moveTo({x:x, y:y, e:emitMM}, speedMMM); emitted += emitMM; } else { - var moveMMM = seekMMM; - // usually wipe speed override - if (out.speed) { - moveMMM = out.speed * 60; - } if (!retracted && out.retract) { retracted = retDist; moveTo({e:-retracted}, retSpeed, "retract (ooze control)"); - moveTo({x:x, y:y}, moveMMM); - } else if (lastp && dist <= glideBridgeDist) { - // connect ends of infill - var e = (layer === 0 ? emitPerMMLayer1 : emitPerMM) * dist; - moveTo({x:x, y:y, e:e}, outMMM); + moveTo({x:x, y:y}, speedMMM); + time += (retDist / retSpeed) * 60 * 2; // retraction time } else { - moveTo({x:x, y:y}, moveMMM); + moveTo({x:x, y:y}, speedMMM); } - time += (dist / moveMMM) * 60; // seek distance - time += (retDist / retSpeed) * 60 * 2; // retraction time - // approximate compensation for acceleration & deceleration - time += (shortDist * 2) / moveMMM / 10 * 60; } - lastp = out.point; - laste = out.emit; + + // update time and distance + time += (dist / speedMMM) * 60; + distance += dist; + progress = Math.round((distance / totaldistance) * 100); + // emit tracked progress if (trackProgress && progress != lastProgress) { append(constReplace(trackProgress, {progress:progress})); lastProgress = progress; } + + lastp = out.point; + laste = out.emit; } layer++; } diff --git a/js/kiri-driver-laser.js b/js/kiri-driver-laser.js index 9e5ed2ba..584a10bf 100644 --- a/js/kiri-driver-laser.js +++ b/js/kiri-driver-laser.js @@ -56,7 +56,7 @@ var gs_kiri_laser = exports; laserOut(pi, object); }); } else { - print.polyPrintPath(poly, start, object, 1); + print.polyPrintPath(poly, start, object, {extrude: 1}); } } diff --git a/js/kiri-print.js b/js/kiri-print.js index 35743ccc..b3412a7e 100644 --- a/js/kiri-print.js +++ b/js/kiri-print.js @@ -222,7 +222,7 @@ var gs_kiri_print = exports; // data to speed up worker -> browser transfer newlayer.push({ emit: out.emit, - speed: out.speed, + speed: out.speed * 60, // retract: out.retract, point: {x: out.point.x, y: out.point.y, z: out.point.z} }); @@ -366,7 +366,7 @@ var gs_kiri_print = exports; * @param {Point} point * @param {number} emit (0=move, !0=filament emit/laser on/cut mode) * @param {number} [speed] speed - * @param {number} [tool] tool + * @param {number} [tool] tool # or nozzle # */ function addOutput(array, point, emit, speed, tool) { // drop duplicates (usually intruced by FDM bisections) @@ -381,6 +381,18 @@ var gs_kiri_print = exports; array.push(new Output(point, emit, speed, tool)); } + 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; + while (steps-- > 0) { + spd += sd; + p1 = p1.offsetPointTo(p2, dd); + addOutput(output, p1, mult, spd); + } + } + /** * FDM only. add points in polygon to an output array (print path) * @@ -391,27 +403,50 @@ 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, extrude, onfirst) { + PRO.polyPrintPath = function(poly, startPoint, output, options) { poly.setClockwise(); - var closest = poly.findClosestPointTo(startPoint), + var options = options || {}, + process = this.settings.process, + shortDist = process.outputShortDistance, + shortFact = process.outputShortFactor, + shellMult = options.extrude || process.outputShellMult, + printSpeed = options.rate || process.outputFeedrate, + shortSpeed = printSpeed * shortFact, + moveSpeed = process.outputSeekrate, + closest = poly.findClosestPointTo(startPoint), first = true, - settings = this.settings, - shellMult = extrude || settings.process.outputShellMult, - shellSpeed = settings.process.outputFinishrate || 0; + last = startPoint; - poly.forEachPoint(function(point) { + poly.forEachPoint(function(point, pos, points, count) { if (first) { - if (onfirst) onfirst(point); + if (options.onfirst) options.onfirst(point); // move from startPoint to point - addOutput(output, point, 0, 0); + addOutput(output, point, 0, moveSpeed); first = false; } else { - addOutput(output, point, shellMult, poly.depth == 0 ? shellSpeed : 0); + var dist = last.distTo2D(point); + if (options.shorten && dist > options.shorten && count === points.length) { + point = last.offsetPointFrom(point, options.shorten); + } + if (options.accel && dist >= options.accel) { + var p2 = last.offsetPointTo(point, shortDist), + p3 = last.offsetPointFrom(point, shortDist); + segmentOutput(output, last, p2, shortSpeed, printSpeed, 5, shellMult); + addOutput(output, p3, shellMult, printSpeed); + segmentOutput(output, p3, point, printSpeed, shortSpeed, 5, shellMult); + } else + if (shortDist && dist < shortDist) { + var shortRate = shortSpeed + (printSpeed - shortSpeed) * (dist / shortDist); + addOutput(output, point, shellMult, shortRate); + } else { + addOutput(output, point, shellMult, printSpeed); + } } + last = point; }, true, closest.index); - return output[output.length - 1].point; + return output.last().point; }; /** @@ -439,6 +474,9 @@ var gs_kiri_print = exports; sparseMult = process.outputSparseMult, wipeDistance = process.outputWipeDistance, wipeSpeed = process.outputWipeSpeed || 20, + firstSpeed = process.firstLayerSpeed * process.outputFeedrate, + printSpeed = slice.index === 0 ? firstSpeed : process.outputFeedrate, + moveSpeed = process.outputSeekrate, origin = startPoint.add(offset), z = slice.z; @@ -447,15 +485,14 @@ var gs_kiri_print = exports; } function outputWipe(poly) { - if (!poly) return; + if (!poly || !wipeDistance) return; var closest = poly.findClosestPointTo(startPoint), distance = wipeDistance, last = startPoint, steps = 0; - if (!distance) return; - + retract(); while (distance > 0) poly.forEachPoint(function(point) { if (distance > 0) { var len = last.distTo2D(point); @@ -467,7 +504,7 @@ var gs_kiri_print = exports; distance -= last.distTo2D(point); } last = point; - if (steps++ === 0) retract(); + // if (steps++ === 0) retract(); } }, true, closest.index); @@ -483,15 +520,22 @@ var gs_kiri_print = exports; lastPoly = next; }); } else { - startPoint = scope.polyPrintPath(poly, startPoint, preout, shellMult, function(point) { - if (startPoint.distTo2D(point) > fillSkip) { - if (last) { - outputWipe(last) - } else { - retract(); - } + var finishShell = poly.depth === 0 && slice.index > 0; + startPoint = scope.polyPrintPath(poly, startPoint, preout, { + rate: finishShell ? process.outputFinishrate : printSpeed, + accel: finishShell ? process.outputShortDistance * 2 : 0, + shorten: finishShell ? nozzle / 2 : 0, + extrude: shellMult, + onfirst: function(firstPoint) { + // if (startPoint.distTo2D(firstPoint) > fillSkip) { + // if (last) { + // outputWipe(last) + // } else { + // retract(); + // } + // } + checkBisect(startPoint, firstPoint, bounds); } - checkBisect(startPoint, point, bounds); }); } } @@ -523,7 +567,7 @@ var gs_kiri_print = exports; // output non-printing bisecting paths routes.forEach(function(path) { path.forEachPoint(function(p) { - addOutput(preout, p, 0); + addOutput(preout, p, 0, moveSpeed); }); }); } @@ -542,14 +586,14 @@ var gs_kiri_print = exports; if (poly.last() === point) poly.reverse(); poly.forEachPoint(function(p, i) { if (i === 0 && lp) checkBisect(lp, p, bounds); - addOutput(preout, p, i === 0 ? 0 : sparseMult); + addOutput(preout, p, i === 0 ? 0 : sparseMult, printSpeed); lp = p; }); }); } function outputFills(lines, bounds) { - var mindist, p1, p2, dist, point, find, find2, list, len, lastout, pass = 0; + var mindist, p1, p2, dist, point, find, list, len, lastout, pass = 0; while (lines) { list = []; mindist = Infinity; @@ -563,12 +607,6 @@ var gs_kiri_print = exports; if (list.length > 0) { list.sort(function(a,b) { return a.d - b.d }); find = list[0]; - find2 = list[4] || list[3] || list [2] || list[1]; - - // do 2nd closest fill lines within bigger fill areas - // if (layer === 0 && pass > 0 && find2 && lastout === 2 && len > thinWall) {//} && find2.d <= fillSkip) { - // find = find2; - // } // order segment by closest to farthest point if (find.i % 2 === 0) { @@ -591,7 +629,7 @@ var gs_kiri_print = exports; // to avoid shaking printer to death. if (find.d <= thinWall && len <= thinWall) { p2 = p1.midPointTo(p2); - addOutput(preout, p2, fillMult * (find.d / thinWall)); + addOutput(preout, p2, fillMult * (find.d / thinWall), printSpeed); lastout = 1; } else { // check for intersection with bounds and if found @@ -600,8 +638,14 @@ var gs_kiri_print = exports; checkBisect(startPoint, p1, bounds); } - addOutput(preout, p1, 0); - addOutput(preout, p2, fillMult); + // bridge ends of fill if they're close together + if (dist < thinWall) { + addOutput(preout, p1, fillMult, printSpeed); + } else { + addOutput(preout, p1, 0, moveSpeed); + } + + addOutput(preout, p2, fillMult, printSpeed); lastout = 2; } @@ -655,8 +699,8 @@ var gs_kiri_print = exports; next.fills.forEach(function(p) { p.z = z }); outputFills(next.fills, next.inner); } - // lastTop = null; } else { + // when skipping between tops, first perform a wipe if (lastTop && lastTop !== next && wipe) { outputWipe(wipe); wipe = null; @@ -668,12 +712,8 @@ var gs_kiri_print = exports; outputSparse(next.fill_sparse, bounds); if (next.inner) { wipe = next.inner.last(); - // best to use inner offset for wipe - // outputWipe(next.inner.last()); } else { wipe = next.traces.last(); - // otherwise fall back to innermost trace - // outputWipe(next.traces.last()); } lastTop = next; } @@ -681,6 +721,9 @@ var gs_kiri_print = exports; return obj instanceof Polygon ? obj : obj.poly; }); + // final wipe before lowering bed + if (wipe) outputWipe(wipe); + // offset print points for (i=0; i - All Rights Reserved", LICENSE:"Unauthorized copying, modification and re-distribution are strictly prohibited without prior written consent.", - VERSION:"1.0.71" + VERSION:"1.0.72" }; if (!module) var module = {}; module.exports = exports;