split cam tools out of init
This commit is contained in:
parent
f05bcbce4e
commit
606dea94e5
7 changed files with 335 additions and 310 deletions
|
|
@ -5,11 +5,11 @@
|
||||||
// dep: kiri-mode.cam.driver
|
// dep: kiri-mode.cam.driver
|
||||||
// use: kiri-mode.cam.animate
|
// use: kiri-mode.cam.animate
|
||||||
// use: kiri-mode.cam.animate2
|
// use: kiri-mode.cam.animate2
|
||||||
|
// use: kiri-mode.cam.tools
|
||||||
// use: load.gbr
|
// use: load.gbr
|
||||||
gapp.register("kiri-mode.cam.client", [], (root, exports) => {
|
gapp.register("kiri-mode.cam.client", [], (root, exports) => {
|
||||||
|
|
||||||
const { base, kiri } = root;
|
const { base, kiri } = root;
|
||||||
const { newPoint, newPolygon } = base;
|
|
||||||
const { driver } = kiri;
|
const { driver } = kiri;
|
||||||
const { CAM } = driver;
|
const { CAM } = driver;
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
|
|
|
||||||
292
src/kiri-mode/cam/tools.js
Normal file
292
src/kiri-mode/cam/tools.js
Normal file
|
|
@ -0,0 +1,292 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// dep: kiri.api
|
||||||
|
// dep: kiri.consts
|
||||||
|
// dep: kiri.settings
|
||||||
|
gapp.register("kiri-mode.cam.tools", (root, exports) => {
|
||||||
|
|
||||||
|
let { kiri } = root,
|
||||||
|
{ api, consts } = kiri,
|
||||||
|
{ uc, ui } = api,
|
||||||
|
{ MODES } = consts,
|
||||||
|
DOC = document,
|
||||||
|
selectedTool = null,
|
||||||
|
editTools = null,
|
||||||
|
maxTool = 0;
|
||||||
|
|
||||||
|
api.show.tools = showTools;
|
||||||
|
|
||||||
|
api.tool = {
|
||||||
|
update: updateTool
|
||||||
|
};
|
||||||
|
|
||||||
|
function settings() {
|
||||||
|
return api.conf.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTools() {
|
||||||
|
ui.toolSelect.innerHTML = '';
|
||||||
|
maxTool = 0;
|
||||||
|
editTools.forEach(function(tool, index) {
|
||||||
|
maxTool = Math.max(maxTool, tool.number);
|
||||||
|
tool.order = index;
|
||||||
|
let opt = DOC.createElement('option');
|
||||||
|
opt.appendChild(DOC.createTextNode(tool.name));
|
||||||
|
opt.onclick = function() { selectTool(tool) };
|
||||||
|
ui.toolSelect.appendChild(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectTool(tool) {
|
||||||
|
selectedTool = tool;
|
||||||
|
ui.toolName.value = tool.name;
|
||||||
|
ui.toolNum.value = tool.number;
|
||||||
|
ui.toolFluteDiam.value = tool.flute_diam;
|
||||||
|
ui.toolFluteLen.value = tool.flute_len;
|
||||||
|
ui.toolShaftDiam.value = tool.shaft_diam;
|
||||||
|
ui.toolShaftLen.value = tool.shaft_len;
|
||||||
|
ui.toolTaperTip.value = tool.taper_tip || 0;
|
||||||
|
ui.toolMetric.checked = tool.metric;
|
||||||
|
ui.toolType.selectedIndex = ['endmill','ballmill','tapermill'].indexOf(tool.type);
|
||||||
|
if (tool.type === 'tapermill') {
|
||||||
|
ui.toolTaperAngle.value = kiri.driver.CAM.calcTaperAngle(
|
||||||
|
(tool.flute_diam - tool.taper_tip) / 2, tool.flute_len
|
||||||
|
).round(1);
|
||||||
|
} else {
|
||||||
|
ui.toolTaperAngle.value = 0;
|
||||||
|
}
|
||||||
|
renderTool(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
function otag(o) {
|
||||||
|
if (Array.isArray(o)) {
|
||||||
|
let out = []
|
||||||
|
o.forEach(oe => out.push(otag(oe)));
|
||||||
|
return out.join('');
|
||||||
|
}
|
||||||
|
let tags = [];
|
||||||
|
Object.keys(o).forEach(key => {
|
||||||
|
let val = o[key];
|
||||||
|
let att = [];
|
||||||
|
Object.keys(val).forEach(tk => {
|
||||||
|
let tv = val[tk];
|
||||||
|
att.push(`${tk.replace(/_/g,'-')}="${tv}"`);
|
||||||
|
});
|
||||||
|
tags.push(`<${key} ${att.join(' ')}></${key}>`);
|
||||||
|
});
|
||||||
|
return tags.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTool(tool) {
|
||||||
|
let type = selectedTool.type;
|
||||||
|
let taper = type === 'tapermill';
|
||||||
|
ui.toolTaperAngle.disabled = taper ? undefined : 'true';
|
||||||
|
ui.toolTaperTip.disabled = taper ? undefined : 'true';
|
||||||
|
$('tool-view').innerHTML = '<svg id="tool-svg" width="100%" height="100%"></svg>';
|
||||||
|
setTimeout(() => {
|
||||||
|
let svg = $('tool-svg');
|
||||||
|
let pad = 10;
|
||||||
|
let dim = { w: svg.clientWidth, h: svg.clientHeight }
|
||||||
|
let max = { w: dim.w - pad * 2, h: dim.h - pad * 2};
|
||||||
|
let off = { x: pad, y: pad };
|
||||||
|
let shaft_fill = "#cccccc";
|
||||||
|
let flute_fill = "#dddddd";
|
||||||
|
let stroke = "#777777";
|
||||||
|
let stroke_width = 3;
|
||||||
|
let stroke_thin = stroke_width / 2;
|
||||||
|
let shaft = tool.shaft_len || 1;
|
||||||
|
let flute = tool.flute_len || 1;
|
||||||
|
let tip_len = type === "ballmill" ? tool.flute_diam / 2 : 0;
|
||||||
|
let total_len = shaft + flute + tip_len;
|
||||||
|
let units = dim.h / total_len;
|
||||||
|
let shaft_len = (shaft / total_len) * max.h;
|
||||||
|
let flute_len = (flute / total_len) * max.h;
|
||||||
|
let total_wid = Math.max(tool.flute_diam, tool.shaft_diam);
|
||||||
|
let shaft_off = (max.w - tool.shaft_diam * units) / 2;
|
||||||
|
let flute_off = (max.w - tool.flute_diam * units) / 2;
|
||||||
|
let taper_off = (max.w - (tool.taper_tip || 0) * units) / 2;
|
||||||
|
let parts = [
|
||||||
|
{ rect: {
|
||||||
|
x:off.x + shaft_off, y:off.y,
|
||||||
|
width:max.w - shaft_off * 2, height:shaft_len,
|
||||||
|
stroke, fill: shaft_fill, stroke_width
|
||||||
|
} }
|
||||||
|
];
|
||||||
|
if (type === "tapermill") {
|
||||||
|
let yoff = off.y + shaft_len;
|
||||||
|
let mid = dim.w / 2;
|
||||||
|
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
|
||||||
|
`M ${off.x + flute_off} ${yoff}`,
|
||||||
|
`L ${off.x + taper_off} ${yoff + flute_len}`,
|
||||||
|
`L ${dim.w - off.x - taper_off} ${yoff + flute_len}`,
|
||||||
|
`L ${dim.w - off.x - flute_off} ${yoff}`,
|
||||||
|
`z`
|
||||||
|
].join('\n')}});
|
||||||
|
} else {
|
||||||
|
let x1 = off.x + flute_off;
|
||||||
|
let y1 = off.y + shaft_len;
|
||||||
|
let x2 = x1 + max.w - flute_off * 2;
|
||||||
|
let y2 = y1 + flute_len;
|
||||||
|
parts.push({ rect: {
|
||||||
|
x:off.x + flute_off, y:off.y + shaft_len,
|
||||||
|
width:max.w - flute_off * 2, height:flute_len,
|
||||||
|
stroke, fill: flute_fill, stroke_width
|
||||||
|
} });
|
||||||
|
parts.push({ line: { x1, y1, x2, y2, stroke, stroke_width: stroke_thin } });
|
||||||
|
parts.push({ line: {
|
||||||
|
x1: (x1 + x2) / 2, y1, x2, y2: (y1 + y2) / 2,
|
||||||
|
stroke, stroke_width: stroke_thin
|
||||||
|
} });
|
||||||
|
parts.push({ line: {
|
||||||
|
x1, y1: (y1 + y2) / 2, x2: (x1 + x2) / 2, y2,
|
||||||
|
stroke, stroke_width: stroke_thin
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
if (type === "ballmill") {
|
||||||
|
let rad = (max.w - flute_off * 2) / 2;
|
||||||
|
let xend = dim.w - off.x - flute_off;
|
||||||
|
let yoff = off.y + shaft_len + flute_len + stroke_width/2;
|
||||||
|
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
|
||||||
|
`M ${off.x + flute_off} ${yoff}`,
|
||||||
|
`A ${rad} ${rad} 0 0 0 ${xend} ${yoff}`,
|
||||||
|
// `L ${off.x + flute_off} ${yoff}`
|
||||||
|
].join('\n')}})
|
||||||
|
}
|
||||||
|
svg.innerHTML = otag(parts);
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTool(ev) {
|
||||||
|
selectedTool.name = ui.toolName.value;
|
||||||
|
selectedTool.number = parseInt(ui.toolNum.value);
|
||||||
|
selectedTool.flute_diam = parseFloat(ui.toolFluteDiam.value);
|
||||||
|
selectedTool.flute_len = parseFloat(ui.toolFluteLen.value);
|
||||||
|
selectedTool.shaft_diam = parseFloat(ui.toolShaftDiam.value);
|
||||||
|
selectedTool.shaft_len = parseFloat(ui.toolShaftLen.value);
|
||||||
|
selectedTool.taper_tip = parseFloat(ui.toolTaperTip.value);
|
||||||
|
selectedTool.metric = ui.toolMetric.checked;
|
||||||
|
selectedTool.type = ['endmill','ballmill','tapermill'][ui.toolType.selectedIndex];
|
||||||
|
if (selectedTool.type === 'tapermill') {
|
||||||
|
const CAM = kiri.driver.CAM;
|
||||||
|
const rad = (selectedTool.flute_diam - selectedTool.taper_tip) / 2;
|
||||||
|
if (ev && ev.target === ui.toolTaperAngle) {
|
||||||
|
const angle = parseFloat(ev.target.value);
|
||||||
|
const len = CAM.calcTaperLength(rad, angle * DEG2RAD);
|
||||||
|
selectedTool.flute_len = len;
|
||||||
|
ui.toolTaperAngle.value = angle.round(1);
|
||||||
|
ui.toolFluteLen.value = selectedTool.flute_len.round(4);
|
||||||
|
} else {
|
||||||
|
ui.toolTaperAngle.value = CAM.calcTaperAngle(rad, selectedTool.flute_len).round(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ui.toolTaperAngle.value = 0;
|
||||||
|
}
|
||||||
|
renderTools();
|
||||||
|
ui.toolSelect.selectedIndex = selectedTool.order;
|
||||||
|
setToolChanged(true);
|
||||||
|
renderTool(selectedTool);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setToolChanged(changed) {
|
||||||
|
editTools.changed = changed;
|
||||||
|
ui.toolsSave.disabled = !changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTools() {
|
||||||
|
if (api.mode.get_id() !== MODES.CAM) return;
|
||||||
|
api.settings.sync.get().then(_showTools);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _showTools() {
|
||||||
|
let selectedIndex = null;
|
||||||
|
|
||||||
|
editTools = settings().tools.slice().sort((a,b) => {
|
||||||
|
return a.name > b.name ? 1 : -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
setToolChanged(false);
|
||||||
|
|
||||||
|
ui.toolsClose.onclick = function() {
|
||||||
|
if (editTools.changed && !confirm("abandon changes?")) return;
|
||||||
|
api.dialog.hide();
|
||||||
|
};
|
||||||
|
ui.toolAdd.onclick = function() {
|
||||||
|
let metric = settings().controller.units === 'mm';
|
||||||
|
editTools.push(Object.assign({
|
||||||
|
id: Date.now(),
|
||||||
|
number: maxTool + 1,
|
||||||
|
name: "new tool",
|
||||||
|
type: "endmill",
|
||||||
|
taper_tip: 0,
|
||||||
|
metric
|
||||||
|
}, metric ? {
|
||||||
|
shaft_diam: 2,
|
||||||
|
shaft_len: 15,
|
||||||
|
flute_diam: 2,
|
||||||
|
flute_len: 20,
|
||||||
|
} : {
|
||||||
|
shaft_diam: 0.25,
|
||||||
|
shaft_len: 1.5,
|
||||||
|
flute_diam: 0.25,
|
||||||
|
flute_len: 2,
|
||||||
|
}));
|
||||||
|
setToolChanged(true);
|
||||||
|
renderTools();
|
||||||
|
ui.toolSelect.selectedIndex = editTools.length-1;
|
||||||
|
selectTool(editTools[editTools.length-1]);
|
||||||
|
};
|
||||||
|
ui.toolCopy.onclick = function() {
|
||||||
|
let clone = Object.assign({}, selectedTool);
|
||||||
|
clone.number = maxTool + 1;
|
||||||
|
clone.name = `${clone.name} copy`;
|
||||||
|
editTools.push(clone);
|
||||||
|
setToolChanged(true);
|
||||||
|
renderTools();
|
||||||
|
ui.toolSelect.selectedIndex = editTools.length-1;
|
||||||
|
selectTool(editTools[editTools.length-1]);
|
||||||
|
};
|
||||||
|
ui.toolDelete.onclick = function() {
|
||||||
|
editTools.remove(selectedTool);
|
||||||
|
setToolChanged(true);
|
||||||
|
renderTools();
|
||||||
|
};
|
||||||
|
ui.toolsSave.onclick = function() {
|
||||||
|
if (selectedTool) updateTool();
|
||||||
|
settings().tools = editTools.sort((a,b) => {
|
||||||
|
return a.name < b.name ? -1 : 1;
|
||||||
|
});
|
||||||
|
setToolChanged(false);
|
||||||
|
api.conf.save();
|
||||||
|
api.conf.update_fields();
|
||||||
|
api.event.settings();
|
||||||
|
api.settings.sync.put();
|
||||||
|
};
|
||||||
|
ui.toolsExport.onclick = () => {
|
||||||
|
uc.prompt("Export Tools Filename", "tools").then(name => {
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const record = {
|
||||||
|
version: kiri.version,
|
||||||
|
tools: api.conf.get().tools,
|
||||||
|
time: Date.now()
|
||||||
|
};
|
||||||
|
api.util.download(api.util.b64enc(record), `${name}.km`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
renderTools();
|
||||||
|
if (editTools.length > 0) {
|
||||||
|
selectTool(editTools[0]);
|
||||||
|
ui.toolSelect.selectedIndex = 0;
|
||||||
|
} else {
|
||||||
|
ui.toolAdd.onclick();
|
||||||
|
}
|
||||||
|
|
||||||
|
api.dialog.show('tools');
|
||||||
|
ui.toolSelect.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -72,29 +72,20 @@ function localSet(key, val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = exports({
|
const api = exports({
|
||||||
|
ajax: ajax,
|
||||||
|
doit: {
|
||||||
|
undo: noop, // set in do.js
|
||||||
|
redo: noop // set in do.js
|
||||||
|
},
|
||||||
clip: (text) => {
|
clip: (text) => {
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.writeText(text)
|
.writeText(text)
|
||||||
.catch(err => console.error('Clipboard Error:', err));
|
.catch(err => console.error('Clipboard Error:', err));
|
||||||
},
|
},
|
||||||
clone: Object.clone,
|
clone: Object.clone,
|
||||||
sdb: data.local,
|
|
||||||
ajax: ajax,
|
|
||||||
js2o: js2o,
|
|
||||||
o2js: o2js,
|
|
||||||
lists: LISTS,
|
|
||||||
doit: {
|
|
||||||
undo: noop, // set in do.js
|
|
||||||
redo: noop // set in do.js
|
|
||||||
},
|
|
||||||
var: {
|
|
||||||
layer_lo: 0,
|
|
||||||
layer_hi: 0,
|
|
||||||
layer_max: 0
|
|
||||||
},
|
|
||||||
feature,
|
|
||||||
devel,
|
devel,
|
||||||
tweak,
|
feature,
|
||||||
|
js2o: js2o,
|
||||||
local: {
|
local: {
|
||||||
get: (key) => localGet(key),
|
get: (key) => localGet(key),
|
||||||
getInt: (key) => parseInt(localGet(key)),
|
getInt: (key) => parseInt(localGet(key)),
|
||||||
|
|
@ -106,7 +97,19 @@ const api = exports({
|
||||||
toggle: (key, val, def) => localSet(key, val ?? !api.local.getBoolean(key, def)),
|
toggle: (key, val, def) => localSet(key, val ?? !api.local.getBoolean(key, def)),
|
||||||
put: (key, val) => localSet(key, val),
|
put: (key, val) => localSet(key, val),
|
||||||
set: (key, val) => localSet(key, val),
|
set: (key, val) => localSet(key, val),
|
||||||
}
|
},
|
||||||
|
lists: LISTS,
|
||||||
|
o2js: o2js,
|
||||||
|
sdb: data.local,
|
||||||
|
show: {},
|
||||||
|
uc: {},
|
||||||
|
ui: {},
|
||||||
|
var: {
|
||||||
|
layer_lo: 0,
|
||||||
|
layer_hi: 0,
|
||||||
|
layer_max: 0
|
||||||
|
},
|
||||||
|
tweak,
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// dep: kiri.api
|
||||||
// dep: kiri.settings
|
// dep: kiri.settings
|
||||||
gapp.register("kiri.devices", (root, exports) => {
|
gapp.register("kiri.devices", (root, exports) => {
|
||||||
|
|
||||||
let { kiri } = root;
|
let { kiri } = root,
|
||||||
let { api, conf } = kiri;
|
{ api, conf } = kiri;
|
||||||
|
|
||||||
|
api.show.devices = showDevices;
|
||||||
|
|
||||||
api.device = {
|
api.device = {
|
||||||
clone: cloneDevice,
|
clone: cloneDevice,
|
||||||
|
|
|
||||||
291
src/kiri/init.js
291
src/kiri/init.js
|
|
@ -15,6 +15,7 @@
|
||||||
// use: kiri.pack
|
// use: kiri.pack
|
||||||
gapp.register("kiri.init", (root, exports) => {
|
gapp.register("kiri.init", (root, exports) => {
|
||||||
|
|
||||||
|
// builds and wires up the UI
|
||||||
let { base, kiri } = root,
|
let { base, kiri } = root,
|
||||||
{ api, catalog, consts, space } = kiri,
|
{ api, catalog, consts, space } = kiri,
|
||||||
{ sdb, stats, platform, selection, ui, uc } = api,
|
{ sdb, stats, platform, selection, ui, uc } = api,
|
||||||
|
|
@ -23,7 +24,6 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
{ CAM, SLA, FDM, LASER, DRAG, WJET, WEDM } = MODES,
|
{ CAM, SLA, FDM, LASER, DRAG, WJET, WEDM } = MODES,
|
||||||
WIN = self.window,
|
WIN = self.window,
|
||||||
DOC = self.document,
|
DOC = self.document,
|
||||||
DEG2RAD = Math.PI / 180,
|
|
||||||
STARTMODE = SETUP.sm && SETUP.sm.length === 1 ? SETUP.sm[0] : null,
|
STARTMODE = SETUP.sm && SETUP.sm.length === 1 ? SETUP.sm[0] : null,
|
||||||
TWOD = [LASER, DRAG, WJET, WEDM],
|
TWOD = [LASER, DRAG, WJET, WEDM],
|
||||||
TWONED = [LASER, DRAG, WJET],
|
TWONED = [LASER, DRAG, WJET],
|
||||||
|
|
@ -34,9 +34,6 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
NO_WEDM = [FDM, CAM, SLA, LASER, DRAG, WJET],
|
NO_WEDM = [FDM, CAM, SLA, LASER, DRAG, WJET],
|
||||||
FDM_CAM = [FDM, CAM],
|
FDM_CAM = [FDM, CAM],
|
||||||
proto = location.protocol,
|
proto = location.protocol,
|
||||||
selectedTool = null,
|
|
||||||
editTools = null,
|
|
||||||
maxTool = 0,
|
|
||||||
platformColor,
|
platformColor,
|
||||||
separator = true,
|
separator = true,
|
||||||
hideable = true,
|
hideable = true,
|
||||||
|
|
@ -46,17 +43,12 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
// copy version from grid app
|
// copy version from grid app
|
||||||
kiri.version = gapp.version;
|
kiri.version = gapp.version;
|
||||||
|
|
||||||
// extend KIRI API with local functions
|
|
||||||
api.show.devices = showDevices;
|
|
||||||
// api.device.set = selectDevice;
|
|
||||||
// api.device.clone = cloneDevice;
|
|
||||||
|
|
||||||
function settings() {
|
function settings() {
|
||||||
return api.conf.get();
|
return api.conf.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showDevices() {
|
function updateTool() {
|
||||||
api.devices.show();
|
api.tool.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSeed(then) {
|
function checkSeed(then) {
|
||||||
|
|
@ -436,10 +428,10 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
settingsLoad();
|
settingsLoad();
|
||||||
break;
|
break;
|
||||||
case cca('e'): // device
|
case cca('e'): // device
|
||||||
showDevices();
|
api.show.devices();
|
||||||
break;
|
break;
|
||||||
case cca('o'): // tools
|
case cca('o'): // tools
|
||||||
showTools();
|
api.show.tools();
|
||||||
break;
|
break;
|
||||||
case cca('c'): // local devices
|
case cca('c'): // local devices
|
||||||
api.show.local();
|
api.show.local();
|
||||||
|
|
@ -648,272 +640,6 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
platform.update_origin();
|
platform.update_origin();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTools() {
|
|
||||||
ui.toolSelect.innerHTML = '';
|
|
||||||
maxTool = 0;
|
|
||||||
editTools.forEach(function(tool, index) {
|
|
||||||
maxTool = Math.max(maxTool, tool.number);
|
|
||||||
tool.order = index;
|
|
||||||
let opt = DOC.createElement('option');
|
|
||||||
opt.appendChild(DOC.createTextNode(tool.name));
|
|
||||||
opt.onclick = function() { selectTool(tool) };
|
|
||||||
ui.toolSelect.appendChild(opt);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectTool(tool) {
|
|
||||||
selectedTool = tool;
|
|
||||||
ui.toolName.value = tool.name;
|
|
||||||
ui.toolNum.value = tool.number;
|
|
||||||
ui.toolFluteDiam.value = tool.flute_diam;
|
|
||||||
ui.toolFluteLen.value = tool.flute_len;
|
|
||||||
ui.toolShaftDiam.value = tool.shaft_diam;
|
|
||||||
ui.toolShaftLen.value = tool.shaft_len;
|
|
||||||
ui.toolTaperTip.value = tool.taper_tip || 0;
|
|
||||||
ui.toolMetric.checked = tool.metric;
|
|
||||||
ui.toolType.selectedIndex = ['endmill','ballmill','tapermill'].indexOf(tool.type);
|
|
||||||
if (tool.type === 'tapermill') {
|
|
||||||
ui.toolTaperAngle.value = kiri.driver.CAM.calcTaperAngle(
|
|
||||||
(tool.flute_diam - tool.taper_tip) / 2, tool.flute_len
|
|
||||||
).round(1);
|
|
||||||
} else {
|
|
||||||
ui.toolTaperAngle.value = 0;
|
|
||||||
}
|
|
||||||
renderTool(tool);
|
|
||||||
}
|
|
||||||
|
|
||||||
function otag(o) {
|
|
||||||
if (Array.isArray(o)) {
|
|
||||||
let out = []
|
|
||||||
o.forEach(oe => out.push(otag(oe)));
|
|
||||||
return out.join('');
|
|
||||||
}
|
|
||||||
let tags = [];
|
|
||||||
Object.keys(o).forEach(key => {
|
|
||||||
let val = o[key];
|
|
||||||
let att = [];
|
|
||||||
Object.keys(val).forEach(tk => {
|
|
||||||
let tv = val[tk];
|
|
||||||
att.push(`${tk.replace(/_/g,'-')}="${tv}"`);
|
|
||||||
});
|
|
||||||
tags.push(`<${key} ${att.join(' ')}></${key}>`);
|
|
||||||
});
|
|
||||||
return tags.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTool(tool) {
|
|
||||||
let type = selectedTool.type;
|
|
||||||
let taper = type === 'tapermill';
|
|
||||||
ui.toolTaperAngle.disabled = taper ? undefined : 'true';
|
|
||||||
ui.toolTaperTip.disabled = taper ? undefined : 'true';
|
|
||||||
$('tool-view').innerHTML = '<svg id="tool-svg" width="100%" height="100%"></svg>';
|
|
||||||
setTimeout(() => {
|
|
||||||
let svg = $('tool-svg');
|
|
||||||
let pad = 10;
|
|
||||||
let dim = { w: svg.clientWidth, h: svg.clientHeight }
|
|
||||||
let max = { w: dim.w - pad * 2, h: dim.h - pad * 2};
|
|
||||||
let off = { x: pad, y: pad };
|
|
||||||
let shaft_fill = "#cccccc";
|
|
||||||
let flute_fill = "#dddddd";
|
|
||||||
let stroke = "#777777";
|
|
||||||
let stroke_width = 3;
|
|
||||||
let stroke_thin = stroke_width / 2;
|
|
||||||
let shaft = tool.shaft_len || 1;
|
|
||||||
let flute = tool.flute_len || 1;
|
|
||||||
let tip_len = type === "ballmill" ? tool.flute_diam / 2 : 0;
|
|
||||||
let total_len = shaft + flute + tip_len;
|
|
||||||
let units = dim.h / total_len;
|
|
||||||
let shaft_len = (shaft / total_len) * max.h;
|
|
||||||
let flute_len = (flute / total_len) * max.h;
|
|
||||||
let total_wid = Math.max(tool.flute_diam, tool.shaft_diam);
|
|
||||||
let shaft_off = (max.w - tool.shaft_diam * units) / 2;
|
|
||||||
let flute_off = (max.w - tool.flute_diam * units) / 2;
|
|
||||||
let taper_off = (max.w - (tool.taper_tip || 0) * units) / 2;
|
|
||||||
let parts = [
|
|
||||||
{ rect: {
|
|
||||||
x:off.x + shaft_off, y:off.y,
|
|
||||||
width:max.w - shaft_off * 2, height:shaft_len,
|
|
||||||
stroke, fill: shaft_fill, stroke_width
|
|
||||||
} }
|
|
||||||
];
|
|
||||||
if (type === "tapermill") {
|
|
||||||
let yoff = off.y + shaft_len;
|
|
||||||
let mid = dim.w / 2;
|
|
||||||
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
|
|
||||||
`M ${off.x + flute_off} ${yoff}`,
|
|
||||||
`L ${off.x + taper_off} ${yoff + flute_len}`,
|
|
||||||
`L ${dim.w - off.x - taper_off} ${yoff + flute_len}`,
|
|
||||||
`L ${dim.w - off.x - flute_off} ${yoff}`,
|
|
||||||
`z`
|
|
||||||
].join('\n')}});
|
|
||||||
} else {
|
|
||||||
let x1 = off.x + flute_off;
|
|
||||||
let y1 = off.y + shaft_len;
|
|
||||||
let x2 = x1 + max.w - flute_off * 2;
|
|
||||||
let y2 = y1 + flute_len;
|
|
||||||
parts.push({ rect: {
|
|
||||||
x:off.x + flute_off, y:off.y + shaft_len,
|
|
||||||
width:max.w - flute_off * 2, height:flute_len,
|
|
||||||
stroke, fill: flute_fill, stroke_width
|
|
||||||
} });
|
|
||||||
parts.push({ line: { x1, y1, x2, y2, stroke, stroke_width: stroke_thin } });
|
|
||||||
parts.push({ line: {
|
|
||||||
x1: (x1 + x2) / 2, y1, x2, y2: (y1 + y2) / 2,
|
|
||||||
stroke, stroke_width: stroke_thin
|
|
||||||
} });
|
|
||||||
parts.push({ line: {
|
|
||||||
x1, y1: (y1 + y2) / 2, x2: (x1 + x2) / 2, y2,
|
|
||||||
stroke, stroke_width: stroke_thin
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
if (type === "ballmill") {
|
|
||||||
let rad = (max.w - flute_off * 2) / 2;
|
|
||||||
let xend = dim.w - off.x - flute_off;
|
|
||||||
let yoff = off.y + shaft_len + flute_len + stroke_width/2;
|
|
||||||
parts.push({path: {stroke_width, stroke, fill:flute_fill, d:[
|
|
||||||
`M ${off.x + flute_off} ${yoff}`,
|
|
||||||
`A ${rad} ${rad} 0 0 0 ${xend} ${yoff}`,
|
|
||||||
// `L ${off.x + flute_off} ${yoff}`
|
|
||||||
].join('\n')}})
|
|
||||||
}
|
|
||||||
svg.innerHTML = otag(parts);
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTool(ev) {
|
|
||||||
selectedTool.name = ui.toolName.value;
|
|
||||||
selectedTool.number = parseInt(ui.toolNum.value);
|
|
||||||
selectedTool.flute_diam = parseFloat(ui.toolFluteDiam.value);
|
|
||||||
selectedTool.flute_len = parseFloat(ui.toolFluteLen.value);
|
|
||||||
selectedTool.shaft_diam = parseFloat(ui.toolShaftDiam.value);
|
|
||||||
selectedTool.shaft_len = parseFloat(ui.toolShaftLen.value);
|
|
||||||
selectedTool.taper_tip = parseFloat(ui.toolTaperTip.value);
|
|
||||||
selectedTool.metric = ui.toolMetric.checked;
|
|
||||||
selectedTool.type = ['endmill','ballmill','tapermill'][ui.toolType.selectedIndex];
|
|
||||||
if (selectedTool.type === 'tapermill') {
|
|
||||||
const CAM = kiri.driver.CAM;
|
|
||||||
const rad = (selectedTool.flute_diam - selectedTool.taper_tip) / 2;
|
|
||||||
if (ev && ev.target === ui.toolTaperAngle) {
|
|
||||||
const angle = parseFloat(ev.target.value);
|
|
||||||
const len = CAM.calcTaperLength(rad, angle * DEG2RAD);
|
|
||||||
selectedTool.flute_len = len;
|
|
||||||
ui.toolTaperAngle.value = angle.round(1);
|
|
||||||
ui.toolFluteLen.value = selectedTool.flute_len.round(4);
|
|
||||||
} else {
|
|
||||||
ui.toolTaperAngle.value = CAM.calcTaperAngle(rad, selectedTool.flute_len).round(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ui.toolTaperAngle.value = 0;
|
|
||||||
}
|
|
||||||
renderTools();
|
|
||||||
ui.toolSelect.selectedIndex = selectedTool.order;
|
|
||||||
setToolChanged(true);
|
|
||||||
renderTool(selectedTool);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setToolChanged(changed) {
|
|
||||||
editTools.changed = changed;
|
|
||||||
ui.toolsSave.disabled = !changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showTools() {
|
|
||||||
if (api.mode.get_id() !== MODES.CAM) return;
|
|
||||||
api.settings.sync.get().then(_showTools);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _showTools() {
|
|
||||||
let selectedIndex = null;
|
|
||||||
|
|
||||||
editTools = settings().tools.slice().sort((a,b) => {
|
|
||||||
return a.name > b.name ? 1 : -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
setToolChanged(false);
|
|
||||||
|
|
||||||
ui.toolsClose.onclick = function() {
|
|
||||||
if (editTools.changed && !confirm("abandon changes?")) return;
|
|
||||||
api.dialog.hide();
|
|
||||||
};
|
|
||||||
ui.toolAdd.onclick = function() {
|
|
||||||
let metric = settings().controller.units === 'mm';
|
|
||||||
editTools.push(Object.assign({
|
|
||||||
id: Date.now(),
|
|
||||||
number: maxTool + 1,
|
|
||||||
name: "new tool",
|
|
||||||
type: "endmill",
|
|
||||||
taper_tip: 0,
|
|
||||||
metric
|
|
||||||
}, metric ? {
|
|
||||||
shaft_diam: 2,
|
|
||||||
shaft_len: 15,
|
|
||||||
flute_diam: 2,
|
|
||||||
flute_len: 20,
|
|
||||||
} : {
|
|
||||||
shaft_diam: 0.25,
|
|
||||||
shaft_len: 1.5,
|
|
||||||
flute_diam: 0.25,
|
|
||||||
flute_len: 2,
|
|
||||||
}));
|
|
||||||
setToolChanged(true);
|
|
||||||
renderTools();
|
|
||||||
ui.toolSelect.selectedIndex = editTools.length-1;
|
|
||||||
selectTool(editTools[editTools.length-1]);
|
|
||||||
};
|
|
||||||
ui.toolCopy.onclick = function() {
|
|
||||||
let clone = Object.assign({}, selectedTool);
|
|
||||||
clone.number = maxTool + 1;
|
|
||||||
clone.name = `${clone.name} copy`;
|
|
||||||
editTools.push(clone);
|
|
||||||
setToolChanged(true);
|
|
||||||
renderTools();
|
|
||||||
ui.toolSelect.selectedIndex = editTools.length-1;
|
|
||||||
selectTool(editTools[editTools.length-1]);
|
|
||||||
};
|
|
||||||
ui.toolDelete.onclick = function() {
|
|
||||||
editTools.remove(selectedTool);
|
|
||||||
setToolChanged(true);
|
|
||||||
renderTools();
|
|
||||||
};
|
|
||||||
ui.toolsSave.onclick = function() {
|
|
||||||
if (selectedTool) updateTool();
|
|
||||||
settings().tools = editTools.sort((a,b) => {
|
|
||||||
return a.name < b.name ? -1 : 1;
|
|
||||||
});
|
|
||||||
setToolChanged(false);
|
|
||||||
api.conf.save();
|
|
||||||
api.conf.update_fields();
|
|
||||||
api.event.settings();
|
|
||||||
sync_put();
|
|
||||||
};
|
|
||||||
ui.toolsExport.onclick = () => {
|
|
||||||
uc.prompt("Export Tools Filename", "tools").then(name => {
|
|
||||||
if (!name) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const record = {
|
|
||||||
version: kiri.version,
|
|
||||||
tools: api.conf.get().tools,
|
|
||||||
time: Date.now()
|
|
||||||
};
|
|
||||||
api.util.download(api.util.b64enc(record), `${name}.km`);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
renderTools();
|
|
||||||
if (editTools.length > 0) {
|
|
||||||
selectTool(editTools[0]);
|
|
||||||
ui.toolSelect.selectedIndex = 0;
|
|
||||||
} else {
|
|
||||||
ui.toolAdd.onclick();
|
|
||||||
}
|
|
||||||
|
|
||||||
api.dialog.show('tools');
|
|
||||||
ui.toolSelect.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// not the best way to do this, but main decl of api.show is broken
|
|
||||||
api.show.tools = showTools;
|
|
||||||
|
|
||||||
async function sync_put() {
|
async function sync_put() {
|
||||||
await api.settings.sync.put();
|
await api.settings.sync.put();
|
||||||
}
|
}
|
||||||
|
|
@ -1862,7 +1588,6 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
|
|
||||||
function selectionRotate(e) {
|
function selectionRotate(e) {
|
||||||
let val = parseFloat(e.target.value) || 0;
|
let val = parseFloat(e.target.value) || 0;
|
||||||
// let deg = val * DEG2RAD;
|
|
||||||
e.target.value = val;
|
e.target.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2223,7 +1948,7 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
|
|
||||||
// bind interface action elements
|
// bind interface action elements
|
||||||
$('app-name').onclick = api.help.show;
|
$('app-name').onclick = api.help.show;
|
||||||
$('mode-device').onclick = showDevices;
|
$('mode-device').onclick = api.show.devices;
|
||||||
$('mode-profile').onclick = settingsLoad;
|
$('mode-profile').onclick = settingsLoad;
|
||||||
$('mode-fdm').onclick = () => api.mode.set('FDM');
|
$('mode-fdm').onclick = () => api.mode.set('FDM');
|
||||||
$('mode-cam').onclick = () => api.mode.set('CAM');
|
$('mode-cam').onclick = () => api.mode.set('CAM');
|
||||||
|
|
@ -2232,9 +1957,9 @@ gapp.register("kiri.init", (root, exports) => {
|
||||||
$('mode-drag').onclick = () => api.mode.set('DRAG');
|
$('mode-drag').onclick = () => api.mode.set('DRAG');
|
||||||
$('mode-wjet').onclick = () => api.mode.set('WJET');
|
$('mode-wjet').onclick = () => api.mode.set('WJET');
|
||||||
$('mode-wedm').onclick = () => api.mode.set('WEDM');
|
$('mode-wedm').onclick = () => api.mode.set('WEDM');
|
||||||
$('set-device').onclick = (ev) => { ev.stopPropagation(); showDevices() };
|
$('set-device').onclick = (ev) => { ev.stopPropagation(); api.show.devices() };
|
||||||
$('set-profs').onclick = (ev) => { ev.stopPropagation(); api.conf.show() };
|
$('set-profs').onclick = (ev) => { ev.stopPropagation(); api.conf.show() };
|
||||||
$('set-tools').onclick = (ev) => { ev.stopPropagation(); showTools() };
|
$('set-tools').onclick = (ev) => { ev.stopPropagation(); api.show.tools() };
|
||||||
$('set-prefs').onclick = (ev) => { ev.stopPropagation(); api.modal.show('prefs') };
|
$('set-prefs').onclick = (ev) => { ev.stopPropagation(); api.modal.show('prefs') };
|
||||||
ui.acct.help.onclick = (ev) => { ev.stopPropagation(); api.help.show() };
|
ui.acct.help.onclick = (ev) => { ev.stopPropagation(); api.help.show() };
|
||||||
ui.acct.mesh.onclick = (ev) => { ev.stopPropagation(); WIN.location = "/mesh" };
|
ui.acct.mesh.onclick = (ev) => { ev.stopPropagation(); WIN.location = "/mesh" };
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ gapp.register("kiri.main", (root, exports) => {
|
||||||
|
|
||||||
// extend API
|
// extend API
|
||||||
Object.assign(api, {
|
Object.assign(api, {
|
||||||
ui: UI,
|
ui: UI = Object.assign(api.ui, UI),
|
||||||
uc: UC,
|
uc: UC = Object.assign(api.uc, UC),
|
||||||
stats,
|
stats,
|
||||||
focus: noop,
|
focus: noop,
|
||||||
catalog: FILES,
|
catalog: FILES,
|
||||||
|
|
@ -138,17 +138,15 @@ gapp.register("kiri.main", (root, exports) => {
|
||||||
code: currentProcessCode,
|
code: currentProcessCode,
|
||||||
get: currentProcessName
|
get: currentProcessName
|
||||||
},
|
},
|
||||||
show: {
|
show: Object.assign({
|
||||||
alert() { return api.alerts.show(...arguments) },
|
alert() { return api.alerts.show(...arguments) },
|
||||||
devices: noop, // set during init
|
|
||||||
progress: setProgress,
|
progress: setProgress,
|
||||||
controls: setControlsVisible,
|
controls: setControlsVisible,
|
||||||
slices: showSlices,
|
slices: showSlices,
|
||||||
layer: setVisibleLayer,
|
layer: setVisibleLayer,
|
||||||
local: showLocal,
|
local: showLocal,
|
||||||
tools: noop, // set during init
|
|
||||||
import: function() { UI.import.style.display = '' }
|
import: function() { UI.import.style.display = '' }
|
||||||
},
|
}, api.show),
|
||||||
space: {
|
space: {
|
||||||
reload,
|
reload,
|
||||||
auto_save,
|
auto_save,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,11 @@ function safeFN(fn, name) {
|
||||||
try {
|
try {
|
||||||
return fn(...arguments);
|
return fn(...arguments);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log({ register_fail: name, error });
|
if (error.stack) {
|
||||||
|
console.log(`[${name}]`, error.stack);
|
||||||
|
} else {
|
||||||
|
console.log({ register_fail: name, error });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue