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()