checkpoint settings work

This commit is contained in:
Stewart Allen 2020-04-09 14:52:43 -04:00
commit 499f4ff2c2
9 changed files with 392 additions and 348 deletions

View file

@ -2,23 +2,187 @@
"use strict";
var gs_kiri_conf = exports;
let gs_kiri_conf = exports;
(function() {
if (!self.kiri) self.kiri = { };
if (self.kiri.conf) return;
let KIRI = self.kiri;
let KIRI = self.kiri,
CVER = 2;
function genID() {
while (true) {
var k = Math.round(Math.random() * 9999999999).toString(36);
let k = Math.round(Math.random() * 9999999999).toString(36);
if (k.length >= 4 && k.length <= 8) return k;
}
}
KIRI.conf = {
// add fields to o(bject) from t(arget) that are missing
// remove fields from o(bject) that don't exist in f(ilter)
function fill_cull(o, t, f) {
// add missing
for (let k in t) {
if (!t.hasOwnProperty(k)) {
continue;
}
let okv = o[k];
if (f[k] !== undefined && (okv === undefined || okv === null)) {
// console.log({fill: k});
o[k] = t[k];
}
}
// remove invalid
for (let k in o) {
if (!o.hasOwnProperty(k)) {
continue;
}
if (!f.hasOwnProperty(k)) {
// console.log({cull: k});
delete o[k];
}
}
}
function valueOf(val, dv) {
return typeof(val) !== 'undefined' ? val : dv;
}
function device_v1_to_v2(device) {
if (device && device.filamentSize) {
device.extruders = [{
extFilament: device.filamentSize,
extNozzle: device.nozzleSize,
extSelect: ["T0"],
extDeselect: [],
extOffsetX: 0,
extOffsetY: 0
}];
delete device.filamentSize;
delete device.nozzleSize;
}
}
// convert default filter (from server) into device structure
function device_from_code(code,mode) {
// presence of internal field indicates already converted
if (code.internal >= 0) return code;
let API = KIRI.api,
cmd = code.cmd || {},
set = code.settings || {},
ext = code.extruders;
let device = {
mode: mode || '',
internal: 0,
bedHeight: 2.5,
bedWidth: valueOf(set.bed_width, 300),
bedDepth: valueOf(set.bed_depth, 175),
bedRound: valueOf(set.bed_circle, false),
maxHeight: valueOf(set.build_height, 150),
originCenter: valueOf(set.origin_center, false),
extrudeAbs: valueOf(set.extrude_abs, false),
spindleMax: valueOf(set.spindle_max, 0),
gcodeFan: valueOf(cmd.fan_power, ''),
gcodeTrack: valueOf(cmd.progress, ''),
gcodeLayer: valueOf(cmd.layer, []),
gcodePre: valueOf(code.pre, []),
gcodePost: valueOf(code.post, []),
gcodeProc: valueOf(code.proc, ''),
gcodePause: valueOf(code.pause, []),
gcodeDwell: valueOf(code.dwell, []),
gcodeSpindle: valueOf(cmd.spindle, []),
gcodeChange: valueOf(code['tool-change'], []),
gcodeFExt: valueOf(code['file-ext'], 'gcode'),
gcodeSpace: valueOf(code['token-space'], ''),
gcodeStrip: valueOf(code['strip-comments'], false),
gcodeLaserOn: valueOf(code['laser-on'], []),
gcodeLaserOff: valueOf(code['laser-off'], []),
extruders: []
};
if (ext) {
// synthesize extruders from new style settings
ext.forEach(rec => {
let e = API.clone(CONF.template.device.extruders[0]);
if (rec.nozzle) e.extNozzle = rec.nozzle;
if (rec.filament) e.extFilament = rec.filament;
if (rec.offset_x) e.extOffsetX = rec.offset_x;
if (rec.offset_y) e.extOffsetY = rec.offset_y;
if (rec.select) e.extSelect = rec.select;
if (rec.deselect) e.extDeselect= rec.deselect;
device.extruders.push(e);
});
} else {
// synthesize extruders from old style settings
device.extruders = [API.clone(CONF.template.device.extruders[0])];
device.extruders[0].extNozzle = valueOf(set.nozzle_size, 0.4);
device.extruders[0].extFilament = valueOf(set.filament_diameter, 1.75);
}
return device;
}
function forValues(o, fn) {
Object.values(o).forEach(v => fn(v));
}
// ensure settings structure is up-to-date
function normalize(settings) {
let API = KIRI.api,
filter = CONF.filter,
defaults = CONF.template,
filter_dev = filter.fdm.d,
filter_pro = filter.fdm.p;
switch (settings.mode) {
case 'FDM':
break;
case 'CAM':
filter_dev = filter.cam.d;
filter_pro = filter.cam.p;
break;
case 'LASER':
filter_dev = filter.laser.d;
filter_pro = filter.laser.p;
break;
}
// v1 to v2 changed FDM extruder / nozzle / filament structure
if (settings.ver === 1) {
// backup settings before upgrade
API.sdb.setItem(`ws-settings-${Date.now()}`, JSON.stringify(settings));
device_v1_to_v2(settings.device);
device_v1_to_v2(settings.cdev.FDM);
settings.ver = 2;
}
fill_cull(settings, defaults, defaults);
fill_cull(settings.device, defaults.device, filter_dev);
fill_cull(settings.process, defaults.process, filter_pro);
fill_cull(settings.cdev.FDM, defaults.device, filter.fdm.d);
forValues(settings.sproc.FDM, proc => {
fill_cull(proc, defaults.process, filter.fdm.p);
});
fill_cull(settings.cdev.CAM, defaults.device, filter.cam.d);
forValues(settings.sproc.CAM, proc => {
fill_cull(proc, defaults.process, filter.cam.p);
});
fill_cull(settings.cdev.LASER, defaults.device, filter.laser.d);
forValues(settings.sproc.LASER, proc => {
fill_cull(proc, defaults.process, filter.laser.p);
});
fill_cull(settings.controller, defaults.controller, defaults.controller);
return settings;
}
let CONF = KIRI.conf = {
// --------------- helper functions
normalize: normalize,
device_from_code: device_from_code,
// ---------------
MODES: {
FDM: 1, // fused deposition modeling (also FFF)
@ -30,11 +194,13 @@ var gs_kiri_conf = exports;
SLICE: 2,
PREVIEW: 3
},
// --------------- settings filters (for loading/saving)
// --------------- settings field filters
filter: {
fdm:{
// fields permitted in FDM:Device
d:{
mode: 1,
internal: 1,
bedWidth: 1,
bedDepth: 1,
bedHeight: 1,
@ -42,8 +208,6 @@ var gs_kiri_conf = exports;
maxHeight: 1,
extrudeAbs: 1,
originCenter: 1,
filamentSize: 1,
nozzleSize: 1,
gcodePre: 1,
gcodePost: 1,
gcodeProc: 1,
@ -120,6 +284,8 @@ var gs_kiri_conf = exports;
cam:{
// fields permitted in CAM:Device
d:{
mode: 1,
internal: 1,
bedWidth: 1,
bedDepth: 1,
bedHeight: 1,
@ -192,8 +358,11 @@ var gs_kiri_conf = exports;
laser: {
// fields permitted in Laser:Device
d:{
mode: 1,
internal: 1,
bedWidth: 1,
bedDepth: 1,
bedHeight: 1,
gcodePre: 1,
gcodePost: 1,
gcodeFExt: 1,
@ -220,8 +389,9 @@ var gs_kiri_conf = exports;
}
}
},
// --------------- (default)
// --------------- default settings
template: {
// use by UI for populating selectors
infill:[
{ name: "vase" },
{ name: "hex" },
@ -278,24 +448,24 @@ var gs_kiri_conf = exports;
taper_tip: 0,
}
],
// FDM/CAM/Laser
// FDM/CAM/Laser merged
device:{
mode: "", // device local
internal: 0, // device edit state
bedWidth: 300, // FDM/CAM/Laser
bedDepth: 175, // FDM/CAM/Laser
bedHeight: 2.5, // display only (deprecate)
bedRound: false, // FDM
originCenter: false,// FDM/CAM
maxHeight: 150, // FDM
filamentSize: 1.75, // FDM
nozzleSize: 0.4, // FDM
spindleMax: 0, // CAM
gcodePre: [], // FDM/CAM header script
gcodePost: [], // FDM/CAM footer script
gcodeProc: "", // FDM post processor script (encoding, etc)
gcodePause: [], // FDM pause script
gcodeProc: "", // FDM post processor script (encoding, etc)
gcodeFan: "", // FDM fan command
gcodeTrack: "", // FDM progress command
gcodeLayer: "", // FDM layer output
gcodeLayer: [], // FDM layer output
gcodeFExt: "", // CAM file extension
gcodeSpace: "", // CAM token spacing
gcodeStrip: true, // CAM strip comments
@ -305,27 +475,30 @@ var gs_kiri_conf = exports;
gcodeLaserOn: ["M106 S{power}"],// LASER turn on
gcodeLaserOff: ["M107"], // LASER turn off
extruders:[{ // FDM extruders structure
filament: 1.75,
nozzle: 0.4,
select: [],
deselect: [],
offsetX: 0,
offsetY: 0
extFilament: 1.75,
extNozzle: 0.4,
extSelect: ["T0"],
extDeselect: [],
extOffsetX: 0,
extOffsetY: 0
}]
},
// FDM/CAM/Laser
// FDM/CAM/Laser merged
process:{
// --- shared ---
processName: "default",
outputOriginBounds: true,
outputOriginCenter: true,
outputInvertX: false,
outputInvertY: false,
// --- FDM ---
sliceHeight: 0.25,
sliceShells: 3,
sliceFillAngle: 45,
sliceFillOverlap: 0.3,
sliceFillSparse: 0.5,
sliceFillType: "hex",
sliceSupportEnable: false,
sliceSupportDensity: 0.25,
sliceSupportOffset: 1.0,
@ -334,21 +507,18 @@ var gs_kiri_conf = exports;
sliceSupportArea: 1,
sliceSupportExtra: 0,
sliceSupportSpan: 6,
sliceSolidMinArea: 1,
sliceSolidLayers: 3,
sliceBottomLayers: 3,
sliceTopLayers: 3,
firstSliceHeight: 0.25,
firstLayerRate: 30,
firstLayerFillRate: 40,
firstLayerPrintMult: 1.0,
outputRaft: false,
outputRaftSpacing: 0.2,
firstLayerNozzleTemp: 0,
firstLayerBedTemp: 0,
outputRaft: false,
outputRaftSpacing: 0.2,
outputTemp: 200,
outputFanMax: 255,
outputBedTemp: 0,
@ -379,11 +549,9 @@ var gs_kiri_conf = exports;
gcodePauseLayers: "",
// --- LASER ---
laserOffset: 0.25,
laserSliceHeight: 1,
laserSliceSingle: false,
outputTileSpacing: 1,
outputTileScaling: 1,
outputLaserPower: 100,
@ -392,9 +560,7 @@ var gs_kiri_conf = exports;
outputLaserMerged: false,
// --- CAM ---
camFastFeed: 6000,
roughingTool: 1000,
roughingSpindle: 1000,
roughingDown: 2,
@ -404,7 +570,6 @@ var gs_kiri_conf = exports;
roughingStock: 0,
camPocketOnlyRough: false,
roughingOn: true,
finishingTool: 1000,
finishingSpindle: 1000,
finishingDown: 3,
@ -417,7 +582,6 @@ var gs_kiri_conf = exports;
finishingYOn: true,
finishCurvesOnly: false,
camPocketOnlyFinish: false,
drillTool: 1000,
drillSpindle: 1000,
drillDownSpeed: 250,
@ -425,13 +589,11 @@ var gs_kiri_conf = exports;
drillDwell: 250,
drillLift: 2,
drillingOn: false,
camTabsAngle: 0,
camTabsCount: 4,
camTabsWidth: 5,
camTabsHeight: 5,
camTabsOn: false,
camPocketOnly: false,
camDepthFirst: false,
camEaseDown: false,
@ -440,20 +602,11 @@ var gs_kiri_conf = exports;
camZTopOffset: 0,
camZBottom: 0,
camZClearance: 1,
camStockX: 0,
camStockY: 0,
camStockZ: 0,
camStockOffset: true,
outputClockwise: false,
// --- shared FDM/Laser/CAM ---
outputOriginBounds: true,
outputOriginCenter: true,
outputInvertX: false,
outputInvertY: false
},
// current process name
cproc:{
@ -470,12 +623,14 @@ var gs_kiri_conf = exports;
// cached device settings by mode
cdev: {
FDM: null,
CAM: null
CAM: null,
LASER: null
},
// now they're called devices instead of gcode filters
filter:{
FDM: "Any.Generic.Marlin",
CAM: "Any.Generic.Grbl"
CAM: "Any.Generic.Grbl",
LASER: "Any.Generic.Laser"
},
// custom devices by name
devices:{
@ -522,7 +677,7 @@ var gs_kiri_conf = exports;
},
mode: 'FDM',
id: genID(),
ver: 1
ver: CVER
}
};

View file

@ -11,6 +11,7 @@ var gs_kiri_init = exports;
let KIRI = self.kiri,
MOTO = self.moto,
CONF = KIRI.conf,
WIN = self.window,
DOC = self.document,
LOC = self.location,
@ -478,8 +479,8 @@ var gs_kiri_init = exports;
API.conf.show();
}
function putLocalDevice(devicename, code) {
settings().devices[devicename] = code;
function putLocalDevice(devicename, obj) {
settings().devices[devicename] = obj;
API.conf.save();
}
@ -490,7 +491,6 @@ var gs_kiri_init = exports;
function isLocalDevice(devicename) {
return settings().devices[devicename] ? true : false;
// return localFilters.contains(devicename);
}
function isFavoriteDevice(devicename) {
@ -514,50 +514,13 @@ var gs_kiri_init = exports;
$('selected-device').innerHTML = devicename;
}
function valueOf(val, dv) {
return typeof(val) !== 'undefined' ? val : dv;
}
// only for local filters
function updateDeviceCode(override) {
let oldname = getSelectedDevice(),
newname = override || UI.deviceName.value,
code = {
mode: API.mode.get(),
settings: {
bed_width: parseInt(UI.deviceWidth.value) || 300,
bed_depth: parseInt(UI.deviceDepth.value) || 175,
bed_circle: UI.deviceRound.checked,
build_height: parseInt(UI.deviceHeight.value) || 150,
nozzle_size: parseFloat(UI.extruderNozzle.value) || 0.4,
filament_diameter: parseFloat(UI.extruderFilament.value) || 1.75,
origin_center: UI.deviceOrigin.checked,
origin_top: UI.deviceOriginTop.checked,
extrude_abs: UI.extrudeAbsolute.checked,
spindle_max: parseInt(UI.deviceMaxSpindle.value) || 0
},
cmd: {
fan_power: UI.gcodeFan.value,
progress: UI.gcodeProgress.value,
spindle: UI.gcodeSpindle.value.split('\n'),
layer: UI.gcodeLayer.value.split('\n')
},
pre: UI.gcodeHeader.value.split('\n'),
post: UI.gcodeFooter.value.split('\n'),
pause: UI.gcodePause.value.split('\n'),
dwell: UI.gcodeDwell.value.split('\n'),
'laser-on': UI.gcodeLaserOn.value.split('\n'),
'laser-off': UI.gcodeLaserOff.value.split('\n'),
'tool-change': UI.gcodeToolChange.value.split('\n'),
'file-ext': UI.gcodeExtension.value,
'token-space': UI.gcodeToken.checked ? ' ' : '',
'strip-comments': UI.gcodeStrip.checked
};
if (oldname !== newname && isLocalDevice(oldname)) removeLocalDevice(oldname);
putLocalDevice(newname, code);
setDeviceCode(code, newname);
function cloneDevice() {
let name = `${getSelectedDevice()}.copy`;
let code = API.clone(settings().device);
code.mode = API.mode.get();
putLocalDevice(name, code);
setDeviceCode(code, name);
}
function setDeviceCode(code, devicename) {
@ -566,49 +529,15 @@ var gs_kiri_init = exports;
if (typeof(code) === 'string') code = js2o(code) || {};
let cmd = code.cmd || {},
set = code.settings || {},
local = isLocalDevice(devicename),
let mode = API.mode.get(),
current = settings(),
local = isLocalDevice(devicename),
dproc = current.devproc[devicename],
mode = API.mode.get();
current.device = {
bedHeight: 2.5,
bedWidth: valueOf(set.bed_width, 300),
bedDepth: valueOf(set.bed_depth, 175),
bedRound: valueOf(set.bed_circle, false),
maxHeight: valueOf(set.build_height, 150),
nozzleSize: valueOf(set.nozzle_size, 0.4),
filamentSize: valueOf(set.filament_diameter, 1.75),
originCenter: valueOf(set.origin_center, false),
extrudeAbs: valueOf(set.extrude_abs, false),
spindleMax: valueOf(set.spindle_max, 0),
gcodeFan: valueOf(cmd.fan_power, ''),
gcodeTrack: valueOf(cmd.progress, ''),
gcodeLayer: valueOf(cmd.layer, []),
gcodePre: valueOf(code.pre, []),
gcodePost: valueOf(code.post, []),
gcodeProc: valueOf(code.proc, ''),
gcodePause: valueOf(code.pause, []),
gcodeDwell: valueOf(code.dwell, []),
gcodeSpindle: valueOf(cmd.spindle, []),
gcodeChange: valueOf(code['tool-change'], []),
gcodeFExt: valueOf(code['file-ext'], 'gcode'),
gcodeSpace: valueOf(code['token-space'], ''),
gcodeStrip: valueOf(code['strip-comments'], false),
gcodeLaserOn: valueOf(code['laser-on'], []),
gcodeLaserOff: valueOf(code['laser-off'], [])
};
let dev = current.device,
dev = current.device = CONF.device_from_code(code,mode),
proc = current.process;
proc.outputOriginCenter = valueOf(set.origin_center, true);
proc.camOriginTop = valueOf(set.origin_top, true);
proc.outputOriginCenter = dev.outputOriginCenter;
UI.deviceName.value = devicename;
// common
UI.gcodeHeader.value = dev.gcodePre.join('\n');
UI.gcodeFooter.value = dev.gcodePost.join('\n');
UI.gcodePause.value = dev.gcodePause.join('\n');
@ -617,65 +546,69 @@ var gs_kiri_init = exports;
UI.deviceHeight.value = dev.maxHeight;
UI.deviceRound.checked = dev.bedRound;
UI.deviceOrigin.checked = proc.outputOriginCenter;
// FDM
UI.gcodeFan.value = dev.gcodeFan;
UI.gcodeProgress.value = dev.gcodeTrack;
UI.gcodeLayer.value = dev.gcodeLayer.join('\n');
UI.extruderFilament.value = dev.filamentSize;
UI.extruderNozzle.value = dev.nozzleSize;
UI.extrudeAbsolute.checked = dev.extrudeAbs;
// CAM
UI.deviceMaxSpindle.value = dev.spindleMax;
UI.gcodeSpindle.value = dev.gcodeSpindle.join('\n');
UI.gcodeDwell.value = dev.gcodeDwell.join('\n');
UI.gcodeToolChange.value = dev.gcodeChange.join('\n');
UI.gcodeExtension.value = dev.gcodeFExt;
UI.gcodeToken.checked = dev.gcodeSpace ? true : false;
UI.gcodeStrip.checked = dev.gcodeStrip;
// LASER
UI.gcodeLaserOn.value = dev.gcodeLaserOn.join('\n');
UI.gcodeLaserOff.value = dev.gcodeLaserOff.join('\n');
if (mode === 'FDM') {
UI.gcodeFan.value = dev.gcodeFan;
UI.gcodeProgress.value = dev.gcodeTrack;
UI.gcodeLayer.value = dev.gcodeLayer.join('\n');
UI.extrudeAbsolute.checked = dev.extrudeAbs;
}
if (mode === 'CAM') {
proc.camOriginTop = dev.outputOriginTop;
UI.deviceMaxSpindle.value = dev.spindleMax;
UI.gcodeSpindle.value = dev.gcodeSpindle.join('\n');
UI.gcodeDwell.value = dev.gcodeDwell.join('\n');
UI.gcodeToolChange.value = dev.gcodeChange.join('\n');
UI.gcodeToken.checked = dev.gcodeSpace ? true : false;
UI.gcodeStrip.checked = dev.gcodeStrip;
}
if (mode === 'LASER') {
UI.gcodeLaserOn.value = dev.gcodeLaserOn.join('\n');
UI.gcodeLaserOff.value = dev.gcodeLaserOff.join('\n');
}
// disable editing for non-local devices
[
UI.deviceName,
UI.gcodeHeader,
UI.gcodeFooter,
UI.gcodePause,
UI.deviceDepth,
UI.deviceWidth,
UI.deviceHeight,
UI.extrudeAbsolute,
UI.deviceOrigin,
UI.deviceOriginTop,
UI.deviceRound,
UI.gcodeFan,
UI.gcodeProgress,
UI.gcodeLayer,
UI.extruderFilament,
UI.extruderNozzle,
UI.deviceMaxSpindle,
UI.gcodeSpindle,
UI.gcodeDwell,
UI.gcodeToolChange,
UI.gcodeExtension,
UI.gcodeToken,
UI.gcodeStrip,
UI.gcodeLaserOn,
UI.gcodeLaserOff
UI.deviceName,
UI.gcodeHeader,
UI.gcodeFooter,
UI.gcodePause,
UI.deviceDepth,
UI.deviceWidth,
UI.deviceHeight,
UI.extrudeAbsolute,
UI.deviceOrigin,
UI.deviceOriginTop,
UI.deviceRound,
UI.gcodeFan,
UI.gcodeProgress,
UI.gcodeLayer,
UI.extFilament,
UI.extNozzle,
UI.deviceMaxSpindle,
UI.gcodeSpindle,
UI.gcodeDwell,
UI.gcodeToolChange,
UI.gcodeExtension,
UI.gcodeToken,
UI.gcodeStrip,
UI.gcodeLaserOn,
UI.gcodeLaserOff
].forEach(function(e) {
e.disabled = !local;
});
// hide spindle fields when device doens't support it
if (mode === 'CAM')
[
UI.extrudeAbsolute,
UI.roughingSpindle,
UI.finishingSpindle,
UI.drillSpindle
if (mode === 'CAM') [
UI.extrudeAbsolute,
UI.roughingSpindle,
UI.finishingSpindle,
UI.drillSpindle
].forEach(function(e) {
e.parentNode.style.display = dev.spindleMax >= 0 ? 'none' : 'block';
e.parentNode.style.display = dev.spindleMax >= 0 ? 'none' : 'block';
});
UI.deviceSave.disabled = !local;
@ -693,9 +626,10 @@ var gs_kiri_init = exports;
API.conf.save();
} catch (e) {
console.log({error:e, device:code, devicename});
throw e;
API.show.alert(`invalid or deprecated device: "${devicename}"`, 10);
API.show.alert(`please select a new device`, 10);
showDevices();
// showDevices();
}
API.function.clear();
API.event.settings();
@ -727,13 +661,12 @@ var gs_kiri_init = exports;
UI.deviceClose.onclick = API.dialog.hide;
UI.deviceSave.onclick = function() {
API.function.clear();
updateDeviceCode();
API.conf.save();
showDevices();
};
UI.deviceAdd.onclick = function() {
API.function.clear();
updateDeviceCode(getSelectedDevice()+".copy");
cloneDevice();
showDevices();
};
UI.deviceDelete.onclick = function() {
@ -787,11 +720,11 @@ var gs_kiri_init = exports;
}
showDevices();
};
if (API.show.favorites()) {
// if (API.show.favorites()) {
if (loc) opt.setAttribute("local", 1);
} else {
if (fav) opt.setAttribute("favorite", 1);
}
// } else {
if (loc || fav) opt.setAttribute("favorite", 1);
// }
UI.deviceSelect.appendChild(opt);
if (device === selected) {
selectedIndex = incr;
@ -1200,14 +1133,14 @@ var gs_kiri_init = exports;
deviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM}),
extruder: UC.newGroup(LANG.dv_gr_ext, $('device'), {group:"dext", nocompact:true, modes:FDM}),
extruderFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
extruderNozzle: UC.newInput(LANG.dv_nozl_s, {title:LANG.dv_nozl_l, convert:UC.toFloat, modes:FDM}),
extruderOffX: UC.newInput(LANG.dv_exox_s, {title:LANG.dv_exox_l, convert:UC.toFloat, modes:FDM, expert:true}),
extruderOffY: UC.newInput(LANG.dv_exoy_s, {title:LANG.dv_exoy_l, convert:UC.toFloat, modes:FDM, expert:true}),
extruderSelect: UC.newText(LANG.dv_exts_s, {title:LANG.dv_exts_l, modes:FDM, size:14, height:3, modes:FDM, expert:true}),
extruderDeselect: UC.newText(LANG.dv_extd_s, {title:LANG.dv_extd_l, modes:FDM, size:14, height:3, modes:FDM, expert:true}),
extFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
extNozzle: UC.newInput(LANG.dv_nozl_s, {title:LANG.dv_nozl_l, convert:UC.toFloat, modes:FDM}),
extOffsetX: UC.newInput(LANG.dv_exox_s, {title:LANG.dv_exox_l, convert:UC.toFloat, modes:FDM, expert:true}),
extOffsetY: UC.newInput(LANG.dv_exoy_s, {title:LANG.dv_exoy_l, convert:UC.toFloat, modes:FDM, expert:true}),
extSelect: UC.newText(LANG.dv_exts_s, {title:LANG.dv_exts_l, modes:FDM, size:14, height:3, modes:FDM, expert:true}),
extDeselect: UC.newText(LANG.dv_extd_s, {title:LANG.dv_extd_l, modes:FDM, size:14, height:3, modes:FDM, expert:true}),
extrudeAbsolute: UC.newBoolean(LANG.dv_xtab_s, onBooleanClick, {title:LANG.dv_xtab_l, modes:FDM}),
extruders: UC.newTableRow([[
extActions: UC.newTableRow([[
UC.newButton("<", undefined),
UC.newButton("+", undefined),
UC.newButton("-", undefined),

View file

@ -32,11 +32,11 @@ self.kiri.copyright = exports.COPYRIGHT;
STATS = new Stats(SDB),
SEED = 'kiri-seed',
// ---------------
MODES = KIRI.conf.MODES,
VIEWS = KIRI.conf.VIEWS,
filter = KIRI.conf.filter,
settings = KIRI.conf.template,
settingsDefault = settings,
CONF = KIRI.conf,
MODES = CONF.MODES,
VIEWS = CONF.VIEWS,
settings = clone(CONF.template),
settingsDefault = clone(settings),
// ---------------
Widget = kiri.Widget,
newWidget = kiri.newWidget,
@ -133,6 +133,7 @@ self.kiri.copyright = exports.COPYRIGHT;
o2js: o2js,
js2o: js2o,
ajax: ajax,
clone: clone,
focus: setFocus,
stats: STATS,
catalog: CATALOG,
@ -255,7 +256,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function Stats(db) {
this.db = db;
this.obj = js2o(this.db['stats'] || '{}');
var o = this.obj, k;
let o = this.obj, k;
for (k in o) {
if (!o.hasOwnProperty(k)) continue;
if (k === 'dn' || k.indexOf('-') > 0 || k.indexOf('_') > 0) {
@ -376,7 +377,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function parseOpt(ov) {
var opt = {}, kv, kva;
let opt = {}, kv, kva;
// handle kiri legacy and proper url encoding better
ov.replace(/&/g,',').split(',').forEach(function(el) {
kv = decodeURIComponent(el).split(':');
@ -409,17 +410,6 @@ self.kiri.copyright = exports.COPYRIGHT;
return js2o(SDB.getItem(key),def);
}
function cull(o, f) {
for (var k in o) {
if (!o.hasOwnProperty(k)) {
continue;
}
if (!f.hasOwnProperty(k)) {
delete o[k];
}
}
}
function setProgress(value, msg) {
if (value) {
value = UTIL.round(value*100,4);
@ -440,7 +430,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function meshArray() {
var out = [];
let out = [];
forAllWidgets(function(widget) {
out.push(widget.mesh);
});
@ -479,7 +469,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function updateSliderMax(set) {
var max = 0;
let max = 0;
if (viewMode === VIEWS.PREVIEW && currentPrint) {
max = currentPrint.getLayerCount();
} else {
@ -503,7 +493,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function hideSlices() {
var showing = false;
let showing = false;
setOpacity(color.model_opacity);
forAllWidgets(function(widget) {
widget.setWireframe(false);
@ -538,7 +528,7 @@ self.kiri.copyright = exports.COPYRIGHT;
UI.layerID.value = layer;
UI.layerSlider.value = layer;
var j,
let j,
slice,
slices,
layers,
@ -640,7 +630,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function preparePrint(callback) {
// kick off slicing it hasn't been done already
for (var i=0; i < WIDGETS.length; i++) {
for (let i=0; i < WIDGETS.length; i++) {
if (!WIDGETS[i].slices || WIDGETS[i].isModified()) {
prepareSlices(function() {
if (!WIDGETS[i].slices || WIDGETS[i].isModified()) {
@ -725,7 +715,7 @@ self.kiri.copyright = exports.COPYRIGHT;
setViewMode(VIEWS.SLICE);
API.conf.save();
var firstMesh = true,
let firstMesh = true,
countdown = WIDGETS.length,
preserveMax = API.var.layer_max,
preserveLayer = API.var.layer_at,
@ -739,7 +729,7 @@ self.kiri.copyright = exports.COPYRIGHT;
// for each widget, slice
forAllWidgets(function(widget) {
var segtimes = {},
let segtimes = {},
segNumber = 0,
errored = false,
startTime,
@ -748,7 +738,7 @@ self.kiri.copyright = exports.COPYRIGHT;
widget.stats.progress = 0;
widget.setColor(color.slicing);
widget.slice(settings, function(sliced, error) {
var mark = UTIL.time();
let mark = UTIL.time();
// on done
widget.render(renderMode, MODE === MODES.CAM);
// clear wireframe
@ -788,7 +778,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
}, function(update, msg) {
if (msg !== lastMsg) {
var mark = UTIL.time();
let mark = UTIL.time();
if (lastMsg) segtimes[segNumber+"_"+lastMsg] = mark - startTime;
lastMsg = msg;
startTime = mark;
@ -858,13 +848,13 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function scaleSelection(ev) {
var dv = parseFloat(ev.target.value || 1);
let dv = parseFloat(ev.target.value || 1);
if (UI.scaleUniform.checked) {
UI.scaleX.value = dv;
UI.scaleY.value = dv;
UI.scaleZ.value = dv;
}
var x = parseFloat(UI.scaleX.value || dv),
let x = parseFloat(UI.scaleX.value || dv),
y = parseFloat(UI.scaleY.value || dv),
z = parseFloat(UI.scaleZ.value || dv);
forSelectedGroups(function (w) {
@ -941,7 +931,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function platformUpdateSize() {
var dev = settings.device,
let dev = settings.device,
width, depth,
height = Math.round(Math.max(dev.bedHeight, dev.bedWidth/100, dev.bedDepth/100));
SPACE.platform.setRound(dev.bedRound);
@ -956,7 +946,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function platformUpdateBounds() {
var bounds = new THREE.Box3();
let bounds = new THREE.Box3();
forAllWidgets(function(widget) {
let wp = widget.track.pos;
let wb = widget.mesh.getBoundingBox().clone();
@ -968,7 +958,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function platformSelect(widget, shift) {
if (viewMode !== VIEWS.ARRANGE) return;
var mesh = widget.mesh,
let mesh = widget.mesh,
sel = (selectedMeshes.indexOf(mesh) >= 0);
if (sel) {
if (shift) {
@ -1010,7 +1000,7 @@ self.kiri.copyright = exports.COPYRIGHT;
});
return;
}
var mesh = widget.mesh,
let mesh = widget.mesh,
si = selectedMeshes.indexOf(mesh),
sel = (si >= 0);
if (sel) {
@ -1079,7 +1069,7 @@ self.kiri.copyright = exports.COPYRIGHT;
return;
}
if (Array.isArray(widget)) {
var mc = widget.slice(), i;
let mc = widget.slice(), i;
for (i=0; i<mc.length; i++) {
platform.delete(mc[i].widget);
}
@ -1103,7 +1093,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function platformLayout(event, space) {
var auto = UI.autoLayout.checked,
let auto = UI.autoLayout.checked,
proc = settings.process,
oldmode = viewMode,
layout = (viewMode === VIEWS.ARRANGE && auto),
@ -1132,17 +1122,17 @@ self.kiri.copyright = exports.COPYRIGHT;
return SPACE.update();
}
var gap = space;
let gap = space;
// in CNC mode with >1 widget, force layout with spacing @ 1.5x largest tool diameter
if (MODE === MODES.CAM && WIDGETS.length > 1) {
var spacing = space || 1, CAM = KIRI.driver.CAM;
let spacing = space || 1, CAM = KIRI.driver.CAM;
if (proc.roughingOn) spacing = Math.max(spacing, CAM.getToolDiameter(settings, proc.roughingTool));
if (proc.finishingOn || proc.finishingXOn || proc.finishingYOn) spacing = Math.max(spacing, CAM.getToolDiameter(settings, proc.finishingTool));
gap = spacing * 1.5;
}
var i, m, sz = SPACE.platform.size(),
let i, m, sz = SPACE.platform.size(),
mp = [sz.x, sz.y],
ms = [mp[0] / 2, mp[1] / 2],
mi = mp[0] > mp[1] ? [(mp[0] / mp[1]) * 10, 10] : [10, (mp[1] / mp[1]) * 10],
@ -1213,9 +1203,9 @@ self.kiri.copyright = exports.COPYRIGHT;
$('stock-height').innerText = (csz/scale).toFixed(2);
}
if (!camStock) {
var geo = new THREE.BoxGeometry(1, 1, 1);
var mat = new THREE.MeshBasicMaterial({ color: 0x777777, opacity: 0.2, transparent: true, side:THREE.DoubleSide });
var cube = new THREE.Mesh(geo, mat);
let geo = new THREE.BoxGeometry(1, 1, 1);
let mat = new THREE.MeshBasicMaterial({ color: 0x777777, opacity: 0.2, transparent: true, side:THREE.DoubleSide });
let cube = new THREE.Mesh(geo, mat);
SPACE.platform.add(cube);
camStock = cube;
}
@ -1247,66 +1237,32 @@ self.kiri.copyright = exports.COPYRIGHT;
* Settings Functions
******************************************************************* */
function resetSettings(force) {
if (force || confirm('reset all values to system defaults?')) {
settings = settingsDefault;
updateFields();
};
}
/**
* fill in missing settings from default template to pick up new fields
* that may have been recently added and expected in the code
*
* @param {Object} osrc
* @param {Object} odst
*/
function fillMissingSettings(osrc, odst) {
var key, val;
for (key in osrc) {
if (!osrc.hasOwnProperty(key)) continue;
val = odst[key];
if (typeof val === 'undefined' || val === null || val === '') {
odst[key] = osrc[key];
} else if (typeof osrc[key] === 'object') {
fillMissingSettings(osrc[key], odst[key]);
}
}
}
/**
* @returns {Object}
*/
// given a settings region, update values of matching bound UI fields
function updateFieldsFromSettings(scope) {
if (!scope) return console.trace("missing scope");
var key, val;
// CONF.normalize(settings);
fillMissingSettings(settingsDefault, settings);
settings.infill = settingsDefault.infill;
settings.units = settingsDefault.units;
for (key in scope) {
for (let key in scope) {
if (!scope.hasOwnProperty(key)) continue;
val = scope[key];
let val = scope[key];
if (UI.hasOwnProperty(key)) {
var uie = UI[key],
typ = uie ? uie.type : null;
let uie = UI[key], typ = uie ? uie.type : null;
if (typ === 'text') {
uie.value = val;
} else if (typ === 'checkbox') {
uie.checked = val;
} else if (typ === 'select-one') {
uie.innerHTML = '<option></option>';
var chosen = null;
var source = uie.parentNode.getAttribute('source');
var list = settings[source];
let source = uie.parentNode.getAttribute('source'),
list = settings[source],
chosen = null;
list.forEach(function(tool, index) {
let id = tool.id || tool.name;
if (val === id) {
chosen = index + 1;
}
var opt = DOC.createElement('option');
let opt = DOC.createElement('option');
opt.appendChild(DOC.createTextNode(tool.name));
opt.setAttribute('value', id);
uie.appendChild(opt);
@ -1315,8 +1271,6 @@ self.kiri.copyright = exports.COPYRIGHT;
}
}
}
return settings;
}
/**
@ -1325,17 +1279,19 @@ self.kiri.copyright = exports.COPYRIGHT;
function updateSettingsFromFields(scope) {
if (!scope) return console.trace("missing scope");
var key,
changed = false;
let key, changed = false;
// for each key in scope object
for (key in scope) {
if (!scope.hasOwnProperty(key)) continue;
if (!scope.hasOwnProperty(key)) {
continue;
}
if (UI.hasOwnProperty(key)) {
var nval = null,
uie = UI[key];
let nval = null, uie = UI[key];
// skip empty UI values
if (!uie || uie === '') continue;
if (!uie || uie === '') {
continue;
}
if (uie.type === 'text') {
nval = UI[key].convert();
} else if (uie.type === 'checkbox') {
@ -1348,6 +1304,8 @@ self.kiri.copyright = exports.COPYRIGHT;
nval = parseInt(nval);
}
}
} else {
continue;
}
if (scope[key] != nval) {
scope[key] = nval;
@ -1366,6 +1324,10 @@ self.kiri.copyright = exports.COPYRIGHT;
updateFieldsFromSettings(settings.process);
updateFieldsFromSettings(settings.layers);
updateFieldsFromSettings(settings.controller);
let device = settings.device;
if (device.extruders && device.extruders[device.internal]) {
updateFieldsFromSettings(device.extruders[device.internal]);
}
}
function updateSettings() {
@ -1373,33 +1335,19 @@ self.kiri.copyright = exports.COPYRIGHT;
updateSettingsFromFields(settings.process);
updateSettingsFromFields(settings.layers);
updateSettingsFromFields(settings.controller);
let device = settings.device;
if (device.extruders && device.extruders[device.internal]) {
updateSettingsFromFields(device.extruders[device.internal]);
}
API.conf.save();
platform.update_stock();
}
function saveSettings() {
// remove settings invalid for a given mode (cleanup)
cull(settings, settingsDefault);
switch (settings.mode) {
case 'FDM':
cull(settings.device, filter.fdm.d);
cull(settings.process, filter.fdm.p);
break;
case 'CAM':
cull(settings.device, filter.cam.d);
cull(settings.process, filter.cam.p);
break;
case 'LASER':
cull(settings.device, filter.laser.d);
cull(settings.process, filter.laser.p);
settings.cdev.LASER = clone(settings.device);
break;
}
cull(settings.cdev.FDM, filter.fdm.d);
cull(settings.cdev.CAM, filter.cam.d);
// store camera view
let view = SPACE.view.save();
if (view.left || view.up) settings.controller.view = view;
// CONF.normalize(settings);
SDB.setItem('ws-settings', JSON.stringify(settings));
}
@ -1408,19 +1356,20 @@ self.kiri.copyright = exports.COPYRIGHT;
try {
data = JSON.parse(atob(data));
} catch (e) {
console.log({data})
alert('invalid settings format');
console.log('data',data);
return;
}
}
if (!(data.settings && data.moto && data.time)) {
if (!(data.settings && data.version && data.time)) {
alert('invalid settings format');
console.log('data',data);
return;
}
if (ask && !confirm(`Import settings made on ${new Date(data.time)} from Kiri:Moto version ${data.version}?`)) {
return;
}
settings = data.settings;
settings = CONF.normalize(data.settings);
// MOTO.restore(data.moto);
// SDB.setItem('kiri-init', data.init || 2);
API.conf.save();
@ -1479,7 +1428,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function saveWorkspace() {
API.conf.save();
var newWidgets = [],
let newWidgets = [],
oldWidgets = js2o(SDB.getItem('ws-widgets'), []);
forAllWidgets(function(widget) {
newWidgets.push(widget.id);
@ -1494,12 +1443,11 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function restoreSettings(save) {
var newset = ls2o('ws-settings'),
let newset = ls2o('ws-settings'),
camera = ls2o('ws-camera');
if (newset) {
fillMissingSettings(settingsDefault, newset);
settings = newset;
settings = CONF.normalize(newset);
// override camera from settings
if (settings.controller.view) {
camera = settings.controller.view;
@ -1508,7 +1456,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
// merge custom filters from localstorage into settings
localFilters.forEach(function(fname) {
var fkey = "gcode-filter-"+fname, ov = ls2o(fkey);
let fkey = "gcode-filter-"+fname, ov = ls2o(fkey);
if (ov) settings.devices[fname] = ov;
SDB.removeItem(fkey)
});
@ -1573,7 +1521,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function modalShowing() {
var showing = $('modal').style.display !== 'none';
let showing = $('modal').style.display !== 'none';
return showing || UC.isPopped();
}
@ -1594,7 +1542,7 @@ self.kiri.copyright = exports.COPYRIGHT;
return;
}
["catalog","devices","tools","settings"].forEach(function(dialog) {
var style = UI[dialog].style;
let style = UI[dialog].style;
style.display = (dialog === which && (force || style.display !== 'flex') ? 'flex' : 'none');
});
}
@ -1608,13 +1556,13 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function putSettings(newset) {
settings = newset;
settings = CONF.normalize(newset);
API.conf.save()
API.space.restore(null, true);
}
function editSettings(e) {
var mode = getMode(),
let mode = getMode(),
name = e.target.getAttribute("name"),
load = settings.sproc[mode][name],
edit = prompt(`settings for "${name}"`, JSON.stringify(load));
@ -1633,19 +1581,12 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function loadSettings(e, named) {
var mode = getMode(),
let mode = getMode(),
name = e ? e.target.getAttribute("load") : named || settings.cproc[mode],
load = settings.sproc[mode][name];
if (!load) return;
for (var k in load) {
if (!load.hasOwnProperty(k)) continue;
// prevent stored process from overwriting device defaults
//if (k === "outputOriginCenter" && mode == "FDM") continue;
settings.process[k] = load[k];
}
settings.process.processName = name;
settings.cproc[mode] = name;
@ -1662,16 +1603,17 @@ self.kiri.copyright = exports.COPYRIGHT;
settings.process.outputOriginCenter = (settings.device.originCenter || false);
}
updateFields();
if (!named) {
hideDialog();
}
updateFields();
API.conf.update();
if (e) triggerSettingsEvent();
}
function deleteSettings(e) {
var name = e.target.getAttribute("del");
let name = e.target.getAttribute("del");
delete settings.sproc[getMode()][name];
updateSettingsList();
API.conf.save();
@ -1679,13 +1621,13 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function updateSettingsList() {
var list = [], s = settings, sp = s.sproc[getMode()] || {}, table = UI.settingsList;
let list = [], s = settings, sp = s.sproc[getMode()] || {}, table = UI.settingsList;
table.innerHTML = '';
for (var k in sp) {
for (let k in sp) {
if (sp.hasOwnProperty(k)) list.push(k);
}
list.sort().forEach(function(sk) {
var row = DOC.createElement('div'),
let row = DOC.createElement('div'),
load = DOC.createElement('button'),
edit = DOC.createElement('button'),
del = DOC.createElement('button'),
@ -1788,7 +1730,7 @@ self.kiri.copyright = exports.COPYRIGHT;
function setFocus(el) {
el = [ el || UI.load, UI.import, UI.ctrlLeft, UI.container, UI.assets, UI.control, UI.modeFDM, UI.reverseZoom, UI.modelOpacity, DOC.body ];
for (var es, i=0; i<el.length; i++) {
for (let es, i=0; i<el.length; i++) {
es = el[i];
es.focus();
if (DOC.activeElement === es) {
@ -1798,7 +1740,7 @@ self.kiri.copyright = exports.COPYRIGHT;
}
function setViewMode(mode) {
var oldMode = viewMode;
let oldMode = viewMode;
viewMode = mode;
platform.deselect();
updateSelectedInfo();

View file

@ -1,7 +1,7 @@
var exports = {
COPYRIGHT:"Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
LICENSE:"See the license.md file included with the source distribution",
VERSION:"1.8.2"
VERSION:"1.8.3"
};
if (!module) var module = {};
module.exports = exports;

View file

@ -567,7 +567,6 @@ var MOTO = window.moto = window.moto || {};
setColor: setPlatformColor,
setOrigin: setOrigin,
setGrid: setGrid,
add: function(o) { WORLD.add(o) },
remove: function(o) { WORLD.remove(o) },
setMaxZ: function(z) { panY = z / 2 },
@ -577,16 +576,13 @@ var MOTO = window.moto = window.moto || {};
setZOff: function(z) { platformZOff = z; updatePlatformPosition() },
setGZOff: function(z) { gridZOff = z; updatePlatformPosition() },
opacity: function(o) { platform.material.opacity = o },
onMove: function(f) { platformOnMove = f },
onHover: function(f) { platformHover = f },
onClick: function(f) { platformClick = f},
size: function() { return platform.scale },
isVisible: function() { return platform.visible },
showGrid: function(b) { gridView.visible = b },
setRound: function(bool) {
setRound: function(bool) {
let current = platform;
isRound = bool;
if (bool) {

View file

@ -38,6 +38,7 @@
* `B` fails in pancaking (clone) when there are no sliced layers (like z bottom too high)
* `B` linear finishing should extend beyond part boundaries by tool radius
* `B` outside cutting direction in roughing mode inverted
* `F` use arcs to connect hard angles
* `F` do not rough areas that go all the way through the part
https://github.com/GridSpace/grid-apps/issues/20
* `F` send gcode to cncjs

View file

@ -24,24 +24,20 @@
"G28 X0 Y0 ; home XY axes",
"M84 ; disable stepper motors"
],
"extruder":[
"extruders":[
{
"nozzle": 0.4,
"filament": 1.75,
"offset_x": 0,
"offset_y": 0,
"select": [
"T0"
],
"select": [ "T0" ],
"deselect": []
},
},{
"nozzle": 0.4,
"filament": 1.75,
"offset_x": 30,
"offset_y": 0,
"select": [
"T1"
],
"select": [ "T1" ],
"deselect": []
}
],

View file

@ -473,6 +473,11 @@ button.selected {
#devices-body {
height: 100%;
}
#device .tablerow button {
margin: 5px 3px 5px 3px;
padding-top: 0;
padding-bottom: 2px;
}
#device-labels span {
width: 200px;
padding: 2px 5px 2px 5px;

View file

@ -237,6 +237,23 @@ th, tr, td, span, div, label, button {
* ID
******************************************************************* */
.dark #appid span {
border-color: #555;
background-color: rgba(100,120,150,0.75);
color: #eee;
}
.dark #appid a {
color: #eee;
}
.dark #appid a:hover {
color: #eee;
}
.dark #appid span:hover {
background-color: rgba(80,100,230,0.75);
}
.dark #langpop {
color: black;
}
#appid {
text-align: center;
position: fixed;
@ -335,10 +352,9 @@ th, tr, td, span, div, label, button {
background-color: rgba(100,120,150,0.75);
border: 1px solid #555;
color: #eee;
xfont-weight: normal;
}
.dark .compact .grouphead:hover {
background-color: rgba(80,100,180,0.75);
background-color: rgba(80,100,230,0.75);
}
.dark .compact.control {
background-color: rgba(128,128,128,0.2) !important;