Merge branch 'rel-4.3'
This commit is contained in:
commit
d22c020750
18 changed files with 344 additions and 93 deletions
21
notes.md
21
notes.md
|
|
@ -31,27 +31,19 @@
|
|||
* `B` multi-extruder rendering of raft fails to offset the rest of the print
|
||||
* `B` multi-extruder purge blocks fail to generate properly for rafts
|
||||
|
||||
* `F` min layer time
|
||||
* `F` separate bridging speed / fan control
|
||||
* `F` elephant foot compensation
|
||||
* `F` inner / outer perimeter compensation
|
||||
* `F` better thin-wall (like arachne)
|
||||
* `F` add scarf seams
|
||||
* `F` add 'random' and 'seam' start point options
|
||||
* `F` new parameter to cap output flow rate (on printer device)
|
||||
* `F` new parameters for bridging speed / bridge fan control
|
||||
* `F` convert ranges to z offsets while continuing to show layer #
|
||||
* `F` support pillar top/bottom should conform to part
|
||||
* `F` more explicit line width control with ranges and min/max adaptive
|
||||
* `F` test outlining solid projected areas (internally)
|
||||
* `F` gradient infill https://www.youtube.com/watch?v=hq53gsYREHU&feature=emb_logo
|
||||
* `F` feather sharp tips by reducing extrusion in area of overlap
|
||||
* `F` segment large flat areas on first layer to mitigate peeling
|
||||
* `F` option to support interior bridges when 0% infill
|
||||
* `F` calculate filament use per extruder per print
|
||||
* `F` expand internal supporting flats / solids before projection (threshold)
|
||||
|
||||
* `P` reduce fan speed, feed rate, and extrusion factor for bridges
|
||||
* `P` auto purge pillars when quick layers are detected for extra cooling
|
||||
* `P` extruder + filament max flow rate cap in planner
|
||||
* `P` solid fill the tops of supports for down facing flats
|
||||
|
||||
# FDM - BELT
|
||||
|
|
@ -91,8 +83,8 @@
|
|||
* `F` ease-in and ease-out especially on tab cut-out start/stop
|
||||
* `F` maintain several part orientations + op chains in a single profile
|
||||
|
||||
* `P` outer outside corners as arc moves
|
||||
* `P` improve parser - do not require spaced tokens and support implied G0 / G1
|
||||
* `P` outer corner arc moves
|
||||
* `P` log Z interpolation for contour XYZ moves
|
||||
* `P` option to start with the smallest poly by area on layer change
|
||||
* `P` redo all path route / planning in prepare to account for terrain before camOut
|
||||
|
|
@ -106,11 +98,12 @@
|
|||
* subfolder parameter for dropped files
|
||||
* auto-kick check box in preferences
|
||||
|
||||
|
||||
# Mesh:Tool
|
||||
|
||||
* add undo/redo
|
||||
* add TextGeometry
|
||||
* https://threejs.org/docs/#examples/en/geometries/TextGeometry
|
||||
* https://dustinpfister.github.io/2023/07/05/threejs-text-geometry/
|
||||
* font to path with https://github.com/paulzi/svg-text-to-path
|
||||
* click to repair normals based on a known good (selected) face
|
||||
* send to Kiri:Moto workspace (or update model vertices in place)
|
||||
|
|
@ -122,3 +115,7 @@
|
|||
* fix mirror to work with groups (just models currently)
|
||||
* add analyze results dialog
|
||||
* remove/hide auto-repair function
|
||||
|
||||
# Other
|
||||
|
||||
* preferred icons https://icons.getbootstrap.com/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "grid-apps",
|
||||
"version": "4.3.1",
|
||||
"version": "4.3.2",
|
||||
"description": "grid.space 3d slicing & modeling tools",
|
||||
"author": "Stewart Allen <sa@grid.space>",
|
||||
"license": "MIT",
|
||||
|
|
|
|||
|
|
@ -1323,15 +1323,15 @@ export class Polygon {
|
|||
pp2.pos = ip2;
|
||||
}
|
||||
});
|
||||
list.sort(function(p1, p2) {
|
||||
return util.distSq(lp1, p1) - util.distSq(lp1, p2);
|
||||
});
|
||||
if (deep && this.inner) {
|
||||
this.inner.forEach(p => {
|
||||
let ints = p.intersections(lp1, lp2);
|
||||
if (ints) list.appendAll(ints);
|
||||
});
|
||||
}
|
||||
list.sort(function(p1, p2) {
|
||||
return util.distSq(lp1, p1) - util.distSq(lp1, p2);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -1392,6 +1392,23 @@ export class Polygon {
|
|||
return poly;
|
||||
}
|
||||
|
||||
/**
|
||||
* emit the shortest poly that connects two points on a closed CW poly
|
||||
* because traveling around the 'end point' may yield a shorter route.
|
||||
* if the poly is open, use emitSegment()
|
||||
*/
|
||||
emitShortestSegment(i1, i2) {
|
||||
if (this.open) {
|
||||
return this.emitSegment(i1, i2);
|
||||
}
|
||||
let start = i1.p2.pos,
|
||||
end = i2.p1.pos,
|
||||
points = this.points,
|
||||
seg0 = new Polygon([ i1, ...points.slice(start, end + 1), i2 ]).setOpen(),
|
||||
seg1 = new Polygon([ i2, ...points.slice(end +1 ), ...points.slice(0, start), i1 ]).setOpen();
|
||||
return seg0.perimeter() < seg1.perimeter() ? seg0 : seg1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Polygon} poly
|
||||
* @param {number} [tolerance]
|
||||
|
|
@ -2324,9 +2341,12 @@ export class Polygon {
|
|||
return obj;
|
||||
}
|
||||
|
||||
// split long straight lines into segments no longer than max
|
||||
// and return a new polygon
|
||||
segment(max = 1, mark, wrap) {
|
||||
// split long straight lines into segments no longer than `max`
|
||||
// and return a new polygon. optionally `mark` points with their
|
||||
// derived segment start point (hinting for thin walls), `wrap`
|
||||
// the poly first point by appending to the end (adaptive walls),
|
||||
// or stopping segmentation at `maxoff`
|
||||
segment(max = 1, mark = false, wrap = false, maxoff = Infinity) {
|
||||
const newp = [];
|
||||
const points = this.points;
|
||||
const length = points.length;
|
||||
|
|
@ -2339,9 +2359,13 @@ export class Polygon {
|
|||
const dl = Math.sqrt(dx * dx + dy * dy);
|
||||
newp.push(p1);
|
||||
if (mark) p1.segment = p1;
|
||||
if (dl < max) {
|
||||
// if segment shorter than max (delta) or
|
||||
// maxoff is exhausted (only segmenting up to some length)
|
||||
// then skip sub-segmenting the current segment
|
||||
if (dl < max || maxoff < 0) {
|
||||
continue;
|
||||
}
|
||||
maxoff -= dl;
|
||||
const div = dl / max;
|
||||
const fit = div | 0;
|
||||
const add = fit - 1;
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ let UC = UI.prefix('kiri').inputAction(settings.conf.update),
|
|||
put: (key, val) => localSet(key, val),
|
||||
set: (key, val) => localSet(key, val),
|
||||
setItem: (key, val) => localSet(key, val),
|
||||
removeItem: (key) => localRemove(key)
|
||||
},
|
||||
tweak = {
|
||||
line_precision(v) { api.work.config({ base: { clipperClean: v } }) },
|
||||
|
|
@ -119,6 +120,11 @@ function localSet(key, val) {
|
|||
return val;
|
||||
}
|
||||
|
||||
function localRemove(key) {
|
||||
let sloc = api.conf.get().local;
|
||||
return delete sloc[key];
|
||||
}
|
||||
|
||||
export const api = {
|
||||
ajax,
|
||||
beta,
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ Polygon.prototype.encode = function(state) {
|
|||
|
||||
state.poly[this.id] = this;
|
||||
|
||||
return {
|
||||
let enc = {
|
||||
type: TYPE.POLY,
|
||||
id: this.id,
|
||||
array: encodePointArray(this.points, state, this.z),
|
||||
|
|
@ -322,6 +322,20 @@ Polygon.prototype.encode = function(state) {
|
|||
color: this.color,
|
||||
open: this.open
|
||||
};
|
||||
|
||||
// encode extended point info for tagged polys
|
||||
if (this._epk) {
|
||||
let epk = enc.epk = {};
|
||||
for (let key of this._epk) {
|
||||
let arr = epk[key] = [];
|
||||
let pts = this.points;
|
||||
for (let i=0, l=pts.length; i<l; i++) {
|
||||
if (pts[i][key]) arr.push(i, pts[i][key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enc;
|
||||
};
|
||||
|
||||
registerDecoder(TYPE.POLY, function(v, state) {
|
||||
|
|
@ -340,6 +354,18 @@ registerDecoder(TYPE.POLY, function(v, state) {
|
|||
poly.push(newPoint(array[vid++], array[vid++], array[vid++]));
|
||||
}
|
||||
|
||||
// decode extended point when present
|
||||
if (v.epk) {
|
||||
let pts = poly.points;
|
||||
for (let [key, arr] of Object.entries(v.epk)) {
|
||||
for (let i=0; i<arr.length; ) {
|
||||
let pos = arr[i++];
|
||||
let val = arr[i++];
|
||||
pts[pos][key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.poly[v.id] = poly;
|
||||
|
||||
poly.id = v.id;
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ export const conf = {
|
|||
sliceLayerStartX: 0,
|
||||
sliceLayerStartY: 0,
|
||||
sliceLineWidth: 0,
|
||||
sliceCompInner: 0,
|
||||
sliceCompOuter: 0,
|
||||
sliceFillGrow: 0,
|
||||
sliceFillAngle: 45,
|
||||
sliceFillWidth: 1,
|
||||
|
|
@ -327,8 +329,10 @@ export const conf = {
|
|||
outputRetractDwell: 20,
|
||||
outputBrimCount: 2,
|
||||
outputBrimOffset: 2,
|
||||
outputScarfLength: 0,
|
||||
outputShortPoly: 100.0,
|
||||
outputMinSpeed: 10.0,
|
||||
outputMinLayerTime: 0,
|
||||
outputCoastDist: 0,
|
||||
outputPurgeTower: 0,
|
||||
outputBeltFirst: false,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ const LISTS = {
|
|||
{ name: "center" },
|
||||
{ name: "origin" },
|
||||
{ name: "random" },
|
||||
{ name: "spiral" },
|
||||
],
|
||||
infill: [
|
||||
{ name: "none" },
|
||||
|
|
|
|||
|
|
@ -80,11 +80,9 @@ class Print {
|
|||
return lastOut;
|
||||
}
|
||||
|
||||
addPrintPoints(input, output, startPoint, tool) {
|
||||
addPrintPoints(input, output) {
|
||||
if (this.startPoint && input.length > 0) {
|
||||
this.lastPoint = this.startPoint;
|
||||
// TODO: revisit seek to origin as the first move
|
||||
// addOutput(output, startPoint, 0, undefined, tool);
|
||||
}
|
||||
output.appendAll(input);
|
||||
}
|
||||
|
|
@ -98,6 +96,7 @@ class Print {
|
|||
* @param {Array} output - the array to print to
|
||||
* @param {Object} [options] - optional parameters
|
||||
* @param {boolean} [options.ccw] - set the polygon to be counter-clockwise
|
||||
* @param {boolean} [options.scarf] - scarf seam permitted
|
||||
* @param {number} [options.extrude] - extrude factor for the polygon
|
||||
* @param {number} [options.rate] - print speed in mm/s
|
||||
* @param {number} [options.coast] - distance to coast at the end of the polygon
|
||||
|
|
@ -119,15 +118,16 @@ class Print {
|
|||
const { settings } = scope;
|
||||
const { process } = settings;
|
||||
|
||||
let shortDist = process.outputShortDistance,
|
||||
shellMult = numOrDefault(options.extrude, process.outputShellMult),
|
||||
let shellMult = numOrDefault(options.extrude, process.outputShellMult),
|
||||
printSpeed = options.rate || process.outputFeedrate,
|
||||
moveSpeed = process.outputSeekrate,
|
||||
minSpeed = process.outputMinSpeed,
|
||||
nozzleSize = options.nozzleSize,
|
||||
coastDist = options.coast || 0,
|
||||
closest = options.simple ? poly.first() : poly.findClosestPointTo(startPoint),
|
||||
perimeter = poly.perimeter(),
|
||||
close = !options.open,
|
||||
scarf = !poly.open ? (options.scarf ?? 0) : false,
|
||||
tool = options.tool,
|
||||
last = startPoint,
|
||||
first = true;
|
||||
|
|
@ -137,14 +137,74 @@ class Print {
|
|||
printSpeed = minSpeed + (printSpeed - minSpeed) * (perimeter / process.outputShortPoly);
|
||||
}
|
||||
|
||||
// if not starting at first point in poly, rotate to move start to index = 0
|
||||
let pp = poly.points;
|
||||
if (closest.index > 0) {
|
||||
let cio = pp.indexOf(closest.point);
|
||||
pp = poly.points = [ ...pp.slice(cio), ...pp.slice(0, cio) ];
|
||||
}
|
||||
|
||||
// scarf sanity checks
|
||||
if (scarf) {
|
||||
// cancel scarf for thin wall polys
|
||||
if (pp.filter(p => p.skip || p.moved).length) {
|
||||
scarf = 0;
|
||||
} else {
|
||||
// cancel scarf if any point.z differs
|
||||
let z0 = pp[0].z;
|
||||
let zd = 0;
|
||||
for (let p of pp) zd += Math.abs(p.z - z0);
|
||||
if (zd) scarf = 0;
|
||||
}
|
||||
// console.log({ scarf });
|
||||
}
|
||||
|
||||
// when creating scarf seams, segment poly up to seam length
|
||||
// create array of step up points at start of poly with increasing z
|
||||
// and increasing shellMult and then append the same points on the back
|
||||
// end of the poly with fixed z and decreasing shellMult
|
||||
if (scarf) {
|
||||
let epz = Math.max(...poly.points.map(p => p.z));
|
||||
let spz = startPoint.z;
|
||||
poly = poly.segment(options.nozzleSize ?? 0.4, false, false, scarf * 2);
|
||||
pp = poly.points;
|
||||
let lp, sp = [];
|
||||
for (let p of pp) {
|
||||
let d = lp?.distTo2D(p) ?? 0;
|
||||
sp.push(lp = p);
|
||||
scarf -= d;
|
||||
if (scarf <= 0) break;
|
||||
}
|
||||
let fcs = 1.0; // flow compensation seam
|
||||
let fco = (1 / sp.length) * 0.0; // flow compensation offset (- half step)
|
||||
let zd = (epz - spz) / sp.length;
|
||||
let zi = 1;
|
||||
for (let p of sp) {
|
||||
p.z -= zd * (sp.length - zi);
|
||||
p.moved = (((zi++) / sp.length) * fcs) - 1 - fco;
|
||||
}
|
||||
let esp = sp.map(p => p.clone()); // ending scarf points
|
||||
for (let p of esp) {
|
||||
p.z = epz;
|
||||
p.moved = (((--zi) / esp.length) * fcs) - 1 - fco;
|
||||
}
|
||||
pp.push(...esp);
|
||||
scarf = true;
|
||||
}
|
||||
|
||||
// scarf manages its own close point
|
||||
if (close && !scarf) {
|
||||
pp.push(pp[0]);
|
||||
}
|
||||
|
||||
let lpo;
|
||||
poly.forEachPoint((point, pos, points, count) => {
|
||||
for (let point of pp) {
|
||||
if (point.skip && lpo?.skip) {
|
||||
scope.addOutput(output, point, 0, moveSpeed, tool);
|
||||
} else if (first) {
|
||||
// if (point.skip) console.log({ skip: point });
|
||||
if (options.onfirst) {
|
||||
options.onfirst(point);
|
||||
options.onfirst(point, output);
|
||||
}
|
||||
// move to first output point on poly
|
||||
let out = scope.addOutput(output, point, 0, moveSpeed, tool);
|
||||
|
|
@ -154,7 +214,8 @@ class Print {
|
|||
first = false;
|
||||
} else {
|
||||
let seglen = last.distTo2D(point);
|
||||
if (coastDist && shellMult && perimeter - seglen <= coastDist) {
|
||||
// cancel coast when using scarf seam
|
||||
if (!scarf && coastDist && shellMult && perimeter - seglen <= coastDist) {
|
||||
let delta = perimeter - coastDist;
|
||||
let offset = seglen - delta;
|
||||
let offPoint = last.offsetPointFrom(point, offset)
|
||||
|
|
@ -168,7 +229,7 @@ class Print {
|
|||
scope.addOutput(output, point, multOut, printSpeed, tool);
|
||||
}
|
||||
last = lpo = point;
|
||||
}, close, closest.index);
|
||||
}
|
||||
|
||||
this.lastPoly = poly;
|
||||
|
||||
|
|
@ -176,6 +237,14 @@ class Print {
|
|||
}
|
||||
|
||||
constReplace(str, consts, start, pad, short) {
|
||||
function tryeval(str) {
|
||||
try {
|
||||
return eval(`{ ${str} }`)
|
||||
} catch (e) {
|
||||
console.log({ eval_error: e, str });
|
||||
return str;
|
||||
}
|
||||
}
|
||||
let cs = str.indexOf("{", start || 0),
|
||||
ce = str.indexOf("}", cs),
|
||||
tok, nutok, nustr;
|
||||
|
|
@ -199,8 +268,7 @@ class Print {
|
|||
}
|
||||
eva.push(`function range(a,b) { return (a + (layer / layers) * (b-a)).round(4) }`);
|
||||
eva.push(`try {( ${tok} )} catch (e) {console.log(e);0}`);
|
||||
let scr = eva.join('');
|
||||
let evl = eval(`{ ${scr} }`);
|
||||
let evl = tryeval(eva.join(''));
|
||||
nutok = evl;
|
||||
if (pad === 666) {
|
||||
return evl;
|
||||
|
|
|
|||
|
|
@ -181,8 +181,8 @@ async function path(levels, update, opts = {}) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (lastOut) { // if last outpoint is defined
|
||||
|
||||
// if last outpoint is defined
|
||||
if (lastOut) {
|
||||
if (arrowAll || lastOut.emit !== out.emit) {
|
||||
heads.push({p1: lastOutPoint, p2: outPoint});
|
||||
}
|
||||
|
|
@ -200,13 +200,10 @@ async function path(levels, update, opts = {}) {
|
|||
current.color = color(out);
|
||||
pushPrint(out.tool, current);
|
||||
}
|
||||
|
||||
out.arcPoints.forEach(p => {
|
||||
current.push(p);
|
||||
})
|
||||
|
||||
current.push(outPoint);
|
||||
|
||||
} else if (out.emit) {
|
||||
// explicity G1 in CAM mode
|
||||
// just a non-move in other modes
|
||||
|
|
|
|||
|
|
@ -782,9 +782,11 @@ class Widget {
|
|||
}
|
||||
if (set) {
|
||||
let dark = this.api.space.is_dark();
|
||||
let cam = this.api.mode.is_cam();
|
||||
let color = dark && !cam ? 0xffffff : 0;
|
||||
let angle = this.api.conf.get().controller.edgeangle || 20;
|
||||
let edges = new THREE.EdgesGeometry(mesh.geometry, angle);
|
||||
let material = new THREE.LineBasicMaterial({ color: 0 });
|
||||
let material = new THREE.LineBasicMaterial({ color });
|
||||
this.outline = new THREE.LineSegments(edges, material);
|
||||
this.outline.renderOrder = -20;
|
||||
mesh.add(this.outline);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
retSpeed = process.outputRetractSpeed * 60 || 1, // range
|
||||
retDwell = process.outputRetractDwell || 0, // range
|
||||
timeDwell = retDwell / 1000,
|
||||
arcDist = isBelt ? 0 : (process.arcTolerance || 0),
|
||||
scarfZ = process.outputScarfLength ? true : false,
|
||||
arcDist = isBelt || scarfZ ? 0 : (process.arcTolerance || 0),
|
||||
arcMin = 1,
|
||||
arcRes = 20,
|
||||
arcDev = 0.5,
|
||||
|
|
@ -111,7 +112,11 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
progress: 0,
|
||||
nozzle: tool,
|
||||
tool: tool,
|
||||
model_labels: model_labels.sort().join(',')
|
||||
oid: '',
|
||||
oname: '',
|
||||
model_labels: model_labels.sort().join(','),
|
||||
total_time: Math.ceil(print.total_time / 60),
|
||||
remain_time: Math.ceil(print.total_time / 60),
|
||||
},
|
||||
pidx, path, out, speedMMM, emitMM, emitPerMM, lastp, laste, dist,
|
||||
lines = 0,
|
||||
|
|
@ -525,6 +530,7 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
// retract before first move
|
||||
retract();
|
||||
|
||||
subst.remain_time = Math.ceil(print.total_time / 60);
|
||||
while (layer < layers.length) {
|
||||
path = layers[layer];
|
||||
layerno = path.slice.index;
|
||||
|
|
@ -598,7 +604,7 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
}
|
||||
|
||||
// move Z to layer height
|
||||
if (layer > 0 || !isBelt) {
|
||||
if (layer === 0 || ((layer > 0 || !isBelt) && !scarfZ)) {
|
||||
moveTo({z:zpos}, seekMMM);
|
||||
}
|
||||
|
||||
|
|
@ -620,6 +626,8 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
let b64 = encodeBitOffset(off);
|
||||
append(`; start object id: ${out.widget.track.grid_id}`);
|
||||
isBambu && append(`M624 ${b64}`);
|
||||
subst.oid = out.widget.track.grid_id;
|
||||
subst.oname = out.widget.meta.file;
|
||||
}
|
||||
cwidget = out.widget;
|
||||
}
|
||||
|
|
@ -779,12 +787,20 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
} else {
|
||||
// emitMM = emitPerMM * out.emit * dist;
|
||||
emitMM = extrudeMM(dist, emitPerMM, out.emit);
|
||||
moveTo({x:x, y:y, e:emitMM}, speedMMM);
|
||||
if (scarfZ) {
|
||||
moveTo({x, y, z:z + path.height/2, e:emitMM}, speedMMM);
|
||||
} else {
|
||||
moveTo({x, y, e:emitMM}, speedMMM);
|
||||
}
|
||||
emitted += emitMM;
|
||||
}
|
||||
} else {
|
||||
drainQ();
|
||||
moveTo({x:x, y:y}, seekMMM);
|
||||
if (scarfZ) {
|
||||
moveTo({x, y, z:z + path.height/2}, speedMMM);
|
||||
} else {
|
||||
moveTo({x, y}, seekMMM);
|
||||
}
|
||||
// TODO disabling out of plane z moves until a better mechanism
|
||||
// can be built that doesn't rely on computed zpos from layer heights...
|
||||
// when making z moves (like polishing) allow slowdown vs fast seek
|
||||
|
|
@ -830,11 +846,13 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
append(`M808`);
|
||||
}
|
||||
drainQ();
|
||||
|
||||
print.total_time -= path.print_time;
|
||||
subst.remain_time = Math.ceil(print.total_time / 60);
|
||||
}
|
||||
|
||||
function emitQrec(rec) {
|
||||
let {e, x, y, dist, emitPerMM, speedMMM} = rec;
|
||||
// emitMM = emitPerMM * e * dist;
|
||||
emitMM = extrudeMM(dist, emitPerMM, e);
|
||||
moveTo({x:x, y:y, e:emitMM}, speedMMM);
|
||||
emitted += emitMM;
|
||||
|
|
@ -958,7 +976,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
|||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (inloops) {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ export function menu() {
|
|||
sliceBottomLayers: newInput(LANG.sl_lbot_s, { title:LANG.sl_lbot_l, convert:toInt }),
|
||||
separator: newBlank({ class:"set-sep", driven }),
|
||||
sliceAdaptive: newBoolean(LANG.ad_adap_s, onBooleanClick, { title: LANG.ad_adap_l }),
|
||||
outputLayerRetract: newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l}),
|
||||
sliceLayerStart: newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l}, "start"),
|
||||
_____: newGroup(LANG.sw_menu, $('fdm-walls'), { modes:FDM, driven, hideable, separator, group:"fdm-walls" }),
|
||||
sliceShells: newInput(LANG.sl_shel_s, { title:LANG.sl_shel_l, convert:toFloat }),
|
||||
sliceLineWidth: newInput(LANG.sl_line_s, { title:LANG.sl_line_l, convert:toFloat, bound:bound(0,5) }),
|
||||
|
|
@ -100,6 +102,7 @@ export function menu() {
|
|||
_____: newGroup(LANG.fc_menu, $('fdm-cool'), { modes:FDM, driven, hideable, separator, group:"fdm-cool" }),
|
||||
outputFanLayer: newInput(LANG.ou_fanl_s, { title:LANG.ou_fanl_l, convert:toInt, bound:bound(0,255) }),
|
||||
outputFanSpeed: newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:toInt, bound:bound(0,255)}),
|
||||
outputMinLayerTime: newInput(LANG.ou_layt_s, { title:LANG.ou_layt_l, convert:toInt, bound:bound(0,200) }),
|
||||
_____: newGroup(LANG.sp_menu, $('fdm-support'), { modes:FDM, driven, hideable, separator, group:"fdm-supp" }),
|
||||
sliceSupportNozzle: newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, show:isMultiHead}, "extruders"),
|
||||
sliceSupportDensity: newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:toFloat, bound:bound(0.0,1.0)}),
|
||||
|
|
@ -165,8 +168,6 @@ export function menu() {
|
|||
outputRetractSpeed: newInput(LANG.ad_rrat_s, {title:LANG.ad_rrat_l, convert:toInt}),
|
||||
outputRetractWipe: newInput(LANG.ad_wpln_s, {title:LANG.ad_wpln_l, convert:toFloat, bound:bound(0.0,10)}),
|
||||
separator: newBlank({ class:"set-sep", driven }),
|
||||
sliceLayerStart: newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l}, "start"),
|
||||
outputLayerRetract: newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l}),
|
||||
outputAvoidGaps: newBoolean(LANG.ad_agap_s, onBooleanClick, {title:LANG.ad_agap_l}),
|
||||
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
||||
outputBeltFirst: newBoolean(LANG.ad_lbir_s, onBooleanClick, {title:LANG.ad_lbir_l, show:isBelt}),
|
||||
|
|
@ -177,8 +178,11 @@ export function menu() {
|
|||
outputRetractDwell: newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:toInt}),
|
||||
outputMinSpeed: newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, convert:toFloat, bound:bound(1,200)}),
|
||||
outputPurgeTower: newInput(LANG.ad_purg_s, {title:LANG.ad_purg_l, convert:toInt, bound:bound(0,1000)}),
|
||||
outputScarfLength: newInput(LANG.ad_scar_s, {title:LANG.ad_scar_l, convert:toFloat, bound:bound(0,1000)}),
|
||||
outputShortPoly: newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, convert:toFloat, bound:bound(0,10000)}),
|
||||
outputCoastDist: newInput(LANG.ad_scst_s, {title:LANG.ad_scst_l, convert:toFloat, bound:bound(0.0,10)}),
|
||||
sliceCompInner: newInput(LANG.sl_ofin_s, {title:LANG.sl_ofin_l, convert:toFloat, bound:bound(-10.0,10.0)}),
|
||||
sliceCompOuter: newInput(LANG.sl_ofot_s, {title:LANG.sl_ofot_l, convert:toFloat, bound:bound(-10.0,10.0)}),
|
||||
zHopDistance: newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, convert:toFloat, bound:bound(0,3.0)}),
|
||||
outputLoops: newInput(LANG.ag_loop_s, {title:LANG.ag_loop_l, convert:toInt, bound:bound(-1,1000), show:isBelt}),
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,44 @@ slicer.slicePost.FDM = slicePost;
|
|||
* data object. return is ignored.
|
||||
*/
|
||||
export function slicePost(data, options) {
|
||||
const { z, lines, groups } = data;
|
||||
const { useAssembly, post_args, zIndexes } = options;
|
||||
const { process, isSynth, vaseMode } = post_args;
|
||||
const { shellOffset, fillOffset, clipOffset } = post_args;
|
||||
data.tops = POLY.nest(groups);
|
||||
const { groups, z } = data;
|
||||
const { post_args, useAssembly, zIndexes } = options;
|
||||
const { isSynth, process, vaseMode } = post_args;
|
||||
const { compInner, compOuter, pump } = post_args;
|
||||
const { clipOffset, fillOffset, shellOffset } = post_args;
|
||||
|
||||
if (pump) {
|
||||
let nugroups = [];
|
||||
let pump = shellOffset / 10;
|
||||
for (let p of groups) {
|
||||
let retop = POLY.offset([ p ], -pump, {
|
||||
join: ClipperLib.JoinType.jtRound,
|
||||
arc: (1/pump) * 4
|
||||
});
|
||||
retop = POLY.offset(retop, pump, {
|
||||
join: ClipperLib.JoinType.jtRound,
|
||||
arc: (1/pump) * 4
|
||||
});
|
||||
nugroups.push(...retop);
|
||||
}
|
||||
data.tops = POLY.nest(nugroups);
|
||||
} else {
|
||||
data.tops = POLY.nest(groups);
|
||||
}
|
||||
|
||||
// perimeter and inner hole compensation offsets
|
||||
if (compInner || compOuter) {
|
||||
let inner = POLY.inner(data.tops).flat();
|
||||
let outer = POLY.outer(data.tops);
|
||||
if (compInner) {
|
||||
inner = POLY.flatten(POLY.offset(inner, compInner/2));
|
||||
}
|
||||
if (compOuter) {
|
||||
outer = POLY.flatten(POLY.offset(outer, -compOuter/2));
|
||||
}
|
||||
data.tops = POLY.nest([...inner, ...outer]);
|
||||
}
|
||||
|
||||
if (isSynth) {
|
||||
const process = post_args.process;
|
||||
if (process.sliceSupportGrow > 0) {
|
||||
|
|
@ -35,6 +68,7 @@ export function slicePost(data, options) {
|
|||
delete data.groups;
|
||||
return;
|
||||
}
|
||||
|
||||
const index = zIndexes.indexOf(z);
|
||||
const range = getRangeParameters(process, index);
|
||||
// calculate fractional shells
|
||||
|
|
@ -110,7 +144,7 @@ function offset_default(params) {
|
|||
}
|
||||
|
||||
const deltaBig = 160;
|
||||
const deltSmall = 20;
|
||||
const deltaSmall = 20;
|
||||
|
||||
// look for close points on adjacent segmented polys and merge
|
||||
let test_polys = first !== last ? [ ...first, ...last ] : last;
|
||||
|
|
@ -120,6 +154,8 @@ function offset_default(params) {
|
|||
for (let poly of test_flats)
|
||||
poly.forEachSegment((p0, p1) => {
|
||||
p0.angle = new Slope(p0, p1);
|
||||
// todo calc vertex angle
|
||||
// exclude segment vertex from merge when angle < deltaSmall
|
||||
});
|
||||
|
||||
// segment each poly to be tested
|
||||
|
|
@ -146,14 +182,13 @@ function offset_default(params) {
|
|||
if (p0 === p1 || p0.segment === p1.segment) continue;
|
||||
let dist = p0.distTo2D(p1);
|
||||
if (dist < offset1) {
|
||||
let diff = p0.segment.angle.angleDiff(p1.segment.angle,false);
|
||||
if (p0.segment === p1.segment && diff < deltaBig) continue;
|
||||
if (p0.segment !== p1.segment && diff > deltSmall && diff < deltaBig) continue;
|
||||
let diff = p0.segment.angle.angleDiff(p1.segment.angle,true);
|
||||
if (diff < deltaBig) continue;
|
||||
// merge points marking point offset and skip
|
||||
let mid = p0.midPointTo(p1);
|
||||
let inc = p0.distTo2D(mid) / offset1;
|
||||
moved = p0.moved = p1.moved = inc;
|
||||
p1.skip = true;
|
||||
moved = p0.moved = p1.moved = inc.round(4);
|
||||
p1.skip = 1;
|
||||
p0.x = p1.x = mid.x;
|
||||
p0.y = p1.y = mid.y;
|
||||
}
|
||||
|
|
@ -168,6 +203,8 @@ function offset_default(params) {
|
|||
for (let rec of thin_test) {
|
||||
if (rec.moved) {
|
||||
let last_seg;
|
||||
// tag for codec extended point encoding
|
||||
rec.poly._epk = ["moved", "skip"];
|
||||
rec.poly.points = rec.points.filter((p,i) => {
|
||||
let keep = (last_seg !== p.segment || p.moved || p.skip);
|
||||
last_seg = p.segment;
|
||||
|
|
@ -485,6 +522,7 @@ function trace_noodle(noodle, noodleWidth, minR, midR, maxR, opt = {}) {
|
|||
// construct medial axis lines. this appears to produce duplicate
|
||||
// reverse segments in a subset of cases
|
||||
let ma = JSPoly.construct_medial_axis(out, inr);
|
||||
if (ma.length === 0) throw('cannot construct medial axis');
|
||||
// dedup the points so we can track them uniquely
|
||||
for (let { point0, point1 } of ma) {
|
||||
pointsToLine(point0, point1);
|
||||
|
|
@ -694,7 +732,8 @@ export function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {
|
|||
if (dist < 1) p.open = false;
|
||||
} });
|
||||
let ret = { last, gaps };
|
||||
switch (opt.thinType) {
|
||||
let ttype = opt.thinType;
|
||||
switch (ttype) {
|
||||
case "legacy 1":
|
||||
ret = thin_type_1({ z, top, count, top_poly, offsetN, fillOffset });
|
||||
break;
|
||||
|
|
@ -702,13 +741,18 @@ export function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {
|
|||
ret = thin_type_2({ z, top, count, top_poly, offset1, offsetN, fillOffset, gaps, wasm });
|
||||
break;
|
||||
case "adaptive":
|
||||
ret = thin_type_3({ z, top, count, offsetN });
|
||||
break;
|
||||
try {
|
||||
ret = thin_type_3({ z, top, count, offsetN });
|
||||
break;
|
||||
} catch (e) {
|
||||
console.log('adaptive layer failed. falling back to basic.', e);
|
||||
ttype = "basic";
|
||||
}
|
||||
case "basic":
|
||||
default:
|
||||
ret = offset_default({
|
||||
z, top, count, top_poly, offset1, offsetN, wasm,
|
||||
thin: opt.thinType === 'basic'
|
||||
thin: ttype === 'basic'
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
zneg = 0,
|
||||
zoff = 0,
|
||||
zmin = 0,
|
||||
zmax = 0,
|
||||
shield,
|
||||
output = [],
|
||||
layerout = [];
|
||||
|
|
@ -141,6 +142,7 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
});
|
||||
layerout.z = zoff + height;
|
||||
layerout.height = height;
|
||||
layerout.print_time = printPoint.layer_time;
|
||||
output.append(layerout);
|
||||
|
||||
layerout = [];
|
||||
|
|
@ -195,7 +197,7 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
});
|
||||
});
|
||||
|
||||
print.addPrintPoints(preout, layerout, null);
|
||||
print.addPrintPoints(preout, layerout);
|
||||
|
||||
if (preout.length) {
|
||||
// retract between brims and print
|
||||
|
|
@ -224,6 +226,7 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
}
|
||||
for (let slice of widget.slices) {
|
||||
zmin = Math.min(zmin, slice.z);
|
||||
zmax = Math.max(zmax, slice.z);
|
||||
if (!slice.supports) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -469,6 +472,9 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
let lastExt;
|
||||
let lastOut;
|
||||
|
||||
print.zmax = zmax;
|
||||
print.total_time = 0;
|
||||
|
||||
// walk cake layers bottom up
|
||||
for (let layer of cake) {
|
||||
// track purge blocks generated for each layer
|
||||
|
|
@ -570,6 +576,8 @@ export async function fdm_prepare(widgets, settings, update) {
|
|||
}
|
||||
}
|
||||
);
|
||||
layerout.print_time = printPoint.layer_time;
|
||||
print.total_time += printPoint.layer_time;
|
||||
print.setWidget(null);
|
||||
|
||||
lastOut = slice;
|
||||
|
|
@ -796,6 +804,8 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
process = opt.params || settings.process,
|
||||
originCenter = device.originCenter || bedRound,
|
||||
extruder = parseInt(slice.extruder || 0),
|
||||
scarfLength = process.outputScarfLength || 0,
|
||||
minLayerTime = process.outputMinLayerTime || 0,
|
||||
nozzleSize = process.sliceLineWidth || device.extruders[extruder].extNozzle,
|
||||
firstLayer = (opt.first || false) && !opt.support,
|
||||
thinWall = nozzleSize * (opt.thinWall || 1.75),
|
||||
|
|
@ -884,7 +894,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
|
||||
// return true if move path from p1 to p2 intersects a
|
||||
// top and a path around the top (inside print) was not found
|
||||
function intersectsTop(p1, p2) {
|
||||
function requiresRetract(p1, p2) {
|
||||
if (slice.index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -909,15 +919,20 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
if (dbug === slice.index) console.log(slice.index, {p1, p2, d: p1.distTo2D(p2)});
|
||||
|
||||
let ints = [];
|
||||
let intk = new Set();
|
||||
let tops = slice.topRouteFlat();
|
||||
for (let poly of tops) {
|
||||
poly.forEachSegment((s1, s2) => {
|
||||
let ip = util.intersect(p1,p2,s1,s2,base.key.SEGINT);
|
||||
if (ip) {
|
||||
if (ip) ip._key = undefined;
|
||||
if (ip && !intk.has(ip.key)) {
|
||||
ints.push({ip, poly});
|
||||
intk.add(ip.key);
|
||||
ip.p1.poly.hits = (ip.p1.poly.hits ?? 0) + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
ints = ints.filter(i => i.poly.hits === 2);
|
||||
|
||||
// no intersections
|
||||
if (ints.length === 0) {
|
||||
|
|
@ -1032,8 +1047,8 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// solid infill
|
||||
function outputTraces(poly, opt = {}) {
|
||||
// output shell wall
|
||||
function outputTraces(poly, opt = {}, traceNo = 0) {
|
||||
if (!poly) return;
|
||||
if (Array.isArray(poly)) {
|
||||
if (opt.sort) {
|
||||
|
|
@ -1066,30 +1081,32 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
if (next) {
|
||||
last = next;
|
||||
polys.remove(next);
|
||||
outputTraces(next, opt);
|
||||
outputTraces(next, opt, traceNo++);
|
||||
} else {
|
||||
last = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
outputOrderClosest(poly, function(next) {
|
||||
outputTraces(next, opt);
|
||||
outputTraces(next, opt, traceNo++);
|
||||
}, null);
|
||||
}
|
||||
} else {
|
||||
let finishShell = poly.depth === 0 && !firstLayer;
|
||||
let scarf = (slice.index > 0 && traceNo === 0 && z - startPoint?.z > 1e-3) ? scarfLength : 0;
|
||||
startPoint = print.polyPrintPath(poly, startPoint, preout, {
|
||||
ccw: opt.shell && process.outputAlternating && slice.index % 2,
|
||||
tool: extruder,
|
||||
rate: finishShell ? finishSpeed : printSpeed,
|
||||
accel: finishShell,
|
||||
wipe: process.outputWipeDistance || 0,
|
||||
ccw: opt.shell && process.outputAlternating && slice.index % 2,
|
||||
coast: firstLayer ? 0 : coastDist,
|
||||
extrude: numOrDefault(opt.extrude, shellMult),
|
||||
onfirst: function(firstPoint) {
|
||||
nozzleSize,
|
||||
rate: finishShell ? finishSpeed : printSpeed,
|
||||
scarf,
|
||||
tool: extruder,
|
||||
onfirst: (firstPoint, preout) => {
|
||||
let from = seedPoint || startPoint;
|
||||
if (from.distTo2D(firstPoint) > retractDist) {
|
||||
if (intersectsTop(from, firstPoint)) {
|
||||
if (requiresRetract(from, firstPoint)) {
|
||||
retract();
|
||||
}
|
||||
}
|
||||
|
|
@ -1171,7 +1188,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
poly.forEachPoint((p, i) => {
|
||||
let dist = lp.distTo2D(p);
|
||||
let rdst = dist > retractDist;
|
||||
let itop = rdst && intersectsTop(lp,p);
|
||||
let itop = rdst && requiresRetract(lp,p);
|
||||
let emit = extrude;
|
||||
// retract if dist trigger and crosses a slice top polygon
|
||||
if (i === 0) {
|
||||
|
|
@ -1215,7 +1232,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
}
|
||||
let first = points[0];
|
||||
let last = first;
|
||||
if (startPoint && startPoint.distTo2D(first) > thinWall && intersectsTop(startPoint, first)) {
|
||||
if (startPoint && startPoint.distTo2D(first) > thinWall && requiresRetract(startPoint, first)) {
|
||||
retract();
|
||||
}
|
||||
print.addOutput(preout, first, 0, moveSpeed, extruder);
|
||||
|
|
@ -1364,7 +1381,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
print.addOutput(preout, p2, fill, fillSpeed, extruder);
|
||||
} else {
|
||||
// retract if dist trigger or crosses a slice top polygon
|
||||
if (!fast && dist > retractDist && (zhop || intersectsTop(startPoint, p1))) {
|
||||
if (!fast && dist > retractDist && (zhop || requiresRetract(startPoint, p1))) {
|
||||
retract();
|
||||
}
|
||||
|
||||
|
|
@ -1473,7 +1490,15 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
}
|
||||
|
||||
// control of layer start point
|
||||
if (!lastTop)
|
||||
switch (process.sliceLayerStart) {
|
||||
case "spiral": {
|
||||
let center = top.poly.bounds.center();
|
||||
let angle = (Math.PI * 2) * (slice.z / print.zmax);
|
||||
let x = center.x + Math.cos(angle)*10000;
|
||||
let y = center.y + Math.sin(angle)*10000;
|
||||
startPoint = newPoint(x,y,startPoint.z);
|
||||
} break;
|
||||
case "last":
|
||||
break;
|
||||
case "random":
|
||||
|
|
@ -1559,13 +1584,38 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
// adjust layer output speeds (by slowing them down)
|
||||
// if layer print time is less than minimum (required for cooling)
|
||||
let lp, td = 0, tt = 0;
|
||||
for (let p of preout) {
|
||||
if (!p.emit) continue;
|
||||
let mms = p.speed ?? 1;
|
||||
let dst = lp?.distTo2D(p.point) ?? 0;
|
||||
if (dst) {
|
||||
tt += (dst/mms);
|
||||
td += dst;
|
||||
}
|
||||
lp = p.point;
|
||||
}
|
||||
if (minLayerTime && tt < minLayerTime) {
|
||||
let fact = tt / minLayerTime;
|
||||
for (let p of preout) {
|
||||
if (p.emit) p.speed *= fact;
|
||||
}
|
||||
}
|
||||
|
||||
// offset print points
|
||||
for (let i=0; i<preout.length; i++) {
|
||||
preout[i].point = preout[i].point.add(offset);
|
||||
}
|
||||
|
||||
// add offset points to total print
|
||||
print.addPrintPoints(preout, output, origin, extruder);
|
||||
print.addPrintPoints(preout, output);
|
||||
|
||||
return startPoint.add(offset);
|
||||
// create next layer start point and annotate
|
||||
// with print time for previous layer (hack to
|
||||
// avoid changing return signature rn)
|
||||
let newStart = startPoint.add(offset);
|
||||
newStart.layer_time = Math.max(tt, minLayerTime);
|
||||
return newStart;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,7 +140,8 @@ export function fdm_slice(settings, widget, onupdate, ondone) {
|
|||
fillOffset = lineWidth * fillOffsetMult,
|
||||
clipOffset = process.sliceSupportOffset,
|
||||
sliceFillAngle = process.sliceFillAngle,
|
||||
supportDensity = process.sliceSupportDensity;
|
||||
supportDensity = process.sliceSupportDensity,
|
||||
{ sliceCompInner, sliceCompOuter } = process;
|
||||
|
||||
// override globals used by vopt()
|
||||
isFlat = controller.lineType === "flat";
|
||||
|
|
@ -230,6 +231,8 @@ export function fdm_slice(settings, widget, onupdate, ondone) {
|
|||
useAssembly,
|
||||
post: 'FDM',
|
||||
post_args: {
|
||||
compInner: sliceCompInner,
|
||||
compOuter: sliceCompOuter,
|
||||
shellOffset,
|
||||
fillOffset,
|
||||
clipOffset,
|
||||
|
|
@ -345,7 +348,7 @@ export function fdm_slice(settings, widget, onupdate, ondone) {
|
|||
}
|
||||
}
|
||||
if (process.xray) {
|
||||
slice.index = process.xrayi.shift();
|
||||
slice.index = process.xray.shift();
|
||||
slice.lines = lines;
|
||||
slice.groups = groups;
|
||||
slice.xray = process.xray;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
const terms = {
|
||||
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
|
||||
LICENSE: "See the license.md file included with the source distribution",
|
||||
VERSION: "4.3.1"
|
||||
VERSION: "4.3.2"
|
||||
};
|
||||
|
||||
export const beta = 0;
|
||||
|
|
|
|||
|
|
@ -360,8 +360,12 @@ self.lang['en-us'] = {
|
|||
sl_line_l: ["extrusion width in millimeters","0 = nozzle diameter"],
|
||||
sl_ordr_s: "shell order",
|
||||
sl_ordr_l: ["output shell order","inside to outside","or outside to inside","affects surface quality"],
|
||||
sl_strt_s: "layer start",
|
||||
sl_strt_l: ["layer starting point","last = last layer end","center = part center","origin = device origin"],
|
||||
sl_strt_s: "start point",
|
||||
sl_strt_l: ["layer starting point","last = where last layer ended","center = part center","origin = device origin","random = yolo"],
|
||||
sl_ofin_s: "shell inner offset",
|
||||
sl_ofin_l: ["inner hole perimeter offset","in millimeters"],
|
||||
sl_ofot_s: "shell outer offset",
|
||||
sl_ofot_l: ["outer wall perimeter offset","in millimeters"],
|
||||
|
||||
// FDM SOLID
|
||||
fs_menu: "solid fill",
|
||||
|
|
@ -765,8 +769,10 @@ self.lang['en-us'] = {
|
|||
ou_exml_l: ["extrusion multiplier","0.0 - 2.0"],
|
||||
ou_fanl_s: "fan on layer",
|
||||
ou_fanl_l: ["layer # to turn on fan","layers start at 0"],
|
||||
ou_fans_s: "fan speed",
|
||||
ou_fans_s: "fan on speed",
|
||||
ou_fans_l: "0 - 255",
|
||||
ou_layt_s: "min layer time",
|
||||
ou_layt_l: ["minimum allowable layer print time in seconds. printing will be slowed if the layer would outerwise complete in fewer seconds.","0 = disabled"],
|
||||
|
||||
// OUTPUT CAM
|
||||
ou_toll_s: "precision",
|
||||
|
|
@ -848,7 +854,7 @@ self.lang['en-us'] = {
|
|||
|
||||
// FDM ADVANCED
|
||||
ad_menu: "expert",
|
||||
ad_rdst_s: "retract dist",
|
||||
ad_rdst_s: "retract distance",
|
||||
ad_rdst_l: ["amount to retract filament","for long moves. in millimeters"],
|
||||
ad_rrat_s: "retract rate",
|
||||
ad_rrat_l: ["speed of filament","retraction in mm/s"],
|
||||
|
|
@ -862,11 +868,13 @@ self.lang['en-us'] = {
|
|||
ad_msol_l: ["minimum area (mm^2)","required to keep solid","must be > 0.1"],
|
||||
ad_mins_s: "min speed",
|
||||
ad_mins_l: ["minimum speed","for short segments"],
|
||||
ad_scar_s: "scarf length",
|
||||
ad_scar_l: ["ease up length for scarf joint. disables arc detection","0 = disabled"],
|
||||
ad_spol_s: "short path",
|
||||
ad_spol_l: ["polygons shorter than this","will have their print speed","scaled down to min speed","in millimeters"],
|
||||
ad_arct_s: "arc tolerance",
|
||||
ad_arct_l: ["convert faceted lines to arcs","center point drift tolerance","when matching arc points","consider values around 0.15","in millimeters","0 to disable"],
|
||||
ad_zhop_s: "z hop dist",
|
||||
ad_arct_l: ["convert faceted lines to arcs","center point drift tolerance","when matching arc points","consider values around 0.15","value in millimeters","0 or scarf disables this"],
|
||||
ad_zhop_s: "z hop distance",
|
||||
ad_zhop_l: ["amount to raise z","on retraction moves","in millimeters","0 to disable"],
|
||||
ad_abkl_s: "anti-backlash",
|
||||
ad_abkl_l: ["for better flat surface finish","use micro-movements to cancel","backlash in solid layer output","in millimeters","0 to disable","if your firmware has M425","put that in the gcode header","and leave this as 0"],
|
||||
|
|
@ -876,8 +884,8 @@ self.lang['en-us'] = {
|
|||
ad_altr_l: ["alternate shell winding order","clockwise / counter-clockwise","may reduce warping in thin areas","and help with belt edge adhesion"],
|
||||
ad_zint_s: "interleave z",
|
||||
ad_zint_l: ["interleave Z heights with odd number shells"],
|
||||
ad_lret_s: "layer retract",
|
||||
ad_lret_l: ["force filament retraction","between layers"],
|
||||
ad_lret_s: "force retract",
|
||||
ad_lret_l: ["force filament retraction between layers"],
|
||||
ad_agap_s: "avoid gaps",
|
||||
ad_agap_l: ["route around gaps rather","than perform a retract","when possible"],
|
||||
ad_play_s: "polish layers",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "Kiri:Moto 4.3.1",
|
||||
"name": "Kiri:Moto 4.3.2",
|
||||
"short_name": "Kiri:Moto",
|
||||
"description": "Slicer for 3D printers, CNC mills, laser cutters and more",
|
||||
"start_url": "/kiri/",
|
||||
|
|
|
|||
Loading…
Reference in a new issue