Merge branch 'rel-4.3' into helical-op
This commit is contained in:
commit
45ba762d1e
60 changed files with 1116 additions and 639 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,6 +5,7 @@ app.json
|
||||||
build
|
build
|
||||||
data
|
data
|
||||||
dist
|
dist
|
||||||
|
jszip-esm.js
|
||||||
logs
|
logs
|
||||||
mod
|
mod
|
||||||
node_modules
|
node_modules
|
||||||
|
|
|
||||||
147
app.js
147
app.js
|
|
@ -36,6 +36,7 @@ let http;
|
||||||
let util;
|
let util;
|
||||||
let dir;
|
let dir;
|
||||||
let log;
|
let log;
|
||||||
|
let pre;
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
class AppEmitter extends EventEmitter {}
|
class AppEmitter extends EventEmitter {}
|
||||||
|
|
@ -46,9 +47,13 @@ netdb.create = async function(map = {}) {
|
||||||
Object.assign(map, JSON.parse(fs.readFileSync(map.conf)));
|
Object.assign(map, JSON.parse(fs.readFileSync(map.conf)));
|
||||||
}
|
}
|
||||||
const client = new netdb();
|
const client = new netdb();
|
||||||
|
try {
|
||||||
if (map.host && map.port) await client.open(map.host, map.port);
|
if (map.host && map.port) await client.open(map.host, map.port);
|
||||||
if (map.user && map.pass) await client.auth(map.user, map.pass);
|
if (map.user && map.pass) await client.auth(map.user, map.pass);
|
||||||
if (map.base) await client.use(map.base);
|
if (map.base) await client.use(map.base);
|
||||||
|
} catch (e) {
|
||||||
|
logger.log({ netdb_setup_error: e });
|
||||||
|
}
|
||||||
logger.log({ netdb: map.host, user: map.user, base: map.base });
|
logger.log({ netdb: map.host, user: map.user, base: map.base });
|
||||||
return client;
|
return client;
|
||||||
};
|
};
|
||||||
|
|
@ -59,6 +64,7 @@ function init(mod) {
|
||||||
startTime = time();
|
startTime = time();
|
||||||
lastmod = mod.util.lastmod;
|
lastmod = mod.util.lastmod;
|
||||||
logger = mod.log;
|
logger = mod.log;
|
||||||
|
pre = ENV.pre || mod.meta.pre;
|
||||||
debug = ENV.debug || mod.meta.debug;
|
debug = ENV.debug || mod.meta.debug;
|
||||||
oversion = ENV.over || mod.meta.over;
|
oversion = ENV.over || mod.meta.over;
|
||||||
crossOrigin = ENV.xorigin || mod.meta.xorigin || false;
|
crossOrigin = ENV.xorigin || mod.meta.xorigin || false;
|
||||||
|
|
@ -72,17 +78,24 @@ function init(mod) {
|
||||||
dversion = debug ? `_${version}` : version;
|
dversion = debug ? `_${version}` : version;
|
||||||
forceUseCache = ENV.cache ? true : false;
|
forceUseCache = ENV.cache ? true : false;
|
||||||
|
|
||||||
const approot = PATH.join("main","gapp");
|
|
||||||
const refcache = {};
|
|
||||||
const callstack = [];
|
|
||||||
let xxxx = false;
|
|
||||||
|
|
||||||
if (!ENV.electron) {
|
if (!ENV.electron) {
|
||||||
generateDevices();
|
generateDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pre) {
|
||||||
|
for (let [k,v] of Object.entries(productionMap)) {
|
||||||
|
productionMap[`${pre}${k}`] = `${pre}${v}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod.on.test((req) => {
|
mod.on.test((req) => {
|
||||||
let cookie = cookieValue(req.headers.cookie, "version") || undefined;
|
if (req.app?.path?.startsWith(pre)) {
|
||||||
|
req.url = req.url.substring(pre.length);
|
||||||
|
req.app.path = req.app.path.substring(pre.length);
|
||||||
|
req.app.ispre = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let cookie = cookieValue(req.headers.cookie, "version") || '';
|
||||||
let vmatch = mod.meta.version || "*";
|
let vmatch = mod.meta.version || "*";
|
||||||
if (!Array.isArray(vmatch)) {
|
if (!Array.isArray(vmatch)) {
|
||||||
vmatch = [ vmatch ];
|
vmatch = [ vmatch ];
|
||||||
|
|
@ -93,17 +106,28 @@ function init(mod) {
|
||||||
return vmatch.indexOf(cookie) >= 0;
|
return vmatch.indexOf(cookie) >= 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mod.on.testv((version) => {
|
||||||
|
let vmatch = mod.meta.version || "*";
|
||||||
|
if (!Array.isArray(vmatch)) {
|
||||||
|
vmatch = [ vmatch ];
|
||||||
|
}
|
||||||
|
if (vmatch.indexOf("*") >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return vmatch.indexOf(version) >= 0;
|
||||||
|
});
|
||||||
|
|
||||||
mod.add(handleSetup);
|
mod.add(handleSetup);
|
||||||
mod.add(handleOptions);
|
mod.add(handleOptions);
|
||||||
mod.add(serveWasm);
|
mod.add(serveWasm);
|
||||||
mod.add(serveCode);
|
mod.add(serveCode);
|
||||||
mod.add(fullpath({
|
mod.add(fullpath({
|
||||||
"/kiri" : redir("/kiri/", 301),
|
"/kiri" : redir((pre??"") + "/kiri/", 301),
|
||||||
"/mesh" : redir("/mesh/", 301),
|
"/mesh" : redir((pre??"") + "/mesh/", 301),
|
||||||
"/meta" : redir("/meta/", 301),
|
"/meta" : redir((pre??"") + "/meta/", 301),
|
||||||
"/kiri/index.html" : redir("/kiri/", 301),
|
"/kiri/index.html" : redir((pre??"") + "/kiri/", 301),
|
||||||
"/mesh/index.html" : redir("/mesh/", 301),
|
"/mesh/index.html" : redir((pre??"") + "/mesh/", 301),
|
||||||
"/meta/index.html" : redir("/meta/", 301)
|
"/meta/index.html" : redir((pre??"") + "/meta/", 301)
|
||||||
}));
|
}));
|
||||||
mod.add(handleVersion);
|
mod.add(handleVersion);
|
||||||
mod.add(fixedmap("/api/", api));
|
mod.add(fixedmap("/api/", api));
|
||||||
|
|
@ -116,8 +140,6 @@ function init(mod) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mod.add(rewriteHtmlVersion);
|
mod.add(rewriteHtmlVersion);
|
||||||
// example of how to use the new middleware
|
|
||||||
// mod.add(appendContent('/kiri/index.html', '<script>console.log("hello")</script>'));
|
|
||||||
mod.static("/lib/", "src");
|
mod.static("/lib/", "src");
|
||||||
mod.static("/obj/", "web/obj");
|
mod.static("/obj/", "web/obj");
|
||||||
mod.static("/font/", "web/font");
|
mod.static("/font/", "web/font");
|
||||||
|
|
@ -126,8 +148,8 @@ function init(mod) {
|
||||||
mod.static("/moto/", "web/moto");
|
mod.static("/moto/", "web/moto");
|
||||||
mod.static("/kiri/", "web/kiri");
|
mod.static("/kiri/", "web/kiri");
|
||||||
|
|
||||||
|
// module loader
|
||||||
function load_modules(root, force) {
|
function load_modules(root, force) {
|
||||||
// load modules
|
|
||||||
lastmod(`${dir}/${root}`) && fs.readdirSync(`${dir}/${root}`).forEach(mdir => {
|
lastmod(`${dir}/${root}`) && fs.readdirSync(`${dir}/${root}`).forEach(mdir => {
|
||||||
const modpath = `${root}/${mdir}`;
|
const modpath = `${root}/${mdir}`;
|
||||||
if (dir.charAt(0) === '.' && !ENV.single) return;
|
if (dir.charAt(0) === '.' && !ENV.single) return;
|
||||||
|
|
@ -152,7 +174,7 @@ function init(mod) {
|
||||||
// load optional local modules
|
// load optional local modules
|
||||||
load_modules('mods');
|
load_modules('mods');
|
||||||
|
|
||||||
// run loads injected by modules
|
// run load functions injected by modules
|
||||||
while (load.length) {
|
while (load.length) {
|
||||||
try {
|
try {
|
||||||
load.shift()();
|
load.shift()();
|
||||||
|
|
@ -161,7 +183,7 @@ function init(mod) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// minify appends
|
// minify appends in production mode
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
for (let key of Object.keys(append)) {
|
for (let key of Object.keys(append)) {
|
||||||
append[key] = minify(append[key]);
|
append[key] = minify(append[key]);
|
||||||
|
|
@ -177,6 +199,9 @@ function loadModule(mod, dir) {
|
||||||
if (lastmod(`${mod.dir}/${dir}/.ignore`)) {
|
if (lastmod(`${mod.dir}/${dir}/.ignore`)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// either load the module, or if it's not a module
|
||||||
|
// directory, serve the module as static content
|
||||||
|
// bound to the root
|
||||||
lastmod(`${mod.dir}/${dir}/init.js`) ?
|
lastmod(`${mod.dir}/${dir}/init.js`) ?
|
||||||
initModule(mod, `./${dir}/init.js`, dir) :
|
initModule(mod, `./${dir}/init.js`, dir) :
|
||||||
mod.static("/", `${mod.dir}/${dir}`);
|
mod.static("/", `${mod.dir}/${dir}`);
|
||||||
|
|
@ -189,14 +214,14 @@ function initModule(mod, file, dir) {
|
||||||
// express functions added here show up at "/api/" url root
|
// express functions added here show up at "/api/" url root
|
||||||
api: api,
|
api: api,
|
||||||
adm: {
|
adm: {
|
||||||
setver: (ver) => { oversion = ver },
|
setver(ver) { oversion = ver },
|
||||||
crossOrigin: (bool) => { crossOrigin = bool }
|
crossOrigin(bool) { crossOrigin = bool }
|
||||||
},
|
},
|
||||||
events,
|
events,
|
||||||
const: {
|
const: {
|
||||||
args: {},
|
args: {},
|
||||||
meta: mod.meta,
|
meta: mod.meta,
|
||||||
debug: debug,
|
debug,
|
||||||
moddir: dir,
|
moddir: dir,
|
||||||
rootdir: mod.dir,
|
rootdir: mod.dir,
|
||||||
version: oversion || version
|
version: oversion || version
|
||||||
|
|
@ -209,35 +234,21 @@ function initModule(mod, file, dir) {
|
||||||
},
|
},
|
||||||
mod: mods,
|
mod: mods,
|
||||||
util: {
|
util: {
|
||||||
|
guid,
|
||||||
|
time,
|
||||||
log: logger.log,
|
log: logger.log,
|
||||||
time: time,
|
logger: log.new,
|
||||||
guid: guid,
|
|
||||||
mkdirs: util.mkdir,
|
mkdirs: util.mkdir,
|
||||||
isfile: util.isfile,
|
|
||||||
confdir: util.confdir,
|
confdir: util.confdir,
|
||||||
datadir: util.datadir,
|
datadir: util.datadir,
|
||||||
lastmod: lastmod,
|
lastmod: lastmod,
|
||||||
obj2string: obj2string,
|
isfile: util.isfile,
|
||||||
string2obj: string2obj,
|
|
||||||
getCookieValue: cookieValue,
|
getCookieValue: cookieValue,
|
||||||
logger: log.new
|
obj2string(o) { return JSON.stringify(o) },
|
||||||
},
|
string2obj(s) { return JSON.parse(s) },
|
||||||
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 });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
path: {
|
path: {
|
||||||
any: arg => { mod.add(arg) },
|
any(arg) { mod.add(arg) },
|
||||||
code() {
|
code() {
|
||||||
const [ path, file ] = [ ...arguments ];
|
const [ path, file ] = [ ...arguments ];
|
||||||
if (lastmod(file)) {
|
if (lastmod(file)) {
|
||||||
|
|
@ -251,13 +262,13 @@ function initModule(mod, file, dir) {
|
||||||
console.log({ MISSING_CODE: path, file });
|
console.log({ MISSING_CODE: path, file });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
full: arg => { mod.add(fullpath(arg)) },
|
full(arg) { mod.add(fullpath(arg)) },
|
||||||
map: arg => { mod.add(fixedmap(arg)) },
|
map(arg) { mod.add(fixedmap(arg)) },
|
||||||
pre: arg => { mod.add(prepath(arg)) },
|
pre(arg) { mod.add(prepath(arg)) },
|
||||||
redir: redir,
|
redir: redir,
|
||||||
remap: remap,
|
remap: remap,
|
||||||
setup: fn => { setupFn = fn },
|
setup(fn) { setupFn = fn },
|
||||||
static: (root, pre) => {
|
static(root, pre) {
|
||||||
mod.static(pre || "/", root);
|
mod.static(pre || "/", root);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -271,22 +282,29 @@ function initModule(mod, file, dir) {
|
||||||
ws: {
|
ws: {
|
||||||
register: mod.wss
|
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);
|
load.push(fn);
|
||||||
},
|
},
|
||||||
onexit: (fn) => {
|
onexit(fn) {
|
||||||
mod.on.exit(fn);
|
mod.on.exit(fn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// prevent caching of specified modules
|
|
||||||
const cachever = {};
|
|
||||||
|
|
||||||
function promise(resolve, reject) {
|
|
||||||
return new Promise(resolve, reject);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rval() {
|
function rval() {
|
||||||
return (Math.round(Math.random()*0xffffffff)).toString(36);
|
return (Math.round(Math.random()*0xffffffff)).toString(36);
|
||||||
}
|
}
|
||||||
|
|
@ -299,14 +317,6 @@ function time() {
|
||||||
return Date.now();
|
return Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
function obj2string(o) {
|
|
||||||
return JSON.stringify(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
function string2obj(s) {
|
|
||||||
return JSON.parse(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSetup(req, res, next) {
|
function handleSetup(req, res, next) {
|
||||||
if (setupFn) {
|
if (setupFn) {
|
||||||
setupFn(req, res, next);
|
setupFn(req, res, next);
|
||||||
|
|
@ -322,12 +332,16 @@ const productionMap = {
|
||||||
'/lib/kiri/run/engine.js' : '/lib/pack/kiri-eng.js',
|
'/lib/kiri/run/engine.js' : '/lib/pack/kiri-eng.js',
|
||||||
'/lib/kiri/run/minion.js' : '/lib/pack/kiri-pool.js',
|
'/lib/kiri/run/minion.js' : '/lib/pack/kiri-pool.js',
|
||||||
'/lib/kiri/run/worker.js' : '/lib/pack/kiri-work.js',
|
'/lib/kiri/run/worker.js' : '/lib/pack/kiri-work.js',
|
||||||
// '/lib/kiri/run/frame.js' : '/lib/pack/kiri-frame.js',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const redirList = [
|
||||||
|
"/kiri/",
|
||||||
|
"/mesh/"
|
||||||
|
];
|
||||||
|
|
||||||
function handleVersion(req, res, next) {
|
function handleVersion(req, res, next) {
|
||||||
let vstr = oversion || dversion || version;
|
let vstr = oversion || dversion || version;
|
||||||
if (["/kiri/","/mesh/"].indexOf(req.app.path) >= 0 && req.url.indexOf(vstr) < 0) {
|
if (!req.app.ispre && redirList.indexOf(req.app.path) === 0 && req.url.indexOf(vstr) < 0) {
|
||||||
if (req.url.indexOf("?") > 0) {
|
if (req.url.indexOf("?") > 0) {
|
||||||
return http.redirect(res, `${req.url},ver:${vstr}`);
|
return http.redirect(res, `${req.url},ver:${vstr}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -550,7 +564,8 @@ function rewriteHtmlVersion(req, res, next) {
|
||||||
"/lib/main/mesh.js"
|
"/lib/main/mesh.js"
|
||||||
].indexOf(req.app.path) >= 0) {
|
].indexOf(req.app.path) >= 0) {
|
||||||
addCorsHeaders(req, res);
|
addCorsHeaders(req, res);
|
||||||
const data = append[req.app.path.split('/')[3].split('.')[0]];
|
// const data = append[req.app.path.split('/')[3].split('.')[0]];
|
||||||
|
const data = append[req.app.path.split('.')[0].split('/').pop()];
|
||||||
|
|
||||||
if (!data) return next();
|
if (!data) return next();
|
||||||
if (debug) logger.log({ append: req.app.path, data: data.length });
|
if (debug) logger.log({ append: req.app.path, data: data.length });
|
||||||
|
|
|
||||||
7
bin/webpack-jszip-bundle.js
Normal file
7
bin/webpack-jszip-bundle.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import * as JSZip from "../node_modules/jszip/dist/jszip.js";
|
||||||
|
|
||||||
|
export default JSZip;
|
||||||
|
|
||||||
|
export {
|
||||||
|
JSZip
|
||||||
|
};
|
||||||
38
bin/webpack-jszip-esm.js
Normal file
38
bin/webpack-jszip-esm.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
|
entry: path.resolve(__dirname, './webpack-jszip-bundle.js'),
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, '../src/ext'),
|
||||||
|
filename: 'jszip-esm.js',
|
||||||
|
library: {
|
||||||
|
type: 'module'
|
||||||
|
},
|
||||||
|
module: true
|
||||||
|
},
|
||||||
|
experiments: {
|
||||||
|
outputModule: true
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.mjs', '.js'],
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.m?js$/,
|
||||||
|
resolve: {
|
||||||
|
fullySpecified: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: false
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
hints: false,
|
||||||
|
maxAssetSize: 2 * 1024 * 1024,
|
||||||
|
maxEntrypointSize: 2 * 1024 * 1024,
|
||||||
|
},
|
||||||
|
};
|
||||||
27
notes.md
27
notes.md
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
||||||
|
|
||||||
* `F` experiment with structuredClone(), SharedArrayBuffer, createImageBitmap()
|
|
||||||
* `F` test #private fields, array.at() for negative indices
|
|
||||||
* `F` option to hide platform when viewing from below
|
* `F` option to hide platform when viewing from below
|
||||||
|
|
||||||
# Kiri:Moto
|
# Kiri:Moto
|
||||||
|
|
@ -14,7 +12,6 @@
|
||||||
|
|
||||||
* `P` refactor vertex replacement and widget update matrix tracking
|
* `P` refactor vertex replacement and widget update matrix tracking
|
||||||
* `P` duplicate objects should share same slice data unless rotated or scaled
|
* `P` duplicate objects should share same slice data unless rotated or scaled
|
||||||
* `P` allow selection to be decimated on demand (context menu?)
|
|
||||||
* `P` move all persisted / workspace settings/data to IndexedDB (LS limitations)
|
* `P` move all persisted / workspace settings/data to IndexedDB (LS limitations)
|
||||||
* `P` faster ray intersect https://github.com/gkjohnson/three-mesh-bvh/
|
* `P` faster ray intersect https://github.com/gkjohnson/three-mesh-bvh/
|
||||||
* `P` try material clipping planes for slice range selection
|
* `P` try material clipping planes for slice range selection
|
||||||
|
|
@ -26,7 +23,7 @@
|
||||||
* `F` complete and expose grouping feature
|
* `F` complete and expose grouping feature
|
||||||
* `F` add svgnest-like arrange algorithm
|
* `F` add svgnest-like arrange algorithm
|
||||||
* `F` date column and sorting in recent files list
|
* `F` date column and sorting in recent files list
|
||||||
* `F` warn if part hanging in negative Z space or off bed in general
|
* `F` highlight part outside workspace bounds (like can neg Z shader)
|
||||||
|
|
||||||
# FDM
|
# FDM
|
||||||
|
|
||||||
|
|
@ -34,6 +31,7 @@
|
||||||
* `B` multi-extruder rendering of raft fails to offset the rest of the print
|
* `B` multi-extruder rendering of raft fails to offset the rest of the print
|
||||||
* `B` multi-extruder purge blocks fail to generate properly for rafts
|
* `B` multi-extruder purge blocks fail to generate properly for rafts
|
||||||
|
|
||||||
|
* `F` better thin-wall (like arachne)
|
||||||
* `F` add scarf seams
|
* `F` add scarf seams
|
||||||
* `F` add 'random' and 'seam' start point options
|
* `F` add 'random' and 'seam' start point options
|
||||||
* `F` convert ranges to z offsets while continuing to show layer #
|
* `F` convert ranges to z offsets while continuing to show layer #
|
||||||
|
|
@ -52,12 +50,6 @@
|
||||||
* `P` extruder + filament max flow rate cap in planner
|
* `P` extruder + filament max flow rate cap in planner
|
||||||
* `P` solid fill the tops of supports for down facing flats
|
* `P` solid fill the tops of supports for down facing flats
|
||||||
|
|
||||||
# FDM - SLA
|
|
||||||
|
|
||||||
# `P` common support area detection (fork new fdm code)
|
|
||||||
* `P` prioritize supports by length of unsupported span. mandatory when circularity > X
|
|
||||||
* or % area of inner to outer poly is high (making it a thin shell)
|
|
||||||
|
|
||||||
# FDM - BELT
|
# FDM - BELT
|
||||||
|
|
||||||
* `B` auto bed resizing leaves the origin in the wrong place at first
|
* `B` auto bed resizing leaves the origin in the wrong place at first
|
||||||
|
|
@ -69,7 +61,6 @@
|
||||||
|
|
||||||
# CAM
|
# CAM
|
||||||
|
|
||||||
* `B` roughing leave stock should also increase Z slightly (sqrt(2) * leave)
|
|
||||||
* `B` rapid moves should be max of terrain zmax and last cut layer height (roughing)
|
* `B` rapid moves should be max of terrain zmax and last cut layer height (roughing)
|
||||||
* `B` feed rate for next tool set before tool change (push/pop feed rates?)
|
* `B` feed rate for next tool set before tool change (push/pop feed rates?)
|
||||||
* `B` tab cuts cause loss of direction, parenting, depth, and it's hard to fix
|
* `B` tab cuts cause loss of direction, parenting, depth, and it's hard to fix
|
||||||
|
|
@ -84,18 +75,14 @@
|
||||||
* `F` add `match faces` option in `outline` operation
|
* `F` add `match faces` option in `outline` operation
|
||||||
* `F` add {progress} substitution and maybe {time-remaining} if can be calc'd
|
* `F` add {progress} substitution and maybe {time-remaining} if can be calc'd
|
||||||
* `F` import and follow 2D paths (conformed like pocket contours)
|
* `F` import and follow 2D paths (conformed like pocket contours)
|
||||||
* `F` add user-defined origin (issue #28)
|
|
||||||
* `F` intelligently turn circle hole pocket clear into spiral down
|
|
||||||
* `F` add `plunge max` to contouring that can override z feed limit
|
* `F` add `plunge max` to contouring that can override z feed limit
|
||||||
* `F` add lead-in milling (requires adding clamp / no go areas)
|
* `F` add lead-in milling (requires adding clamp / no go areas)
|
||||||
* `F` add linear clearing strategy
|
* `F` add linear clearing strategy
|
||||||
* `F` add adaptive clearing strategy
|
* `F` add adaptive clearing strategy
|
||||||
* `F` add ease-down support to trace op
|
|
||||||
* `F` add support for tapered ball mills
|
* `F` add support for tapered ball mills
|
||||||
* `F` change color of line selection in trace op when not a closed poly
|
* `F` change color of line selection in trace op when not a closed poly
|
||||||
* `F` limit cut depth to flute length of selected tool (or warn)
|
* `F` limit cut depth to flute length of selected tool (or warn)
|
||||||
* `F` validate muti-part layout and spacing exceeds largest outside tool diameter
|
* `F` validate muti-part layout and spacing exceeds largest outside tool diameter
|
||||||
* `F` parameterize dropping close points in prep.js. ensure long segments remain straight
|
|
||||||
* `F` trapezoidal tabs in Z
|
* `F` trapezoidal tabs in Z
|
||||||
* `F` ease-in and ease-out especially on tab cut-out start/stop
|
* `F` ease-in and ease-out especially on tab cut-out start/stop
|
||||||
* `F` maintain several part orientations + op chains in a single profile
|
* `F` maintain several part orientations + op chains in a single profile
|
||||||
|
|
@ -104,14 +91,8 @@
|
||||||
* `P` outer corner arc moves
|
* `P` outer corner arc moves
|
||||||
* `P` log Z interpolation for contour XYZ moves
|
* `P` log Z interpolation for contour XYZ moves
|
||||||
* `P` option to start with the smallest poly by area on layer change
|
* `P` option to start with the smallest poly by area on layer change
|
||||||
* `P` refactor slicing engine to add minion threading
|
|
||||||
* `P` port arc code from FDM export to CAM export
|
|
||||||
* `P` redo all path route / planning in prepare to account for terrain before camOut
|
* `P` redo all path route / planning in prepare to account for terrain before camOut
|
||||||
|
|
||||||
# SLA
|
|
||||||
|
|
||||||
* `P` blit layers w/ 3JS ortho camera to canvas
|
|
||||||
|
|
||||||
# Laser
|
# Laser
|
||||||
|
|
||||||
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
|
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
|
||||||
|
|
@ -124,8 +105,9 @@
|
||||||
|
|
||||||
# Mesh:Tool
|
# Mesh:Tool
|
||||||
|
|
||||||
* font to path with https://github.com/paulzi/svg-text-to-path
|
|
||||||
* add undo/redo
|
* add undo/redo
|
||||||
|
* add TextGeometry
|
||||||
|
* font to path with https://github.com/paulzi/svg-text-to-path
|
||||||
* click to repair normals based on a known good (selected) face
|
* click to repair normals based on a known good (selected) face
|
||||||
* send to Kiri:Moto workspace (or update model vertices in place)
|
* send to Kiri:Moto workspace (or update model vertices in place)
|
||||||
* better z snap using just vertexes from face intersected
|
* better z snap using just vertexes from face intersected
|
||||||
|
|
@ -134,6 +116,5 @@
|
||||||
* add flatten/crush op: for z bottoms (or surfaces?)
|
* add flatten/crush op: for z bottoms (or surfaces?)
|
||||||
* allow setting model/group origin for scale/rotate
|
* allow setting model/group origin for scale/rotate
|
||||||
* fix mirror to work with groups (just models currently)
|
* fix mirror to work with groups (just models currently)
|
||||||
* bounding box toggle should be global, not selection
|
|
||||||
* add analyze results dialog
|
* add analyze results dialog
|
||||||
* remove/hide auto-repair function
|
* remove/hide auto-repair function
|
||||||
|
|
|
||||||
19
package.json
19
package.json
|
|
@ -36,7 +36,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.1.1",
|
"@fortawesome/fontawesome-free": "^6.1.1",
|
||||||
"@gridspace/app-server": "^0.0.17",
|
"@gridspace/app-server": "^0.0.18",
|
||||||
"@gridspace/basic-ftp": "^5.0.5",
|
"@gridspace/basic-ftp": "^5.0.5",
|
||||||
"@gridspace/net-level-client": "^0.2.3",
|
"@gridspace/net-level-client": "^0.2.3",
|
||||||
"@tracespace/parser": "^5.0.0-next.0",
|
"@tracespace/parser": "^5.0.0-next.0",
|
||||||
|
|
@ -49,9 +49,11 @@
|
||||||
"earcut": "^3.0.1",
|
"earcut": "^3.0.1",
|
||||||
"express-useragent": "^1.0.13",
|
"express-useragent": "^1.0.13",
|
||||||
"fast-glob": "^3.3.3",
|
"fast-glob": "^3.3.3",
|
||||||
|
"i": "^0.3.7",
|
||||||
"jszip": "^3.7.1",
|
"jszip": "^3.7.1",
|
||||||
"manifold-3d": "^3.1.1",
|
"manifold-3d": "^3.1.1",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
|
"npm": "^11.4.2",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"react-responsive-carousel": "^3.2.23",
|
"react-responsive-carousel": "^3.2.23",
|
||||||
"serve-static": "^1.14.1",
|
"serve-static": "^1.14.1",
|
||||||
|
|
@ -79,7 +81,7 @@
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"setup": "npm i && npm run clean && npm run dev -- --dryrun && npm run webpack3",
|
"setup": "npm i && npm run clean && npm run dev -- --dryrun && npm run webpack-ext",
|
||||||
"build": "npm run prebuild && electron-builder",
|
"build": "npm run prebuild && electron-builder",
|
||||||
"build-nopublish": "npm run prebuild && electron-builder --publish never",
|
"build-nopublish": "npm run prebuild && electron-builder --publish never",
|
||||||
"build-debug": "npm run prebuild && DEBUG=electron-builder electron-builder",
|
"build-debug": "npm run prebuild && DEBUG=electron-builder electron-builder",
|
||||||
|
|
@ -94,8 +96,9 @@
|
||||||
"docs-build": "docusaurus build --config conf/docusaurus.config.js",
|
"docs-build": "docusaurus build --config conf/docusaurus.config.js",
|
||||||
"docs-serve": "docusaurus serve --config conf/docusaurus.config.js",
|
"docs-serve": "docusaurus serve --config conf/docusaurus.config.js",
|
||||||
"docs-check": "prettier --config ./conf/prettier.config.js ./docs --check",
|
"docs-check": "prettier --config ./conf/prettier.config.js ./docs --check",
|
||||||
"dev": "npm run webpack3 && gs-app-server --debug --single",
|
"dev": "npm run webpack-ext && gs-app-server --debug --single",
|
||||||
"prod": "npm run webpack prod && gs-app-server",
|
"prod": "npm run webpack-ext && npm run webpack-src prod && gs-app-server",
|
||||||
|
"prod-pack": "npm run webpack-ext && npm run webpack-src prod",
|
||||||
"prod-dryrun": "gs-app-server --dryrun",
|
"prod-dryrun": "gs-app-server --dryrun",
|
||||||
"start": "npm run prebuild prod && electron .",
|
"start": "npm run prebuild prod && electron .",
|
||||||
"start-dev": "npm run prebuild prod && electron . --devel",
|
"start-dev": "npm run prebuild prod && electron . --devel",
|
||||||
|
|
@ -103,11 +106,13 @@
|
||||||
"start-ddb": "npm run prebuild && electron . --devel --debugg",
|
"start-ddb": "npm run prebuild && electron . --devel --debugg",
|
||||||
"mk-links": "find src web -type l | xargs -I{} sh -c 'echo \"{},$(readlink {})\"' > conf/links.csv",
|
"mk-links": "find src web -type l | xargs -I{} sh -c 'echo \"{},$(readlink {})\"' > conf/links.csv",
|
||||||
"mac-verify": "spctl --assess -vv --type install dist/*/*.app",
|
"mac-verify": "spctl --assess -vv --type install dist/*/*.app",
|
||||||
"prebuild": "npm run setup && npm run webpack prod && node bin/electron-pre.js",
|
"prebuild": "npm run setup && npm run webpack-src prod && node bin/electron-pre.js",
|
||||||
"postbuild": "node bin/electron-post.js",
|
"postbuild": "node bin/electron-post.js",
|
||||||
"preinstall": "node bin/install-pre.js",
|
"preinstall": "node bin/install-pre.js",
|
||||||
"webpack": "npm run webpack3 && node bin/esbuild.config.mjs",
|
"webpack-ext": "npm run webpack-three && npm run webpack-zip",
|
||||||
"webpack3": "npx webpack --config bin/webpack-three-esm.js"
|
"webpack-src": "node bin/esbuild.config.mjs",
|
||||||
|
"webpack-three": "npx webpack --config bin/webpack-three-esm.js",
|
||||||
|
"webpack-zip": "npx webpack --config bin/webpack-jszip-esm.js"
|
||||||
},
|
},
|
||||||
"main": "app-el.js",
|
"main": "app-el.js",
|
||||||
"build": {
|
"build": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
|
||||||
|
|
||||||
//import original library
|
|
||||||
import * as JSZip from "./jszip.js";
|
|
||||||
|
|
||||||
//export object attached to the window object
|
|
||||||
export default self.JSZip;
|
|
||||||
|
|
@ -117,7 +117,7 @@ function indexVertices(pos) {
|
||||||
|
|
||||||
let Instance;
|
let Instance;
|
||||||
manifold({
|
manifold({
|
||||||
locateFile() { return "/wasm/manifold.wasm" }
|
locateFile() { return "../wasm/manifold.wasm" }
|
||||||
}).then(inst => {
|
}).then(inst => {
|
||||||
inst.setup();
|
inst.setup();
|
||||||
Instance = inst;
|
Instance = inst;
|
||||||
|
|
|
||||||
|
|
@ -843,6 +843,7 @@ export class Polygon {
|
||||||
* scale polygon around origin
|
* scale polygon around origin
|
||||||
*/
|
*/
|
||||||
scale(scale, round) {
|
scale(scale, round) {
|
||||||
|
this.area2 = undefined;
|
||||||
let x, y, z;
|
let x, y, z;
|
||||||
if (typeof(scale) === 'number') {
|
if (typeof(scale) === 'number') {
|
||||||
x = y = z = scale;
|
x = y = z = scale;
|
||||||
|
|
@ -1073,6 +1074,7 @@ export class Polygon {
|
||||||
* append point to polygon and return point
|
* append point to polygon and return point
|
||||||
*/
|
*/
|
||||||
push(p) {
|
push(p) {
|
||||||
|
this.area2 = undefined;
|
||||||
// clone any point belonging to another polygon
|
// clone any point belonging to another polygon
|
||||||
if (p.poly) p = p.clone();
|
if (p.poly) p = p.clone();
|
||||||
p.poly = this;
|
p.poly = this;
|
||||||
|
|
@ -1117,6 +1119,14 @@ export class Polygon {
|
||||||
return this.first().isEqual(this.last());
|
return this.first().isEqual(this.last());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixClosed() {
|
||||||
|
if (this.appearsClosed()) {
|
||||||
|
this.points.pop();
|
||||||
|
this.open = false;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
setClockwise() {
|
setClockwise() {
|
||||||
if (!this.isClockwise()) this.reverse();
|
if (!this.isClockwise()) this.reverse();
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -1552,7 +1562,12 @@ export class Polygon {
|
||||||
* @returns {number} 0.0 - 1.0 from flat to perfectly circular
|
* @returns {number} 0.0 - 1.0 from flat to perfectly circular
|
||||||
*/
|
*/
|
||||||
circularity() {
|
circularity() {
|
||||||
|
try {
|
||||||
return (4 * Math.PI * this.area()) / util.sqr(this.perimeter());
|
return (4 * Math.PI * this.area()) / util.sqr(this.perimeter());
|
||||||
|
} catch (e) {
|
||||||
|
console.log(this.perimeter(), e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
circularityDeep() {
|
circularityDeep() {
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ export function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
|
||||||
|
|
||||||
function filter(from, to = []) {
|
function filter(from, to = []) {
|
||||||
from.forEach(function(poly) {
|
from.forEach(function(poly) {
|
||||||
if (poly.area() >= min) {
|
if (poly.area() >= min && poly.length > 2) {
|
||||||
to.push(poly);
|
to.push(poly);
|
||||||
out.push(poly);
|
out.push(poly);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { base } from '../geo/base.js';
|
import { base } from '../geo/base.js';
|
||||||
|
import { newPolygon } from './polygon.js';
|
||||||
|
|
||||||
const { config } = base;
|
const { config } = base;
|
||||||
|
|
||||||
const factor = config.clipper;
|
const factor = config.clipper;
|
||||||
|
|
||||||
export const wasm_ctrl = {
|
export const wasm_ctrl = {
|
||||||
|
|
@ -54,7 +54,7 @@ function writePoly(view, poly, inner) {
|
||||||
function readPoly(view, z) {
|
function readPoly(view, z) {
|
||||||
let points = view.readU16(true);
|
let points = view.readU16(true);
|
||||||
if (points === 0) return;
|
if (points === 0) return;
|
||||||
let poly = base.newPolygon();
|
let poly = newPolygon();
|
||||||
while (points-- > 0) {
|
while (points-- > 0) {
|
||||||
poly.add(view.readI32(true)/factor, view.readI32(true)/factor, z || 0);
|
poly.add(view.readI32(true)/factor, view.readI32(true)/factor, z || 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import STACKS from './stacks.js';
|
||||||
|
|
||||||
import { broker } from '../../moto/broker.js';
|
import { broker } from '../../moto/broker.js';
|
||||||
import { client as work } from './client.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 { device, devices } from './devices.js';
|
||||||
import { catalog, dialog, event, group, help, hide, image } from './main.js';
|
import { catalog, dialog, event, group, help, hide, image } from './main.js';
|
||||||
import { modal, mode, probe, process, show, space, util, view } from './main.js';
|
import { modal, mode, probe, process, show, space, util, view } from './main.js';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ const boxes = [];
|
||||||
|
|
||||||
let lastBox;
|
let lastBox;
|
||||||
|
|
||||||
|
export function clearboxes() {
|
||||||
|
boxes.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
export function getlastbox() {
|
export function getlastbox() {
|
||||||
return lastBox;
|
return lastBox;
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +23,7 @@ export function delbox(name) {
|
||||||
export function addbox(point, color, name, dim = {x:1,y:1,z:1,rz:0}, opt = {}) {
|
export function addbox(point, color, name, dim = {x:1,y:1,z:1,rz:0}, opt = {}) {
|
||||||
delbox(name);
|
delbox(name);
|
||||||
|
|
||||||
const box = boxes[name] = new Mesh(
|
const box = new Mesh(
|
||||||
new BoxGeometry(dim.x, dim.y, dim.z),
|
new BoxGeometry(dim.x, dim.y, dim.z),
|
||||||
new MeshPhongMaterial({
|
new MeshPhongMaterial({
|
||||||
transparent: true,
|
transparent: true,
|
||||||
|
|
@ -28,6 +32,10 @@ export function addbox(point, color, name, dim = {x:1,y:1,z:1,rz:0}, opt = {}) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
boxes[name] = box;
|
||||||
|
}
|
||||||
|
|
||||||
box.position.x = point.x;
|
box.position.x = point.x;
|
||||||
box.position.y = point.y;
|
box.position.y = point.y;
|
||||||
box.position.z = point.z;
|
box.position.z = point.z;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import { api } from './api.js';
|
import { api } from './api.js';
|
||||||
import { noop } from './utils.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
|
// this code runs in kiri's main loop
|
||||||
let debug = self.debug === true,
|
let debug = self.debug === true,
|
||||||
|
|
@ -199,7 +202,7 @@ export const client = {
|
||||||
send("rotate", { settings }, reply => {
|
send("rotate", { settings }, reply => {
|
||||||
if (reply.group) {
|
if (reply.group) {
|
||||||
// collect post-rotation data for slice/preview renders
|
// 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;
|
widget.belt = reply.belt;
|
||||||
}
|
}
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
|
|
@ -280,10 +283,10 @@ export const client = {
|
||||||
y: -origin.y,
|
y: -origin.y,
|
||||||
z: origin.z
|
z: origin.z
|
||||||
};
|
};
|
||||||
const output = kiri.newPrint().parseSVG(code, offset);
|
const output = newPrint().parseSVG(code, offset);
|
||||||
send("parse_svg", output, reply => {
|
send("parse_svg", output, reply => {
|
||||||
if (reply.parsed) {
|
if (reply.parsed) {
|
||||||
done(kiri.codec.decode(reply.parsed));
|
done(codec.decode(reply.parsed));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
@ -293,7 +296,7 @@ export const client = {
|
||||||
progress(reply.progress);
|
progress(reply.progress);
|
||||||
}
|
}
|
||||||
if (reply.parsed) {
|
if (reply.parsed) {
|
||||||
done(kiri.codec.decode(reply.parsed), reply.maxSpeed, reply.minSpeed);
|
done(codec.decode(reply.parsed), reply.maxSpeed, reply.minSpeed);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -581,7 +581,8 @@ export const conf = {
|
||||||
outputInvertY: false,
|
outputInvertY: false,
|
||||||
camExpertFast: false,
|
camExpertFast: false,
|
||||||
camTrueShadow: false,
|
camTrueShadow: false,
|
||||||
camArcTolerance: 0.006,
|
camArcEnabled: false,
|
||||||
|
camArcTolerance: 0.15,
|
||||||
camArcResolution: 5,
|
camArcResolution: 5,
|
||||||
camForceZMax: false,
|
camForceZMax: false,
|
||||||
camFirstZMax: false,
|
camFirstZMax: false,
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,8 @@ const PMODES = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const PATHS = {
|
const PATHS = {
|
||||||
work: "/lib/kiri/run/worker.js",
|
work: "../lib/kiri/run/worker.js",
|
||||||
pool: "/lib/kiri/run/minion.js"
|
pool: "./minion.js"
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEED = 'kiri-seed';
|
const SEED = 'kiri-seed';
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ function prepareSlices(callback, scale = 1, offset = 0) {
|
||||||
if (msg && msg !== lastMsg) {
|
if (msg && msg !== lastMsg) {
|
||||||
let mark = Date.now();
|
let mark = Date.now();
|
||||||
if (lastMsg) {
|
if (lastMsg) {
|
||||||
let key = widgets.length > 1 ?
|
let key = slicing.length > 1 ?
|
||||||
`${widget.id}_${segNumber++}_${lastMsg}` :
|
`${widget.id}_${segNumber++}_${lastMsg}` :
|
||||||
`${segNumber++}_${lastMsg}`
|
`${segNumber++}_${lastMsg}`
|
||||||
segtimes[key] = mark - startTime;
|
segtimes[key] = mark - startTime;
|
||||||
|
|
@ -158,7 +158,10 @@ function prepareSlices(callback, scale = 1, offset = 0) {
|
||||||
if (sliced) {
|
if (sliced) {
|
||||||
// update segment time
|
// update segment time
|
||||||
if (lastMsg) {
|
if (lastMsg) {
|
||||||
segtimes[`${widget.id}_${segNumber++}_${lastMsg}`] = mark - startTime;
|
let key = slicing.length > 1 ?
|
||||||
|
`${widget.id}_${segNumber++}_${lastMsg}` :
|
||||||
|
`${segNumber++}_${lastMsg}`
|
||||||
|
segtimes[`${key}`] = mark - startTime;
|
||||||
}
|
}
|
||||||
event.emit('slice', settings.mode);
|
event.emit('slice', settings.mode);
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +240,10 @@ function prepareSlices(callback, scale = 1, offset = 0) {
|
||||||
};
|
};
|
||||||
for (let widget of slicing) {
|
for (let widget of slicing) {
|
||||||
// on done
|
// on done
|
||||||
segtimes[`${widget.id}_${segNumber++}_draw`] = widget.render(widget.stack);
|
let key = slicing.length > 1 ?
|
||||||
|
`${widget.id}_${segNumber++}_draw` :
|
||||||
|
`${segNumber++}_draw`
|
||||||
|
segtimes[`${key}`] = widget.render(widget.stack);
|
||||||
// rotate stack for belt beds
|
// rotate stack for belt beds
|
||||||
if (widget.belt) {
|
if (widget.belt) {
|
||||||
widget.stack.obj.rotate(widget.belt);
|
widget.stack.obj.rotate(widget.belt);
|
||||||
|
|
@ -452,8 +458,7 @@ function cancelWorker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCode(code, type) {
|
function parseCode(code, type) {
|
||||||
const { conf, event, show, widgets, view } = api;
|
const { conf, event, show, stacks, widgets, view } = api;
|
||||||
const { stacks } = kiri;
|
|
||||||
const settings = conf.get();
|
const settings = conf.get();
|
||||||
|
|
||||||
event.emit("code.load", {code, type});
|
event.emit("code.load", {code, type});
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ import { init as initLaser } from '../mode/laser/client.js';
|
||||||
import { init as initSLA } from '../mode/sla/client.js';
|
import { init as initSLA } from '../mode/sla/client.js';
|
||||||
import { init as initWEDM } from '../mode/wedm/client.js';
|
import { init as initWEDM } from '../mode/wedm/client.js';
|
||||||
import { init as initWJET } from '../mode/wjet/client.js';
|
import { init as initWJET } from '../mode/wjet/client.js';
|
||||||
|
import { menu as menuCAM } from '../mode/cam/init-menu.js';
|
||||||
|
import { menu as menuFDM } from '../mode/fdm/init-menu.js';
|
||||||
|
import { menu as menuLaser } from '../mode/laser/init-menu.js';
|
||||||
|
import { menu as menuSLA } from '../mode/sla/init-menu.js';
|
||||||
|
|
||||||
let { CAM, SLA, FDM, LASER, DRAG, WJET, WEDM } = MODES,
|
let { CAM, SLA, FDM, LASER, DRAG, WJET, WEDM } = MODES,
|
||||||
{ client, catalog, platform, selection, stats } = api,
|
{ client, catalog, platform, selection, stats } = api,
|
||||||
|
|
@ -90,15 +94,6 @@ function lineTypeSave() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function thinWallSave() {
|
|
||||||
let opt = ui.sliceDetectThin;
|
|
||||||
let level = opt.options[opt.selectedIndex];
|
|
||||||
if (level) {
|
|
||||||
settings().process.sliceDetectThin = level.value;
|
|
||||||
api.conf.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function detailSave() {
|
function detailSave() {
|
||||||
let level = ui.detail.options[ui.detail.selectedIndex];
|
let level = ui.detail.options[ui.detail.selectedIndex];
|
||||||
if (level) {
|
if (level) {
|
||||||
|
|
@ -123,11 +118,6 @@ function speedSave() {
|
||||||
api.view.update_speeds();
|
api.view.update_speeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
function zAnchorSave() {
|
|
||||||
api.conf.update();
|
|
||||||
api.platform.update_top_z();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setThreaded(bool) {
|
function setThreaded(bool) {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
client.pool.start();
|
client.pool.start();
|
||||||
|
|
@ -234,6 +224,8 @@ function onBooleanClick(el) {
|
||||||
api.devices.update_laser_state();
|
api.devices.update_laser_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.event.on('click.boolean', onBooleanClick);
|
||||||
|
|
||||||
function onButtonClick(ev) {
|
function onButtonClick(ev) {
|
||||||
let target = ev.target;
|
let target = ev.target;
|
||||||
while (target && target.tagName !== 'BUTTON') {
|
while (target && target.tagName !== 'BUTTON') {
|
||||||
|
|
@ -242,6 +234,8 @@ function onButtonClick(ev) {
|
||||||
api.event.emit("button.click", target);
|
api.event.emit("button.click", target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.event.on('click.button', onButtonClick);
|
||||||
|
|
||||||
function inputHasFocus() {
|
function inputHasFocus() {
|
||||||
let active = DOC.activeElement;
|
let active = DOC.activeElement;
|
||||||
return active && (active.nodeName === "INPUT" || active.nodeName === "TEXTAREA");
|
return active && (active.nodeName === "INPUT" || active.nodeName === "TEXTAREA");
|
||||||
|
|
@ -769,11 +763,6 @@ function updateCatalog(files) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMultiHead() {
|
|
||||||
let dev = api.conf.get().device;
|
|
||||||
return isNotBelt() && dev.extruders && dev.extruders.length > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isBelt() {
|
function isBelt() {
|
||||||
return api.device.isBelt();
|
return api.device.isBelt();
|
||||||
}
|
}
|
||||||
|
|
@ -845,7 +834,6 @@ function init_one() {
|
||||||
|
|
||||||
// api augmentation with local functions
|
// api augmentation with local functions
|
||||||
api.device.export = deviceExport;
|
api.device.export = deviceExport;
|
||||||
let anim = ui.anim = {};
|
|
||||||
|
|
||||||
Object.assign(ui, {
|
Object.assign(ui, {
|
||||||
tracker: tracker,
|
tracker: tracker,
|
||||||
|
|
@ -982,33 +970,6 @@ function init_one() {
|
||||||
stockDepth: $('stock-width'),
|
stockDepth: $('stock-width'),
|
||||||
stockHeight: $('stock-width'),
|
stockHeight: $('stock-width'),
|
||||||
|
|
||||||
/** CAM Animation Bar */
|
|
||||||
|
|
||||||
_____: {
|
|
||||||
_____: newDiv({ addto: $('layer-animate'), set:true }),
|
|
||||||
row: newRow([
|
|
||||||
anim.replay = newButton(null,"anim.replay",{icon:'<i class="fas fa-fast-backward"></i>',title:"restart"}),
|
|
||||||
anim.play = newButton(null,"anim.play",{icon:'<i class="fas fa-play"></i>',title:"play"}),
|
|
||||||
anim.pause = newButton(null,"anim.pause",{icon:'<i class="fas fa-pause"></i>',title:"pause"}),
|
|
||||||
anim.step = newButton(null,"anim.step",{icon:'<i class="fas fa-step-forward"></i>',title:"single step"}),
|
|
||||||
anim.speed = newButton(null,"anim.fast",{icon:'<i class="fas fa-forward"></i>',title:"toggle speed"}),
|
|
||||||
anim.labspd = newValue(3, {class:"center padleft"}),
|
|
||||||
anim.labx = newLabel("X", {class:"padleft"}),
|
|
||||||
anim.valx = newValue(7, {class:"center"}),
|
|
||||||
anim.laby = newLabel("Y", {class:"padleft"}),
|
|
||||||
anim.valy = newValue(7, {class:"center"}),
|
|
||||||
anim.labz = newLabel("Z", {class:"padleft"}),
|
|
||||||
anim.valz = newValue(6, {class:"center"}),
|
|
||||||
anim.laba = newLabel("A", {class:"padleft hide"}),
|
|
||||||
anim.vala = newValue(6, {class:"center hide"}),
|
|
||||||
anim.labpro = newLabel("%", {class:"padleft"}),
|
|
||||||
anim.progress = newValue(5, {class:"center"}),
|
|
||||||
anim.trans = newButton(null,"anim.trans",{icon:'<i class="fa-solid fa-border-none"></i>',title:"transparency",class:"padleft"}),
|
|
||||||
anim.model = newButton(null,"anim.model",{icon:'<i class="fa-solid fa-eye"></i>',title:"show model"}),
|
|
||||||
anim.shade = newButton(null,"anim.stock",{icon:'<i class="fa-solid fa-cube"></i>',title:"stock box"}),
|
|
||||||
])
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Device Browser / Editor */
|
/** Device Browser / Editor */
|
||||||
|
|
||||||
_____: newDiv({ class: "f-col t-body t-inset", addto: $('dev-config'), set:true }),
|
_____: newDiv({ class: "f-col t-body t-inset", addto: $('dev-config'), set:true }),
|
||||||
|
|
@ -1110,255 +1071,16 @@ function init_one() {
|
||||||
prefadd: uc.checkpoint($('prefs-add')),
|
prefadd: uc.checkpoint($('prefs-add')),
|
||||||
|
|
||||||
/** FDM Settings */
|
/** FDM Settings */
|
||||||
|
...menuFDM(),
|
||||||
_____: newGroup(LANG.sl_menu, $('fdm-layers'), { modes:FDM, driven, hideable, separator, group:"fdm-layers" }),
|
|
||||||
sliceHeight: newInput(LANG.sl_lahi_s, { title:LANG.sl_lahi_l, convert:toFloat }),
|
|
||||||
sliceMinHeight: newInput(LANG.ad_minl_s, { title:LANG.ad_minl_l, convert:toFloat, bound:bound(0,3.0), show:() => ui.sliceAdaptive.checked }),
|
|
||||||
sliceTopLayers: newInput(LANG.sl_ltop_s, { title:LANG.sl_ltop_l, convert:toInt }),
|
|
||||||
sliceBottomLayers: newInput(LANG.sl_lbot_s, { title:LANG.sl_lbot_l, convert:toInt }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceAdaptive: newBoolean(LANG.ad_adap_s, onBooleanClick, { title: LANG.ad_adap_l }),
|
|
||||||
_____: newGroup(LANG.sw_menu, $('fdm-walls'), { modes:FDM, driven, hideable, separator, group:"fdm-walls" }),
|
|
||||||
sliceShells: newInput(LANG.sl_shel_s, { title:LANG.sl_shel_l, convert:toFloat }),
|
|
||||||
sliceLineWidth: newInput(LANG.sl_line_s, { title:LANG.sl_line_l, convert:toFloat, bound:bound(0,5) }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceShellOrder: newSelect(LANG.sl_ordr_s, { title:LANG.sl_ordr_l}, "shell"),
|
|
||||||
sliceDetectThin: newSelect(LANG.ad_thin_s, { title: LANG.ad_thin_l, action: thinWallSave }, "thin"),
|
|
||||||
outputAlternating: newBoolean(LANG.ad_altr_s, onBooleanClick, {title:LANG.ad_altr_l}),
|
|
||||||
sliceZInterleave: newBoolean(LANG.ad_zint_s, onBooleanClick, {title:LANG.ad_zint_l, show:zIntShow}),
|
|
||||||
_____: newGroup(LANG.fi_menu, $('fdm-fill'), { modes:FDM, driven, hideable, separator, group:"fdm-fill" }),
|
|
||||||
sliceFillType: newSelect(LANG.fi_type, {trigger}, "infill"),
|
|
||||||
sliceFillSparse: newInput(LANG.fi_pcnt_s, {title:LANG.fi_pcnt_l, convert:toFloat, bound:bound(0.0,1.0), show:hasInfill}),
|
|
||||||
sliceFillRepeat: newInput(LANG.fi_rept_s, {title:LANG.fi_rept_l, convert:toInt, bound:bound(1,10), show:fillIsLinear}),
|
|
||||||
sliceFillOverlap: newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:toFloat, bound:bound(0.0,2.0), show:hasInfill}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceFillRate: newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:toInt, bound:bound(0,500)}),
|
|
||||||
sliceSolidRate: newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:toInt, bound:bound(0,500)}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceFillGrow: newInput(LANG.fi_grow_s, {title:LANG.fi_grow_l, convert:toFloat}),
|
|
||||||
sliceFillAngle: newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:toFloat}),
|
|
||||||
_____: newGroup(LANG.fh_menu, $('fdm-heat'), { modes:FDM, driven, hideable, separator, group:"fdm-heat" }),
|
|
||||||
outputTemp: newInput(LANG.ou_nozl_s, {title:LANG.ou_nozl_l, convert:toInt}),
|
|
||||||
outputBedTemp: newInput(LANG.ou_bedd_s, {title:LANG.ou_bedd_l, convert:toInt}),
|
|
||||||
_____: newGroup(LANG.fc_menu, $('fdm-cool'), { modes:FDM, driven, hideable, separator, group:"fdm-cool" }),
|
|
||||||
outputFanLayer: newInput(LANG.ou_fanl_s, { title:LANG.ou_fanl_l, convert:toInt, bound:bound(0,255) }),
|
|
||||||
outputFanSpeed: newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:toInt, bound:bound(0,255)}),
|
|
||||||
_____: newGroup(LANG.sp_menu, $('fdm-support'), { modes:FDM, driven, hideable, separator, group:"fdm-supp" }),
|
|
||||||
sliceSupportNozzle: newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, show:isMultiHead}, "extruders"),
|
|
||||||
sliceSupportDensity: newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:toFloat, bound:bound(0.0,1.0)}),
|
|
||||||
sliceSupportSize: newInput(LANG.sp_size_s, {title:LANG.sp_size_l, convert:toFloat, bound:bound(1.0,200.0)}),
|
|
||||||
sliceSupportOffset: newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, convert:toFloat, bound:bound(0.0,200.0)}),
|
|
||||||
sliceSupportGap: newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, convert:toInt, bound:bound(0,5)}),
|
|
||||||
sliceSupportArea: newInput(LANG.sp_area_s, {title:LANG.sp_area_l, convert:toFloat, bound:bound(0.0,200.0)}),
|
|
||||||
sliceSupportExtra: newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, convert:toFloat, bound:bound(0.0,10.0)}),
|
|
||||||
sliceSupportGrow: newInput(LANG.sp_grow_s, {title:LANG.sp_grow_l, convert:toFloat, bound:bound(0.0,10.0)}),
|
|
||||||
sliceSupportAngle: newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, convert:toFloat, bound:bound(0.0,90.0)}),
|
|
||||||
sliceSupportSpan: newInput(LANG.sp_span_s, {title:LANG.sp_span_l, convert:toFloat, bound:bound(0.0,200.0), show:() => ui.sliceSupportEnable.checked }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceSupportEnable: newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, show:isNotBelt}),
|
|
||||||
sliceSupportOutline: newBoolean(LANG.sp_outl_s, onBooleanClick, {title:LANG.sp_outl_l}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceSupportGen: newRow([
|
|
||||||
ui.ssaGen = newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})
|
|
||||||
], { modes: FDM, class: "ext-buttons f-row grow" }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceSupportManual: newRow([
|
|
||||||
(ui.ssmAdd = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
|
||||||
(ui.ssmDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
|
||||||
(ui.ssmClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
|
||||||
], {class:"ext-buttons f-row"}),
|
|
||||||
_____: newGroup(LANG.fl_menu, $('fdm-base'), { modes:FDM, driven, hideable, separator, group:"fdm-base" }),
|
|
||||||
firstSliceHeight: newInput(LANG.fl_lahi_s, {title:LANG.fl_lahi_l, convert:toFloat, show:isNotBelt}),
|
|
||||||
firstLayerNozzleTemp:newInput(LANG.fl_nozl_s, {title:LANG.fl_nozl_l, convert:toInt, show:isNotBelt}),
|
|
||||||
firstLayerBedTemp: newInput(LANG.fl_bedd_s, {title:LANG.fl_bedd_l, convert:toInt, show:isNotBelt}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
firstLayerFanSpeed: newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:toInt, bound:bound(0,255), show:isBelt}),
|
|
||||||
firstLayerYOffset: newInput(LANG.fl_zoff_s, {title:LANG.fl_zoff_l, convert:toFloat, show:isBelt}),
|
|
||||||
firstLayerFlatten: newInput(LANG.fl_flat_s, {title:LANG.fl_flat_l, convert:toFloat, show:isBelt}),
|
|
||||||
firstLayerRate: newInput(LANG.fl_rate_s, {title:LANG.fl_rate_l, convert:toFloat}),
|
|
||||||
firstLayerFillRate: newInput(LANG.fl_frat_s, {title:LANG.fl_frat_l, convert:toFloat, show:isNotBelt}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
|
||||||
firstLayerLineMult: newInput(LANG.fl_sfac_s, {title:LANG.fl_sfac_l, convert:toFloat, bound:bound(0.5,2), show:isNotBelt}),
|
|
||||||
firstLayerPrintMult: newInput(LANG.fl_mult_s, {title:LANG.fl_mult_l, convert:toFloat}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
|
||||||
firstLayerBrim: newInput(LANG.fl_brim_s, {title:LANG.fl_brim_l, convert:toInt, show:isBelt}),
|
|
||||||
firstLayerBrimIn: newInput(LANG.fl_brin_s, {title:LANG.fl_brin_l, convert:toInt, show:isBelt}),
|
|
||||||
firstLayerBrimTrig: newInput(LANG.fl_brmn_s, {title:LANG.fl_brmn_l, convert:toInt, show:isBelt}),
|
|
||||||
firstLayerBrimGap: newInput(LANG.fl_brgp_s, {title:LANG.fl_brgp_l, convert:toFloat, show:isBelt}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
|
||||||
firstLayerBeltLead: newInput(LANG.fl_bled_s, {title:LANG.fl_bled_l, convert:toFloat, show:isBelt}),
|
|
||||||
firstLayerBeltBump: newInput(LANG.fl_blmp_s, {title:LANG.fl_blmp_l, convert:toFloat, bound:bound(0, 10), show:isBelt}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
|
||||||
outputBrimCount: newInput(LANG.fl_skrt_s, {title:LANG.fl_skrt_l, convert:toInt, show:isNotBelt}),
|
|
||||||
outputBrimOffset: newInput(LANG.fl_skro_s, {title:LANG.fl_skro_l, convert:toFloat, show:isNotBelt}),
|
|
||||||
outputRaftSpacing: newInput(LANG.fr_spac_s, {title:LANG.fr_spac_l, convert:toFloat, bound:bound(0.0,3.0), show: () => ui.outputRaft.checked && isNotBelt() }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
|
||||||
outputRaft: newBoolean(LANG.fr_nabl_s, onBooleanClick, {title:LANG.fr_nabl_l, trigger, show:() => isNotBelt()}),
|
|
||||||
outputDraftShield: newBoolean(LANG.fr_draf_s, onBooleanClick, {title:LANG.fr_draf_l, trigger, show:() => isNotBelt()}),
|
|
||||||
_____: newGroup(LANG.ou_menu, $('fdm-output'), { modes:FDM, driven, hideable, separator, group:"fdm-out" }),
|
|
||||||
outputFeedrate: newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:toInt}),
|
|
||||||
outputFinishrate: newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:toInt}),
|
|
||||||
outputSeekrate: newInput(LANG.ou_move_s, {title:LANG.ou_move_l, convert:toInt}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
outputShellMult: newInput(LANG.ou_shml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
|
||||||
outputFillMult: newInput(LANG.ou_flml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
|
||||||
outputSparseMult: newInput(LANG.ou_spml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
outputRetractDist: newInput(LANG.ad_rdst_s, {title:LANG.ad_rdst_l, convert:toFloat}),
|
|
||||||
outputRetractSpeed: newInput(LANG.ad_rrat_s, {title:LANG.ad_rrat_l, convert:toInt}),
|
|
||||||
outputRetractWipe: newInput(LANG.ad_wpln_s, {title:LANG.ad_wpln_l, convert:toFloat, bound:bound(0.0,10)}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
sliceLayerStart: newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l}, "start"),
|
|
||||||
outputLayerRetract: newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l}),
|
|
||||||
outputAvoidGaps: newBoolean(LANG.ad_agap_s, onBooleanClick, {title:LANG.ad_agap_l}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
|
||||||
outputBeltFirst: newBoolean(LANG.ad_lbir_s, onBooleanClick, {title:LANG.ad_lbir_l, show:isBelt}),
|
|
||||||
_____: newGroup(LANG.ad_menu, $('fdm-expert'), { modes:FDM, driven, hideable, separator, group:"fdm-xprt" }),
|
|
||||||
sliceAngle: newInput(LANG.sl_angl_s, {title:LANG.sl_angl_l, convert:toFloat, show:isBelt}),
|
|
||||||
outputRetractDwell: newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:toInt}),
|
|
||||||
sliceSolidMinArea: newInput(LANG.ad_msol_s, {title:LANG.ad_msol_l, convert:toFloat}),
|
|
||||||
outputMinSpeed: newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, convert:toFloat, bound:bound(1,200)}),
|
|
||||||
outputShortPoly: newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, convert:toFloat, bound:bound(0,10000)}),
|
|
||||||
outputCoastDist: newInput(LANG.ad_scst_s, {title:LANG.ad_scst_l, convert:toFloat, bound:bound(0.0,10)}),
|
|
||||||
zHopDistance: newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, convert:toFloat, bound:bound(0,3.0)}),
|
|
||||||
arcTolerance: newInput(LANG.ad_arct_s, {title:LANG.ad_arct_l, convert:toFloat, bound:bound(0,1.0), show:() => { return isNotBelt() }}),
|
|
||||||
antiBacklash: newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, convert:toInt, bound:bound(0,3)}),
|
|
||||||
outputLoops: newInput(LANG.ag_loop_s, {title:LANG.ag_loop_l, convert:toInt, bound:bound(-1,1000), show:isBelt}),
|
|
||||||
outputPurgeTower: newInput(LANG.ad_purg_s, {title:LANG.ad_purg_l, convert:toInt, bound:bound(0,1000)}),
|
|
||||||
|
|
||||||
fdmRanges: $('fdm-ranges'),
|
|
||||||
|
|
||||||
/** CAM Settings */
|
/** CAM Settings */
|
||||||
|
...menuCAM(),
|
||||||
_____: 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:'<i class="fas fa-plus"></i>'})),
|
|
||||||
(ui.tabDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
|
||||||
(ui.tabClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
|
||||||
], {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}),
|
|
||||||
|
|
||||||
/** LASER/DRAG/WJET/WEDM cut tool Settings */
|
/** LASER/DRAG/WJET/WEDM cut tool Settings */
|
||||||
|
...menuLaser(),
|
||||||
_____: newGroup(LANG.sl_menu, $('lzr-slice'), { modes:TWOD, driven, separator }),
|
|
||||||
ctSliceKerf: newInput(LANG.ls_offs_s, {title:LANG.ls_offs_l, convert:toFloat}),
|
|
||||||
ctSliceHeight: newInput(LANG.ls_lahi_s, {title:LANG.ls_lahi_l, convert:toFloat, trigger}),
|
|
||||||
ctSliceHeightMin: newInput(LANG.ls_lahm_s, {title:LANG.ls_lahm_l, convert:toFloat, show:() => ui.ctSliceHeight.value == 0 && !ui.ctSliceSingle.checked }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
ctSliceSingle: newBoolean(LANG.ls_sngl_s, onBooleanClick, {title:LANG.ls_sngl_l}),
|
|
||||||
ctOmitInner: newBoolean(LANG.we_omit_s, onBooleanClick, {title:LANG.we_omit_l, modes:WEDM}),
|
|
||||||
_____: newGroup('surfaces', $('lzr-surface'), { modes:[-1], driven, separator }),
|
|
||||||
ctSurfaces: newRow([
|
|
||||||
(ui.faceAdd = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
|
||||||
(ui.faceDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
|
||||||
(ui.faceClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
|
||||||
], {class:"ext-buttons f-row", modes:WEDM}),
|
|
||||||
_____: newGroup(LANG.dk_menu, $('lzr-knife'), { modes:DRAG, marker:true, driven, separator }),
|
|
||||||
ctOutKnifeDepth: newInput(LANG.dk_dpth_s, { title:LANG.dk_dpth_l, convert:toFloat, bound:bound(0.0,5.0) }),
|
|
||||||
ctOutKnifePasses: newInput(LANG.dk_pass_s, { title:LANG.dk_pass_l, convert:toInt, bound:bound(0,5) }),
|
|
||||||
ctOutKnifeTip: newInput(LANG.dk_offs_s, { title:LANG.dk_offs_l, convert:toFloat, bound:bound(0.0,10.0) }),
|
|
||||||
_____: newGroup(LANG.lo_menu, $('lzr-layout'), { modes:TWOD, driven, separator }),
|
|
||||||
ctOutTileSpacing: newInput(LANG.ou_spac_s, { title:LANG.ou_spac_l, convert:toInt }),
|
|
||||||
ctOutMerged: newBoolean(LANG.ou_mrgd_s, onBooleanClick, {title:LANG.ou_mrgd_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
|
||||||
ctOutGroup: newBoolean(LANG.ou_grpd_s, onBooleanClick, {title:LANG.ou_grpd_l, show:() => !(ui.ctOutMark.checked || ui.ctOutStack.checked) }),
|
|
||||||
_____: newGroup(LANG.ou_menu, $('lzr-output'), { modes:TWOD, driven, separator, group:"lzr-output" }),
|
|
||||||
ctOutPower: newInput(LANG.ou_powr_s, {title:LANG.ou_powr_l, convert:toInt, bound:bound(1,100), modes:TWONED }),
|
|
||||||
ctOutSpeed: newInput(LANG.ou_sped_s, {title:LANG.ou_sped_l, convert:toInt }),
|
|
||||||
ctAdaptive: newBoolean('adaptive speed', onBooleanClick, {modes:WEDM, title:'controller determines best cutting speed based on material feedback at runtime'}),
|
|
||||||
separator: newBlank({ class:"set-sep", driven }),
|
|
||||||
ctOriginBounds: newBoolean(LANG.or_bnds_s, onBooleanClick, { title:LANG.or_bnds_l, show:() => !ui.ctOriginCenter.checked }),
|
|
||||||
ctOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, { title:LANG.or_cntr_l, show:() => !ui.ctOriginBounds.checked }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
|
||||||
ctOriginOffX: newInput(LANG.or_offx_s, { title:LANG.or_offx_l, convert:toFloat, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
|
||||||
ctOriginOffY: newInput(LANG.or_offy_s, { title:LANG.or_offy_l, convert:toFloat, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, modes:TWONED }),
|
|
||||||
ctOutZColor: newBoolean(LANG.ou_layo_s, onBooleanClick, { title:LANG.ou_layo_l, modes:TWONED, show:() => !ui.ctOutMerged.checked }),
|
|
||||||
ctOutLayer: newBoolean(LANG.ou_layr_s, onBooleanClick, { title:LANG.ou_layr_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
|
||||||
ctOutMark: newBoolean(LANG.ou_lays_s, onBooleanClick, { title:LANG.ou_lays_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
|
||||||
separator: newBlank({ class:"set-sep", driven, modes:LASER }),
|
|
||||||
ctOutInches: newBoolean(LANG.ou_inch_s, onBooleanClick, { title:LANG.ou_inch_l, modes:LASER }),
|
|
||||||
ctOutStack: newBoolean(LANG.ou_stak_s, onBooleanClick, { title:LANG.ou_stak_l, modes:LASER }),
|
|
||||||
ctOutShaper: newBoolean(LANG.ou_shap_s, onBooleanClick, { title:LANG.ou_shap_l, modes:LASER, show:() => ui.ctOutStack.checked }),
|
|
||||||
|
|
||||||
/** SLA SETTINGS */
|
/** SLA SETTINGS */
|
||||||
|
...menuSLA(),
|
||||||
slaProc: newGroup(LANG.sa_menu, $('sla-slice'), { modes:SLA, group:"sla-slice", driven, separator }),
|
|
||||||
slaSlice: newInput(LANG.sa_lahe_s, {title:LANG.sa_lahe_l, convert:toFloat}),
|
|
||||||
slaShell: newInput(LANG.sa_shel_s, {title:LANG.sa_shel_l, convert:toFloat}),
|
|
||||||
slaOpenTop: newBoolean(LANG.sa_otop_s, onBooleanClick, {title:LANG.sa_otop_l}),
|
|
||||||
slaOpenBase: newBoolean(LANG.sa_obas_s, onBooleanClick, {title:LANG.sa_obas_l}),
|
|
||||||
slaLayers: newGroup(LANG.sa_layr_m, $('sla-layers'), { modes:SLA, group:"sla-layers", driven, separator }),
|
|
||||||
slaLayerOn: newInput(LANG.sa_lton_s, {title:LANG.sa_lton_l, convert:toFloat}),
|
|
||||||
slaLayerOff: newInput(LANG.sa_ltof_s, {title:LANG.sa_ltof_l, convert:toFloat}),
|
|
||||||
slaPeelDist: newInput(LANG.sa_pldi_s, {title:LANG.sa_pldi_l, convert:toFloat}),
|
|
||||||
slaPeelLiftRate: newInput(LANG.sa_pllr_s, {title:LANG.sa_pllr_l, convert:toFloat}),
|
|
||||||
slaPeelDropRate: newInput(LANG.sa_pldr_s, {title:LANG.sa_pldr_l, convert:toFloat}),
|
|
||||||
slaBase: newGroup(LANG.sa_base_m, $('sla-base'), { modes:SLA, group:"sla-base", driven, separator }),
|
|
||||||
slaBaseLayers: newInput(LANG.sa_balc_s, {title:LANG.sa_balc_l, convert:toInt}),
|
|
||||||
slaBaseOn: newInput(LANG.sa_lton_s, {title:LANG.sa_bltn_l, convert:toFloat}),
|
|
||||||
slaBaseOff: newInput(LANG.sa_ltof_s, {title:LANG.sa_bltf_l, convert:toFloat}),
|
|
||||||
slaBasePeelDist: newInput(LANG.sa_pldi_s, {title:LANG.sa_pldi_l, convert:toFloat}),
|
|
||||||
slaBasePeelLiftRate: newInput(LANG.sa_pllr_s, {title:LANG.sa_pllr_l, convert:toFloat}),
|
|
||||||
slaFill: newGroup(LANG.sa_infl_m, $('sla-fill'), { modes:SLA, group:"sla-infill", driven, separator }),
|
|
||||||
slaFillDensity: newInput(LANG.sa_ifdn_s, {title:LANG.sa_ifdn_l, convert:toFloat, bound:bound(0,1)}),
|
|
||||||
slaFillLine: newInput(LANG.sa_iflw_s, {title:LANG.sa_iflw_l, convert:toFloat, bound:bound(0,5)}),
|
|
||||||
slaSupport: newGroup(LANG.sa_supp_m, $('sla-support'), { modes:SLA, group:"sla-support", driven, separator }),
|
|
||||||
slaSupportLayers: newInput(LANG.sa_slyr_s, {title:LANG.sa_slyr_l, convert:toInt, bound:bound(5,100)}),
|
|
||||||
slaSupportGap: newInput(LANG.sa_slgp_s, {title:LANG.sa_slgp_l, convert:toInt, bound:bound(3,30)}),
|
|
||||||
slaSupportDensity: newInput(LANG.sa_sldn_s, {title:LANG.sa_sldn_l, convert:toFloat, bound:bound(0.01,0.9)}),
|
|
||||||
slaSupportSize: newInput(LANG.sa_slsz_s, {title:LANG.sa_slsz_l, convert:toFloat, bound:bound(0.1,1)}),
|
|
||||||
slaSupportPoints: newInput(LANG.sa_slpt_s, {title:LANG.sa_slpt_l, convert:toInt, bound:bound(3,10)}),
|
|
||||||
slaSupportEnable: newBoolean(LANG.enable, onBooleanClick, {title:LANG.sl_slen_l}),
|
|
||||||
slaOutput: newGroup(LANG.sa_outp_m, $('sla-output'), { modes:SLA, driven, separator, group:"sla-output" }),
|
|
||||||
slaFirstOffset: newInput(LANG.sa_opzo_s, {title:LANG.sa_opzo_l, convert:toFloat, bound:bound(0,1)}),
|
|
||||||
slaAntiAlias: newSelect(LANG.sa_opaa_s, {title:LANG.sa_opaa_l}, "antialias"),
|
|
||||||
|
|
||||||
layers: uc.setGroup($("layers")),
|
layers: uc.setGroup($("layers")),
|
||||||
|
|
||||||
|
|
@ -1367,6 +1089,8 @@ function init_one() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// run client mode initializations right after UI is bound
|
// 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();
|
initCAM();
|
||||||
initDRAG();
|
initDRAG();
|
||||||
initFDM();
|
initFDM();
|
||||||
|
|
@ -1380,27 +1104,6 @@ function init_one() {
|
||||||
settingsSave(undefined, ui.settingsName.value);
|
settingsSave(undefined, ui.settingsName.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
function optSelected(sel) {
|
|
||||||
let opt = sel.options[sel.selectedIndex];
|
|
||||||
return opt ? opt.value : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasInfill() {
|
|
||||||
return optSelected(ui.sliceFillType) !== 'none'
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillIsLinear() {
|
|
||||||
return hasInfill() && optSelected(ui.sliceFillType) === 'linear';
|
|
||||||
}
|
|
||||||
|
|
||||||
function spindleShow() {
|
|
||||||
return settings().device.spindleMax > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function zIntShow() {
|
|
||||||
return settings().controller.devel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// slider setup
|
// slider setup
|
||||||
const mobile = space.info.mob;
|
const mobile = space.info.mob;
|
||||||
const slbar = mobile ? 80 : 30;
|
const slbar = mobile ? 80 : 30;
|
||||||
|
|
@ -2099,8 +1802,12 @@ function init_two() {
|
||||||
sdb.kiri_beta = beta;
|
sdb.kiri_beta = beta;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide url params
|
// hide url params but preserve version root (when present)
|
||||||
history.replaceState({}, '', '/kiri/');
|
let wlp = WIN.location.pathname;
|
||||||
|
let kio = wlp.indexOf('/kiri/');
|
||||||
|
if (kio >= 0) {
|
||||||
|
history.replaceState({}, '', wlp.substring(0,kio + 6));
|
||||||
|
}
|
||||||
|
|
||||||
// lift curtain
|
// lift curtain
|
||||||
$('curtain').style.display = 'none';
|
$('curtain').style.display = 'none';
|
||||||
|
|
@ -2165,7 +1872,7 @@ function init_lang() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function run() {
|
export function run() {
|
||||||
init_lang();
|
|
||||||
client.start();
|
client.start();
|
||||||
|
init_lang();
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -613,10 +613,15 @@ class Print {
|
||||||
scope.belt = belt;
|
scope.belt = belt;
|
||||||
|
|
||||||
if (scope.debugE) {
|
if (scope.debugE) {
|
||||||
console.log({ bounds, print_time: time.round(2) });
|
console.log({
|
||||||
|
bounds,
|
||||||
|
minf,
|
||||||
|
maxf,
|
||||||
|
print_time: time.round(2),
|
||||||
|
output: scope.output
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(scope.output)
|
|
||||||
done({ output: scope.output });
|
done({ output: scope.output });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { space } from '../../moto/space.js';
|
||||||
import { local } from '../../data/local.js';
|
import { local } from '../../data/local.js';
|
||||||
import { utils } from './utils.js';
|
import { utils } from './utils.js';
|
||||||
import { version } from '../../moto/license.js';
|
import { version } from '../../moto/license.js';
|
||||||
|
import { JSZip } from '../../ext/jszip-esm.js';
|
||||||
|
|
||||||
const { areEqual, ls2o, js2o } = utils;
|
const { areEqual, ls2o, js2o } = utils;
|
||||||
const { COLOR } = consts;
|
const { COLOR } = consts;
|
||||||
|
|
@ -221,7 +222,7 @@ function updateSettingsFromFields(setrec, uirec = api.ui, changes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a settings region, update values of matching bound UI fields
|
// given a settings region, update values of matching bound UI fields
|
||||||
function updateFieldsFromSettings(setrec, uirec = api.ui, trace) {
|
function updateFieldsFromSettings(setrec, uirec = api.ui, opt = {}) {
|
||||||
if (!setrec) {
|
if (!setrec) {
|
||||||
updateFieldsFromSettings(settings.device);
|
updateFieldsFromSettings(settings.device);
|
||||||
updateFieldsFromSettings(settings.process);
|
updateFieldsFromSettings(settings.process);
|
||||||
|
|
@ -229,6 +230,9 @@ function updateFieldsFromSettings(setrec, uirec = api.ui, trace) {
|
||||||
updateExtruderFields(settings.device);
|
updateExtruderFields(settings.device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (opt.trace) {
|
||||||
|
console.log({ setrec, uirec });
|
||||||
|
}
|
||||||
for (let key in setrec) {
|
for (let key in setrec) {
|
||||||
if (!setrec.hasOwnProperty(key)) {
|
if (!setrec.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -238,6 +242,9 @@ function updateFieldsFromSettings(setrec, uirec = api.ui, trace) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let uie = uirec[key], typ = uie ? uie.type : null;
|
let uie = uirec[key], typ = uie ? uie.type : null;
|
||||||
|
if (opt.trace) {
|
||||||
|
console.log({ key, uie, typ, val });
|
||||||
|
}
|
||||||
if (typ === 'text') {
|
if (typ === 'text') {
|
||||||
if (uie.setv) {
|
if (uie.setv) {
|
||||||
uie.setv(val);
|
uie.setv(val);
|
||||||
|
|
@ -271,6 +278,8 @@ function updateFieldsFromSettings(setrec, uirec = api.ui, trace) {
|
||||||
} else {
|
} else {
|
||||||
uie.value = '';
|
uie.value = '';
|
||||||
}
|
}
|
||||||
|
} else if (opt.trace) {
|
||||||
|
console.log('skipped', { key, val, typ });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -651,7 +660,7 @@ function settingsImportUrl(url, ask) {
|
||||||
|
|
||||||
function settingsImportZip(data, ask) {
|
function settingsImportZip(data, ask) {
|
||||||
let alert = api.show.alert("Importing Workspace");
|
let alert = api.show.alert("Importing Workspace");
|
||||||
JSZip.loadAsync(data).then(zip => {
|
new JSZip().loadAsync(data).then(zip => {
|
||||||
for (let [key,value] of Object.entries(zip.files)) {
|
for (let [key,value] of Object.entries(zip.files)) {
|
||||||
if (key === "workspace.json") {
|
if (key === "workspace.json") {
|
||||||
value.async("string").then(json => {
|
value.async("string").then(json => {
|
||||||
|
|
|
||||||
|
|
@ -434,8 +434,13 @@ function newDiv(opt = {}) {
|
||||||
(opt.addto || addTo).appendChild(div);
|
(opt.addto || addTo).appendChild(div);
|
||||||
if (opt.addto) lastDiv = addTo = div;
|
if (opt.addto) lastDiv = addTo = div;
|
||||||
if (opt.class) div.setAttribute('class', opt.class);
|
if (opt.class) div.setAttribute('class', opt.class);
|
||||||
|
if (opt.group !== false) {
|
||||||
lastGroup?.push(div);
|
lastGroup?.push(div);
|
||||||
div._group = groupName;
|
div._group = groupName;
|
||||||
|
} else {
|
||||||
|
lastGroup = undefined;
|
||||||
|
groupName = undefined;
|
||||||
|
}
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -685,6 +690,7 @@ function addUnits(input, round) {
|
||||||
} else {
|
} else {
|
||||||
input.value = value;
|
input.value = value;
|
||||||
}
|
}
|
||||||
|
// console.log({ value }, input.real, input.value );
|
||||||
return input.real;
|
return input.real;
|
||||||
};
|
};
|
||||||
return input;
|
return input;
|
||||||
|
|
|
||||||
|
|
@ -104,16 +104,16 @@
|
||||||
"sliceFillWidth": 1,
|
"sliceFillWidth": 1,
|
||||||
"sliceFillRate": 0,
|
"sliceFillRate": 0,
|
||||||
"sliceSupportEnable": false,
|
"sliceSupportEnable": false,
|
||||||
"firstSliceHeight": 0.25,
|
"firstSliceHeight": 0.5,
|
||||||
"firstLayerFillRate": 20,
|
"firstLayerFillRate": 20,
|
||||||
"firstLayerLineMult": 1,
|
"firstLayerLineMult": 1,
|
||||||
"firstLayerNozzleTemp": 0,
|
"firstLayerNozzleTemp": 0,
|
||||||
"firstLayerBedTemp": 0,
|
"firstLayerBedTemp": 0,
|
||||||
"firstLayerBrimTrig": 0,
|
"firstLayerBrimTrig": 0,
|
||||||
"firstLayerBrimGap": 0,
|
"firstLayerBrimGap": 0,
|
||||||
"outputRaft": true,
|
"outputRaft": false,
|
||||||
"outputRaftSpacing": 0.2,
|
"outputRaftSpacing": 0.2,
|
||||||
"outputBrimCount": 5,
|
"outputBrimCount": 0,
|
||||||
"outputBrimOffset": 2,
|
"outputBrimOffset": 2,
|
||||||
"outputPurgeTower": 0,
|
"outputPurgeTower": 0,
|
||||||
"outputInvertX": false,
|
"outputInvertX": false,
|
||||||
|
|
|
||||||
|
|
@ -104,16 +104,16 @@
|
||||||
"sliceFillWidth": 1,
|
"sliceFillWidth": 1,
|
||||||
"sliceFillRate": 0,
|
"sliceFillRate": 0,
|
||||||
"sliceSupportEnable": false,
|
"sliceSupportEnable": false,
|
||||||
"firstSliceHeight": 0.25,
|
"firstSliceHeight": 0.5,
|
||||||
"firstLayerFillRate": 20,
|
"firstLayerFillRate": 20,
|
||||||
"firstLayerLineMult": 1,
|
"firstLayerLineMult": 1,
|
||||||
"firstLayerNozzleTemp": 0,
|
"firstLayerNozzleTemp": 0,
|
||||||
"firstLayerBedTemp": 0,
|
"firstLayerBedTemp": 0,
|
||||||
"firstLayerBrimTrig": 0,
|
"firstLayerBrimTrig": 0,
|
||||||
"firstLayerBrimGap": 0,
|
"firstLayerBrimGap": 0,
|
||||||
"outputRaft": true,
|
"outputRaft": false,
|
||||||
"outputRaftSpacing": 0.2,
|
"outputRaftSpacing": 0.2,
|
||||||
"outputBrimCount": 5,
|
"outputBrimCount": 0,
|
||||||
"outputBrimOffset": 2,
|
"outputBrimOffset": 2,
|
||||||
"outputPurgeTower": 0,
|
"outputPurgeTower": 0,
|
||||||
"outputInvertX": false,
|
"outputInvertX": false,
|
||||||
|
|
|
||||||
|
|
@ -87,10 +87,10 @@ Object.assign(client, {
|
||||||
|
|
||||||
animate_setup2(settings, ondone) {
|
animate_setup2(settings, ondone) {
|
||||||
color = settings.controller.dark ? 0x888888 : 0;
|
color = settings.controller.dark ? 0x888888 : 0;
|
||||||
material = new THREE.MeshMatcapMaterial({
|
material = new THREE.MeshPhongMaterial({
|
||||||
flatShading: true,
|
flatShading: true,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
opacity: 0.9,
|
opacity: 0.5,
|
||||||
color: 0x888888,
|
color: 0x888888,
|
||||||
side: THREE.DoubleSide
|
side: THREE.DoubleSide
|
||||||
});
|
});
|
||||||
|
|
|
||||||
140
src/kiri/mode/cam/cl-origin.js
Normal file
140
src/kiri/mode/cam/cl-origin.js
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { api } from '../../core/api.js';
|
||||||
|
import { env, clearPops } from './client.js';
|
||||||
|
import { CAM } from './driver-fe.js';
|
||||||
|
import { addbox, clearboxes } 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<br>[esc] to cancel", 1000);
|
||||||
|
let ends = {};
|
||||||
|
let points = {};
|
||||||
|
let color = new THREE.Color( 0xff0000 );
|
||||||
|
function incpoint(widget, point) {
|
||||||
|
let rec = ends[point.key];
|
||||||
|
if (rec && rec.count++ === 2) {
|
||||||
|
addpoint(widget, point);
|
||||||
|
} else if (!rec) {
|
||||||
|
rec = ends[point.key] = { count: 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function addpoint(widget, center) {
|
||||||
|
let box = addbox(center, color, undefined, undefined, { opacity: 1 });
|
||||||
|
widget.adds.push(box);
|
||||||
|
world.add(box);
|
||||||
|
box._origin = center;
|
||||||
|
points[center.key] = { box, center };
|
||||||
|
}
|
||||||
|
api.widgets.for(widget => {
|
||||||
|
let { pos, tzoff } = widget.track;
|
||||||
|
let polys = widget.traces.map(trace => {
|
||||||
|
return trace.fixClosed().clone().move(pos).move({ x:0, y:0, z: -tzoff });
|
||||||
|
});
|
||||||
|
for (let poly of polys) {
|
||||||
|
if (poly.circularity() >= 0.99) {
|
||||||
|
let center = poly.calcCircleCenter();
|
||||||
|
if (points[center.key]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addpoint(widget, center);
|
||||||
|
} else if (poly.isOpen()) {
|
||||||
|
incpoint(widget, poly.first());
|
||||||
|
incpoint(widget, poly.last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lastPoints = Object.values(points);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function originReset() {
|
||||||
|
let { process} = api.conf.get();
|
||||||
|
process.camOriginOffX = 0;
|
||||||
|
process.camOriginOffY = 0;
|
||||||
|
process.camOriginOffZ = 0;
|
||||||
|
api.settings.update_fields(process);
|
||||||
|
api.platform.update_origin();
|
||||||
|
api.conf.save();
|
||||||
|
originSelectDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
clearboxes();
|
||||||
|
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(process);
|
||||||
|
api.platform.update_origin();
|
||||||
|
api.conf.save();
|
||||||
|
originSelectDone();
|
||||||
|
}
|
||||||
|
|
@ -52,7 +52,6 @@ export function updateStock() {
|
||||||
});
|
});
|
||||||
env.camStock = new THREE.Mesh(geo, mat);
|
env.camStock = new THREE.Mesh(geo, mat);
|
||||||
env.camStock.renderOrder = 2;
|
env.camStock.renderOrder = 2;
|
||||||
|
|
||||||
let lo = 0.5;
|
let lo = 0.5;
|
||||||
let lidat = [
|
let lidat = [
|
||||||
lo, lo, lo, lo, lo, -lo,
|
lo, lo, lo, lo, lo, -lo,
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
import { api } from '../../core/api.js';
|
import { api } from '../../core/api.js';
|
||||||
import { env, isDark } from './client.js';
|
import { env, isDark } from './client.js';
|
||||||
import { addbox, delbox } from '../../core/boxes.js';
|
import { addbox, delbox, clearboxes } from '../../core/boxes.js';
|
||||||
import { traceDone } from './cl-trace.js';
|
import { traceDone } from './cl-trace.js';
|
||||||
|
import { space as SPACE } from '../../../moto/space.js';
|
||||||
|
|
||||||
let showTab, lastTab, tab, iw, ic;
|
let showTab, lastTab, tab, iw, ic;
|
||||||
|
|
||||||
|
|
@ -107,6 +108,7 @@ export function clearTabs(widget, skiprec) {
|
||||||
if (!skiprec) {
|
if (!skiprec) {
|
||||||
delete api.widgets.annotate(widget.id).tab;
|
delete api.widgets.annotate(widget.id).tab;
|
||||||
}
|
}
|
||||||
|
clearboxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateTabs() {
|
export function updateTabs() {
|
||||||
|
|
@ -198,6 +200,7 @@ export function tabAdd() {
|
||||||
|
|
||||||
export function tabDone() {
|
export function tabDone() {
|
||||||
delbox('tabb');
|
delbox('tabb');
|
||||||
|
clearboxes();
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
api.feature.hover = false;
|
api.feature.hover = false;
|
||||||
if (lastTab) {
|
if (lastTab) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { api } from '../../core/api.js';
|
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 { CAM } from './driver-fe.js';
|
||||||
import { Layers } from '../../core/layers.js';
|
import { Layers } from '../../core/layers.js';
|
||||||
import { Stack } from '../../core/stack.js';
|
import { Stack } from '../../core/stack.js';
|
||||||
|
|
@ -123,7 +123,7 @@ export function traceHover(data) {
|
||||||
let material = lastTrace.material[0] || lastTrace.material;
|
let material = lastTrace.material[0] || lastTrace.material;
|
||||||
let color = material.color;
|
let color = material.color;
|
||||||
material.colorSave = color.clone();
|
material.colorSave = color.clone();
|
||||||
color.setHex(env.isDark() ? 0x0066ff : 0x0000ff);
|
color.setHex(isDark() ? 0x0066ff : 0x0000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceHoverUp(int, ev) {
|
export function traceHoverUp(int, ev) {
|
||||||
|
|
@ -157,7 +157,7 @@ export function traceToggle(obj, skip) {
|
||||||
colorSave = material.colorSave = color.clone();
|
colorSave = material.colorSave = color.clone();
|
||||||
}
|
}
|
||||||
if (obj.selected) {
|
if (obj.selected) {
|
||||||
color.setHex(env.isDark() ? 0xdd0011 : 0xff0033);
|
color.setHex(isDark() ? 0xdd0011 : 0xff0033);
|
||||||
colorSave.r = color.r;
|
colorSave.r = color.r;
|
||||||
colorSave.g = color.g;
|
colorSave.g = color.g;
|
||||||
colorSave.b = color.b;
|
colorSave.b = color.b;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
import { $, h } from '../../../moto/webui.js';
|
import { $ } from '../../../moto/webui.js';
|
||||||
import { api } from '../../core/api.js';
|
import { api } from '../../core/api.js';
|
||||||
import { load } from '../../../load/file.js';
|
import { load } from '../../../load/file.js';
|
||||||
import { animate as anim_2d, animate_clear as anim_2d_clear } from './anim-2d-fe.js';
|
import { animate as anim_2d, animate_clear as anim_2d_clear } from './anim-2d-fe.js';
|
||||||
|
|
@ -10,18 +10,19 @@ import { Layers } from '../../core/layers.js';
|
||||||
import { Stack } from '../../core/stack.js';
|
import { Stack } from '../../core/stack.js';
|
||||||
import { updateStock } from './cl-stock.js';
|
import { updateStock } from './cl-stock.js';
|
||||||
import { createPopOps } from './cl-ops.js';
|
import { createPopOps } from './cl-ops.js';
|
||||||
import { tabAdd, tabDone, tabClear, restoreTabs, updateTabs } from './cl-tab.js';
|
import { tabAdd, tabDone, tabClear, restoreTabs, rotateTabs, updateTabs } from './cl-tab.js';
|
||||||
import { traceOn, traceDone, unselectTraces } from './cl-trace.js';
|
import { traceOn, traceDone, unselectTraces } from './cl-trace.js';
|
||||||
import { holeSelOn, selectHolesDone, clearHolesRec } from './cl-hole.js';
|
import { holeSelOn, selectHolesDone, clearHolesRec } from './cl-hole.js';
|
||||||
import { surfaceOn, surfaceDone } from './cl-surface.js';
|
import { surfaceOn, surfaceDone } from './cl-surface.js';
|
||||||
import { helicalOn, helicalDone } from './cl-helical.js';
|
import { helicalOn, helicalDone } from './cl-helical.js';
|
||||||
|
import { originSelectDone } from './cl-origin.js';
|
||||||
|
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
const RAD2DEG = 180 / Math.PI;
|
const RAD2DEG = 180 / Math.PI;
|
||||||
const hasSharedArrays = self.SharedArrayBuffer ? true : false;
|
const hasSharedArrays = self.SharedArrayBuffer ? true : false;
|
||||||
|
|
||||||
const { VIEWS, STACKS } = api.const;
|
const { VIEWS, STACKS } = api.const;
|
||||||
const { noop, space } = api;
|
const { noop } = api;
|
||||||
const { ui: UI, uc: UC } = api;
|
const { ui: UI, uc: UC } = api;
|
||||||
const { widgets: WIDGETS } = api;
|
const { widgets: WIDGETS } = api;
|
||||||
|
|
||||||
|
|
@ -55,6 +56,9 @@ export function isDark() {
|
||||||
|
|
||||||
export function clearPops() {
|
export function clearPops() {
|
||||||
if (env.func.unpop) env.func.unpop();
|
if (env.func.unpop) env.func.unpop();
|
||||||
|
originSelectDone();
|
||||||
|
selectHolesDone();
|
||||||
|
surfaceDone();
|
||||||
tabDone();
|
tabDone();
|
||||||
traceDone();
|
traceDone();
|
||||||
surfaceDone();
|
surfaceDone();
|
||||||
|
|
|
||||||
128
src/kiri/mode/cam/init-menu.js
Normal file
128
src/kiri/mode/cam/init-menu.js
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { api } from '../../core/api.js';
|
||||||
|
import { originReset, 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, 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() {
|
||||||
|
let anim = ui.anim = {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
/** Animation Bar */
|
||||||
|
|
||||||
|
_____: {
|
||||||
|
_____: newDiv({ addto: $('layer-animate'), set:true, group:false }),
|
||||||
|
row: newRow([
|
||||||
|
anim.replay = newButton(null,"anim.replay",{icon:'<i class="fas fa-fast-backward"></i>',title:"restart"}),
|
||||||
|
anim.play = newButton(null,"anim.play",{icon:'<i class="fas fa-play"></i>',title:"play"}),
|
||||||
|
anim.pause = newButton(null,"anim.pause",{icon:'<i class="fas fa-pause"></i>',title:"pause"}),
|
||||||
|
anim.step = newButton(null,"anim.step",{icon:'<i class="fas fa-step-forward"></i>',title:"single step"}),
|
||||||
|
anim.speed = newButton(null,"anim.fast",{icon:'<i class="fas fa-forward"></i>',title:"toggle speed"}),
|
||||||
|
anim.labspd = newValue(3, {class:"center padleft"}),
|
||||||
|
anim.labx = newLabel("X", {class:"padleft"}),
|
||||||
|
anim.valx = newValue(7, {class:"center"}),
|
||||||
|
anim.laby = newLabel("Y", {class:"padleft"}),
|
||||||
|
anim.valy = newValue(7, {class:"center"}),
|
||||||
|
anim.labz = newLabel("Z", {class:"padleft"}),
|
||||||
|
anim.valz = newValue(6, {class:"center"}),
|
||||||
|
anim.laba = newLabel("A", {class:"padleft hide"}),
|
||||||
|
anim.vala = newValue(6, {class:"center hide"}),
|
||||||
|
anim.labpro = newLabel("%", {class:"padleft"}),
|
||||||
|
anim.progress = newValue(5, {class:"center"}),
|
||||||
|
anim.trans = newButton(null,null,{icon:'<i class="fa-solid fa-border-none"></i>',title:"transparency",class:"padleft"}),
|
||||||
|
anim.model = newButton(null,null,{icon:'<i class="fa-solid fa-eye"></i>',title:"show model"}),
|
||||||
|
anim.shade = newButton(null,null,{icon:'<i class="fa-solid fa-cube"></i>',title:"stock box"}),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Left Side Menu */
|
||||||
|
|
||||||
|
_____: 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:'<i class="fas fa-plus"></i>'})),
|
||||||
|
(ui.tabDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
||||||
|
(ui.tabClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
||||||
|
], {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),
|
||||||
|
newButton("reset", originReset),
|
||||||
|
], { 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 }),
|
||||||
|
camArcEnabled: newBoolean(LANG.cx_arce_s, onBooleanClick, {title:LANG.cx_arce_l}),
|
||||||
|
camArcTolerance: newInput(LANG.cx_arct_s, {title:LANG.cx_arct_l, convert:toFloat, bound:bound(0,100), units, trigger, show:() => ui.camArcEnabled.checked}),
|
||||||
|
camArcResolution: newInput(LANG.cx_arcr_s, {title:LANG.cx_arcr_l, convert:toFloat, bound:bound(0,180), trigger, show:() => ui.camArcEnabled.checked}),
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -38,8 +38,10 @@ class OpContour extends CamOp {
|
||||||
|
|
||||||
async slice(progress) {
|
async slice(progress) {
|
||||||
let { op, state } = this;
|
let { op, state } = this;
|
||||||
let { addSlices } = state;
|
let { addSlices, settings, updateToolDiams } = state;
|
||||||
let filter = createFilter(op);
|
let filter = createFilter(op);
|
||||||
|
let toolDiam = this.toolDiam = new Tool(settings, op.tool).fluteDiameter();
|
||||||
|
updateToolDiams(toolDiam);
|
||||||
// we need topo for safe travel moves when roughing and outlining
|
// we need topo for safe travel moves when roughing and outlining
|
||||||
// not generated when drilling-only. then all z moves use bounds max.
|
// not generated when drilling-only. then all z moves use bounds max.
|
||||||
// also generates x and y contouring when selected
|
// also generates x and y contouring when selected
|
||||||
|
|
@ -69,7 +71,7 @@ class OpContour extends CamOp {
|
||||||
let { camOut, polyEmit, newLayer, printPoint, lastPoint } = ops;
|
let { camOut, polyEmit, newLayer, printPoint, lastPoint } = ops;
|
||||||
let { bounds, zmax } = ops;
|
let { bounds, zmax } = ops;
|
||||||
|
|
||||||
let toolDiam = this.toolDiam = new Tool(settings, op.tool).fluteDiameter();
|
let toolDiam = this.toolDiam;
|
||||||
let stepover = toolDiam * op.step * 2;
|
let stepover = toolDiam * op.step * 2;
|
||||||
let depthFirst = process.camDepthFirst;
|
let depthFirst = process.camDepthFirst;
|
||||||
let depthData = [];
|
let depthData = [];
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ export class OpIndex extends CamOp {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weight() {
|
||||||
|
return 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
async slice() {
|
async slice() {
|
||||||
let { op, state } = this;
|
let { op, state } = this;
|
||||||
if (!state.isIndexed) {
|
if (!state.isIndexed) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { CamOp } from './op.js';
|
import { CamOp } from './op.js';
|
||||||
import { Tool } from './tool.js';
|
import { Tool } from './tool.js';
|
||||||
|
import { generate as topo4_generate } from './topo4.js';
|
||||||
import { newPoint } from '../../../geo/point.js';
|
import { newPoint } from '../../../geo/point.js';
|
||||||
|
|
||||||
function createFilter(op) {
|
function createFilter(op) {
|
||||||
|
|
@ -38,7 +39,7 @@ class OpLathe extends CamOp {
|
||||||
let { addSlices } = state;
|
let { addSlices } = state;
|
||||||
let filter = createFilter(op);
|
let filter = createFilter(op);
|
||||||
|
|
||||||
this.topo = await Topo4({
|
this.topo = await topo4_generate({
|
||||||
op,
|
op,
|
||||||
state,
|
state,
|
||||||
onupdate: (pct, msg) => {
|
onupdate: (pct, msg) => {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class OpOutline extends CamOp {
|
||||||
async slice(progress) {
|
async slice(progress) {
|
||||||
let { op, state } = this;
|
let { op, state } = this;
|
||||||
let { settings, widget, slicer, addSlices, tshadow, thruHoles, unsafe, color } = state;
|
let { settings, widget, slicer, addSlices, tshadow, thruHoles, unsafe, color } = state;
|
||||||
let { updateToolDiams, tabs, cutTabs, cutPolys, workarea, zMax } = state;
|
let { updateToolDiams, tabs, cutTabs, cutPolys, workarea, zMax, shadowAt } = state;
|
||||||
let { process, stock } = settings;
|
let { process, stock } = settings;
|
||||||
|
|
||||||
if (op.down <= 0) {
|
if (op.down <= 0) {
|
||||||
|
|
@ -37,6 +37,7 @@ class OpOutline extends CamOp {
|
||||||
};
|
};
|
||||||
let indices = slicer.interval(op.down, intopt);
|
let indices = slicer.interval(op.down, intopt);
|
||||||
let trueShadow = process.camTrueShadow === true;
|
let trueShadow = process.camTrueShadow === true;
|
||||||
|
let lastShadowZ;
|
||||||
// shift out first (top-most) slice
|
// shift out first (top-most) slice
|
||||||
indices.shift();
|
indices.shift();
|
||||||
// add flats to shadow
|
// add flats to shadow
|
||||||
|
|
@ -44,7 +45,6 @@ class OpOutline extends CamOp {
|
||||||
.map(v => (parseFloat(v) - 0.01).round(5))
|
.map(v => (parseFloat(v) - 0.01).round(5))
|
||||||
.filter(v => v > 0 && indices.indexOf(v) < 0);
|
.filter(v => v > 0 && indices.indexOf(v) < 0);
|
||||||
indices = indices.appendAll(flats).sort((a,b) => b-a);
|
indices = indices.appendAll(flats).sort((a,b) => b-a);
|
||||||
|
|
||||||
let cnt = 0;
|
let cnt = 0;
|
||||||
let tot = 0;
|
let tot = 0;
|
||||||
if (op.outside && !op.inside) {
|
if (op.outside && !op.inside) {
|
||||||
|
|
@ -65,7 +65,7 @@ class OpOutline extends CamOp {
|
||||||
// exclude flats injected to complete shadow
|
// exclude flats injected to complete shadow
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.shadow = trueShadow ? shadowAt(widget, data.z) : shadow.clone(true);
|
data.shadow = trueShadow ? shadowAt(data.z, lastShadowZ) : shadow.clone(true);
|
||||||
data.slice.shadow = data.shadow;
|
data.slice.shadow = data.shadow;
|
||||||
// data.slice.tops[0].inner = data.shadow;
|
// data.slice.tops[0].inner = data.shadow;
|
||||||
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
|
// data.slice.tops[0].inner = POLY.setZ(tshadow.clone(true), data.z);
|
||||||
|
|
@ -73,6 +73,7 @@ class OpOutline extends CamOp {
|
||||||
// data.slice.xray();
|
// data.slice.xray();
|
||||||
// onupdate(0.2 + (index/total) * 0.1, "outlines");
|
// onupdate(0.2 + (index/total) * 0.1, "outlines");
|
||||||
progress(0.5 + 0.5 * (++cnt / tot));
|
progress(0.5 + 0.5 * (++cnt / tot));
|
||||||
|
lastShadowZ = data.z;
|
||||||
}, progress: (index, total) => {
|
}, progress: (index, total) => {
|
||||||
tot = total;
|
tot = total;
|
||||||
progress((index / total) * 0.5);
|
progress((index / total) * 0.5);
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ class OpRough extends CamOp {
|
||||||
indices = indices.filter(v => v >= workarea.bottom_z);
|
indices = indices.filter(v => v >= workarea.bottom_z);
|
||||||
// console.log('indices', ...indices, {zBottom});
|
// console.log('indices', ...indices, {zBottom});
|
||||||
|
|
||||||
|
let lsz;
|
||||||
let cnt = 0;
|
let cnt = 0;
|
||||||
let tot = 0;
|
let tot = 0;
|
||||||
await slicer.slice(indices, { each: data => {
|
await slicer.slice(indices, { each: data => {
|
||||||
|
|
@ -125,9 +126,10 @@ class OpRough extends CamOp {
|
||||||
if (data.z > workarea.top_z) {
|
if (data.z > workarea.top_z) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.shadow = trueShadow ? shadowAt(data.z) : shadow.clone(true);
|
data.shadow = trueShadow ? shadowAt(data.z, lsz) : shadow.clone(true);
|
||||||
data.slice.shadow = data.shadow;
|
data.slice.shadow = data.shadow;
|
||||||
slices.push(data.slice);
|
slices.push(data.slice);
|
||||||
|
lsz = data.z;
|
||||||
progress(0.25 + 0.25 * (++cnt / tot));
|
progress(0.25 + 0.25 * (++cnt / tot));
|
||||||
}, progress: (index, total) => {
|
}, progress: (index, total) => {
|
||||||
tot = total;
|
tot = total;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ class OpShadow extends CamOp {
|
||||||
super(state, op);
|
super(state, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weight() {
|
||||||
|
return 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
async slice(progress) {
|
async slice(progress) {
|
||||||
let state = this.state;
|
let state = this.state;
|
||||||
let { ops, slicer, widget, unsafe, addSlices, shadowAt } = state;
|
let { ops, slicer, widget, unsafe, addSlices, shadowAt } = state;
|
||||||
|
|
|
||||||
|
|
@ -107,15 +107,28 @@ class OpTrace extends CamOp {
|
||||||
for (let z of zs) {
|
for (let z of zs) {
|
||||||
let clip = [], shadow;
|
let clip = [], shadow;
|
||||||
shadow = shadowAt(z);
|
shadow = shadowAt(z);
|
||||||
|
// for cases where the shadow IS the poly like
|
||||||
|
// with lettering without a bounding frame, clip
|
||||||
|
// will fail and we need to restore the matching poly
|
||||||
|
let subshadow = true;
|
||||||
|
for (let spo of shadow) {
|
||||||
|
if (poly.isInside(spo, 0.01)) {
|
||||||
|
subshadow = false;
|
||||||
|
clip = [ poly ];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (subshadow) {
|
||||||
POLY.subtract([ poly ], shadow, clip, undefined, undefined, 0);
|
POLY.subtract([ poly ], shadow, clip, undefined, undefined, 0);
|
||||||
|
}
|
||||||
if (op.outline) {
|
if (op.outline) {
|
||||||
POLY.clearInner(clip);
|
POLY.clearInner(clip);
|
||||||
}
|
}
|
||||||
if (clip.length === 0) {
|
if (clip.length === 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let slice = newSliceOut(z);
|
|
||||||
let count = 999;
|
let count = 999;
|
||||||
|
let slice = newSliceOut(z);
|
||||||
slice.camTrace = { tool, rate, plunge };
|
slice.camTrace = { tool, rate, plunge };
|
||||||
if (toolDiam) {
|
if (toolDiam) {
|
||||||
const offs = [ -toolDiam / 2, -toolOver ];
|
const offs = [ -toolDiam / 2, -toolOver ];
|
||||||
|
|
@ -132,12 +145,15 @@ class OpTrace extends CamOp {
|
||||||
slice.camLines = POLY.flatten(slice.camLines, null, true);
|
slice.camLines = POLY.flatten(slice.camLines, null, true);
|
||||||
}
|
}
|
||||||
POLY.setWinding(slice.camLines, cutdir, false);
|
POLY.setWinding(slice.camLines, cutdir, false);
|
||||||
slice.output()
|
|
||||||
.setLayer("trace", {line: color}, false)
|
|
||||||
.addPolys(slice.camLines)
|
|
||||||
if (debug && shadow) slice.output()
|
if (debug && shadow) slice.output()
|
||||||
.setLayer("trace shadow", {line: 0xff8811}, false)
|
.setLayer("trace shadow", {line: 0xff8811}, false)
|
||||||
.addPolys(shadow)
|
.addPolys(shadow)
|
||||||
|
if (debug) slice.output()
|
||||||
|
.setLayer("trace poly", {line: 0x1188ff}, false)
|
||||||
|
.addPolys([ poly ])
|
||||||
|
slice.output()
|
||||||
|
.setLayer("trace", {line: color}, false)
|
||||||
|
.addPolys(slice.camLines)
|
||||||
progress(zpro, "trace");
|
progress(zpro, "trace");
|
||||||
zpro += zinc;
|
zpro += zinc;
|
||||||
addSlices(slice);
|
addSlices(slice);
|
||||||
|
|
@ -254,6 +270,7 @@ class OpTrace extends CamOp {
|
||||||
case "clear":
|
case "clear":
|
||||||
const zbo = widget.track.top - widget.track.box.d;
|
const zbo = widget.track.top - widget.track.box.d;
|
||||||
let zmap = {};
|
let zmap = {};
|
||||||
|
polys = POLY.nest(polys);
|
||||||
for (let poly of polys) {
|
for (let poly of polys) {
|
||||||
let z = minZ(poly.minZ());
|
let z = minZ(poly.minZ());
|
||||||
if (offover) {
|
if (offover) {
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
engageFactor = process.camFullEngage,
|
engageFactor = process.camFullEngage,
|
||||||
arcTolerance = process.camArcTolerance,
|
arcTolerance = process.camArcTolerance,
|
||||||
arcRes = toRadians(process.camArcResolution),
|
arcRes = toRadians(process.camArcResolution),
|
||||||
|
arcEnabled = process.camArcEnabled && arcTolerance > 0 && arcRes > 0,
|
||||||
tolerance = 0,
|
tolerance = 0,
|
||||||
drillDown = 0,
|
drillDown = 0,
|
||||||
drillLift = 0,
|
drillLift = 0,
|
||||||
|
|
@ -177,6 +178,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
}
|
}
|
||||||
feedRate = feed || feedRate || plunge;
|
feedRate = feed || feedRate || plunge;
|
||||||
plungeRate = Math.min(feedRate || plunge, plunge || plungeRate || feedRate);
|
plungeRate = Math.min(feedRate || plunge, plunge || plungeRate || feedRate);
|
||||||
|
// console.log({ setTool: toolID, feed, plunge, plungeRate });
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLasering(bool, power = 0) {
|
function setLasering(bool, power = 0) {
|
||||||
|
|
@ -241,7 +243,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
camOut(point.clone().setZ(zmax));
|
camOut(point.clone().setZ(zmax_outer));
|
||||||
points.forEach(function (point, index) {
|
points.forEach(function (point, index) {
|
||||||
camOut(point, 1);
|
camOut(point, 1);
|
||||||
if (index > 0 && index < points.length - 1) {
|
if (index > 0 && index < points.length - 1) {
|
||||||
|
|
@ -249,7 +251,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
if (lift) camOut(point.clone().setZ(point.z + lift), 0);
|
if (lift) camOut(point.clone().setZ(point.z + lift), 0);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
camOut(point.clone().setZ(zmax), 0);
|
camOut(point.clone().setZ(zmax_outer), 0);
|
||||||
newLayer();
|
newLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,7 +319,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
p.x + wmx,
|
p.x + wmx,
|
||||||
p.y + wmy,
|
p.y + wmy,
|
||||||
p.z + zadd
|
p.z + zadd
|
||||||
)
|
).setA(p.a ?? lastPoint?.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -343,6 +345,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
const isArc = emit == 2 || emit == 3;
|
const isArc = emit == 2 || emit == 3;
|
||||||
|
|
||||||
// apply widget movement pos
|
// apply widget movement pos
|
||||||
|
const pointA = point.a;
|
||||||
point = applyWidgetMovement(point);
|
point = applyWidgetMovement(point);
|
||||||
|
|
||||||
// console.log(point.z);
|
// console.log(point.z);
|
||||||
|
|
@ -354,15 +357,13 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
let rate = feedRate * factor;
|
let rate = feedRate * factor;
|
||||||
|
|
||||||
// carry rotation forward when not overridden
|
// carry rotation forward when not overridden
|
||||||
if (point.a === undefined && lastPoint) {
|
if (lastPoint && pointA !== undefined && lastPoint.a !== undefined) {
|
||||||
point.a = lastPoint.a;
|
let DA = lastPoint.a - pointA;
|
||||||
} else if (lastPoint && point.a !== undefined && lastPoint.a !== undefined) {
|
|
||||||
let DA = lastPoint.a - point.a;
|
|
||||||
let MZ = Math.max(lastPoint.z, point.z)
|
let MZ = Math.max(lastPoint.z, point.z)
|
||||||
// find arc length
|
// find arc length
|
||||||
let AL = (Math.abs(DA) / 360) * (2 * Math.PI * MZ);
|
let AL = (Math.abs(DA) / 360) * (2 * Math.PI * MZ);
|
||||||
if (AL >= 1) {
|
if (AL >= 1) {
|
||||||
let lerp = base.util.lerp(lastPoint.a, point.a, 1);
|
let lerp = base.util.lerp(lastPoint.a, pointA, 1);
|
||||||
// create interpolated point set for rendering and animation
|
// create interpolated point set for rendering and animation
|
||||||
// console.log({ DA, MZ, AL }, lerp.length);
|
// console.log({ DA, MZ, AL }, lerp.length);
|
||||||
for (let a of lerp) {
|
for (let a of lerp) {
|
||||||
|
|
@ -461,16 +462,27 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set new plunge rate
|
// set new plunge rate
|
||||||
if (!lasering && deltaZ < -tolerance && !isLathe) {
|
if (!lasering && !isLathe && deltaZ < -tolerance) {
|
||||||
let threshold = Math.min(deltaXY / 2, absDeltaZ),
|
let threshold = Math.min(deltaXY / 2, absDeltaZ),
|
||||||
modifier = threshold / absDeltaZ;
|
modifier = threshold / absDeltaZ;
|
||||||
if (synthPlunge && threshold && modifier && deltaXY > tolerance) {
|
if (synthPlunge && threshold && modifier && deltaXY > tolerance) {
|
||||||
// use modifier to speed up long XY move plunge rates
|
// use modifier to speed up long XY move plunge rates
|
||||||
// console.log('modifier', modifier);
|
// console.log('modifier', modifier);
|
||||||
rate = Math.round(plungeRate + ((feedRate - plungeRate) * modifier));
|
rate = Math.max(
|
||||||
cut = 1;
|
plungeRate,
|
||||||
|
Math.round(plungeRate + ((feedRate - plungeRate) * modifier))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
rate = 1 / Math.hypot(deltaXY / feedRate, absDeltaZ / plungeRate);
|
let L = Math.hypot(deltaXY, absDeltaZ);
|
||||||
|
let limXY = feedRate * L / deltaXY;
|
||||||
|
let limZ = plungeRate * L / Math.abs(deltaZ);
|
||||||
|
rate = Math.min(feedRate, limXY, limZ);
|
||||||
|
// let zps = len / absDeltaZ;
|
||||||
|
// rate = Math.max(
|
||||||
|
// plungeRate,
|
||||||
|
// 1 / Math.hypot(deltaXY / feedRate, absDeltaZ / plungeRate)
|
||||||
|
// );
|
||||||
|
// console.log({ rate, deltaXY, deltaZ });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -765,7 +777,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
if (indexA == startIndex) {
|
if (indexA == startIndex) {
|
||||||
camOut(pointA.clone(), 0, { factor: engageFactor });
|
camOut(pointA.clone(), 0, { factor: engageFactor });
|
||||||
// if first point, move to and call export function
|
// if first point, move to and call export function
|
||||||
arcQ.push(pointA);
|
if (arcEnabled) arcQ.push(pointA);
|
||||||
}
|
}
|
||||||
lastPoint = arcExport(pointB, pointA);
|
lastPoint = arcExport(pointB, pointA);
|
||||||
}, !poly.isClosed(), startIndex);
|
}, !poly.isClosed(), startIndex);
|
||||||
|
|
@ -782,7 +794,7 @@ export function prepEach(widget, settings, print, firstPoint, update) {
|
||||||
function arcExport(point, lastp) {
|
function arcExport(point, lastp) {
|
||||||
let dist = lastp ? point.distTo2D(lastp) : 0;
|
let dist = lastp ? point.distTo2D(lastp) : 0;
|
||||||
if (lastp) {
|
if (lastp) {
|
||||||
if (dist > lineTolerance && lastp) {
|
if (arcEnabled && dist > lineTolerance && lastp) {
|
||||||
let rec = Object.assign(point, { dist });
|
let rec = Object.assign(point, { dist });
|
||||||
arcQ.push(rec);
|
arcQ.push(rec);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,15 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
|
||||||
top_stock, top_part, top_gap, top_z,
|
top_stock, top_part, top_gap, top_z,
|
||||||
workarea;
|
workarea;
|
||||||
|
|
||||||
|
axisRotation = axisIndex = undefined;
|
||||||
|
dark = settings.controller.dark;
|
||||||
|
color = dark ? 0xbbbbbb : 0;
|
||||||
|
minToolDiam = Infinity;
|
||||||
|
maxToolDiam = -Infinity;
|
||||||
|
tabs = widget.anno.tab;
|
||||||
|
unsafe = proc.camExpertFast;
|
||||||
|
units = settings.controller.units === 'in' ? 25.4 : 1;
|
||||||
|
|
||||||
// allow recomputing later if widget or settings changes
|
// allow recomputing later if widget or settings changes
|
||||||
const var_compute = () => {
|
const var_compute = () => {
|
||||||
let { camStockX, camStockY, camStockZ, camStockOffset } = proc;
|
let { camStockX, camStockY, camStockZ, camStockOffset } = proc;
|
||||||
|
|
@ -46,9 +55,9 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
|
||||||
x: camStockX,
|
x: camStockX,
|
||||||
y: camStockY,
|
y: camStockY,
|
||||||
z: camStockZ
|
z: camStockZ
|
||||||
}
|
};
|
||||||
track = widget.track;
|
|
||||||
({ camZTop, camZBottom, camZThru } = proc);
|
({ camZTop, camZBottom, camZThru } = proc);
|
||||||
|
track = widget.track;
|
||||||
wztop = track.top;
|
wztop = track.top;
|
||||||
ztOff = isIndexed ? (stock.z - bounds.dim.z) / 2 : (stock.z - wztop);
|
ztOff = isIndexed ? (stock.z - bounds.dim.z) / 2 : (stock.z - wztop);
|
||||||
zbOff = isIndexed ? (stock.z - bounds.dim.z) / 2 : (wztop - track.box.d);
|
zbOff = isIndexed ? (stock.z - bounds.dim.z) / 2 : (wztop - track.box.d);
|
||||||
|
|
@ -57,14 +66,6 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
|
||||||
zMax = bounds.max.z;
|
zMax = bounds.max.z;
|
||||||
zThru = camZThru;
|
zThru = camZThru;
|
||||||
zTop = zMax + ztOff;
|
zTop = zMax + ztOff;
|
||||||
minToolDiam = Infinity;
|
|
||||||
maxToolDiam = -Infinity;
|
|
||||||
dark = !!settings.controller.dark;
|
|
||||||
color = dark ? 0xbbbbbb : 0;
|
|
||||||
tabs = widget.anno.tab;
|
|
||||||
unsafe = proc.camExpertFast;
|
|
||||||
units = settings.controller.units === 'in' ? 25.4 : 1;
|
|
||||||
axisRotation = axisIndex = undefined;
|
|
||||||
part_size = bounds.dim;
|
part_size = bounds.dim;
|
||||||
bottom_gap = zbOff;
|
bottom_gap = zbOff;
|
||||||
bottom_part = 0;
|
bottom_part = 0;
|
||||||
|
|
@ -223,7 +224,7 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAxisIndex(degrees = 0, absolute = true) {
|
function setAxisIndex(degrees = 0, absolute = true) {
|
||||||
axisIndex = absolute ? degrees : axisIndex + degrees;
|
axisIndex = absolute ? degrees : (axisIndex || 0) + degrees;
|
||||||
axisRotation = (Math.PI / 180) * axisIndex;
|
axisRotation = (Math.PI / 180) * axisIndex;
|
||||||
widget.setAxisIndex(isIndexed ? -axisIndex : 0);
|
widget.setAxisIndex(isIndexed ? -axisIndex : 0);
|
||||||
return isIndexed ? -axisIndex : 0;
|
return isIndexed ? -axisIndex : 0;
|
||||||
|
|
@ -266,10 +267,14 @@ export async function cam_slice(settings, widget, onupdate, ondone) {
|
||||||
|
|
||||||
// silently preface op list with OpShadow
|
// silently preface op list with OpShadow
|
||||||
if (isIndexed) {
|
if (isIndexed) {
|
||||||
if (activeOps.length === 0 || activeOps[0].type !== 'index')
|
if (activeOps.length === 0 || activeOps[0].type !== 'index') {
|
||||||
opList.push(new OPS.index(state, { type: "index", index: 0 }));
|
opList.push(new OPS.index(state, { type: "index", index: 0 }));
|
||||||
|
opTot += opList.peek().weight();
|
||||||
|
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
opList.push(new OPS.shadow(state, { type: "shadow", silent: true }));
|
opList.push(new OPS.shadow(state, { type: "shadow", silent: true }));
|
||||||
|
opTot += opList.peek().weight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// determing # of steps and step weighting for progress bar
|
// determing # of steps and step weighting for progress bar
|
||||||
|
|
@ -399,7 +404,7 @@ export function addDogbones(poly, dist, reverse) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function traces(settings, widget, single) {
|
export async function traces(settings, widget) {
|
||||||
if (widget.traces) {
|
if (widget.traces) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -652,7 +657,6 @@ export async function holes(settings, widget, individual, rec, onProgress) {
|
||||||
// keeps the z bottom relative to the part when z align changes
|
// keeps the z bottom relative to the part when z align changes
|
||||||
zBottom = isIndexed ? camZBottom : camZBottom - zbOff;
|
zBottom = isIndexed ? camZBottom : camZBottom - zbOff;
|
||||||
|
|
||||||
|
|
||||||
let slicerOpts = { flatoff: 0.001 }
|
let slicerOpts = { flatoff: 0.001 }
|
||||||
let slicer = new cam_slicer(widget, slicerOpts);
|
let slicer = new cam_slicer(widget, slicerOpts);
|
||||||
let zFlats = Object.keys(slicer.zFlat).map(Number).map(z => [z, z - 0.002]).flat()
|
let zFlats = Object.keys(slicer.zFlat).map(Number).map(z => [z, z - 0.002]).flat()
|
||||||
|
|
@ -920,7 +924,7 @@ export function computeShadowAt(widget, z, ztop) {
|
||||||
.add(a[2].x, a[2].y, a[2].z);
|
.add(a[2].x, a[2].y, a[2].z);
|
||||||
});
|
});
|
||||||
|
|
||||||
polys = POLY.union(polys, 0.001, true);
|
polys = POLY.union(polys, 0, true);
|
||||||
|
|
||||||
return polys;
|
return polys;
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ import { Tool } from './tool.js';
|
||||||
const RAD2DEG = 180 / Math.PI;
|
const RAD2DEG = 180 / Math.PI;
|
||||||
const DEG2RAD = Math.PI / 180;
|
const DEG2RAD = Math.PI / 180;
|
||||||
|
|
||||||
class Topo {
|
export class Topo {
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
async generate(opt = {}) {
|
async generate(opt = {}) {
|
||||||
|
|
@ -226,9 +226,11 @@ class Topo {
|
||||||
// define sharded ranges
|
// define sharded ranges
|
||||||
if (minions.running > 1) {
|
if (minions.running > 1) {
|
||||||
|
|
||||||
dispatch.putCache({ key: widget.id, data: vertices }, { done: data => {
|
dispatch.putCache({ key: widget.id, data: vertices }, {
|
||||||
|
done: data => {
|
||||||
// console.log({ put_cache_done: data });
|
// console.log({ put_cache_done: data });
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let promises = slices.map(slice => {
|
let promises = slices.map(slice => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
@ -256,9 +258,11 @@ class Topo {
|
||||||
return box2;
|
return box2;
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch.clearCache({}, { done: data => {
|
dispatch.clearCache({}, {
|
||||||
|
done: data => {
|
||||||
// console.log({ clear_cache_done: data });
|
// console.log({ clear_cache_done: data });
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { codec } from '../../core/codec.js';
|
||||||
import { newPoint } from '../../../geo/point.js';
|
import { newPoint } from '../../../geo/point.js';
|
||||||
import { newPolygon } from '../../../geo/polygon.js';
|
import { newPolygon } from '../../../geo/polygon.js';
|
||||||
import { sliceConnect } from '../../../geo/slicer.js';
|
import { sliceConnect } from '../../../geo/slicer.js';
|
||||||
|
import { newSlice } from '../../core/slice.js';
|
||||||
import { Tool } from './tool.js';
|
import { Tool } from './tool.js';
|
||||||
import { Slicer as topo_slicer } from './slicer_topo.js';
|
import { Slicer as topo_slicer } from './slicer_topo.js';
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ function scale(fn, factor = 1, base = 0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Topo4 {
|
export class Topo {
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
async generate(opt = {}) {
|
async generate(opt = {}) {
|
||||||
|
|
@ -132,7 +133,8 @@ class Topo4 {
|
||||||
slices.push(slice);
|
slices.push(slice);
|
||||||
// console.log({ shards, range, step, slices });
|
// console.log({ shards, range, step, slices });
|
||||||
|
|
||||||
if (kiri.minions.running > 1) {
|
const { minions } = self.kiri_worker;
|
||||||
|
if (minions?.running > 1) {
|
||||||
return await this.sliceMinions(onupdate);
|
return await this.sliceMinions(onupdate);
|
||||||
} else {
|
} else {
|
||||||
return await this.sliceWorker(onupdate);
|
return await this.sliceWorker(onupdate);
|
||||||
|
|
@ -202,7 +204,8 @@ class Topo4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
async lathe(onupdate) {
|
async lathe(onupdate) {
|
||||||
if (kiri.minions.running > 1) {
|
const { minions } = self.kiri_worker;
|
||||||
|
if (minions?.running > 1) {
|
||||||
return await this.latheMinions(onupdate);
|
return await this.latheMinions(onupdate);
|
||||||
} else {
|
} else {
|
||||||
return await this.latheWorker(onupdate);
|
return await this.latheWorker(onupdate);
|
||||||
|
|
@ -293,7 +296,7 @@ class Topo4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
async latheWorker(onupdate) {
|
async latheWorker(onupdate) {
|
||||||
const { sliced, tool, zoff, leave } = this;
|
const { sliced, tool, zoff, leave, linear } = this;
|
||||||
|
|
||||||
const rota = this.angle * DEG2RAD;
|
const rota = this.angle * DEG2RAD;
|
||||||
const steps = (Math.PI * 2) / rota;
|
const steps = (Math.PI * 2) / rota;
|
||||||
|
|
@ -316,13 +319,25 @@ class Topo4 {
|
||||||
onupdate(count / steps);
|
onupdate(count / steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = recs[0].heights.length / 3;
|
count = linear ? recs.length : recs[0].heights.length / 3;
|
||||||
|
// count = recs[0].heights.length / 3;
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
let slice = newSlice(count);
|
let slice = newSlice(count);
|
||||||
slice.camLines = [newPolygon().setOpen()];
|
slice.camLines = [newPolygon().setOpen()];
|
||||||
paths.push(slice);
|
paths.push(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (linear) {
|
||||||
|
recs.forEach((rec, i) => {
|
||||||
|
const { degrees, heights } = rec;
|
||||||
|
[...heights].group(3).forEach((a) => {
|
||||||
|
paths[i].camLines[0].push(newPoint(a[0], a[1], a[2] + leave).setA(degrees));
|
||||||
|
});
|
||||||
|
if (i % 2 === 1) {
|
||||||
|
paths[i].camLines[0].reverse();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
for (let rec of recs) {
|
for (let rec of recs) {
|
||||||
const { degrees, heights } = rec;
|
const { degrees, heights } = rec;
|
||||||
[...heights].group(3).forEach((a, i) => {
|
[...heights].group(3).forEach((a, i) => {
|
||||||
|
|
@ -330,6 +345,7 @@ class Topo4 {
|
||||||
paths[i].camLines[0].push(newPoint(a[0], a[1], a[2] + leave).setA(degrees + i * -360));
|
paths[i].camLines[0].push(newPoint(a[0], a[1], a[2] + leave).setA(degrees + i * -360));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let slice of paths) {
|
for (let slice of paths) {
|
||||||
const poly = slice.camLines[0];
|
const poly = slice.camLines[0];
|
||||||
|
|
@ -392,8 +408,6 @@ class Topo4 {
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
recs.sort((a, b) => { return b.angle - a.angle });
|
recs.sort((a, b) => { return b.angle - a.angle });
|
||||||
|
|
||||||
// let linear = true;
|
|
||||||
|
|
||||||
count = linear ? recs.length : recs[0].heights.length / 3;
|
count = linear ? recs.length : recs[0].heights.length / 3;
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
let slice = newSlice(count);
|
let slice = newSlice(count);
|
||||||
|
|
@ -444,24 +458,27 @@ class Topo4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
putCache(key, data) {
|
putCache(key, data) {
|
||||||
kiri.worker.putCache({ key, data }, { done: data => { } });
|
const { dispatch } = self.kiri_worker;
|
||||||
|
dispatch.putCache({ key, data }, { done: data => { } });
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCache() {
|
clearCache() {
|
||||||
kiri.worker.clearCache({}, { done: data => { } });
|
const { dispatch } = self.kiri_worker;
|
||||||
|
dispatch.clearCache({}, { done: data => { } });
|
||||||
}
|
}
|
||||||
|
|
||||||
queue(cmd, params) {
|
queue(cmd, params) {
|
||||||
|
const { minions } = self.kiri_worker;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
kiri.minions.queue({ cmd, ...params }, resolve);
|
minions.queue({ cmd, ...params }, resolve);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotatePoints(lines, rot) {
|
export function rotatePoints(lines, rot) {
|
||||||
new THREE.BufferAttribute(lines, 3).applyMatrix4(rot);
|
new THREE.BufferAttribute(lines, 3).applyMatrix4(rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Topo4(opt) {
|
export async function generate(opt) {
|
||||||
return new Topo4().generate(opt);
|
return new Topo().generate(opt);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
188
src/kiri/mode/fdm/init-menu.js
Normal file
188
src/kiri/mode/fdm/init-menu.js
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { api } from '../../core/api.js';
|
||||||
|
|
||||||
|
let LANG = api.language.current;
|
||||||
|
let { FDM } = api.const.MODES,
|
||||||
|
{ $ } = api.web,
|
||||||
|
{ uc, ui } = api,
|
||||||
|
{ bound, toInt, toFloat } = uc,
|
||||||
|
{ newBlank, newButton, newBoolean, newGroup, newInput, newSelect, newRow } = uc,
|
||||||
|
driven = true,
|
||||||
|
hideable = true,
|
||||||
|
separator = true,
|
||||||
|
trigger = true
|
||||||
|
;
|
||||||
|
|
||||||
|
function onBooleanClick(el) {
|
||||||
|
api.event.emit('click.boolean', el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onButtonClick(el) {
|
||||||
|
api.event.emit('click.button', el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function thinWallSave() {
|
||||||
|
let opt = ui.sliceDetectThin;
|
||||||
|
let level = opt.options[opt.selectedIndex];
|
||||||
|
if (level) {
|
||||||
|
api.conf.get().process.sliceDetectThin = level.value;
|
||||||
|
api.conf.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMultiHead() {
|
||||||
|
let dev = api.conf.get().device;
|
||||||
|
return isNotBelt() && dev.extruders && dev.extruders.length > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function optSelected(sel) {
|
||||||
|
let opt = sel.options[sel.selectedIndex];
|
||||||
|
return opt ? opt.value : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasInfill() {
|
||||||
|
return optSelected(ui.sliceFillType) !== 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillIsLinear() {
|
||||||
|
return hasInfill() && optSelected(ui.sliceFillType) === 'linear';
|
||||||
|
}
|
||||||
|
|
||||||
|
function zIntShow() {
|
||||||
|
return settings().controller.devel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBelt() {
|
||||||
|
return api.device.isBelt();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNotBelt() {
|
||||||
|
return !isBelt();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function menu() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
/** Left Side Menu */
|
||||||
|
|
||||||
|
_____: newGroup(LANG.sl_menu, $('fdm-layers'), { modes:FDM, driven, hideable, separator, group:"fdm-layers" }),
|
||||||
|
sliceHeight: newInput(LANG.sl_lahi_s, { title:LANG.sl_lahi_l, convert:toFloat }),
|
||||||
|
sliceMinHeight: newInput(LANG.ad_minl_s, { title:LANG.ad_minl_l, convert:toFloat, bound:bound(0,3.0), show:() => ui.sliceAdaptive.checked }),
|
||||||
|
sliceTopLayers: newInput(LANG.sl_ltop_s, { title:LANG.sl_ltop_l, convert:toInt }),
|
||||||
|
sliceBottomLayers: newInput(LANG.sl_lbot_s, { title:LANG.sl_lbot_l, convert:toInt }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceAdaptive: newBoolean(LANG.ad_adap_s, onBooleanClick, { title: LANG.ad_adap_l }),
|
||||||
|
_____: newGroup(LANG.sw_menu, $('fdm-walls'), { modes:FDM, driven, hideable, separator, group:"fdm-walls" }),
|
||||||
|
sliceShells: newInput(LANG.sl_shel_s, { title:LANG.sl_shel_l, convert:toFloat }),
|
||||||
|
sliceLineWidth: newInput(LANG.sl_line_s, { title:LANG.sl_line_l, convert:toFloat, bound:bound(0,5) }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceShellOrder: newSelect(LANG.sl_ordr_s, { title:LANG.sl_ordr_l}, "shell"),
|
||||||
|
sliceDetectThin: newSelect(LANG.ad_thin_s, { title: LANG.ad_thin_l, action: thinWallSave }, "thin"),
|
||||||
|
outputAlternating: newBoolean(LANG.ad_altr_s, onBooleanClick, {title:LANG.ad_altr_l}),
|
||||||
|
sliceZInterleave: newBoolean(LANG.ad_zint_s, onBooleanClick, {title:LANG.ad_zint_l, show:zIntShow}),
|
||||||
|
_____: newGroup(LANG.fi_menu, $('fdm-fill'), { modes:FDM, driven, hideable, separator, group:"fdm-fill" }),
|
||||||
|
sliceFillType: newSelect(LANG.fi_type, {trigger}, "infill"),
|
||||||
|
sliceFillSparse: newInput(LANG.fi_pcnt_s, {title:LANG.fi_pcnt_l, convert:toFloat, bound:bound(0.0,1.0), show:hasInfill}),
|
||||||
|
sliceFillRepeat: newInput(LANG.fi_rept_s, {title:LANG.fi_rept_l, convert:toInt, bound:bound(1,10), show:fillIsLinear}),
|
||||||
|
sliceFillOverlap: newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:toFloat, bound:bound(0.0,2.0), show:hasInfill}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceFillRate: newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:toInt, bound:bound(0,500)}),
|
||||||
|
sliceSolidRate: newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:toInt, bound:bound(0,500)}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceFillGrow: newInput(LANG.fi_grow_s, {title:LANG.fi_grow_l, convert:toFloat}),
|
||||||
|
sliceFillAngle: newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:toFloat}),
|
||||||
|
_____: newGroup(LANG.fh_menu, $('fdm-heat'), { modes:FDM, driven, hideable, separator, group:"fdm-heat" }),
|
||||||
|
outputTemp: newInput(LANG.ou_nozl_s, {title:LANG.ou_nozl_l, convert:toInt}),
|
||||||
|
outputBedTemp: newInput(LANG.ou_bedd_s, {title:LANG.ou_bedd_l, convert:toInt}),
|
||||||
|
_____: newGroup(LANG.fc_menu, $('fdm-cool'), { modes:FDM, driven, hideable, separator, group:"fdm-cool" }),
|
||||||
|
outputFanLayer: newInput(LANG.ou_fanl_s, { title:LANG.ou_fanl_l, convert:toInt, bound:bound(0,255) }),
|
||||||
|
outputFanSpeed: newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:toInt, bound:bound(0,255)}),
|
||||||
|
_____: newGroup(LANG.sp_menu, $('fdm-support'), { modes:FDM, driven, hideable, separator, group:"fdm-supp" }),
|
||||||
|
sliceSupportNozzle: newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, show:isMultiHead}, "extruders"),
|
||||||
|
sliceSupportDensity: newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:toFloat, bound:bound(0.0,1.0)}),
|
||||||
|
sliceSupportSize: newInput(LANG.sp_size_s, {title:LANG.sp_size_l, convert:toFloat, bound:bound(1.0,200.0)}),
|
||||||
|
sliceSupportOffset: newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, convert:toFloat, bound:bound(0.0,200.0)}),
|
||||||
|
sliceSupportGap: newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, convert:toInt, bound:bound(0,5)}),
|
||||||
|
sliceSupportArea: newInput(LANG.sp_area_s, {title:LANG.sp_area_l, convert:toFloat, bound:bound(0.0,200.0)}),
|
||||||
|
sliceSupportExtra: newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, convert:toFloat, bound:bound(0.0,10.0)}),
|
||||||
|
sliceSupportGrow: newInput(LANG.sp_grow_s, {title:LANG.sp_grow_l, convert:toFloat, bound:bound(0.0,10.0)}),
|
||||||
|
sliceSupportAngle: newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, convert:toFloat, bound:bound(0.0,90.0)}),
|
||||||
|
sliceSupportSpan: newInput(LANG.sp_span_s, {title:LANG.sp_span_l, convert:toFloat, bound:bound(0.0,200.0), show:() => ui.sliceSupportEnable.checked }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceSupportEnable: newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, show:isNotBelt}),
|
||||||
|
sliceSupportOutline: newBoolean(LANG.sp_outl_s, onBooleanClick, {title:LANG.sp_outl_l}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceSupportGen: newRow([
|
||||||
|
ui.ssaGen = newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})
|
||||||
|
], { modes: FDM, class: "ext-buttons f-row grow" }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceSupportManual: newRow([
|
||||||
|
(ui.ssmAdd = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
||||||
|
(ui.ssmDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
||||||
|
(ui.ssmClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
||||||
|
], {class:"ext-buttons f-row"}),
|
||||||
|
_____: newGroup(LANG.fl_menu, $('fdm-base'), { modes:FDM, driven, hideable, separator, group:"fdm-base" }),
|
||||||
|
firstSliceHeight: newInput(LANG.fl_lahi_s, {title:LANG.fl_lahi_l, convert:toFloat, show:isNotBelt}),
|
||||||
|
firstLayerNozzleTemp:newInput(LANG.fl_nozl_s, {title:LANG.fl_nozl_l, convert:toInt, show:isNotBelt}),
|
||||||
|
firstLayerBedTemp: newInput(LANG.fl_bedd_s, {title:LANG.fl_bedd_l, convert:toInt, show:isNotBelt}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
firstLayerFanSpeed: newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:toInt, bound:bound(0,255), show:isBelt}),
|
||||||
|
firstLayerYOffset: newInput(LANG.fl_zoff_s, {title:LANG.fl_zoff_l, convert:toFloat, show:isBelt}),
|
||||||
|
firstLayerFlatten: newInput(LANG.fl_flat_s, {title:LANG.fl_flat_l, convert:toFloat, show:isBelt}),
|
||||||
|
firstLayerRate: newInput(LANG.fl_rate_s, {title:LANG.fl_rate_l, convert:toFloat}),
|
||||||
|
firstLayerFillRate: newInput(LANG.fl_frat_s, {title:LANG.fl_frat_l, convert:toFloat, show:isNotBelt}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
||||||
|
firstLayerLineMult: newInput(LANG.fl_sfac_s, {title:LANG.fl_sfac_l, convert:toFloat, bound:bound(0.5,2), show:isNotBelt}),
|
||||||
|
firstLayerPrintMult: newInput(LANG.fl_mult_s, {title:LANG.fl_mult_l, convert:toFloat}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
||||||
|
firstLayerBrim: newInput(LANG.fl_brim_s, {title:LANG.fl_brim_l, convert:toInt, show:isBelt}),
|
||||||
|
firstLayerBrimIn: newInput(LANG.fl_brin_s, {title:LANG.fl_brin_l, convert:toInt, show:isBelt}),
|
||||||
|
firstLayerBrimTrig: newInput(LANG.fl_brmn_s, {title:LANG.fl_brmn_l, convert:toInt, show:isBelt}),
|
||||||
|
firstLayerBrimGap: newInput(LANG.fl_brgp_s, {title:LANG.fl_brgp_l, convert:toFloat, show:isBelt}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
||||||
|
firstLayerBeltLead: newInput(LANG.fl_bled_s, {title:LANG.fl_bled_l, convert:toFloat, show:isBelt}),
|
||||||
|
firstLayerBeltBump: newInput(LANG.fl_blmp_s, {title:LANG.fl_blmp_l, convert:toFloat, bound:bound(0, 10), show:isBelt}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
||||||
|
outputBrimCount: newInput(LANG.fl_skrt_s, {title:LANG.fl_skrt_l, convert:toInt, show:isNotBelt}),
|
||||||
|
outputBrimOffset: newInput(LANG.fl_skro_s, {title:LANG.fl_skro_l, convert:toFloat, show:isNotBelt}),
|
||||||
|
outputRaftSpacing: newInput(LANG.fr_spac_s, {title:LANG.fr_spac_l, convert:toFloat, bound:bound(0.0,3.0), show: () => ui.outputRaft.checked && isNotBelt() }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isNotBelt }),
|
||||||
|
outputRaft: newBoolean(LANG.fr_nabl_s, onBooleanClick, {title:LANG.fr_nabl_l, trigger, show:() => isNotBelt()}),
|
||||||
|
outputDraftShield: newBoolean(LANG.fr_draf_s, onBooleanClick, {title:LANG.fr_draf_l, trigger, show:() => isNotBelt()}),
|
||||||
|
_____: newGroup(LANG.ou_menu, $('fdm-output'), { modes:FDM, driven, hideable, separator, group:"fdm-out" }),
|
||||||
|
outputFeedrate: newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:toInt}),
|
||||||
|
outputFinishrate: newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:toInt}),
|
||||||
|
outputSeekrate: newInput(LANG.ou_move_s, {title:LANG.ou_move_l, convert:toInt}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
outputShellMult: newInput(LANG.ou_shml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
||||||
|
outputFillMult: newInput(LANG.ou_flml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
||||||
|
outputSparseMult: newInput(LANG.ou_spml_s, {title:LANG.ou_exml_l, convert:toFloat, bound:bound(0.0,2.0)}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
outputRetractDist: newInput(LANG.ad_rdst_s, {title:LANG.ad_rdst_l, convert:toFloat}),
|
||||||
|
outputRetractSpeed: newInput(LANG.ad_rrat_s, {title:LANG.ad_rrat_l, convert:toInt}),
|
||||||
|
outputRetractWipe: newInput(LANG.ad_wpln_s, {title:LANG.ad_wpln_l, convert:toFloat, bound:bound(0.0,10)}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
sliceLayerStart: newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l}, "start"),
|
||||||
|
outputLayerRetract: newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l}),
|
||||||
|
outputAvoidGaps: newBoolean(LANG.ad_agap_s, onBooleanClick, {title:LANG.ad_agap_l}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, show:isBelt }),
|
||||||
|
outputBeltFirst: newBoolean(LANG.ad_lbir_s, onBooleanClick, {title:LANG.ad_lbir_l, show:isBelt}),
|
||||||
|
_____: newGroup(LANG.ad_menu, $('fdm-expert'), { modes:FDM, driven, hideable, separator, group:"fdm-xprt" }),
|
||||||
|
sliceAngle: newInput(LANG.sl_angl_s, {title:LANG.sl_angl_l, convert:toFloat, show:isBelt}),
|
||||||
|
outputRetractDwell: newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:toInt}),
|
||||||
|
sliceSolidMinArea: newInput(LANG.ad_msol_s, {title:LANG.ad_msol_l, convert:toFloat}),
|
||||||
|
outputMinSpeed: newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, convert:toFloat, bound:bound(1,200)}),
|
||||||
|
outputShortPoly: newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, convert:toFloat, bound:bound(0,10000)}),
|
||||||
|
outputCoastDist: newInput(LANG.ad_scst_s, {title:LANG.ad_scst_l, convert:toFloat, bound:bound(0.0,10)}),
|
||||||
|
zHopDistance: newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, convert:toFloat, bound:bound(0,3.0)}),
|
||||||
|
arcTolerance: newInput(LANG.ad_arct_s, {title:LANG.ad_arct_l, convert:toFloat, bound:bound(0,1.0), show:() => { return isNotBelt() }}),
|
||||||
|
antiBacklash: newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, convert:toInt, bound:bound(0,3)}),
|
||||||
|
outputLoops: newInput(LANG.ag_loop_s, {title:LANG.ag_loop_l, convert:toInt, bound:bound(-1,1000), show:isBelt}),
|
||||||
|
outputPurgeTower: newInput(LANG.ad_purg_s, {title:LANG.ad_purg_l, convert:toInt, bound:bound(0,1000)}),
|
||||||
|
|
||||||
|
fdmRanges: $('fdm-ranges'),
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
74
src/kiri/mode/laser/init-menu.js
Normal file
74
src/kiri/mode/laser/init-menu.js
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { api } from '../../core/api.js';
|
||||||
|
|
||||||
|
let LANG = api.language.current;
|
||||||
|
let { LASER, DRAG, WJET, WEDM } = api.const.MODES,
|
||||||
|
TWOD = [ LASER, DRAG, WJET, WEDM ],
|
||||||
|
TWONED = [ LASER, DRAG, WJET ],
|
||||||
|
{ $ } = api.web,
|
||||||
|
{ uc, ui } = api,
|
||||||
|
{ bound, toInt, toFloat } = uc,
|
||||||
|
{ newBlank, newButton, newBoolean, newGroup, newInput, newRow } = uc,
|
||||||
|
driven = true,
|
||||||
|
separator = true,
|
||||||
|
trigger = true
|
||||||
|
;
|
||||||
|
|
||||||
|
function onBooleanClick(el) {
|
||||||
|
api.event.emit('click.boolean', el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onButtonClick(el) {
|
||||||
|
api.event.emit('click.button', el);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function menu() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
/** Left Side Menu */
|
||||||
|
|
||||||
|
_____: newGroup(LANG.sl_menu, $('lzr-slice'), { modes:TWOD, driven, separator }),
|
||||||
|
ctSliceKerf: newInput(LANG.ls_offs_s, {title:LANG.ls_offs_l, convert:toFloat}),
|
||||||
|
ctSliceHeight: newInput(LANG.ls_lahi_s, {title:LANG.ls_lahi_l, convert:toFloat, trigger}),
|
||||||
|
ctSliceHeightMin: newInput(LANG.ls_lahm_s, {title:LANG.ls_lahm_l, convert:toFloat, show:() => ui.ctSliceHeight.value == 0 && !ui.ctSliceSingle.checked }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
ctSliceSingle: newBoolean(LANG.ls_sngl_s, onBooleanClick, {title:LANG.ls_sngl_l}),
|
||||||
|
ctOmitInner: newBoolean(LANG.we_omit_s, onBooleanClick, {title:LANG.we_omit_l, modes:WEDM}),
|
||||||
|
_____: newGroup('surfaces', $('lzr-surface'), { modes:[-1], driven, separator }),
|
||||||
|
ctSurfaces: newRow([
|
||||||
|
(ui.faceAdd = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
||||||
|
(ui.faceDun = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
||||||
|
(ui.faceClr = newButton(undefined, onButtonClick, {icon:'<i class="fas fa-trash-alt"></i>'}))
|
||||||
|
], {class:"ext-buttons f-row", modes:WEDM}),
|
||||||
|
_____: newGroup(LANG.dk_menu, $('lzr-knife'), { modes:DRAG, marker:true, driven, separator }),
|
||||||
|
ctOutKnifeDepth: newInput(LANG.dk_dpth_s, { title:LANG.dk_dpth_l, convert:toFloat, bound:bound(0.0,5.0) }),
|
||||||
|
ctOutKnifePasses: newInput(LANG.dk_pass_s, { title:LANG.dk_pass_l, convert:toInt, bound:bound(0,5) }),
|
||||||
|
ctOutKnifeTip: newInput(LANG.dk_offs_s, { title:LANG.dk_offs_l, convert:toFloat, bound:bound(0.0,10.0) }),
|
||||||
|
_____: newGroup(LANG.lo_menu, $('lzr-layout'), { modes:TWOD, driven, separator }),
|
||||||
|
ctOutTileSpacing: newInput(LANG.ou_spac_s, { title:LANG.ou_spac_l, convert:toInt }),
|
||||||
|
ctOutMerged: newBoolean(LANG.ou_mrgd_s, onBooleanClick, {title:LANG.ou_mrgd_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
||||||
|
ctOutGroup: newBoolean(LANG.ou_grpd_s, onBooleanClick, {title:LANG.ou_grpd_l, show:() => !(ui.ctOutMark.checked || ui.ctOutStack.checked) }),
|
||||||
|
_____: newGroup(LANG.ou_menu, $('lzr-output'), { modes:TWOD, driven, separator, group:"lzr-output" }),
|
||||||
|
ctOutPower: newInput(LANG.ou_powr_s, {title:LANG.ou_powr_l, convert:toInt, bound:bound(1,100), modes:TWONED }),
|
||||||
|
ctOutSpeed: newInput(LANG.ou_sped_s, {title:LANG.ou_sped_l, convert:toInt }),
|
||||||
|
ctAdaptive: newBoolean('adaptive speed', onBooleanClick, {modes:WEDM, title:'controller determines best cutting speed based on material feedback at runtime'}),
|
||||||
|
separator: newBlank({ class:"set-sep", driven }),
|
||||||
|
ctOriginBounds: newBoolean(LANG.or_bnds_s, onBooleanClick, { title:LANG.or_bnds_l, show:() => !ui.ctOriginCenter.checked }),
|
||||||
|
ctOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, { title:LANG.or_cntr_l, show:() => !ui.ctOriginBounds.checked }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
||||||
|
ctOriginOffX: newInput(LANG.or_offx_s, { title:LANG.or_offx_l, convert:toFloat, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
||||||
|
ctOriginOffY: newInput(LANG.or_offy_s, { title:LANG.or_offy_l, convert:toFloat, modes:WEDM, show:() => ui.ctOriginBounds.checked }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, modes:TWONED }),
|
||||||
|
ctOutZColor: newBoolean(LANG.ou_layo_s, onBooleanClick, { title:LANG.ou_layo_l, modes:TWONED, show:() => !ui.ctOutMerged.checked }),
|
||||||
|
ctOutLayer: newBoolean(LANG.ou_layr_s, onBooleanClick, { title:LANG.ou_layr_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
||||||
|
ctOutMark: newBoolean(LANG.ou_lays_s, onBooleanClick, { title:LANG.ou_lays_l, modes:TWONED, show:() => !ui.ctOutStack.checked }),
|
||||||
|
separator: newBlank({ class:"set-sep", driven, modes:LASER }),
|
||||||
|
ctOutInches: newBoolean(LANG.ou_inch_s, onBooleanClick, { title:LANG.ou_inch_l, modes:LASER }),
|
||||||
|
ctOutStack: newBoolean(LANG.ou_stak_s, onBooleanClick, { title:LANG.ou_stak_l, modes:LASER }),
|
||||||
|
ctOutShaper: newBoolean(LANG.ou_shap_s, onBooleanClick, { title:LANG.ou_shap_l, modes:LASER, show:() => ui.ctOutStack.checked }),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
58
src/kiri/mode/sla/init-menu.js
Normal file
58
src/kiri/mode/sla/init-menu.js
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
import { api } from '../../core/api.js';
|
||||||
|
|
||||||
|
let LANG = api.language.current;
|
||||||
|
let { SLA } = api.const.MODES,
|
||||||
|
{ $ } = api.web,
|
||||||
|
{ uc, ui } = api,
|
||||||
|
{ bound, toInt, toFloat } = uc,
|
||||||
|
{ newBoolean, newGroup, newInput, newSelect } = uc,
|
||||||
|
driven = true,
|
||||||
|
separator = true
|
||||||
|
;
|
||||||
|
|
||||||
|
function onBooleanClick(el) {
|
||||||
|
api.event.emit('click.boolean', el);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function menu() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
/** Left Side Menu */
|
||||||
|
|
||||||
|
slaProc: newGroup(LANG.sa_menu, $('sla-slice'), { modes:SLA, group:"sla-slice", driven, separator }),
|
||||||
|
slaSlice: newInput(LANG.sa_lahe_s, {title:LANG.sa_lahe_l, convert:toFloat}),
|
||||||
|
slaShell: newInput(LANG.sa_shel_s, {title:LANG.sa_shel_l, convert:toFloat}),
|
||||||
|
slaOpenTop: newBoolean(LANG.sa_otop_s, onBooleanClick, {title:LANG.sa_otop_l}),
|
||||||
|
slaOpenBase: newBoolean(LANG.sa_obas_s, onBooleanClick, {title:LANG.sa_obas_l}),
|
||||||
|
slaLayers: newGroup(LANG.sa_layr_m, $('sla-layers'), { modes:SLA, group:"sla-layers", driven, separator }),
|
||||||
|
slaLayerOn: newInput(LANG.sa_lton_s, {title:LANG.sa_lton_l, convert:toFloat}),
|
||||||
|
slaLayerOff: newInput(LANG.sa_ltof_s, {title:LANG.sa_ltof_l, convert:toFloat}),
|
||||||
|
slaPeelDist: newInput(LANG.sa_pldi_s, {title:LANG.sa_pldi_l, convert:toFloat}),
|
||||||
|
slaPeelLiftRate: newInput(LANG.sa_pllr_s, {title:LANG.sa_pllr_l, convert:toFloat}),
|
||||||
|
slaPeelDropRate: newInput(LANG.sa_pldr_s, {title:LANG.sa_pldr_l, convert:toFloat}),
|
||||||
|
slaBase: newGroup(LANG.sa_base_m, $('sla-base'), { modes:SLA, group:"sla-base", driven, separator }),
|
||||||
|
slaBaseLayers: newInput(LANG.sa_balc_s, {title:LANG.sa_balc_l, convert:toInt}),
|
||||||
|
slaBaseOn: newInput(LANG.sa_lton_s, {title:LANG.sa_bltn_l, convert:toFloat}),
|
||||||
|
slaBaseOff: newInput(LANG.sa_ltof_s, {title:LANG.sa_bltf_l, convert:toFloat}),
|
||||||
|
slaBasePeelDist: newInput(LANG.sa_pldi_s, {title:LANG.sa_pldi_l, convert:toFloat}),
|
||||||
|
slaBasePeelLiftRate: newInput(LANG.sa_pllr_s, {title:LANG.sa_pllr_l, convert:toFloat}),
|
||||||
|
slaFill: newGroup(LANG.sa_infl_m, $('sla-fill'), { modes:SLA, group:"sla-infill", driven, separator }),
|
||||||
|
slaFillDensity: newInput(LANG.sa_ifdn_s, {title:LANG.sa_ifdn_l, convert:toFloat, bound:bound(0,1)}),
|
||||||
|
slaFillLine: newInput(LANG.sa_iflw_s, {title:LANG.sa_iflw_l, convert:toFloat, bound:bound(0,5)}),
|
||||||
|
slaSupport: newGroup(LANG.sa_supp_m, $('sla-support'), { modes:SLA, group:"sla-support", driven, separator }),
|
||||||
|
slaSupportLayers: newInput(LANG.sa_slyr_s, {title:LANG.sa_slyr_l, convert:toInt, bound:bound(5,100)}),
|
||||||
|
slaSupportGap: newInput(LANG.sa_slgp_s, {title:LANG.sa_slgp_l, convert:toInt, bound:bound(3,30)}),
|
||||||
|
slaSupportDensity: newInput(LANG.sa_sldn_s, {title:LANG.sa_sldn_l, convert:toFloat, bound:bound(0.01,0.9)}),
|
||||||
|
slaSupportSize: newInput(LANG.sa_slsz_s, {title:LANG.sa_slsz_l, convert:toFloat, bound:bound(0.1,1)}),
|
||||||
|
slaSupportPoints: newInput(LANG.sa_slpt_s, {title:LANG.sa_slpt_l, convert:toInt, bound:bound(3,10)}),
|
||||||
|
slaSupportEnable: newBoolean(LANG.enable, onBooleanClick, {title:LANG.sl_slen_l}),
|
||||||
|
slaOutput: newGroup(LANG.sa_outp_m, $('sla-output'), { modes:SLA, driven, separator, group:"sla-output" }),
|
||||||
|
slaFirstOffset: newInput(LANG.sa_opzo_s, {title:LANG.sa_opzo_l, convert:toFloat, bound:bound(0,1)}),
|
||||||
|
slaAntiAlias: newSelect(LANG.sa_opaa_s, {title:LANG.sa_opaa_l}, "antialias"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ import { load } from '../../load/file.js';
|
||||||
import { newWidget } from '../core/widget.js';
|
import { newWidget } from '../core/widget.js';
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
constructor() {
|
constructor({ workURL, poolURL } = {}) {
|
||||||
this.widget = newWidget();
|
this.widget = newWidget();
|
||||||
this.settings = {
|
this.settings = {
|
||||||
mode: "FDM",
|
mode: "FDM",
|
||||||
|
|
@ -22,7 +22,13 @@ class Engine {
|
||||||
widget: { [this.widget.id]: {} }
|
widget: { [this.widget.id]: {} }
|
||||||
};
|
};
|
||||||
this.listener = () => { };
|
this.listener = () => { };
|
||||||
client.start();
|
try {
|
||||||
|
client.setWorkPath(workURL);
|
||||||
|
client.setPoolPath(poolURL);
|
||||||
|
client.restart();
|
||||||
|
} catch (error) {
|
||||||
|
console.log({ error });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load(url) {
|
load(url) {
|
||||||
|
|
@ -190,7 +196,7 @@ class Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function newEngine() {
|
export function newEngine() {
|
||||||
return new Engine();
|
return new Engine(...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Engine };
|
export { Engine };
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ import { codec, encode, encodePointArray } from '../core/codec.js';
|
||||||
import { doTopShells } from '../mode/fdm/post.js';
|
import { doTopShells } from '../mode/fdm/post.js';
|
||||||
import { newPoint } from '../../geo/point.js';
|
import { newPoint } from '../../geo/point.js';
|
||||||
import { polygons as POLY } from '../../geo/polygons.js';
|
import { polygons as POLY } from '../../geo/polygons.js';
|
||||||
import { sliceZ } from '../../geo/slicer.js';
|
import { sliceZ, sliceConnect } from '../../geo/slicer.js';
|
||||||
import { Slicer as cam_slicer } from '../mode/cam/slicer.js';
|
import { Slicer as cam_slicer } from '../mode/cam/slicer.js';
|
||||||
import { Slicer as topo_slicer } from '../mode/cam/slicer_topo.js';
|
import { Slicer as topo_slicer } from '../mode/cam/slicer_topo.js';
|
||||||
import { Probe, Trace, raster_slice } from '../mode/cam/topo3.js';
|
import { Probe, Trace, raster_slice } from '../mode/cam/topo3.js';
|
||||||
|
import { Topo as Topo4, rotatePoints } from '../mode/cam/topo4.js';
|
||||||
import { wasm_ctrl } from '../../geo/wasm.js';
|
import { wasm_ctrl } from '../../geo/wasm.js';
|
||||||
|
|
||||||
const clib = self.ClipperLib;
|
const clib = self.ClipperLib;
|
||||||
|
|
@ -53,9 +54,13 @@ function debug() {
|
||||||
// console.log(`[${name}]`, ...arguments);
|
// console.log(`[${name}]`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let invalid = 0;
|
||||||
const funcs = self.minion = {
|
const funcs = self.minion = {
|
||||||
invalid(data, seq, cmd) {
|
invalid(data, seq, cmd) {
|
||||||
|
if (invalid++ < 20) {
|
||||||
|
// prevent flooding console and killing session
|
||||||
console.error({ invalid_minion_command: cmd, data });
|
console.error({ invalid_minion_command: cmd, data });
|
||||||
|
}
|
||||||
reply({ seq, error: `invalid command (${cmd})` });
|
reply({ seq, error: `invalid command (${cmd})` });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -271,7 +276,7 @@ const funcs = self.minion = {
|
||||||
topo4_slice(data, seq) {
|
topo4_slice(data, seq) {
|
||||||
const { slice, resolution } = data;
|
const { slice, resolution } = data;
|
||||||
const vertices = cache.vertices;
|
const vertices = cache.vertices;
|
||||||
const recs = new kiri.topo_slicer(slice.index)
|
const recs = new topo_slicer(slice.index)
|
||||||
.setFromArray(vertices, slice)
|
.setFromArray(vertices, slice)
|
||||||
.slice(resolution)
|
.slice(resolution)
|
||||||
.map(rec => {
|
.map(rec => {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
import '../../add/array.js';
|
import '../../add/array.js';
|
||||||
import '../../add/class.js';
|
import '../../add/class.js';
|
||||||
import '../../add/three.js';
|
import '../../add/three.js';
|
||||||
import '../../ext/jszip.js';
|
|
||||||
|
|
||||||
import { base } from '../../geo/base.js';
|
import { base } from '../../geo/base.js';
|
||||||
import { codec } from '../core/codec.js';
|
import { codec } from '../core/codec.js';
|
||||||
|
|
@ -17,6 +16,7 @@ import { wasm_ctrl } from '../../geo/wasm.js';
|
||||||
import { version } from '../../moto/license.js';
|
import { version } from '../../moto/license.js';
|
||||||
import { Widget, newWidget } from '../core/widget.js';
|
import { Widget, newWidget } from '../core/widget.js';
|
||||||
import { load } from "../../load/png.js";
|
import { load } from "../../load/png.js";
|
||||||
|
import { JSZip } from '../../ext/jszip-esm.js';
|
||||||
|
|
||||||
import { CAM } from '../mode/cam/driver-be.js';
|
import { CAM } from '../mode/cam/driver-be.js';
|
||||||
import { DRAG } from '../mode/drag/driver.js';
|
import { DRAG } from '../mode/drag/driver.js';
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { THREE } from '../ext/three.js';
|
import { THREE } from '../ext/three.js';
|
||||||
import JSZip from '../ext/jszip.esm.js';
|
import { JSZip } from '../ext/jszip-esm.js';
|
||||||
|
|
||||||
let { BufferAttribute, Matrix4 } = THREE;
|
let { BufferAttribute, Matrix4 } = THREE;
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ function extractItems(records) {
|
||||||
*/
|
*/
|
||||||
export function parseAsync(data) {
|
export function parseAsync(data) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let zip = await JSZip.loadAsync(data);
|
let zip = await new JSZip().loadAsync(data);
|
||||||
let models = {};
|
let models = {};
|
||||||
for (let [key, value] of Object.entries(zip.files)) {
|
for (let [key, value] of Object.entries(zip.files)) {
|
||||||
if (key.endsWith(".model")) {
|
if (key.endsWith(".model")) {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ function init() {
|
||||||
motoClient.on('ready', restore_space);
|
motoClient.on('ready', restore_space);
|
||||||
|
|
||||||
// start worker
|
// start worker
|
||||||
motoClient.start('/lib/mesh/work.js?' + version);
|
motoClient.start('../lib/mesh/work.js?' + version);
|
||||||
|
|
||||||
// trigger space event binding
|
// trigger space event binding
|
||||||
call.space_init({ space: space, platform });
|
call.space_init({ space: space, platform });
|
||||||
|
|
@ -91,7 +91,11 @@ function init() {
|
||||||
call.ui_build();
|
call.ui_build();
|
||||||
|
|
||||||
// hide url params
|
// hide url params
|
||||||
history.replaceState({}, '', '/mesh/');
|
let wlp = window.location.pathname;
|
||||||
|
let mio = wlp.indexOf('/mesh/');
|
||||||
|
if (mio >= 0) {
|
||||||
|
history.replaceState({}, '', wlp.substring(0,mio + 6));
|
||||||
|
}
|
||||||
|
|
||||||
// for electron
|
// for electron
|
||||||
self.mesh = { api };
|
self.mesh = { api };
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
||||||
<!-- <script src="/lib/kiri-run/engine.js" type="module"></script> -->
|
<!-- <script src="/lib/kiri-run/engine.js" type="module"></script> -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { Engine } from '/lib/kiri-run/engine.js';
|
import { Engine } from '/lib/kiri/run/engine.js';
|
||||||
const engine = new Engine();
|
|
||||||
let edit, saveit = "";
|
let edit, saveit = "";
|
||||||
function $(id) { return document.getElementById(id) }
|
function $(id) { return document.getElementById(id) }
|
||||||
function onload() {
|
function onload() {
|
||||||
|
|
@ -127,7 +126,7 @@
|
||||||
eval(`(function(){${code}})()`);
|
eval(`(function(){${code}})()`);
|
||||||
}
|
}
|
||||||
function demoFDM() {
|
function demoFDM() {
|
||||||
engine
|
new Engine()
|
||||||
.setListener(display_message)
|
.setListener(display_message)
|
||||||
.load("/obj/cube.stl")
|
.load("/obj/cube.stl")
|
||||||
.then(eng => eng.setProcess({
|
.then(eng => eng.setProcess({
|
||||||
|
|
@ -144,7 +143,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function demoCAM(){
|
function demoCAM(){
|
||||||
engine
|
new Engine()
|
||||||
.setListener(display_message)
|
.setListener(display_message)
|
||||||
.load("/obj/cube.stl")
|
.load("/obj/cube.stl")
|
||||||
// should to call widget.setTopZ here ideally
|
// should to call widget.setTopZ here ideally
|
||||||
|
|
@ -244,7 +243,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function demoLASER(){
|
function demoLASER(){
|
||||||
engine
|
new Engine()
|
||||||
.setListener(display_message)
|
.setListener(display_message)
|
||||||
.load("/obj/cube.stl")
|
.load("/obj/cube.stl")
|
||||||
// should to call widget.setTopZ here ideally
|
// should to call widget.setTopZ here ideally
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
||||||
<script src="/lib/kiri-run/frame.js"></script>
|
<script src="/lib/kiri/run/frame.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let defc = [
|
let defc = [
|
||||||
"let api = kiri.frame;",
|
"let api = kiri.frame;",
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
/* surface size configuration and font import */
|
/* surface size configuration and font import */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Russo One';
|
font-family: 'Russo One';
|
||||||
src: url('/moto/russo-one.ttf');
|
src: url('../moto/russo-one.ttf');
|
||||||
}
|
}
|
||||||
@media only screen and (max-width : 1000px) {
|
@media only screen and (max-width : 1000px) {
|
||||||
.top-menu > span > label {
|
.top-menu > span > label {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
<meta http-equiv="origin-trial" content="Aixo1di7jfA+ystPFy70vGYyODYVAju1y8EQWwdkdtl5sB7i990oDCnqLQntpfl7NsW74wz99Og7xgQqeLKiBQsAAAB0eyJvcmlnaW4iOiJodHRwczovL2dyaWQuc3BhY2U6NDQzIiwiZmVhdHVyZSI6IlVucmVzdHJpY3RlZFNoYXJlZEFycmF5QnVmZmVyIiwiZXhwaXJ5IjoxNzUzMTQyNDAwLCJpc1N1YmRvbWFpbiI6dHJ1ZX0=">
|
<meta http-equiv="origin-trial" content="AobHyD9RXtmfFOTcY506ANNJjG8lYuuvQ3/C7YJvprSP6Kk2pjKIBSKAUbUh64Nx6aCZaqlZ+7sSSswiIFHflgYAAAB0eyJvcmlnaW4iOiJodHRwczovL2dyaWQuc3BhY2U6NDQzIiwiZmVhdHVyZSI6IlVucmVzdHJpY3RlZFNoYXJlZEFycmF5QnVmZmVyIiwiZXhwaXJ5IjoxNzY5NDcyMDAwLCJpc1N1YmRvbWFpbiI6dHJ1ZX0=">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||||
<title>Kiri:Moto</title>
|
<title>Kiri:Moto</title>
|
||||||
<link rel="icon" href="favicon.ico">
|
<link rel="icon" href="favicon.ico">
|
||||||
|
|
|
||||||
|
|
@ -875,6 +875,8 @@ self.lang['en-us'] = {
|
||||||
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
||||||
cx_true_s: "true shadow",
|
cx_true_s: "true shadow",
|
||||||
cx_true_l: ["computationally correct shadow","will be slower but produce","better cuts for complex parts"],
|
cx_true_l: ["computationally correct shadow","will be slower but produce","better cuts for complex parts"],
|
||||||
|
cx_arce_s: "arc output",
|
||||||
|
cx_arce_l: ["EXPERIMENTAL: enable path to arc conversion"],
|
||||||
cx_arct_s: "arc tolerance",
|
cx_arct_s: "arc tolerance",
|
||||||
cx_arct_l: ["convert cicrular paths to arcs;","center point drift tolerance","when matching arc points","consider values around 0.15","in mm, or 0.006 inches;","High values may cause","unexpected behavior","0 to disable"],
|
cx_arct_l: ["convert cicrular paths to arcs;","center point drift tolerance","when matching arc points","consider values around 0.15","in mm, or 0.006 inches;","High values may cause","unexpected behavior","0 to disable"],
|
||||||
cx_arcr_s: "arc resolution",
|
cx_arcr_s: "arc resolution",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Kiri:Moto 4.2.0",
|
"name": "Kiri:Moto 4.3.0",
|
||||||
"short_name": "Kiri:Moto",
|
"short_name": "Kiri:Moto",
|
||||||
"description": "Slicer for 3D printers, CNC mills, laser cutters and more",
|
"description": "Slicer for 3D printers, CNC mills, laser cutters and more",
|
||||||
"start_url": "/kiri/",
|
"start_url": "/kiri/",
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
"background_color": "#ffffff",
|
"background_color": "#ffffff",
|
||||||
"orientation": "landscape-primary",
|
"orientation": "landscape-primary",
|
||||||
"icons": [
|
"icons": [
|
||||||
{ "src": "/kiri/logo-cube-512.png", "type": "image/png", "sizes": "512x512" },
|
{ "src": "./logo-cube-512.png", "type": "image/png", "sizes": "512x512" },
|
||||||
{ "src": "/kiri/logo-cube-144.png", "type": "image/png", "sizes": "144x144" }
|
{ "src": "./logo-cube-144.png", "type": "image/png", "sizes": "144x144" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Russo One';
|
font-family: 'Russo One';
|
||||||
src: url('/moto/russo-one.ttf');
|
src: url('../moto/russo-one.ttf');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** defaults */
|
/** defaults */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue