add laser z banding and flatten options

This commit is contained in:
Stewart Allen 2022-10-19 10:17:19 -04:00
commit 5f07f82eb3
6 changed files with 95 additions and 13 deletions

View file

@ -9,8 +9,8 @@
"gcodePre": [ "gcodePre": [
"G21 ; set units to MM (required)", "G21 ; set units to MM (required)",
"G90 ; absolute position mode (required)", "G90 ; absolute position mode (required)",
"G0 F6000 ; default rapid move speed", "G0 F2000 ; default rapid move speed",
"G1 F1500 ; default cutting speed" "G1 F250 ; default cutting speed"
], ],
"gcodePost": [ "gcodePost": [
"M30 ; program end" "M30 ; program end"

View file

@ -1277,12 +1277,29 @@ CAM.init = function(kiri, api) {
on: 'camLaserOn', on: 'camLaserOn',
off: 'camLaserOff', off: 'camLaserOff',
power: 'camLaserPower', power: 'camLaserPower',
adapt: 'camLaserAdaptive',
adaptrp: 'camLaserAdaptMod',
flat: 'camLaserFlatten',
flatz: 'camLaserFlatZ',
minp: 'camLaserPowerMin',
maxp: 'camLaserPowerMax',
minz: 'camLaserZMin',
maxz: 'camLaserZMax',
}).inputs = { }).inputs = {
enable: UC.newRow([ UC.newButton(LANG.enable, editEnable) ], {class:"ext-buttons f-row"}), enable: UC.newRow([ UC.newButton(LANG.enable, editEnable) ], {class:"ext-buttons f-row"}),
on: UC.newRow([ UC.newButton(LANG.on, editOn) ], {class:"ext-buttons f-row"}), on: UC.newRow([ UC.newButton(LANG.on, editOn) ], {class:"ext-buttons f-row"}),
off: UC.newRow([ UC.newButton(LANG.off, editOff) ], {class:"ext-buttons f-row"}), off: UC.newRow([ UC.newButton(LANG.off, editOff) ], {class:"ext-buttons f-row"}),
sep: UC.newBlank({class:"pop-sep"}), sep: UC.newBlank({class:"pop-sep"}),
power: UC.newInput(LANG.cl_powr_s, {title:LANG.cl_powr_l, convert:UC.toFloat, bound:UC.bound(0,1.0)}), power: UC.newInput(LANG.cl_powr_s, {title:LANG.cl_powr_l, convert:UC.toFloat, bound:UC.bound(0,1.0), show:() => !poppedRec.adapt}),
flatz: UC.newInput(LANG.cl_flaz_s, {title:LANG.cl_flaz_l, convert:UC.toFloat, show:() => poppedRec.flat}),
minp: UC.newInput(LANG.cl_minp_s, {title:LANG.cl_minp_l, convert:UC.toFloat, bound:UC.bound(0,1.0), show:() => poppedRec.adapt}),
maxp: UC.newInput(LANG.cl_maxp_s, {title:LANG.cl_maxp_l, convert:UC.toFloat, bound:UC.bound(0,1.0), show:() => poppedRec.adapt}),
minz: UC.newInput(LANG.cl_minz_s, {title:LANG.cl_minz_l, convert:UC.toFloat, show:() => poppedRec.adapt}),
maxz: UC.newInput(LANG.cl_maxz_s, {title:LANG.cl_maxz_l, convert:UC.toFloat, show:() => poppedRec.adapt}),
sep: UC.newBlank({class:"pop-sep"}),
adapt: UC.newBoolean(LANG.cl_adap_s, undefined, {title:LANG.cl_adap_l}),
adaptrp: UC.newBoolean(LANG.cl_adrp_s, undefined, {title:LANG.cl_adrp_l, show:() => poppedRec.adapt}),
flat: UC.newBoolean(LANG.cl_flat_s, undefined, {title:LANG.cl_flat_l}),
}; };
const editDisable = gcodeEditor('Laser Disable Script', 'disable'); const editDisable = gcodeEditor('Laser Disable Script', 'disable');

