add fdm volumetric flow output caps
This commit is contained in:
parent
8a908cb373
commit
a26b1d6bef
9 changed files with 48 additions and 20 deletions
|
|
@ -60,7 +60,7 @@
|
||||||
"three": "^0.178.0",
|
"three": "^0.178.0",
|
||||||
"three-mesh-bvh": "^0.7.6",
|
"three-mesh-bvh": "^0.7.6",
|
||||||
"uglify-js": "3.14.5",
|
"uglify-js": "3.14.5",
|
||||||
"validator": ">=13.7.0",
|
"validator": ">=13.15.15",
|
||||||
"ws": "^8.18.2"
|
"ws": "^8.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,7 @@ export const conf = {
|
||||||
outputInvertY: false,
|
outputInvertY: false,
|
||||||
outputLayerRetract: false,
|
outputLayerRetract: false,
|
||||||
outputLoops: 0,
|
outputLoops: 0,
|
||||||
|
outputMaxFlowrate: 15,
|
||||||
outputMinLayerTime: 10,
|
outputMinLayerTime: 10,
|
||||||
outputMinSpeed: 5.0,
|
outputMinSpeed: 5.0,
|
||||||
outputPurgeTower: 0,
|
outputPurgeTower: 0,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ export class Topo {
|
||||||
x: axis === "x",
|
x: axis === "x",
|
||||||
y: axis === "y"
|
y: axis === "y"
|
||||||
},
|
},
|
||||||
zMin = min.z + 0.0001,
|
|
||||||
tolerance = op.tolerance,
|
tolerance = op.tolerance,
|
||||||
resolution = tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y)),
|
resolution = tolerance ? tolerance : 1 / Math.sqrt(density / (span.x * span.y)),
|
||||||
step = this.step = (tool.traceOffset() * 2) * op.step,
|
step = this.step = (tool.traceOffset() * 2) * op.step,
|
||||||
|
|
@ -123,7 +122,9 @@ export class Topo {
|
||||||
let slices = this.slices = [];
|
let slices = this.slices = [];
|
||||||
let slice = { min: range.min, max: range.min + step, index };
|
let slice = { min: range.min, max: range.min + step, index };
|
||||||
|
|
||||||
for (let z = range.min; z < range.max; z += resolution) {
|
// console.log({ shards, step, range, resolution });
|
||||||
|
for (let z = range.min; z <= range.max; z += resolution) {
|
||||||
|
// console.log({ z });
|
||||||
if (z > slice.max) {
|
if (z > slice.max) {
|
||||||
slices.push(slice);
|
slices.push(slice);
|
||||||
slice = { min: z, max: z + step, index };
|
slice = { min: z, max: z + step, index };
|
||||||
|
|
@ -131,7 +132,7 @@ export class Topo {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
slices.push(slice);
|
slices.push(slice);
|
||||||
// console.log({ shards, range, step, slices });
|
// console.log({ shards, range, step, slices: slices.slice() });
|
||||||
|
|
||||||
const { minions } = self.kiri_worker;
|
const { minions } = self.kiri_worker;
|
||||||
if (minions?.running > 1) {
|
if (minions?.running > 1) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { fdm_export } from './export.js';
|
||||||
// fil = filament diameter
|
// fil = filament diameter
|
||||||
// slice = slice height
|
// slice = slice height
|
||||||
function extrudePerMM(noz, fil, slice) {
|
function extrudePerMM(noz, fil, slice) {
|
||||||
|
// (ratio of nozzle to filament) * (ratio of slice to nozzle)
|
||||||
return ((Math.PI * util.sqr(noz / 2)) / (Math.PI * util.sqr(fil / 2))) * (slice / noz);
|
return ((Math.PI * util.sqr(noz / 2)) / (Math.PI * util.sqr(fil / 2))) * (slice / noz);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
{ extrudeAbs } = device,
|
{ extrudeAbs } = device,
|
||||||
{ exportThumb } = controller,
|
{ exportThumb } = controller,
|
||||||
{ extrudeMM, extrudePerMM } = FDM,
|
{ extrudeMM, extrudePerMM } = FDM,
|
||||||
extused = Object.keys(print.extruders).map(v => parseInt(v)),
|
|
||||||
timeFactor = (device.gcodeTime || 1) * 1.5,
|
timeFactor = (device.gcodeTime || 1) * 1.5,
|
||||||
decimals = config.gcode_decimals || 4,
|
decimals = config.gcode_decimals || 4,
|
||||||
zMoveMax = device.deviceZMax || 0,
|
zMoveMax = device.deviceZMax || 0,
|
||||||
|
|
@ -49,7 +48,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
last = null,
|
last = null,
|
||||||
zpos = 0,
|
zpos = 0,
|
||||||
bmax = 0,
|
bmax = 0,
|
||||||
blastz = 0,
|
|
||||||
belt_add_y = (process.firstLayerYOffset || 0) - (belty || 0),
|
belt_add_y = (process.firstLayerYOffset || 0) - (belty || 0),
|
||||||
oloops = process.outputLoops || 0,
|
oloops = process.outputLoops || 0,
|
||||||
zhop = process.zHopDistance || 0, // range
|
zhop = process.zHopDistance || 0, // range
|
||||||
|
|
@ -58,10 +56,8 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
retDist = process.outputRetractDist || 0, // range
|
retDist = process.outputRetractDist || 0, // range
|
||||||
retSpeed = process.outputRetractSpeed * 60 || 1, // range
|
retSpeed = process.outputRetractSpeed * 60 || 1, // range
|
||||||
retDwell = process.outputRetractDwell || 0, // range
|
retDwell = process.outputRetractDwell || 0, // range
|
||||||
timeDwell = retDwell / 1000,
|
|
||||||
scarfZ = process.outputScarfLength ? true : false,
|
scarfZ = process.outputScarfLength ? true : false,
|
||||||
arcDist = isBelt || scarfZ ? 0 : (process.arcTolerance || 0),
|
arcDist = isBelt || scarfZ ? 0 : (process.arcTolerance || 0),
|
||||||
arcMin = 1,
|
|
||||||
arcRes = 20,
|
arcRes = 20,
|
||||||
arcDev = 0.5,
|
arcDev = 0.5,
|
||||||
arcMax = 40,
|
arcMax = 40,
|
||||||
|
|
@ -85,7 +81,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
fanSpeedSave = undefined,
|
fanSpeedSave = undefined,
|
||||||
fanSpeedBase = 0,
|
fanSpeedBase = 0,
|
||||||
fanSpeed = 0,
|
fanSpeed = 0,
|
||||||
lastType = undefined,
|
|
||||||
lastNozzleTemp = nozzleTemp,
|
lastNozzleTemp = nozzleTemp,
|
||||||
lastBedTemp = bedTemp,
|
lastBedTemp = bedTemp,
|
||||||
lastFanSpeed = fanSpeed,
|
lastFanSpeed = fanSpeed,
|
||||||
|
|
@ -169,7 +164,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
retDist = params.outputRetractDist || 0; // range
|
retDist = params.outputRetractDist || 0; // range
|
||||||
retSpeed = params.outputRetractSpeed * 60 || 1; // range
|
retSpeed = params.outputRetractSpeed * 60 || 1; // range
|
||||||
retDwell = params.outputRetractDwell || 0; // range
|
retDwell = params.outputRetractDwell || 0; // range
|
||||||
timeDwell = retDwell / 1000;
|
|
||||||
nozzleTemp = layer === 0 ?
|
nozzleTemp = layer === 0 ?
|
||||||
params.firstLayerNozzleTemp || params.outputTemp :
|
params.firstLayerNozzleTemp || params.outputTemp :
|
||||||
params.outputTemp || params.firstLayerNozzleTemp;
|
params.outputTemp || params.firstLayerNozzleTemp;
|
||||||
|
|
@ -470,7 +464,7 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
if (isBelt) {
|
if (isBelt) {
|
||||||
let zheight = path ? path.height || 0 : 0;
|
let zheight = path ? path.height || 0 : 0;
|
||||||
epos.x = originCenter ? -pos.x : device.bedWidth - pos.x;
|
epos.x = originCenter ? -pos.x : device.bedWidth - pos.x;
|
||||||
epos.z = blastz = pos.z * icos;
|
epos.z = pos.z * icos;
|
||||||
epos.y = -pos.y + epos.z * bcos + belt_add_y;
|
epos.y = -pos.y + epos.z * bcos + belt_add_y;
|
||||||
lout = epos;
|
lout = epos;
|
||||||
}
|
}
|
||||||
|
|
@ -635,7 +629,7 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
|
|
||||||
// emit comment on output type chage
|
// emit comment on output type chage
|
||||||
if (last && out.type !== last.type) {
|
if (last && out.type !== last.type) {
|
||||||
lastType = subst.feature = out.type;
|
subst.feature = out.type;
|
||||||
if (gcodeFeature && gcodeFeature.length) {
|
if (gcodeFeature && gcodeFeature.length) {
|
||||||
appendAllSub(gcodeFeature);
|
appendAllSub(gcodeFeature);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -752,7 +746,6 @@ export function fdm_export(print, online, ondone, ondebug) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if new point is off the arc
|
// if new point is off the arc
|
||||||
// if (deem || depm || desp || dc > arcDist || cc.r < arcMin || cc.r > arcMax || dist > cc.r) {
|
|
||||||
if (deem || depm || desp || dc * arcQ.center.length / arcQ.rSum > arcDist || dist > cc.r || cc.r > arcMax || radFault || !arcValid()) {
|
if (deem || depm || desp || dc * arcQ.center.length / arcQ.rSum > arcDist || dist > cc.r || cc.r > arcMax || radFault || !arcValid()) {
|
||||||
// let debug = [deem, depm, desp, dc * arcQ.center.length / arcQ.rSum > arcDist, dist > cc.r, cc.r > arcMax, radFault];
|
// let debug = [deem, depm, desp, dc * arcQ.center.length / arcQ.rSum > arcDist, dist > cc.r, cc.r > arcMax, radFault];
|
||||||
if (arcQ.length === 4) {
|
if (arcQ.length === 4) {
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,7 @@ export function menu() {
|
||||||
arcTolerance: newInput(LANG.ad_arct_s, {title:LANG.ad_arct_l, convert:toFloat, bound:bound(0,1.0), show:() => { return isNotBelt() }}),
|
arcTolerance: newInput(LANG.ad_arct_s, {title:LANG.ad_arct_l, convert:toFloat, bound:bound(0,1.0), show:() => { return isNotBelt() }}),
|
||||||
outputRetractDwell: newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:toInt}),
|
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)}),
|
outputMinSpeed: newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, convert:toFloat, bound:bound(1,200)}),
|
||||||
|
outputMaxFlowrate: newInput(LANG.ad_maxf_s, {title:LANG.ad_maxf_l, convert:toFloat, bound:bound(1,200)}),
|
||||||
outputPurgeTower: newInput(LANG.ad_purg_s, {title:LANG.ad_purg_l, convert:toInt, bound:bound(0,1000)}),
|
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)}),
|
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)}),
|
outputShortPoly: newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, convert:toFloat, bound:bound(0,10000)}),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { FDM } from './driver-be.js';
|
||||||
import { base, util } from '../../../geo/base.js';
|
import { base, util } from '../../../geo/base.js';
|
||||||
import { poly2polyEmit, tip2tipEmit } from '../../../geo/paths.js';
|
import { poly2polyEmit, tip2tipEmit } from '../../../geo/paths.js';
|
||||||
import { newBounds } from '../../../geo/bounds.js';
|
import { newBounds } from '../../../geo/bounds.js';
|
||||||
|
|
@ -794,10 +795,22 @@ export async function fdm_prepare(widgets, settings, update) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output and route Slice (shell,fill) paths for a single Slice
|
||||||
|
*
|
||||||
|
* @param {*} print Print output Object
|
||||||
|
* @param {*} slice current slice being Output
|
||||||
|
* @param {*} startPoint starting point for this layer
|
||||||
|
* @param {*} offset start point offset
|
||||||
|
* @param {*} output output prebuffer
|
||||||
|
* @param {*} opt options
|
||||||
|
*/
|
||||||
function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
||||||
const { settings } = print;
|
const { settings } = print;
|
||||||
const { device } = settings;
|
const { device } = settings;
|
||||||
const { bedWidth, bedDepth, bedRound } = device;
|
const { bedWidth, bedDepth, bedRound } = device;
|
||||||
|
const { extrudePerMM } = FDM;
|
||||||
|
|
||||||
let preout = [],
|
let preout = [],
|
||||||
process = opt.params || settings.process,
|
process = opt.params || settings.process,
|
||||||
|
|
@ -806,6 +819,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
||||||
scarfLength = process.outputScarfLength || 0,
|
scarfLength = process.outputScarfLength || 0,
|
||||||
minLayerTime = process.outputMinLayerTime || 0,
|
minLayerTime = process.outputMinLayerTime || 0,
|
||||||
nozzleSize = process.sliceLineWidth || device.extruders[extruder].extNozzle,
|
nozzleSize = process.sliceLineWidth || device.extruders[extruder].extNozzle,
|
||||||
|
nozzles = device.extruders.map(e => e.extNozzle),
|
||||||
firstLayer = (opt.first || false) && !opt.support,
|
firstLayer = (opt.first || false) && !opt.support,
|
||||||
thinWall = nozzleSize * (opt.thinWall || 1.75),
|
thinWall = nozzleSize * (opt.thinWall || 1.75),
|
||||||
retractDist = opt.retractOver || (nozzleSize * 5),
|
retractDist = opt.retractOver || (nozzleSize * 5),
|
||||||
|
|
@ -828,6 +842,7 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
||||||
zhop = process.zHopDistance || 0,
|
zhop = process.zHopDistance || 0,
|
||||||
zmax = opt.zmax,
|
zmax = opt.zmax,
|
||||||
antiBacklash = process.antiBacklash,
|
antiBacklash = process.antiBacklash,
|
||||||
|
maxFlowRate = process.outputMaxFlowrate,
|
||||||
wipeDist = process.outputRetractWipe || 0,
|
wipeDist = process.outputRetractWipe || 0,
|
||||||
isBelt = device.bedBelt,
|
isBelt = device.bedBelt,
|
||||||
bedOffset = originCenter ? {
|
bedOffset = originCenter ? {
|
||||||
|
|
@ -1595,16 +1610,34 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
|
||||||
if (!p.emit) continue;
|
if (!p.emit) continue;
|
||||||
let mms = p.speed ?? 1;
|
let mms = p.speed ?? 1;
|
||||||
let dst = lp?.distTo2D(p.point) ?? 0;
|
let dst = lp?.distTo2D(p.point) ?? 0;
|
||||||
|
lp = p.point;
|
||||||
if (dst) {
|
if (dst) {
|
||||||
tt += (dst/mms);
|
tt += (dst/mms);
|
||||||
td += dst;
|
td += dst;
|
||||||
|
p.dst = dst;
|
||||||
}
|
}
|
||||||
lp = p.point;
|
|
||||||
}
|
}
|
||||||
if (minLayerTime && tt < minLayerTime) {
|
if (minLayerTime && tt < minLayerTime) {
|
||||||
let fact = tt / minLayerTime;
|
let fact = tt / minLayerTime;
|
||||||
for (let p of preout) {
|
for (let p of preout) {
|
||||||
if (p.emit) p.speed = Math.max(p.speed * fact, minSpeed);
|
if (p.emit) {
|
||||||
|
p.speed = Math.max(p.speed * fact, minSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply speed damping when output exceeds volumetric flowrate cap
|
||||||
|
if (maxFlowRate) {
|
||||||
|
for (let p of preout) {
|
||||||
|
if (p.emit && p.dst) {
|
||||||
|
let vfr = nozzles[p.tool] * slice.height * p.speed;
|
||||||
|
if (vfr > maxFlowRate) {
|
||||||
|
let old = p.speed;
|
||||||
|
let damp = maxFlowRate / vfr;
|
||||||
|
p.speed = p.speed * damp;
|
||||||
|
// console.log({ vfr, damp, old, new: p.speed });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,16 +127,12 @@ async function redirectOr404(path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fromCacheOrNetwork(req, test) {
|
async function fromCacheOrNetwork(req) {
|
||||||
const cache = await caches.open(CACHE_VERSION);
|
const cache = await caches.open(CACHE_VERSION);
|
||||||
const hit = await cache.match(req, { ignoreSearch: true });
|
const hit = await cache.match(req, { ignoreSearch: true });
|
||||||
if (hit) {
|
if (hit) {
|
||||||
// log(`hit: ${req.url}`);
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
if (test) {
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
const net = await fetch_safe(req);
|
const net = await fetch_safe(req);
|
||||||
cache.put(req, net.clone());
|
cache.put(req, net.clone());
|
||||||
log(`put: ${net.url}`);
|
log(`put: ${net.url}`);
|
||||||
|
|
|
||||||
|
|
@ -868,6 +868,8 @@ self.lang['en-us'] = {
|
||||||
ad_msol_l: ["minimum area (mm^2)","required to keep solid","must be > 0.1"],
|
ad_msol_l: ["minimum area (mm^2)","required to keep solid","must be > 0.1"],
|
||||||
ad_mins_s: "min speed",
|
ad_mins_s: "min speed",
|
||||||
ad_mins_l: ["minimum speed","for short segments"],
|
ad_mins_l: ["minimum speed","for short segments"],
|
||||||
|
ad_maxf_s: "max flowrate",
|
||||||
|
ad_maxf_l: ["maximum volumetric flowrate supported by this print head and filament","in millimeters^3 / second"],
|
||||||
ad_scar_s: "scarf length",
|
ad_scar_s: "scarf length",
|
||||||
ad_scar_l: ["ease up length for scarf joint. disables arc detection","0 = disabled"],
|
ad_scar_l: ["ease up length for scarf joint. disables arc detection","0 = disabled"],
|
||||||
ad_spol_s: "short path",
|
ad_spol_s: "short path",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue