add laser output operators and device settings in CAM mode
This commit is contained in:
parent
cd42021e42
commit
234b8c0a6e
9 changed files with 147 additions and 32 deletions
|
|
@ -5,6 +5,7 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
|
|||
|
||||
# Release 3.6
|
||||
|
||||
* add laser output operators and device settings in CAM mode
|
||||
* add fullscreen option. button next to user profile
|
||||
* mobile pinch zoom and layer slider usability improvements
|
||||
* update CLI to work in CAM mode and add working samples
|
||||
|
|
|
|||
|
|
@ -493,11 +493,12 @@ CAM.init = function(kiri, api) {
|
|||
}
|
||||
});
|
||||
|
||||
func.opGCode = () => {
|
||||
func.opGCode = (label, field = 'gcode') => {
|
||||
console.log({label});
|
||||
API.dialog.show('any');
|
||||
const { c_gcode } = h.bind(
|
||||
$('mod-any'), h.div({ id: "camop_dialog" }, [
|
||||
h.label('custom gcode operation'),
|
||||
h.label(label || 'custom gcode operation'),
|
||||
h.textarea({ id: "c_gcode", rows: 15, cols: 50 }),
|
||||
h.button({ _: 'done', onclick: () => {
|
||||
API.dialog.hide();
|
||||
|
|
@ -505,13 +506,20 @@ CAM.init = function(kiri, api) {
|
|||
} })
|
||||
])
|
||||
);
|
||||
c_gcode.value = poppedRec.gcode || '';
|
||||
c_gcode.value = poppedRec[field] || '';
|
||||
c_gcode.onkeyup = (el) => {
|
||||
poppedRec.gcode = c_gcode.value;
|
||||
poppedRec[field] = c_gcode.value;
|
||||
};
|
||||
c_gcode.focus();
|
||||
};
|
||||
|
||||
// create custom gcode editor function
|
||||
function gcodeEditor(label, field) {
|
||||
return function() {
|
||||
func.opGCode(label, field);
|
||||
}
|
||||
}
|
||||
|
||||
func.opFlip = () => {
|
||||
let widgets = API.widgets.all();
|
||||
let { process } = current;
|
||||
|
|
@ -1023,12 +1031,6 @@ CAM.init = function(kiri, api) {
|
|||
return current.device.spindleMax > 0;
|
||||
}
|
||||
|
||||
createPopOp('gcode', {
|
||||
gcode: 'camCustomGcode',
|
||||
}).inputs = {
|
||||
action: UC.newRow([ UC.newButton(LANG.edit, func.opGCode) ], {class:"ext-buttons f-row"})
|
||||
};
|
||||
|
||||
createPopOp('level', {
|
||||
tool: 'camLevelTool',
|
||||
spindle: 'camLevelSpindle',
|
||||
|
|
@ -1260,12 +1262,35 @@ CAM.init = function(kiri, api) {
|
|||
], {class:"ext-buttons f-row"})
|
||||
};
|
||||
|
||||
createPopOp('laser on', {
|
||||
createPopOp('gcode', {
|
||||
gcode: 'camCustomGcode',
|
||||
}).inputs = {
|
||||
action: UC.newRow([ UC.newButton(LANG.edit, gcodeEditor()) ], {class:"ext-buttons f-row"})
|
||||
};
|
||||
|
||||
createPopOp('laser off', {
|
||||
const editEnable = gcodeEditor('Laser Enable Script', 'enable');
|
||||
const editOn = gcodeEditor('Laser On Script', 'on');
|
||||
const editOff = gcodeEditor('Laser Off Script', 'off');
|
||||
|
||||
createPopOp('laser on', {
|
||||
enable: 'camLaserEnable',
|
||||
on: 'camLaserOn',
|
||||
off: 'camLaserOff',
|
||||
power: 'camLaserPower',
|
||||
}).inputs = {
|
||||
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"}),
|
||||
off: UC.newRow([ UC.newButton(LANG.off, editOff) ], {class:"ext-buttons f-row"}),
|
||||
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)}),
|
||||
};
|
||||
|
||||
const editDisable = gcodeEditor('Laser Disable Script', 'disable');
|
||||
|
||||
createPopOp('laser off', {
|
||||
disable: 'camLaserDisable',
|
||||
}).inputs = {
|
||||
disable: UC.newRow([ UC.newButton(LANG.disable, editDisable) ], {class:"ext-buttons f-row"}),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,14 @@ CAM.export = function(print, online) {
|
|||
maxZd = spro.camFastFeedZ,
|
||||
maxXYd = spro.camFastFeed,
|
||||
decimals = base.config.gcode_decimals || 4,
|
||||
pos = { x:null, y:null, z:null, f:null, t:null },
|
||||
pos = { x:null, y:null, z:null, f:null, t:null, emit:null },
|
||||
line,
|
||||
cidx,
|
||||
mode,
|
||||
point,
|
||||
points = 0,
|
||||
lasering = false,
|
||||
currentOp,
|
||||
stock = settings.stock || { },
|
||||
hasStock = spro.camStockOn && stock.x && stock.y && stock.z,
|
||||
ztOff = hasStock ? stock.z - widget.track.top : 0,
|
||||
|
|
@ -141,6 +143,7 @@ CAM.export = function(print, online) {
|
|||
}
|
||||
|
||||
function moveTo(out) {
|
||||
let laser = out.type === 'laser';
|
||||
let newpos = out.point;
|
||||
|
||||
// no point == dwell
|
||||
|
|
@ -245,6 +248,28 @@ CAM.export = function(print, online) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!lasering && laser) {
|
||||
// enable laser
|
||||
filterEmit(currentOp.camLaserOn, consts);
|
||||
}
|
||||
|
||||
// if (laser && pos.emit !== out.emit) {
|
||||
if (laser) {
|
||||
nl.append(space).append(`S${out.emit}`);
|
||||
}
|
||||
|
||||
if (laser) {
|
||||
pos.emit = out.emit;
|
||||
}
|
||||
|
||||
if (lasering && !laser) {
|
||||
// disable laser
|
||||
filterEmit(currentOp.camLaserOff, consts);
|
||||
}
|
||||
|
||||
// update lasering state
|
||||
lasering = laser;
|
||||
|
||||
// update time calculation
|
||||
time += (dist / (pos.f || 1000)) * 60;
|
||||
|
||||
|
|
@ -277,6 +302,10 @@ CAM.export = function(print, online) {
|
|||
let toolz = {}, ctool;
|
||||
// remap points as necessary for origins, offsets, inversions
|
||||
print.output.forEach(function(layer) {
|
||||
if (layer.op) {
|
||||
console.log({ op: layer.op });
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(layer)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -331,6 +360,10 @@ CAM.export = function(print, online) {
|
|||
}
|
||||
newSpindle = layerout.spindle;
|
||||
for (let out of layerout) {
|
||||
if (out.op) {
|
||||
currentOp = out.op;
|
||||
continue;
|
||||
}
|
||||
moveTo(out);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,29 @@ class OpGCode extends CamOp {
|
|||
}
|
||||
|
||||
prepare(ops, progress) {
|
||||
if (this.op.gcode) {
|
||||
ops.addGCode(this.op.gcode);
|
||||
}
|
||||
ops.addGCode(this.op.gcode);
|
||||
}
|
||||
}
|
||||
|
||||
class OpLaserOn extends CamOp {
|
||||
constructor(state, op) {
|
||||
super(state, op);
|
||||
}
|
||||
|
||||
prepare(ops, progress) {
|
||||
ops.addGCode(this.op.enable);
|
||||
ops.setLasering(true, this.op.power);
|
||||
}
|
||||
}
|
||||
|
||||
class OpLaserOff extends CamOp {
|
||||
constructor(state, op) {
|
||||
super(state, op);
|
||||
}
|
||||
|
||||
prepare(ops, progress) {
|
||||
ops.addGCode(this.op.disable);
|
||||
ops.setLasering(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1612,18 +1632,20 @@ CAM.shadowAt = function(widget, z, ztop) {
|
|||
};
|
||||
|
||||
CAM.OPS = CamOp.MAP = {
|
||||
"xray": OpXRay,
|
||||
"shadow": OpShadow,
|
||||
"level": OpLevel,
|
||||
"rough": OpRough,
|
||||
"outline": OpOutline,
|
||||
"contour": OpContour,
|
||||
"pocket": OpPocket,
|
||||
"trace": OpTrace,
|
||||
"drill": OpDrill,
|
||||
"register": OpRegister,
|
||||
"gcode": OpGCode,
|
||||
"flip": CamOp
|
||||
"xray": OpXRay,
|
||||
"shadow": OpShadow,
|
||||
"level": OpLevel,
|
||||
"rough": OpRough,
|
||||
"outline": OpOutline,
|
||||
"contour": OpContour,
|
||||
"pocket": OpPocket,
|
||||
"trace": OpTrace,
|
||||
"drill": OpDrill,
|
||||
"register": OpRegister,
|
||||
"laser on": OpLaserOn,
|
||||
"laser off": OpLaserOff,
|
||||
"gcode": OpGCode,
|
||||
"flip": CamOp
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
drillDown = 0,
|
||||
drillLift = 0,
|
||||
drillDwell = 0,
|
||||
lasering = false,
|
||||
laserPower = 0,
|
||||
newOutput = print.output || [],
|
||||
layerOut = [],
|
||||
printPoint,
|
||||
|
|
@ -129,6 +131,9 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
}
|
||||
|
||||
function addGCode(text) {
|
||||
if (!text || text.length === 0) {
|
||||
return;
|
||||
}
|
||||
newOutput.push(text);
|
||||
if (layerOut.length) {
|
||||
layerOut = [];
|
||||
|
|
@ -162,6 +167,11 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
plungeRate = plunge || plungeRate || feedRate;
|
||||
}
|
||||
|
||||
function setLasering(bool, power = 0) {
|
||||
lasering = bool;
|
||||
laserPower = power;
|
||||
}
|
||||
|
||||
function setDrill(down, lift, dwell) {
|
||||
drillDown = down;
|
||||
drillLift = lift;
|
||||
|
|
@ -238,7 +248,11 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
*/
|
||||
function layerPush(point, emit, speed, tool) {
|
||||
layerOut.mode = lastMode;
|
||||
print.addOutput(layerOut, point, emit, speed, tool);
|
||||
if (lasering) {
|
||||
print.addOutput(layerOut, point, emit ? laserPower : emit, speed, tool, 'laser');
|
||||
} else {
|
||||
print.addOutput(layerOut, point, emit, speed, tool);
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +298,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
}
|
||||
|
||||
// convert short planar moves to cuts in some cases
|
||||
if (isMove && deltaXY <= moveLen && deltaZ <= 0) {
|
||||
if (isMove && deltaXY <= moveLen && deltaZ <= 0 && !lasering) {
|
||||
let iscontour = tolerance > 0;
|
||||
let isflat = absDeltaZ < 0.001;
|
||||
// restrict this to contouring
|
||||
|
|
@ -299,9 +313,10 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
}
|
||||
} else if (isMove) {
|
||||
// for longer moves, check the terrain to see if we need to go up and over
|
||||
const bigXY = (deltaXY > moveLen);
|
||||
const bigXY = (deltaXY > moveLen && !lasering);
|
||||
const bigZ = (deltaZ > toolDiam/2 && deltaXY > tolerance);
|
||||
const midZ = (absDeltaZ >= tolerance);
|
||||
const midZ = (tolerance && absDeltaZ >= tolerance);
|
||||
|
||||
if (bigXY || bigZ || midZ) {
|
||||
let maxz = getZClearPath(
|
||||
terrain,
|
||||
|
|
@ -380,6 +395,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
setSpindle,
|
||||
setTolerance,
|
||||
setPrintPoint,
|
||||
setLasering,
|
||||
printPoint,
|
||||
newLayer,
|
||||
addGCode,
|
||||
|
|
@ -404,6 +420,7 @@ function prepEach(widget, settings, print, firstPoint, update) {
|
|||
nextIsMove = true;
|
||||
lastMode = op.op.type;
|
||||
let weight = op.weight();
|
||||
layerOut.push({ op });
|
||||
op.prepare(ops, (progress, message) => {
|
||||
update((opSum + (progress * weight)) / opTot, message || op.type(), message);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -527,6 +527,12 @@ const conf = exports({
|
|||
camRegisterThru: 5,
|
||||
camFlipAxis: "X",
|
||||
camFlipOther: "",
|
||||
camLaserEnable: "M321",
|
||||
camLaserDisable: "M322",
|
||||
camLaserOn: "M3",
|
||||
camLaserOff: "M5",
|
||||
camLaserSpeed: 100,
|
||||
camLaserPower: 1,
|
||||
// camDrillReg: "none",
|
||||
camTabsWidth: 5,
|
||||
camTabsHeight: 5,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Print {
|
|||
this.nextType = type;
|
||||
}
|
||||
|
||||
addOutput(array, point, emit, speed, tool) {
|
||||
addOutput(array, point, emit, speed, tool, type) {
|
||||
let { lastPoint, lastEmit, lastOut } = this;
|
||||
// drop duplicates (usually intruced by FDM bisections)
|
||||
if (lastPoint && point) {
|
||||
|
|
@ -47,7 +47,7 @@ class Print {
|
|||
// if (emit && emit < 1) console.log(emit);
|
||||
this.lastPoint = point;
|
||||
this.lastEmit = emit;
|
||||
this.lastOut = lastOut = new Output(point, emit, speed, tool, this.nextType);
|
||||
this.lastOut = lastOut = new Output(point, emit, speed, tool, type || this.nextType);
|
||||
if (tool !== undefined) {
|
||||
this.tools[tool] = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,10 @@ async function path(levels, update, opts = {}) {
|
|||
let emits = 0;
|
||||
|
||||
level.forEach(out => {
|
||||
// skip cam op records
|
||||
if (out.op) {
|
||||
return;
|
||||
}
|
||||
if (retracted && out.emit) {
|
||||
retracted = false;
|
||||
engages.push(lastOut.point);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ self.kiri.lang['en-us'] = {
|
|||
done: "done",
|
||||
edit: "edit",
|
||||
enable: "enable",
|
||||
disable: "disable",
|
||||
export: "export",
|
||||
files: "files",
|
||||
fullscreen: "fullscreen",
|
||||
|
|
@ -26,6 +27,8 @@ self.kiri.lang['en-us'] = {
|
|||
mesh: "mesh", // mesh editing
|
||||
metric: "metric",
|
||||
name: "name",
|
||||
off: "off", // turn something off (like a lightbulb)
|
||||
on: "on", // turn something on (like a lightbulb)
|
||||
prefs: "prefs", // left menu "preferences"
|
||||
preview: "preview",
|
||||
recent: "recent",
|
||||
|
|
@ -551,6 +554,10 @@ self.kiri.lang['en-us'] = {
|
|||
cf_nvrt_s: "z bottom",
|
||||
cf_nvrt_l: "invert z bottom setting to follow stock",
|
||||
|
||||
// CNC LASER
|
||||
cl_powr_s: "power",
|
||||
cl_powr_l: "laser power from 0 to 1.0",
|
||||
|
||||
// CNC CUTOUT TABS
|
||||
ct_menu: "tabs",
|
||||
ct_angl_s: "angle",
|
||||
|
|
|
|||
Loading…
Reference in a new issue