View file

@ -106,8 +106,8 @@ function prepEach(widget, settings, print, firstPoint, update) {
plungeRate = process.camFastFeedZ, plungeRate = process.camFastFeedZ,
feedRate, feedRate,
lastTool, lastTool,
lastMode,
lastPoint, lastPoint,
currentOp,
nextIsMove = true, nextIsMove = true,
synthPlunge = false, synthPlunge = false,
spindle = 0, spindle = 0,
@ -125,7 +125,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
newOutput.push(layerOut); newOutput.push(layerOut);
} }
layerOut = []; layerOut = [];
layerOut.mode = op || lastMode; layerOut.mode = op || currentOp;
layerOut.spindle = spindle; layerOut.spindle = spindle;
} }
@ -139,7 +139,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
newOutput.push([{ gcode: text }]); newOutput.push([{ gcode: text }]);
if (layerOut.length) { if (layerOut.length) {
layerOut = []; layerOut = [];
layerOut.mode = lastMode; layerOut.mode = currentOp;
layerOut.spindle = spindle; layerOut.spindle = spindle;
} }
} }
@ -170,7 +170,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
} }
function setLasering(bool, power = 0) { function setLasering(bool, power = 0) {
lasering = bool; lasering = bool ? currentOp : undefined;
laserPower = power; laserPower = power;
} }
@ -249,9 +249,28 @@ function prepEach(widget, settings, print, firstPoint, update) {
* @param {number} [tool] tool * @param {number} [tool] tool
*/ */
function layerPush(point, emit, speed, tool) { function layerPush(point, emit, speed, tool) {
layerOut.mode = lastMode; layerOut.mode = currentOp;
if (lasering) { if (lasering) {
print.addOutput(layerOut, point, emit ? laserPower : emit, speed, tool, 'laser'); let power = emit ? laserPower : 0;
if (emit && lasering.adapt) {
let { minz, maxz, minp, maxp, adaptrp } = lasering;
maxz = maxz || wztop;
let deltaz = maxz - minz;
let { z } = point;
if (adaptrp) {
while (z > maxz) z -= deltaz;
while (z < minz) z += deltaz;
} else if (z < minz || z > maxz) {
// skip outside of band
return point;
}
z -= minz;
power = minp + (z / deltaz) * (maxp - minp);
}
if (lasering.flat) {
point.z = lasering.flatz;
}
print.addOutput(layerOut, point, power, speed, tool, 'laser');
} else { } else {
print.addOutput(layerOut, point, emit, speed, tool); print.addOutput(layerOut, point, emit, speed, tool);
} }
@ -362,7 +381,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
} }
// todo synthesize move speed from feed / plunge accordingly // todo synthesize move speed from feed / plunge accordingly
layerOut.mode = lastMode; layerOut.mode = currentOp;
layerOut.spindle = spindle; layerOut.spindle = spindle;
lastPoint = layerPush( lastPoint = layerPush(
point, point,
@ -420,7 +439,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
for (let op of widget.camops) { for (let op of widget.camops) {
setTolerance(0); setTolerance(0);
nextIsMove = true; nextIsMove = true;
lastMode = op.op; currentOp = op.op;
let weight = op.weight(); let weight = op.weight();
newLayer(op.op); newLayer(op.op);
op.prepare(ops, (progress, message) => { op.prepare(ops, (progress, message) => {

View file

@ -533,7 +533,14 @@ const conf = exports({
camLaserOff: ["M5"], camLaserOff: ["M5"],
camLaserSpeed: 100, camLaserSpeed: 100,
camLaserPower: 1, camLaserPower: 1,
// camDrillReg: "none", camLaserAdaptive: false,
camLaserAdaptMod: false,
camLaserFlatten: false,
camLaserFlatZ: 0,
camLaserPowerMin: 0,
camLaserPowerMax: 1,
camLaserZMin: 0,
camLaserZMax: 0,
camTabsWidth: 5, camTabsWidth: 5,
camTabsHeight: 5, camTabsHeight: 5,
camTabsDepth: 5, camTabsDepth: 5,

View file

@ -106,6 +106,7 @@ async function path(levels, update, opts = {}) {
let lastEnd = null; let lastEnd = null;
let lastOut = null; let lastOut = null;
let current = null; let current = null;
let currentLaser = null;
let retracted = false; let retracted = false;
let retractz = 0; let retractz = 0;
@ -124,6 +125,7 @@ async function path(levels, update, opts = {}) {
const changes = []; const changes = [];
const retracts = []; const retracts = [];
const engages = []; const engages = [];
const lasers = [];
const output = new kiri.Layers(); const output = new kiri.Layers();
layers.push(output); layers.push(output);
@ -189,6 +191,19 @@ async function path(levels, update, opts = {}) {
} }
current.push(out.point); current.push(out.point);
} }
if (out.type === 'laser') {
current.isLaser = true;
if (out.emit) {
if (!lastOut.emit || out.emit !== lastOut.emit) {
// off to on or different power
currentLaser = newPolygon().setOpen();
currentLaser.push(lastOut.point);
currentLaser.color = rate_to_color(out.emit, 1);
lasers.push(currentLaser);
}
currentLaser.push(out.point);
}
}
lastEnd = null; lastEnd = null;
} else { } else {
current = newPolygon().setOpen(); current = newPolygon().setOpen();
@ -215,6 +230,13 @@ async function path(levels, update, opts = {}) {
pushPrint(lastOut.tool, current) pushPrint(lastOut.tool, current)
} }
if (lasers.length) {
for (let poly of lasers)
output
.setLayer('power', { line: 0x000055, face: 0x0000ff, opacity: 0.5 }, true)
.addPolys([ poly ], { thin: true, z: opts.z, color: poly.color });
}
if (changes.length) { if (changes.length) {
output output
.setLayer('tool', { line: 0x000055, face: 0x0000ff, opacity: 0.5 }, true) .setLayer('tool', { line: 0x000055, face: 0x0000ff, opacity: 0.5 }, true)
@ -267,8 +289,9 @@ async function path(levels, update, opts = {}) {
poly.setClosed(); poly.setClosed();
poly.points.pop(); poly.points.pop();
} }
let action = poly.isLaser ? 'speed' : opts.action || 'print';
output output
.setLayer(opts.action || 'print', printOpt) .setLayer(action, printOpt)
.addPolys([ poly ], .addPolys([ poly ],
thin ? { thin, z: opts.z, color: poly.color } : thin ? { thin, z: opts.z, color: poly.color } :
flat ? { flat ? {

View file

@ -557,6 +557,22 @@ self.kiri.lang['en-us'] = {
// CNC LASER // CNC LASER
cl_powr_s: "power", cl_powr_s: "power",
cl_powr_l: "laser power from 0 to 1.0", cl_powr_l: "laser power from 0 to 1.0",
cl_adap_s: "adaptive",
cl_adap_l: "use adaptive power based on Z height",
cl_adrp_s: "repeating",
cl_adrp_l: "apply a moduluse of Z height using the given band to make repeating patterns",
cl_flat_s: "flatten",
cl_flat_l: "flatten output to a given Z height",
cl_flaz_s: "height",
cl_flaz_l: ["flatten output to this Z height", "in workspace units"],
cl_minp_s: "min power",
cl_minp_l: ["lowest power for the Z band. when "],
cl_maxp_s: "max power",
cl_maxp_l: ["highest power for the Z band"],
cl_minz_s: "min height",
cl_minz_l: ["lowest Z band position"],
cl_maxz_s: "max height",
cl_maxz_l: ["highest Z band position. when set to 0, uses the highest Z point of the workspace"],
// CNC CUTOUT TABS // CNC CUTOUT TABS
ct_menu: "tabs", ct_menu: "tabs",