diff --git a/app.js b/app.js
index aa58c139..a93473d8 100644
--- a/app.js
+++ b/app.js
@@ -72,11 +72,6 @@ function init(mod) {
dversion = debug ? `_${version}` : version;
forceUseCache = ENV.cache ? true : false;
- const approot = PATH.join("main","gapp");
- const refcache = {};
- const callstack = [];
- let xxxx = false;
-
if (!ENV.electron) {
generateDevices();
}
@@ -116,8 +111,6 @@ function init(mod) {
});
}
mod.add(rewriteHtmlVersion);
- // example of how to use the new middleware
- // mod.add(appendContent('/kiri/index.html', ''));
mod.static("/lib/", "src");
mod.static("/obj/", "web/obj");
mod.static("/font/", "web/font");
@@ -126,8 +119,8 @@ function init(mod) {
mod.static("/moto/", "web/moto");
mod.static("/kiri/", "web/kiri");
+ // module loader
function load_modules(root, force) {
- // load modules
lastmod(`${dir}/${root}`) && fs.readdirSync(`${dir}/${root}`).forEach(mdir => {
const modpath = `${root}/${mdir}`;
if (dir.charAt(0) === '.' && !ENV.single) return;
@@ -152,7 +145,7 @@ function init(mod) {
// load optional local modules
load_modules('mods');
- // run loads injected by modules
+ // run load functions injected by modules
while (load.length) {
try {
load.shift()();
@@ -161,7 +154,7 @@ function init(mod) {
}
}
- // minify appends
+ // minify appends in production mode
if (!debug) {
for (let key of Object.keys(append)) {
append[key] = minify(append[key]);
@@ -189,14 +182,14 @@ function initModule(mod, file, dir) {
// express functions added here show up at "/api/" url root
api: api,
adm: {
- setver: (ver) => { oversion = ver },
- crossOrigin: (bool) => { crossOrigin = bool }
+ setver(ver) { oversion = ver },
+ crossOrigin(bool) { crossOrigin = bool }
},
events,
const: {
args: {},
meta: mod.meta,
- debug: debug,
+ debug,
moddir: dir,
rootdir: mod.dir,
version: oversion || version
@@ -209,35 +202,21 @@ function initModule(mod, file, dir) {
},
mod: mods,
util: {
+ guid,
+ time,
log: logger.log,
- time: time,
- guid: guid,
+ logger: log.new,
mkdirs: util.mkdir,
- isfile: util.isfile,
confdir: util.confdir,
datadir: util.datadir,
lastmod: lastmod,
- obj2string: obj2string,
- string2obj: string2obj,
+ isfile: util.isfile,
getCookieValue: cookieValue,
- logger: log.new
- },
- inject: (code, file, opt = {}) => {
- const path = mod.dir + '/' + dir + '/' + file;
- try {
- const body = fs.readFileSync(path);
- // console.log({ inject: code, file, opt });
- if (opt.first) {
- append[code] = body.toString() + '\n' + append[code];
- } else {
- append[code] += body.toString() + '\n';
- }
- } catch (e) {
- console.log({ missing_file: path, dir, mod });
- }
+ obj2string(o) { return JSON.stringify(o) },
+ string2obj(s) { return JSON.parse(s) },
},
path: {
- any: arg => { mod.add(arg) },
+ any(arg) { mod.add(arg) },
code() {
const [ path, file ] = [ ...arguments ];
if (lastmod(file)) {
@@ -251,13 +230,13 @@ function initModule(mod, file, dir) {
console.log({ MISSING_CODE: path, file });
}
},
- full: arg => { mod.add(fullpath(arg)) },
- map: arg => { mod.add(fixedmap(arg)) },
- pre: arg => { mod.add(prepath(arg)) },
+ full(arg) { mod.add(fullpath(arg)) },
+ map(arg) { mod.add(fixedmap(arg)) },
+ pre(arg) { mod.add(prepath(arg)) },
redir: redir,
remap: remap,
- setup: fn => { setupFn = fn },
- static: (root, pre) => {
+ setup(fn) { setupFn = fn },
+ static(root, pre) {
mod.static(pre || "/", root);
},
},
@@ -271,22 +250,29 @@ function initModule(mod, file, dir) {
ws: {
register: mod.wss
},
- onload: (fn) => {
+ inject(code, file, opt = {}) {
+ const path = mod.dir + '/' + dir + '/' + file;
+ try {
+ const body = fs.readFileSync(path);
+ // console.log({ inject: code, file, opt });
+ if (opt.first) {
+ append[code] = body.toString() + '\n' + append[code];
+ } else {
+ append[code] += body.toString() + '\n';
+ }
+ } catch (e) {
+ console.log({ missing_file: path, dir, mod });
+ }
+ },
+ onload(fn) {
load.push(fn);
},
- onexit: (fn) => {
+ onexit(fn) {
mod.on.exit(fn);
}
});
}
-// prevent caching of specified modules
-const cachever = {};
-
-function promise(resolve, reject) {
- return new Promise(resolve, reject);
-}
-
function rval() {
return (Math.round(Math.random()*0xffffffff)).toString(36);
}
@@ -299,14 +285,6 @@ function time() {
return Date.now();
}
-function obj2string(o) {
- return JSON.stringify(o);
-}
-
-function string2obj(s) {
- return JSON.parse(s);
-}
-
function handleSetup(req, res, next) {
if (setupFn) {
setupFn(req, res, next);
diff --git a/src/geo/polygon.js b/src/geo/polygon.js
index 6e665522..395e0351 100644
--- a/src/geo/polygon.js
+++ b/src/geo/polygon.js
@@ -1117,6 +1117,14 @@ export class Polygon {
return this.first().isEqual(this.last());
}
+ fixClosed() {
+ if (this.appearsClosed()) {
+ this.points.pop();
+ this.open = false;
+ }
+ return this;
+ }
+
setClockwise() {
if (!this.isClockwise()) this.reverse();
return this;
diff --git a/src/geo/wasm.js b/src/geo/wasm.js
index 87ec5cdd..72c7578f 100644
--- a/src/geo/wasm.js
+++ b/src/geo/wasm.js
@@ -1,9 +1,9 @@
/** Copyright Stewart Allen -- All Rights Reserved */
import { base } from '../geo/base.js';
+import { newPolygon } from './polygon.js';
const { config } = base;
-
const factor = config.clipper;
export const wasm_ctrl = {
@@ -54,7 +54,7 @@ function writePoly(view, poly, inner) {
function readPoly(view, z) {
let points = view.readU16(true);
if (points === 0) return;
- let poly = base.newPolygon();
+ let poly = newPolygon();
while (points-- > 0) {
poly.add(view.readI32(true)/factor, view.readI32(true)/factor, z || 0);
}
diff --git a/src/kiri/core/api.js b/src/kiri/core/api.js
index c81a6954..c66292a3 100644
--- a/src/kiri/core/api.js
+++ b/src/kiri/core/api.js
@@ -6,7 +6,7 @@ import STACKS from './stacks.js';
import { broker } from '../../moto/broker.js';
import { client as work } from './client.js';
-import { consts, COLOR as color, LISTS as lists, MODES, VIEWS, PATHS } from './consts.js';
+import { consts, COLOR as color, LISTS as lists } from './consts.js';
import { device, devices } from './devices.js';
import { catalog, dialog, event, group, help, hide, image } from './main.js';
import { modal, mode, probe, process, show, space, util, view } from './main.js';
diff --git a/src/kiri/core/client.js b/src/kiri/core/client.js
index 363161fb..a6a5a116 100644
--- a/src/kiri/core/client.js
+++ b/src/kiri/core/client.js
@@ -2,6 +2,9 @@
import { api } from './api.js';
import { noop } from './utils.js';
+import { codec } from './codec.js';
+import { Widget } from './widget.js';
+import { newPrint } from './print.js';
// this code runs in kiri's main loop
let debug = self.debug === true,
@@ -199,7 +202,7 @@ export const client = {
send("rotate", { settings }, reply => {
if (reply.group) {
// collect post-rotation data for slice/preview renders
- for (let widget of kiri.Widget.Groups.forid(reply.group)) {
+ for (let widget of Widget.Groups.forid(reply.group)) {
widget.belt = reply.belt;
}
} else if (callback) {
@@ -280,10 +283,10 @@ export const client = {
y: -origin.y,
z: origin.z
};
- const output = kiri.newPrint().parseSVG(code, offset);
+ const output = newPrint().parseSVG(code, offset);
send("parse_svg", output, reply => {
if (reply.parsed) {
- done(kiri.codec.decode(reply.parsed));
+ done(codec.decode(reply.parsed));
}
});
return;
@@ -293,7 +296,7 @@ export const client = {
progress(reply.progress);
}
if (reply.parsed) {
- done(kiri.codec.decode(reply.parsed), reply.maxSpeed, reply.minSpeed);
+ done(codec.decode(reply.parsed), reply.maxSpeed, reply.minSpeed);
}
});
},
diff --git a/src/kiri/core/init.js b/src/kiri/core/init.js
index c7829d66..df797448 100644
--- a/src/kiri/core/init.js
+++ b/src/kiri/core/init.js
@@ -16,6 +16,7 @@ import { init as initLaser } from '../mode/laser/client.js';
import { init as initSLA } from '../mode/sla/client.js';
import { init as initWEDM } from '../mode/wedm/client.js';
import { init as initWJET } from '../mode/wjet/client.js';
+import { menu as menuCAM } from '../mode/cam/init-menu.js';
let { CAM, SLA, FDM, LASER, DRAG, WJET, WEDM } = MODES,
{ client, catalog, platform, selection, stats } = api,
@@ -123,11 +124,6 @@ function speedSave() {
api.view.update_speeds();
}
-function zAnchorSave() {
- api.conf.update();
- api.platform.update_top_z();
-}
-
function setThreaded(bool) {
if (bool) {
client.pool.start();
@@ -234,6 +230,8 @@ function onBooleanClick(el) {
api.devices.update_laser_state();
}
+api.event.on('click.boolean', onBooleanClick);
+
function onButtonClick(ev) {
let target = ev.target;
while (target && target.tagName !== 'BUTTON') {
@@ -242,6 +240,8 @@ function onButtonClick(ev) {
api.event.emit("button.click", target);
}
+api.event.on('click.button', onButtonClick);
+
function inputHasFocus() {
let active = DOC.activeElement;
return active && (active.nodeName === "INPUT" || active.nodeName === "TEXTAREA");
@@ -1229,61 +1229,7 @@ function init_one() {
fdmRanges: $('fdm-ranges'),
/** CAM Settings */
-
- _____: newGroup(LANG.ct_menu, $('cam-tabs'), { modes:CAM, marker:true, driven, separator }),
- camTabsWidth: newInput(LANG.ct_wdth_s, {title:LANG.ct_wdth_l, convert:toFloat, bound:bound(0.005,100), units}),
- camTabsHeight: newInput(LANG.ct_hght_s, {title:LANG.ct_hght_l, convert:toFloat, bound:bound(0.005,100), units}),
- camTabsDepth: newInput(LANG.ct_dpth_s, {title:LANG.ct_dpth_l, convert:toFloat, bound:bound(0.005,100), units}),
- separator: newBlank({ class:"set-sep", driven }),
- camTabsMidline: newBoolean(LANG.ct_midl_s, onBooleanClick, {title:LANG.ct_midl_l}),
- separator: newBlank({ class:"set-sep", driven }),
- camTabsManual: newRow([
- (ui.tabAdd = newButton(undefined, onButtonClick, {icon:''})),
- (ui.tabDun = newButton(undefined, onButtonClick, {icon:''})),
- (ui.tabClr = newButton(undefined, onButtonClick, {icon:''}))
- ], {class:"ext-buttons f-row"}),
- _____: newGroup(LANG.cs_menu, $('cam-stock'), { modes:CAM, driven, separator }),
- camStockX: newInput(LANG.cs_wdth_s, {title:LANG.cs_wdth_l, convert:toFloat, bound:bound(0,9999), units}),
- camStockY: newInput(LANG.cs_dpth_s, {title:LANG.cs_dpth_l, convert:toFloat, bound:bound(0,9999), units}),
- camStockZ: newInput(LANG.cs_hght_s, {title:LANG.cs_hght_l, convert:toFloat, bound:bound(0,9999), units}),
- separator: newBlank({ class:"set-sep", driven }),
- camStockOffset: newBoolean(LANG.cs_offs_s, onBooleanClick, {title:LANG.cs_offs_l}),
- camStockClipTo: newBoolean(LANG.cs_clip_s, onBooleanClick, {title:LANG.cs_clip_l}),
- camStockIndexed: newBoolean(LANG.cs_indx_s, onBooleanClick, {title:LANG.cs_indx_l}),
- camStockIndexGrid: newBoolean(LANG.cs_ishg_s, onBooleanClick, {title:LANG.cs_ishg_l, show:() => ui.camStockIndexed.checked}),
- _____: newGroup(LANG.cc_menu, $('cam-limits'), { modes:CAM, driven, separator }),
- camZAnchor: newSelect(LANG.ou_zanc_s, {title: LANG.ou_zanc_l, action:zAnchorSave, show:() => !ui.camStockIndexed.checked}, "zanchor"),
- camZOffset: newInput(LANG.ou_ztof_s, {title:LANG.ou_ztof_l, convert:toFloat, units}),
- camZTop: newInput(LANG.ou_ztop_s, {title:LANG.ou_ztop_l, convert:toFloat, units, trigger}),
- camZBottom: newInput(LANG.ou_zbot_s, {title:LANG.ou_zbot_l, convert:toFloat, units, trigger}),
- camZThru: newInput(LANG.ou_ztru_s, {title:LANG.ou_ztru_l, convert:toFloat, bound:bound(0.0,100), units }),
- camZClearance: newInput(LANG.ou_zclr_s, {title:LANG.ou_zclr_l, convert:toFloat, bound:bound(0.01,100), units }),
- camFastFeedZ: newInput(LANG.cc_rzpd_s, {title:LANG.cc_rzpd_l, convert:toFloat, units}),
- camFastFeed: newInput(LANG.cc_rapd_s, {title:LANG.cc_rapd_l, convert:toFloat, units}),
- _____: newGroup(LANG.ou_menu, $('cam-output'), { modes:CAM, driven, separator, group:"cam-output" }),
- camConventional: newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l}),
- camEaseDown: newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l}),
- camDepthFirst: newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l}),
- camToolInit: newBoolean(LANG.ou_toin_s, onBooleanClick, {title:LANG.ou_toin_l}),
- separator: newBlank({ class:"set-sep", driven }),
- camFirstZMax: newBoolean(LANG.ou_z1st_s, onBooleanClick, {title:LANG.ou_z1st_l}),
- camForceZMax: newBoolean(LANG.ou_forz_s, onBooleanClick, {title:LANG.ou_forz_l}),
- separator: newBlank({ class:"set-sep", driven }),
- camEaseAngle: newInput(LANG.ou_eang_s, {title:LANG.ou_eang_l, convert:toFloat, bound:bound(0.1,85), show:() => ui.camEaseDown.checked}),
- camFullEngage: newInput(LANG.ou_feng_s, {title:LANG.ou_feng_l, convert:toFloat, bound:bound(0.1,1.0)}),
- _____: newGroup(LANG.co_menu, $('cam-origin'), { modes:CAM, driven, separator }),
- camOriginTop: newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l}),
- camOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}),
- separator: newBlank({ class:"set-sep", driven }),
- camOriginOffX: newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:toFloat, units}),
- camOriginOffY: newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:toFloat, units}),
- camOriginOffZ: newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:toFloat, units}),
- _____: newGroup(LANG.op_xprt_s, $('cam-expert'), { group:"cam_expert", modes:CAM, marker: false, driven, separator }),
- camExpertFast: newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, show: () => !ui.camTrueShadow.checked }),
- camTrueShadow: newBoolean(LANG.cx_true_s, onBooleanClick, {title:LANG.cx_true_l, show: () => !ui.camExpertFast.checked }),
- separator: newBlank({ class:"set-sep", driven }),
- camArcTolerance: newInput(LANG.cx_arct_s, {title:LANG.cx_arct_l, convert:toFloat, units, bound:bound(0,100)}),
- camArcResolution: newInput(LANG.cx_arcr_s, {title:LANG.cx_arcr_l, convert:toFloat, bound:bound(0,180), show:() => ui.camArcTolerance.value > 0}),
+ ...menuCAM(),
/** LASER/DRAG/WJET/WEDM cut tool Settings */
@@ -1367,6 +1313,8 @@ function init_one() {
});
// run client mode initializations right after UI is bound
+ // MUST run after main ui menu inits since they rely on passed state
+ // that createPopOps disrupts (should be refactored)
initCAM();
initDRAG();
initFDM();
diff --git a/src/kiri/mode/cam/cl-ops.js b/src/kiri/mode/cam/cl-ops.js
index d4c63b6d..d3559a2d 100644
--- a/src/kiri/mode/cam/cl-ops.js
+++ b/src/kiri/mode/cam/cl-ops.js
@@ -95,6 +95,7 @@ export function createPopOp(type, map) {
return op.rec === rec;
},
bind: (ev) => {
+ console.log({ bind: type, map, op });
api.util.ui2rec(op.rec, op.inputs);
const settings = conf.get();
diff --git a/src/kiri/mode/cam/cl-origin.js b/src/kiri/mode/cam/cl-origin.js
new file mode 100644
index 00000000..073a7f08
--- /dev/null
+++ b/src/kiri/mode/cam/cl-origin.js
@@ -0,0 +1,114 @@
+/** Copyright Stewart Allen -- All Rights Reserved */
+
+import { api } from '../../core/api.js';
+import { env, clearPops } from './client.js';
+import { CAM } from './driver-fe.js';
+import { config } from '../../../geo/base.js';
+import { addbox, delbox } from '../../core/boxes.js';
+
+export let originSelectOn = false;
+
+let { world } = api.SPACE;
+let alert, lastHover, lastPoints;
+
+export function originSelect() {
+ if (originSelectOn) {
+ return originSelectDone();
+ }
+
+ clearPops();
+
+ alert = api.show.alert("analyzing parts...", 1000);
+ originSelectOn = true;
+
+ api.feature.hover = true;
+ api.feature.hoverAdds = true;
+ env.hover = pointHover;
+ env.hoverUp = pointHoverUp;
+
+ CAM.traces((ids) => {
+ api.hide.alert(alert);
+ alert = api.show.alert("select origin
[esc] to cancel", 1000);
+ let points = {};
+ let color = new THREE.Color( 0xff0000 );
+ api.widgets.for(widget => {
+ let { pos, tzoff } = widget.track;
+ let { adds, traces } = widget;
+ let polys = traces.map(trace => {
+ return trace.fixClosed().clone().move(pos).move({ x:0, y:0, z: -tzoff });
+ });
+ for (let poly of polys) {
+ if (poly.circularity() >= config.hint_min_circ) {
+ let center = poly.calcCircleCenter();
+ if (points[center.key]) {
+ continue;
+ }
+ let box = addbox(center, color, center.key, undefined, { opacity: 1 });
+ adds.push(box);
+ world.add(box);
+ box._origin = center;
+ points[center.key] = { box, center };
+ }
+ }
+ });
+ lastPoints = Object.values(points);
+ });
+}
+
+export function originSelectDone() {
+ if (!originSelectOn) {
+ return;
+ }
+ api.hide.alert(alert);
+ api.feature.hover = false;
+ api.feature.hoverAdds = false;
+ api.widgets.for(widget => {
+ for (let box of widget.adds) {
+ world.remove(box);
+ }
+ widget.adds.length = 0;
+ });
+ originSelectOn = false;
+}
+
+function pointHover(data) {
+ if (lastHover) {
+ let { color, colorSave } = lastHover.material[0] || lastHover.material;
+ color.r = colorSave.r;
+ color.g = colorSave.g;
+ color.b = colorSave.b;
+ }
+ lastHover = null;
+ if (data.type === 'platform') {
+ return;
+ }
+ if (!data.int.object._origin) {
+ return;
+ }
+ lastHover = data.int.object;
+ let material = lastHover.material[0] || lastHover.material;
+ let color = material.color;
+ material.colorSave = color.clone();
+ color.setHex(0x00ff00);
+}
+
+function pointHoverUp(int, ev) {
+ if (!int?.object?._origin) return;
+ let { _origin } = int.object;
+ let { process, stock } = api.conf.get();
+ let { x, y, z } = _origin;
+ let { camOriginTop, camOriginCenter } = process;
+ if (camOriginTop) {
+ z = z - stock.z;
+ }
+ if (!camOriginCenter) {
+ x += stock.x / 2;
+ y += stock.y / 2;
+ }
+ process.camOriginOffX = x;
+ process.camOriginOffY = y;
+ process.camOriginOffZ = z;
+ api.settings.update_fields();
+ api.platform.update_origin();
+ originSelectDone();
+}
diff --git a/src/kiri/mode/cam/cl-trace.js b/src/kiri/mode/cam/cl-trace.js
index aef93434..25755670 100644
--- a/src/kiri/mode/cam/cl-trace.js
+++ b/src/kiri/mode/cam/cl-trace.js
@@ -1,7 +1,7 @@
/** Copyright Stewart Allen -- All Rights Reserved */
import { api } from '../../core/api.js';
-import { env, clearPops } from './client.js';
+import { env, clearPops, isDark } from './client.js';
import { CAM } from './driver-fe.js';
import { Layers } from '../../core/layers.js';
import { Stack } from '../../core/stack.js';
@@ -123,7 +123,7 @@ export function traceHover(data) {
let material = lastTrace.material[0] || lastTrace.material;
let color = material.color;
material.colorSave = color.clone();
- color.setHex(env.isDark() ? 0x0066ff : 0x0000ff);
+ color.setHex(isDark() ? 0x0066ff : 0x0000ff);
}
export function traceHoverUp(int, ev) {
@@ -157,7 +157,7 @@ export function traceToggle(obj, skip) {
colorSave = material.colorSave = color.clone();
}
if (obj.selected) {
- color.setHex(env.isDark() ? 0xdd0011 : 0xff0033);
+ color.setHex(isDark() ? 0xdd0011 : 0xff0033);
colorSave.r = color.r;
colorSave.g = color.g;
colorSave.b = color.b;
diff --git a/src/kiri/mode/cam/client.js b/src/kiri/mode/cam/client.js
index e163978c..6e7b9cc8 100644
--- a/src/kiri/mode/cam/client.js
+++ b/src/kiri/mode/cam/client.js
@@ -1,6 +1,6 @@
/** Copyright Stewart Allen -- All Rights Reserved */
-import { $, h } from '../../../moto/webui.js';
+import { $ } from '../../../moto/webui.js';
import { api } from '../../core/api.js';
import { load } from '../../../load/file.js';
import { animate as anim_2d, animate_clear as anim_2d_clear } from './anim-2d-fe.js';
@@ -14,13 +14,14 @@ import { tabAdd, tabDone, tabClear, restoreTabs, updateTabs } from './cl-tab.js'
import { traceOn, traceDone, unselectTraces } from './cl-trace.js';
import { holeSelOn, selectHolesDone, clearHolesRec } from './cl-hole.js';
import { surfaceOn, surfaceDone } from './cl-surface.js';
+import { originSelectDone } from './cl-origin.js';
const DEG2RAD = Math.PI / 180;
const RAD2DEG = 180 / Math.PI;
const hasSharedArrays = self.SharedArrayBuffer ? true : false;
const { VIEWS, STACKS } = api.const;
-const { noop, space } = api;
+const { noop } = api;
const { ui: UI, uc: UC } = api;
const { widgets: WIDGETS } = api;
@@ -54,10 +55,11 @@ export function isDark() {
export function clearPops() {
if (env.func.unpop) env.func.unpop();
+ originSelectDone();
+ selectHolesDone();
+ surfaceDone();
tabDone();
traceDone();
- surfaceDone();
- selectHolesDone();
}
function animFn() {
diff --git a/src/kiri/mode/cam/init-menu.js b/src/kiri/mode/cam/init-menu.js
new file mode 100644
index 00000000..d9972c13
--- /dev/null
+++ b/src/kiri/mode/cam/init-menu.js
@@ -0,0 +1,92 @@
+
+import { api } from '../../core/api.js';
+import { originSelect } from './cl-origin.js';
+
+let LANG = api.language.current;
+let { CAM } = api.const.MODES,
+ { $ } = api.web,
+ { uc, ui } = api,
+ { bound, toInt, toFloat } = uc,
+ { newBlank, newButton, newBoolean, newGroup, newInput } = uc,
+ { newSelect, newLabel, newValue, newRow, newGCode, newDiv } = uc,
+ driven = true,
+ separator = true,
+ trigger = true,
+ units = true
+ ;
+
+function onBooleanClick(el) {
+ api.event.emit('click.boolean', el);
+}
+
+function onButtonClick(el) {
+ api.event.emit('click.button', el);
+}
+
+function zAnchorSave() {
+ api.conf.update();
+ api.platform.update_top_z();
+}
+
+export function menu() {
+ return {
+
+ _____: newGroup(LANG.ct_menu, $('cam-tabs'), { modes:CAM, marker:true, driven, separator }),
+ camTabsWidth: newInput(LANG.ct_wdth_s, {title:LANG.ct_wdth_l, convert:toFloat, bound:bound(0.005,100), units}),
+ camTabsHeight: newInput(LANG.ct_hght_s, {title:LANG.ct_hght_l, convert:toFloat, bound:bound(0.005,100), units}),
+ camTabsDepth: newInput(LANG.ct_dpth_s, {title:LANG.ct_dpth_l, convert:toFloat, bound:bound(0.005,100), units}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camTabsMidline: newBoolean(LANG.ct_midl_s, onBooleanClick, {title:LANG.ct_midl_l}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camTabsManual: newRow([
+ (ui.tabAdd = newButton(undefined, onButtonClick, {icon:''})),
+ (ui.tabDun = newButton(undefined, onButtonClick, {icon:''})),
+ (ui.tabClr = newButton(undefined, onButtonClick, {icon:''}))
+ ], {class:"ext-buttons f-row"}),
+ _____: newGroup(LANG.cs_menu, $('cam-stock'), { modes:CAM, driven, separator }),
+ camStockX: newInput(LANG.cs_wdth_s, {title:LANG.cs_wdth_l, convert:toFloat, bound:bound(0,9999), units}),
+ camStockY: newInput(LANG.cs_dpth_s, {title:LANG.cs_dpth_l, convert:toFloat, bound:bound(0,9999), units}),
+ camStockZ: newInput(LANG.cs_hght_s, {title:LANG.cs_hght_l, convert:toFloat, bound:bound(0,9999), units}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camStockOffset: newBoolean(LANG.cs_offs_s, onBooleanClick, {title:LANG.cs_offs_l}),
+ camStockClipTo: newBoolean(LANG.cs_clip_s, onBooleanClick, {title:LANG.cs_clip_l}),
+ camStockIndexed: newBoolean(LANG.cs_indx_s, onBooleanClick, {title:LANG.cs_indx_l}),
+ camStockIndexGrid: newBoolean(LANG.cs_ishg_s, onBooleanClick, {title:LANG.cs_ishg_l, show:() => ui.camStockIndexed.checked}),
+ _____: newGroup(LANG.cc_menu, $('cam-limits'), { modes:CAM, driven, separator }),
+ camZAnchor: newSelect(LANG.ou_zanc_s, {title: LANG.ou_zanc_l, action:zAnchorSave, show:() => !ui.camStockIndexed.checked}, "zanchor"),
+ camZOffset: newInput(LANG.ou_ztof_s, {title:LANG.ou_ztof_l, convert:toFloat, units}),
+ camZTop: newInput(LANG.ou_ztop_s, {title:LANG.ou_ztop_l, convert:toFloat, units, trigger}),
+ camZBottom: newInput(LANG.ou_zbot_s, {title:LANG.ou_zbot_l, convert:toFloat, units, trigger}),
+ camZThru: newInput(LANG.ou_ztru_s, {title:LANG.ou_ztru_l, convert:toFloat, bound:bound(0.0,100), units }),
+ camZClearance: newInput(LANG.ou_zclr_s, {title:LANG.ou_zclr_l, convert:toFloat, bound:bound(0.01,100), units }),
+ camFastFeedZ: newInput(LANG.cc_rzpd_s, {title:LANG.cc_rzpd_l, convert:toFloat, units}),
+ camFastFeed: newInput(LANG.cc_rapd_s, {title:LANG.cc_rapd_l, convert:toFloat, units}),
+ _____: newGroup(LANG.ou_menu, $('cam-output'), { modes:CAM, driven, separator, group:"cam-output" }),
+ camConventional: newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l}),
+ camEaseDown: newBoolean(LANG.cr_ease_s, onBooleanClick, {title:LANG.cr_ease_l}),
+ camDepthFirst: newBoolean(LANG.ou_depf_s, onBooleanClick, {title:LANG.ou_depf_l}),
+ camToolInit: newBoolean(LANG.ou_toin_s, onBooleanClick, {title:LANG.ou_toin_l}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camFirstZMax: newBoolean(LANG.ou_z1st_s, onBooleanClick, {title:LANG.ou_z1st_l}),
+ camForceZMax: newBoolean(LANG.ou_forz_s, onBooleanClick, {title:LANG.ou_forz_l}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camEaseAngle: newInput(LANG.ou_eang_s, {title:LANG.ou_eang_l, convert:toFloat, bound:bound(0.1,85), show:() => ui.camEaseDown.checked}),
+ camFullEngage: newInput(LANG.ou_feng_s, {title:LANG.ou_feng_l, convert:toFloat, bound:bound(0.1,1.0)}),
+ _____: newGroup(LANG.co_menu, $('cam-origin'), { modes:CAM, driven, separator }),
+ camOriginTop: newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l}),
+ camOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camOriginOffX: newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:toFloat, units}),
+ camOriginOffY: newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:toFloat, units}),
+ camOriginOffZ: newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:toFloat, units}),
+ separator: newBlank({ class:"set-sep", driven }),
+ camOriginSelect: newRow([ newButton("select", originSelect)], { class: "ext-buttons f-row" }),
+ _____: newGroup(LANG.op_xprt_s, $('cam-expert'), { group:"cam_expert", modes:CAM, marker: false, driven, separator }),
+ camExpertFast: newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, show: () => !ui.camTrueShadow.checked }),
+ camTrueShadow: newBoolean(LANG.cx_true_s, onBooleanClick, {title:LANG.cx_true_l, show: () => !ui.camExpertFast.checked }),
+ separator: newBlank({ class:"set-sep", driven }),
+ camArcTolerance: newInput(LANG.cx_arct_s, {title:LANG.cx_arct_l, convert:toFloat, units, bound:bound(0,100)}),
+ camArcResolution: newInput(LANG.cx_arcr_s, {title:LANG.cx_arcr_l, convert:toFloat, bound:bound(0,180), show:() => ui.camArcTolerance.value > 0}),
+
+ };
+};
diff --git a/src/kiri/mode/cam/slice.js b/src/kiri/mode/cam/slice.js
index 9df46bdc..174bdf23 100644
--- a/src/kiri/mode/cam/slice.js
+++ b/src/kiri/mode/cam/slice.js
@@ -398,7 +398,7 @@ export function addDogbones(poly, dist, reverse) {
}
};
-export async function traces(settings, widget, single) {
+export async function traces(settings, widget) {
if (widget.traces) {
return false;
}
@@ -534,7 +534,6 @@ export async function holes(settings, widget, individual, rec, onProgress) {
// keeps the z bottom relative to the part when z align changes
zBottom = isIndexed ? camZBottom : camZBottom - zbOff;
-
let slicerOpts = { flatoff: 0.001 }
let slicer = new cam_slicer(widget, slicerOpts);
let zFlats = Object.keys(slicer.zFlat).map(Number).map(z => [z, z - 0.002]).flat()