merge development branch
This commit is contained in:
commit
9b0fa9dedf
128 changed files with 3943 additions and 4261 deletions
308
app.js
308
app.js
|
|
@ -10,7 +10,7 @@ const fs = require('fs');
|
|||
const uglify = require('uglify-es');
|
||||
const moment = require('moment');
|
||||
const agent = require('express-useragent');
|
||||
const license = require_fresh('./js/license.js');
|
||||
const license = require_fresh('./src/license.js');
|
||||
const version = license.VERSION || "rogue";
|
||||
|
||||
const fileCache = {};
|
||||
|
|
@ -18,12 +18,8 @@ const code_src = {};
|
|||
const code = {};
|
||||
const mods = {};
|
||||
const load = [];
|
||||
const device = {
|
||||
fdm: [],
|
||||
sla: [],
|
||||
cam: [],
|
||||
laser: []
|
||||
};
|
||||
const synth = {};
|
||||
const api = {};
|
||||
|
||||
let level;
|
||||
let cacheDir;
|
||||
|
|
@ -72,7 +68,7 @@ function init(mod) {
|
|||
]));
|
||||
mod.add(fixedmap("/api/", api));
|
||||
if (debug) {
|
||||
mod.static("/js/", "js");
|
||||
mod.static("/src/", "src");
|
||||
mod.static("/mod/", "mod");
|
||||
mod.sync("/reload", () => {
|
||||
mod.reload();
|
||||
|
|
@ -130,6 +126,7 @@ function initModule(mod, file, dir) {
|
|||
},
|
||||
const: {
|
||||
args: {},
|
||||
meta: mod.meta,
|
||||
debug: debug,
|
||||
script: script,
|
||||
moddir: dir,
|
||||
|
|
@ -210,139 +207,118 @@ function initModule(mod, file, dir) {
|
|||
});
|
||||
}
|
||||
|
||||
const api = {
|
||||
"filters-fdm": (req, res, next) => {
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.end(JSON.stringify(device.fdm));
|
||||
},
|
||||
|
||||
"filters-sla": (req, res, next) => {
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.end(JSON.stringify(device.sla));
|
||||
},
|
||||
|
||||
"filters-cam": (req, res, next) => {
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.end(JSON.stringify(device.cam));
|
||||
},
|
||||
|
||||
"filters-laser": (req, res, next) => {
|
||||
res.setHeader("Content-Type", "application/javascript");
|
||||
res.end(JSON.stringify(device.laser));
|
||||
}
|
||||
};
|
||||
|
||||
const script = {
|
||||
kiri : [
|
||||
"ext-three",
|
||||
"license",
|
||||
"ext-clip2",
|
||||
"ext-tween",
|
||||
"ext-fsave",
|
||||
"ext-earcut",
|
||||
"add-array",
|
||||
"add-three",
|
||||
"geo",
|
||||
"geo-debug",
|
||||
"geo-render",
|
||||
"geo-point",
|
||||
"geo-slope",
|
||||
"geo-line",
|
||||
"geo-bounds",
|
||||
"geo-polygon",
|
||||
"geo-polygons",
|
||||
"geo-gyroid",
|
||||
"moto-kv",
|
||||
"moto-ajax",
|
||||
"moto-ctrl",
|
||||
"moto-space",
|
||||
"moto-load-stl",
|
||||
"moto-db",
|
||||
"moto-ui",
|
||||
"kiri-icons",
|
||||
"kiri-lang",
|
||||
"kiri-lang-en",
|
||||
"kiri-fill",
|
||||
"kiri-db",
|
||||
"kiri-slice",
|
||||
"kiri-slicer",
|
||||
"kiri-driver-fdm",
|
||||
"kiri-driver-sla",
|
||||
"kiri-driver-cam",
|
||||
"kiri-driver-laser",
|
||||
"kiri-pack",
|
||||
"kiri-layer",
|
||||
"kiri-widget",
|
||||
"kiri-print",
|
||||
"kiri-codec",
|
||||
"kiri-work",
|
||||
"kiri-conf",
|
||||
"kiri",
|
||||
"kiri-init",
|
||||
"kiri-export"
|
||||
].map(p => `js/${p}.js`),
|
||||
work : [
|
||||
"ext-three",
|
||||
"ext-pngjs",
|
||||
"ext/three",
|
||||
"license",
|
||||
"ext-clip2",
|
||||
"add-array",
|
||||
"add-three",
|
||||
"add-class",
|
||||
"geo",
|
||||
// "geo-wasm",
|
||||
"geo-debug",
|
||||
"geo-point",
|
||||
"geo-slope",
|
||||
"geo-line",
|
||||
"geo-bounds",
|
||||
"geo-polygon",
|
||||
"geo-polygons",
|
||||
"geo-gyroid",
|
||||
"kiri-fill",
|
||||
"kiri-slice",
|
||||
"kiri-slicer",
|
||||
"kiri-driver-fdm",
|
||||
"kiri-driver-sla",
|
||||
"kiri-driver-cam",
|
||||
"kiri-driver-laser",
|
||||
"kiri-pack",
|
||||
"kiri-widget",
|
||||
"kiri-print",
|
||||
"kiri-codec"
|
||||
].map(p => `js/${p}.js`),
|
||||
"ext/clip2",
|
||||
"ext/tween",
|
||||
"ext/fsave",
|
||||
"ext/earcut",
|
||||
"add/array",
|
||||
"add/three",
|
||||
"geo/base",
|
||||
"geo/debug",
|
||||
"geo/render",
|
||||
"geo/point",
|
||||
"geo/slope",
|
||||
"geo/line",
|
||||
"geo/bounds",
|
||||
"geo/polygon",
|
||||
"geo/polygons",
|
||||
"geo/gyroid",
|
||||
"moto/kv",
|
||||
"moto/ajax",
|
||||
"moto/ctrl",
|
||||
"moto/pack",
|
||||
"moto/space",
|
||||
"moto/load-stl",
|
||||
"moto/db",
|
||||
"kiri/ui",
|
||||
"kiri/lang",
|
||||
"kiri/lang-en",
|
||||
"kiri/fill",
|
||||
"kiri/db",
|
||||
"kiri/slice",
|
||||
"kiri/slicer",
|
||||
"mode/fdm/driver",
|
||||
"mode/sla/driver",
|
||||
"mode/cam/driver",
|
||||
"mode/laser/driver",
|
||||
"kiri/layer",
|
||||
"kiri/widget",
|
||||
"kiri/print",
|
||||
"kiri/codec",
|
||||
"kiri/work",
|
||||
"kiri/conf",
|
||||
"kiri/main",
|
||||
"kiri/init",
|
||||
"kiri/export",
|
||||
"@devices",
|
||||
"@icons"
|
||||
].map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p),
|
||||
worker : [
|
||||
"kiri-worker"
|
||||
].map(p => `js/${p}.js`),
|
||||
meta : [
|
||||
"ext-three",
|
||||
"kiri",
|
||||
"ext/three",
|
||||
"ext/pngjs",
|
||||
"license",
|
||||
"ext-tween",
|
||||
"ext-fsave",
|
||||
"ext-earcut",
|
||||
"add-array",
|
||||
"add-three",
|
||||
"geo",
|
||||
"geo-debug",
|
||||
"geo-render",
|
||||
"geo-point",
|
||||
"geo-slope",
|
||||
"geo-line",
|
||||
"geo-bounds",
|
||||
"geo-polygon",
|
||||
"geo-polygons",
|
||||
"geo-gyroid",
|
||||
"kiri-layer",
|
||||
"moto-kv",
|
||||
"moto-ajax",
|
||||
"moto-ctrl",
|
||||
"moto-space",
|
||||
"moto-load-stl",
|
||||
"moto-db",
|
||||
"moto-ui",
|
||||
"kiri-db",
|
||||
"ext/clip2",
|
||||
"add/array",
|
||||
"add/three",
|
||||
"add/class",
|
||||
"geo/base",
|
||||
// "geo/wasm",
|
||||
"geo/debug",
|
||||
"geo/point",
|
||||
"geo/slope",
|
||||
"geo/line",
|
||||
"geo/bounds",
|
||||
"geo/polygon",
|
||||
"geo/polygons",
|
||||
"geo/gyroid",
|
||||
"moto/pack",
|
||||
"kiri/fill",
|
||||
"kiri/slice",
|
||||
"kiri/slicer",
|
||||
"mode/fdm/driver",
|
||||
"mode/sla/driver",
|
||||
"mode/cam/driver",
|
||||
"mode/laser/driver",
|
||||
"kiri/widget",
|
||||
"kiri/print",
|
||||
"kiri/codec",
|
||||
"kiri/worker"
|
||||
].map(p => `src/${p}.js`),
|
||||
meta : [
|
||||
"ext/three",
|
||||
"license",
|
||||
"ext/tween",
|
||||
"ext/fsave",
|
||||
"ext/earcut",
|
||||
"add/array",
|
||||
"add/three",
|
||||
"geo/base",
|
||||
"geo/debug",
|
||||
"geo/render",
|
||||
"geo/point",
|
||||
"geo/slope",
|
||||
"geo/line",
|
||||
"geo/bounds",
|
||||
"geo/polygon",
|
||||
"geo/polygons",
|
||||
"geo/gyroid",
|
||||
"kiri/layer",
|
||||
"moto/kv",
|
||||
"moto/ajax",
|
||||
"moto/ctrl",
|
||||
"moto/space",
|
||||
"moto/load-stl",
|
||||
"moto/db",
|
||||
"moto/ui",
|
||||
"kiri/db",
|
||||
"meta"
|
||||
].map(p => `js/${p}.js`)
|
||||
].map(p => `src/${p}.js`)
|
||||
};
|
||||
|
||||
const db = {
|
||||
|
|
@ -531,8 +507,13 @@ function handleData(req, res, next) {
|
|||
dbVersion = parseInt(version || "0") + 1;
|
||||
checkDone();
|
||||
});
|
||||
} else {
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
next();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,36 +592,46 @@ function serveCode(req, res, code) {
|
|||
res.end(code.code);
|
||||
}
|
||||
|
||||
function generateIcons() {
|
||||
let root = `${dir}/src/ico`;
|
||||
let icos = {};
|
||||
fs.readdirSync(root).forEach(file => {
|
||||
let name = file.split(".")[0] ;
|
||||
icos[name] = fs.readFileSync(`${root}/${file}`).toString();
|
||||
});
|
||||
synth.icons = `self.icons = ${JSON.stringify(icos)};`;
|
||||
}
|
||||
|
||||
function generateDevices() {
|
||||
let root = `${dir}/src/dev`;
|
||||
let devs = {};
|
||||
fs.readdirSync(root).forEach(type => {
|
||||
let map = devs[type] = devs[type] || {};
|
||||
fs.readdirSync(`${root}/${type}`).forEach(device => {
|
||||
map[device] = JSON.parse(fs.readFileSync(`${root}/${type}/${device}`));
|
||||
});
|
||||
});
|
||||
synth.devices = `self.devices = ${JSON.stringify(devs)};`;
|
||||
}
|
||||
|
||||
function prepareScripts() {
|
||||
generateIcons();
|
||||
generateDevices();
|
||||
code.meta = concatCode(script.meta);
|
||||
code.kiri = concatCode(script.kiri);
|
||||
code.work = concatCode(script.work);
|
||||
code.worker = concatCode(script.worker);
|
||||
fs.readdir(dir + "/web/kiri/filter/FDM", function(err, files) {
|
||||
device.fdm = files || device.fdm;
|
||||
});
|
||||
fs.readdir(dir + "/web/kiri/filter/SLA", function(err, files) {
|
||||
device.sla = files || device.sla;
|
||||
});
|
||||
fs.readdir(dir + "/web/kiri/filter/CAM", function(err, files) {
|
||||
device.cam = files || device.cam;
|
||||
});
|
||||
fs.readdir(dir + "/web/kiri/filter/LASER", function(err, files) {
|
||||
device.laser = files || device.laser;
|
||||
});
|
||||
}
|
||||
|
||||
function concatCode(array) {
|
||||
let code = [];
|
||||
let direct = array.filter(f => f.charAt(0) !== '@');
|
||||
let inject = array.filter(f => f.charAt(0) === '@').map(f => f.substring(1));
|
||||
|
||||
// in debug mode, the script should load dependent
|
||||
// scripts instead of serving a complete bundle
|
||||
if (debug) {
|
||||
let code = [ `(function() { let load = [ `];
|
||||
array.forEach(file => {
|
||||
// if (file.indexOf(":\\") > 0) {
|
||||
// file = `/${file}`;
|
||||
// }
|
||||
let code = [ '(function() { let load = [ ' ];
|
||||
direct.forEach(file => {
|
||||
code.push(`"/${file.replace(/\\/g,'/')}?${version}",`);
|
||||
});
|
||||
code.push([
|
||||
|
|
@ -653,19 +644,26 @@ function concatCode(array) {
|
|||
's.src = file;',
|
||||
's.onload = load_next;',
|
||||
'document.head.appendChild(s);',
|
||||
'}; load_next(); })();',
|
||||
'} load_next(); })();',
|
||||
'self.debug=true;'
|
||||
].join('\n'));
|
||||
inject.forEach(key => {
|
||||
code.push(synth[key]);
|
||||
});
|
||||
return code.join('\n');
|
||||
}
|
||||
|
||||
array.forEach(file => {
|
||||
direct.forEach(file => {
|
||||
let cached = getCachedFile(file, function(path) {
|
||||
return minify(`${dir}/${file}`);
|
||||
});
|
||||
code.push(cached);
|
||||
});
|
||||
|
||||
inject.forEach(key => {
|
||||
code.push(synth[key]);
|
||||
});
|
||||
|
||||
return code.join('');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
../node_modules/earcut/src/earcut.js
|
||||
|
|
@ -1 +0,0 @@
|
|||
../node_modules/three/build/three.min.js
|
||||
|
|
@ -1 +0,0 @@
|
|||
../node_modules/tween.js/index.js
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
let gs_kiri_ico = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = { };
|
||||
if (!self.kiri.icon) self.kiri.icons = {
|
||||
|
||||
fdm:atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0IiB2aWV3Qm94PSIwIDAgMTcwIDE3MCIgd2lkdGg9Ijc1cHgiIGhlaWdodD0iNzVweCI+PGRlZnM+PHBhdGggZD0iTTE1IDM4LjMzQzE1IDM4LjMzIDE1IDM4LjMzIDE1IDM4LjMzQzE1IDI1LjQ1IDI1LjQ1IDE1IDM4LjMzIDE1QzQ0LjU2IDE1IDc1LjY3IDE1IDEzMS42NyAxNUMxMzEuNjcgMTUgMTMxLjY3IDE1IDEzMS42NyAxNUMxMzcuODUgMTUgMTQzLjc5IDE3LjQ2IDE0OC4xNyAyMS44M0MxNTIuNTQgMjYuMjEgMTU1IDMyLjE1IDE1NSAzOC4zM0MxNTUgNDcuNjcgMTU1IDEyMi4zMyAxNTUgMTMxLjY3QzE1NSAxNDQuNTUgMTQ0LjU1IDE1NSAxMzEuNjcgMTU1QzEyMi4zMyAxNTUgNDcuNjcgMTU1IDM4LjMzIDE1NUMyNS40NSAxNTUgMTUgMTQ0LjU1IDE1IDEzMS42N0MxNSAxMTkuMjIgMTUgODguMTEgMTUgMzguMzNaIiBpZD0iYTE0R2FsdjlVRiI+PC9wYXRoPjxwYXRoIGQ9Ik00NSAxNUwxMjUgMTVMMTI1IDc1TDQ1IDc1TDQ1IDE1WiIgaWQ9ImMzcTgzOUxVMyI+PC9wYXRoPjxwYXRoIGQ9Ik0zNSAxNDEuNDhDNTMuMTEgMTQxLjQ4IDY0LjQzIDE0MS40OCA2OC45NiAxNDEuNDhDNzcuODIgMTQxLjQ4IDg1IDEzNC4zIDg1IDEyNS40NUM4NSAxMjUuNDUgODUgMTI1LjQ1IDg1IDEyNS40NSIgaWQ9ImNoRTB0MXhmTCI+PC9wYXRoPjxwYXRoIGQ9Ik0xMDUgOTVMODUgMTE1TDY1IDk1TDEwNSA5NVoiIGlkPSJhNks5OThGM0dUIj48L3BhdGg+PHBhdGggZD0iTTc1IDc1TDk1IDc1TDk1IDk1TDc1IDk1TDc1IDc1WiIgaWQ9ImUxaWlNRVJxQWgiPjwvcGF0aD48L2RlZnM+PGc+PGc+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjYTE0R2FsdjlVRiIgb3BhY2l0eT0iMSIgZmlsbD0iIzAwMDAwMCIgZmlsbC1vcGFjaXR5PSIwIj48L3VzZT48Zz48dXNlIHhsaW5rOmhyZWY9IiNhMTRHYWx2OVVGIiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48dXNlIHhsaW5rOmhyZWY9IiNjM3E4MzlMVTMiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjYzNxODM5TFUzIiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48Zz48dXNlIHhsaW5rOmhyZWY9IiNjaEUwdDF4ZkwiIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjguMDEiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjxnPjxnPjx1c2UgeGxpbms6aHJlZj0iI2E2Szk5OEYzR1QiIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjguMDEiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjxnPjx1c2UgeGxpbms6aHJlZj0iI2UxaWlNRVJxQWgiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjZTFpaU1FUnFBaCIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+Cg=='),
|
||||
|
||||
cam:atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0IiB2aWV3Qm94PSIwIDAgMTcwIDE3MCIgd2lkdGg9Ijc1cHgiIGhlaWdodD0iNzVweCI+PGRlZnM+PHBhdGggZD0iTTE1IDM4LjMzQzE1IDM4LjMzIDE1IDM4LjMzIDE1IDM4LjMzQzE1IDI1LjQ1IDI1LjQ1IDE1IDM4LjMzIDE1QzQ0LjU2IDE1IDc1LjY3IDE1IDEzMS42NyAxNUMxMzEuNjcgMTUgMTMxLjY3IDE1IDEzMS42NyAxNUMxMzcuODUgMTUgMTQzLjc5IDE3LjQ2IDE0OC4xNyAyMS44M0MxNTIuNTQgMjYuMjEgMTU1IDMyLjE1IDE1NSAzOC4zM0MxNTUgNDcuNjcgMTU1IDEyMi4zMyAxNTUgMTMxLjY3QzE1NSAxNDQuNTUgMTQ0LjU1IDE1NSAxMzEuNjcgMTU1QzEyMi4zMyAxNTUgNDcuNjcgMTU1IDM4LjMzIDE1NUMyNS40NSAxNTUgMTUgMTQ0LjU1IDE1IDEzMS42N0MxNSAxMTkuMjIgMTUgODguMTEgMTUgMzguMzNaIiBpZD0iZTNpckhhWHI0Ij48L3BhdGg+PHBhdGggZD0iTTY1IDE1TDEwNSAxNUwxMDUgMTI1TDY1IDEyNUw2NSAxNVoiIGlkPSJjMVlrTG9sMTBkIj48L3BhdGg+PHBhdGggZD0iTTEwNSAyNUw2NSA1NSIgaWQ9ImI0aHhqQ0sxenkiPjwvcGF0aD48cGF0aCBkPSJNMTA1IDU1TDY1IDg1IiBpZD0iYXBVYVY4bVp1Ij48L3BhdGg+PHBhdGggZD0iTTEwNSA4NUw2NSAxMTUiIGlkPSJiazIxZElxT3EiPjwvcGF0aD48L2RlZnM+PGc+PGc+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjZTNpckhhWHI0IiBvcGFjaXR5PSIxIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAiPjwvdXNlPjxnPjx1c2UgeGxpbms6aHJlZj0iI2UzaXJIYVhyNCIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PHVzZSB4bGluazpocmVmPSIjYzFZa0xvbDEwZCIgb3BhY2l0eT0iMSIgZmlsbD0iIzAwMDAwMCIgZmlsbC1vcGFjaXR5PSIwIj48L3VzZT48Zz48dXNlIHhsaW5rOmhyZWY9IiNjMVlrTG9sMTBkIiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48Zz48dXNlIHhsaW5rOmhyZWY9IiNiNGh4akNLMXp5IiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4LjAxIiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48Zz48dXNlIHhsaW5rOmhyZWY9IiNhcFVhVjhtWnUiIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjguMDEiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjxnPjxnPjx1c2UgeGxpbms6aHJlZj0iI2JrMjFkSXFPcSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOC4wMSIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+Cg=='),
|
||||
|
||||
laser:atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0IiB2aWV3Qm94PSIwIDAgMTcwIDE3MCIgd2lkdGg9Ijc1cHgiIGhlaWdodD0iNzVweCI+PGRlZnM+PHBhdGggZD0iTTE1IDM4LjMzQzE1IDM4LjMzIDE1IDM4LjMzIDE1IDM4LjMzQzE1IDI1LjQ1IDI1LjQ1IDE1IDM4LjMzIDE1QzQ0LjU2IDE1IDc1LjY3IDE1IDEzMS42NyAxNUMxMzEuNjcgMTUgMTMxLjY3IDE1IDEzMS42NyAxNUMxMzcuODUgMTUgMTQzLjc5IDE3LjQ2IDE0OC4xNyAyMS44M0MxNTIuNTQgMjYuMjEgMTU1IDMyLjE1IDE1NSAzOC4zM0MxNTUgNDcuNjcgMTU1IDEyMi4zMyAxNTUgMTMxLjY3QzE1NSAxNDQuNTUgMTQ0LjU1IDE1NSAxMzEuNjcgMTU1QzEyMi4zMyAxNTUgNDcuNjcgMTU1IDM4LjMzIDE1NUMyNS40NSAxNTUgMTUgMTQ0LjU1IDE1IDEzMS42N0MxNSAxMTkuMjIgMTUgODguMTEgMTUgMzguMzNaIiBpZD0iYTRsMDBtbkVueSI+PC9wYXRoPjxwYXRoIGQ9Ik02NSAxNUwxMDUgMTVMMTA1IDU1TDY1IDU1TDY1IDE1WiIgaWQ9ImJxOG9CV3JmRyI+PC9wYXRoPjxwYXRoIGQ9Ik04NSAxMjVMODUgNjUiIGlkPSJhWHpIdEdic0QiPjwvcGF0aD48cGF0aCBkPSJNNTUgMTA1TDc1IDEzNSIgaWQ9ImFrU3poMFFLeCI+PC9wYXRoPjxwYXRoIGQ9Ik0xMTUgMTA1TDk1IDEzNSIgaWQ9ImJsb0FzOWdpWiI+PC9wYXRoPjxwYXRoIGQ9Ik0zNSAxMjVMNzUgMTQ1IiBpZD0iZ2s2b2hqMEpMIj48L3BhdGg+PHBhdGggZD0iTTEzNSAxMjMuOTZMOTUgMTQ1IiBpZD0iZTQwNGVvajdMIj48L3BhdGg+PC9kZWZzPjxnPjxnPjxnPjxnPjx1c2UgeGxpbms6aHJlZj0iI2E0bDAwbW5FbnkiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjYTRsMDBtbkVueSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PHVzZSB4bGluazpocmVmPSIjYnE4b0JXcmZHIiBvcGFjaXR5PSIxIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAiPjwvdXNlPjxnPjx1c2UgeGxpbms6aHJlZj0iI2JxOG9CV3JmRyIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjYVh6SHRHYnNEIiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4LjAxIiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48Zz48dXNlIHhsaW5rOmhyZWY9IiNha1N6aDBRS3giIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjguMDEiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjxnPjxnPjx1c2UgeGxpbms6aHJlZj0iI2Jsb0FzOWdpWiIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOC4wMSIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjZ2s2b2hqMEpMIiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI4LjAxIiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48Zz48Zz48dXNlIHhsaW5rOmhyZWY9IiNlNDA0ZW9qN0wiIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjguMDEiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPgo='),
|
||||
|
||||
sla:atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0IiB2aWV3Qm94PSIwIDAgMTcwIDE3MCIgd2lkdGg9Ijc1cHgiIGhlaWdodD0iNzVweCI+PGRlZnM+PHBhdGggZD0iTTE1IDM4LjMzQzE1IDM4LjMzIDE1IDM4LjMzIDE1IDM4LjMzQzE1IDI1LjQ1IDI1LjQ1IDE1IDM4LjMzIDE1QzQ0LjU2IDE1IDc1LjY3IDE1IDEzMS42NyAxNUMxMzEuNjcgMTUgMTMxLjY3IDE1IDEzMS42NyAxNUMxMzcuODUgMTUgMTQzLjc5IDE3LjQ2IDE0OC4xNyAyMS44M0MxNTIuNTQgMjYuMjEgMTU1IDMyLjE1IDE1NSAzOC4zM0MxNTUgNDcuNjcgMTU1IDEyMi4zMyAxNTUgMTMxLjY3QzE1NSAxNDQuNTUgMTQ0LjU1IDE1NSAxMzEuNjcgMTU1QzEyMi4zMyAxNTUgNDcuNjcgMTU1IDM4LjMzIDE1NUMyNS40NSAxNTUgMTUgMTQ0LjU1IDE1IDEzMS42N0MxNSAxMTkuMjIgMTUgODguMTEgMTUgMzguMzNaIiBpZD0iYjNUUk5IeWJ4WCI+PC9wYXRoPjxwYXRoIGQ9Ik0zMS44OCA0Mi41TDEzOC4xMiA0Mi41TDEzOC4xMiA0Ny44MUwzMS44OCA0Ny44MUwzMS44OCA0Mi41WiIgaWQ9ImFOTWt6THdiIj48L3BhdGg+PHBhdGggZD0iTTc1IDIxLjg3TDk1IDIxLjg3TDk1IDQxLjg4TDc1IDQxLjg4TDc1IDIxLjg3WiIgaWQ9ImQxZktLZzJKcnUiPjwvcGF0aD48cGF0aCBkPSJNMTE1LjkzIDEwNy4xOUMxMTUuOTMgMTI0LjI3IDEwMi4wNyAxMzguMTMgODUgMTM4LjEzQzY3LjkzIDEzOC4xMyA1NC4wNyAxMjQuMjcgNTQuMDcgMTA3LjE5QzU0LjA3IDkwLjEyIDY3LjkzIDc2LjI2IDg1IDc2LjI2QzEwMi4wNyA3Ni4yNiAxMTUuOTMgOTAuMTIgMTE1LjkzIDEwNy4xOVoiIGlkPSJjbnlyY1RRTWciPjwvcGF0aD48cGF0aCBkPSJNNTMuODcgNDcuODFMNTMuODcgMTA3LjA4IiBpZD0iYTRHOVJyNlZRTCI+PC9wYXRoPjxwYXRoIGQ9Ik0xMTUuNzYgNTEuMjdMMTE1Ljc2IDExMC41MyIgaWQ9ImQ0aHl0eVNReFoiPjwvcGF0aD48cGF0aCBkPSJNNjkuMDYgNzkuNjlMNjkuMDYgNDcuODEiIGlkPSJiMVdRODNFTEFBIj48L3BhdGg+PHBhdGggZD0iTTEwMC45NCA3OS42OUwxMDAuOTQgNDcuODEiIGlkPSJmMmtOSHNsYUxhIj48L3BhdGg+PHBhdGggZD0iTTY5LjA2IDU4LjQ0TDUzLjEzIDc0LjM4IiBpZD0iZzY3dkZKd0FGeSI+PC9wYXRoPjxwYXRoIGQ9Ik0xMTQuNjggNTguNDRMMTAwLjk0IDY5LjA2IiBpZD0iYUFjcDN6NUt2Ij48L3BhdGg+PC9kZWZzPjxnPjxnPjxnPjx1c2UgeGxpbms6aHJlZj0iI2IzVFJOSHlieFgiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjYjNUUk5IeWJ4WCIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PHVzZSB4bGluazpocmVmPSIjYU5Na3pMd2IiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjYU5Na3pMd2IiIG9wYWNpdHk9IjEiIGZpbGwtb3BhY2l0eT0iMCIgc3Ryb2tlPSIjNzc3Nzc3IiBzdHJva2Utd2lkdGg9IjgiIHN0cm9rZS1vcGFjaXR5PSIxIj48L3VzZT48L2c+PC9nPjxnPjx1c2UgeGxpbms6aHJlZj0iI2QxZktLZzJKcnUiIG9wYWNpdHk9IjEiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMCI+PC91c2U+PGc+PHVzZSB4bGluazpocmVmPSIjZDFmS0tnMkpydSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PHVzZSB4bGluazpocmVmPSIjY255cmNUUU1nIiBvcGFjaXR5PSIxIiBmaWxsPSIjMWVhNWU2IiBmaWxsLW9wYWNpdHk9IjAiPjwvdXNlPjxnPjx1c2UgeGxpbms6aHJlZj0iI2NueXJjVFFNZyIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjYTRHOVJyNlZRTCIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjZDRoeXR5U1F4WiIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjYjFXUTgzRUxBQSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjZjJrTkhzbGFMYSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjZzY3dkZKd0FGeSIgb3BhY2l0eT0iMSIgZmlsbC1vcGFjaXR5PSIwIiBzdHJva2U9IiM3Nzc3NzciIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLW9wYWNpdHk9IjEiPjwvdXNlPjwvZz48L2c+PGc+PGc+PHVzZSB4bGluazpocmVmPSIjYUFjcDN6NUt2IiBvcGFjaXR5PSIxIiBmaWxsLW9wYWNpdHk9IjAiIHN0cm9rZT0iIzc3Nzc3NyIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2Utb3BhY2l0eT0iMSI+PC91c2U+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPgo=')
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
@ -1 +0,0 @@
|
|||
../web/kiri/lang/en.js
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
var exports = {
|
||||
COPYRIGHT:"Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
|
||||
LICENSE:"See the license.md file included with the source distribution",
|
||||
VERSION:"2.0.5"
|
||||
};
|
||||
if (!module) var module = {};
|
||||
module.exports = exports;
|
||||
1432
js/web-server.js
1432
js/web-server.js
File diff suppressed because it is too large
Load diff
5
notes.md
5
notes.md
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
||||
|
||||
* `C` hover mode to see device / settings selections
|
||||
* `F` implement an in-app bug reporting system
|
||||
* `F` extend mesh object to store raw + annotations (rot,scale,pos)
|
||||
* share raw data w/ dups, encode/decode
|
||||
|
|
@ -15,6 +16,8 @@
|
|||
|
||||
# FDM
|
||||
|
||||
* `B` fix adaptive slicing with multi-extruder
|
||||
* `B` fix supports with grouped parts
|
||||
* `F` control for size of purge block (with 0=disabled)
|
||||
* `F` add separate fill speed control
|
||||
* `F` manual support addition / control
|
||||
|
|
@ -29,6 +32,7 @@
|
|||
* `F` determine start point from gcode preamble
|
||||
* `F` trim support offset from layer below
|
||||
* `F` option to support interior bridges when 0% infill
|
||||
* `F` calculate filament use per extruder per print
|
||||
* `P` refactor thin fill to use outline and inside poly normal dist to self
|
||||
* `P` segment large polygons for extremely large parts / infill
|
||||
* `P` implement infill clipping in wasm
|
||||
|
|
@ -44,7 +48,6 @@
|
|||
* `B` linear finishing should extend beyond part boundaries by tool radius
|
||||
* `B` outside cutting direction in roughing mode inverted
|
||||
* `F` z bounded slices (extension of z bottom offset feature)
|
||||
* `F` do not mill out thru-pockets. cut outline only.
|
||||
* `F` use arcs to connect hard angles
|
||||
* `F` do not rough areas that go all the way through the part
|
||||
https://github.com/GridSpace/grid-apps/issues/20
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "grid-apps",
|
||||
"version": "1.1.3",
|
||||
"version": "3.0.0-dev",
|
||||
"description": "grid.space 3d slice & modeling tools",
|
||||
"author": "Stewart Allen <sa@grid.space>",
|
||||
"license": "MIT",
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@
|
|||
"tool-change":[
|
||||
"M6 T{tool} ; change tool to '{tool_name}'"
|
||||
],
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 400,
|
||||
"bed_depth": 400
|
||||
}
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 400,
|
||||
"bed_depth": 400
|
||||
}
|
||||
}
|
||||
|
|
@ -5,20 +5,20 @@
|
|||
"pre":[
|
||||
"G21 ; set units to MM (required)",
|
||||
"G90 ; absolute position mode (required)",
|
||||
"M03 S20000 ; spindle on"
|
||||
"M03 S20000 ; spindle on"
|
||||
],
|
||||
"post":[
|
||||
"M05 ; spindle off",
|
||||
"M05 ; spindle off",
|
||||
"M30 ; program end"
|
||||
],
|
||||
"tool-change":[
|
||||
"M6 T{tool} ; change tool to '{tool_name}'"
|
||||
],
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 400,
|
||||
"bed_depth": 400
|
||||
}
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 400,
|
||||
"bed_depth": 400
|
||||
}
|
||||
}
|
||||
|
|
@ -12,11 +12,11 @@
|
|||
"tool-change":[
|
||||
"M6 T{tool} ; change tool to '{tool_name}'"
|
||||
],
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 200,
|
||||
"bed_depth": 200
|
||||
}
|
||||
"dwell":[
|
||||
"G4 P{time} ; dwell for {time}ms"
|
||||
],
|
||||
"settings": {
|
||||
"bed_width": 200,
|
||||
"bed_depth": 200
|
||||
}
|
||||
}
|
||||
1
src/ext/earcut.js
Symbolic link
1
src/ext/earcut.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../node_modules/earcut/src/earcut.js
|
||||
1
src/ext/three.js
Symbolic link
1
src/ext/three.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../node_modules/three/build/three.min.js
|
||||
1
src/ext/tween.js
Symbolic link
1
src/ext/tween.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../node_modules/tween.js/index.js
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.util) return;
|
||||
if (self.base) return;
|
||||
|
||||
var BASE = self.base,
|
||||
const BASE = self.base = {},
|
||||
round_decimal_precision = 8;
|
||||
|
||||
/** ******************************************************************
|
||||
* Utility Functions
|
||||
******************************************************************* */
|
||||
|
||||
function time() { return new Date().getTime() }
|
||||
function time() { return Date.now() }
|
||||
|
||||
/**
|
||||
* call function with all combinations of a1, a2
|
||||
|
|
@ -29,7 +26,7 @@ var gs_base = exports;
|
|||
* @returns {Object}
|
||||
*/
|
||||
function doCombinations(a1, a2, arg, fn) {
|
||||
var i, j;
|
||||
let i, j;
|
||||
for (i = 0; i < a1.length; i++) {
|
||||
for (j = (a1 === a2 ? i + 1 : 0); j < a2.length; j++) {
|
||||
fn(a1[i], a2[j], arg);
|
||||
|
|
@ -151,7 +148,7 @@ var gs_base = exports;
|
|||
* @returns {boolean}
|
||||
*/
|
||||
function inRange(value, min, max) {
|
||||
var val = parseFloat(value);
|
||||
let val = parseFloat(value);
|
||||
return val >= min && val <= max;
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +159,7 @@ var gs_base = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
function round(v, zeros) {
|
||||
var pow = Math.pow(10,zeros || round_decimal_precision);
|
||||
let pow = Math.pow(10,zeros || round_decimal_precision);
|
||||
return Math.round(v * pow) / pow;
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +175,7 @@ var gs_base = exports;
|
|||
* @returns {?Point | String}
|
||||
*/
|
||||
function intersect(p1, p2, p3, p4, test, parallelok) {
|
||||
var keys = BASE.key,
|
||||
let keys = BASE.key,
|
||||
p1x = p1.x,
|
||||
p1y = p1.y,
|
||||
p2x = p2.x,
|
||||
|
|
@ -199,7 +196,7 @@ var gs_base = exports;
|
|||
return test && !parallelok ? null : keys.PARALLEL;
|
||||
}
|
||||
|
||||
var a = p1y - p3y, // origin dy
|
||||
let a = p1y - p3y, // origin dy
|
||||
b = p1x - p3x, // origin dx
|
||||
n1 = (d2x * a) - (d2y * b),
|
||||
n2 = (d1x * a) - (d1y * b);
|
||||
|
|
@ -207,7 +204,7 @@ var gs_base = exports;
|
|||
a = n1 / d; // roughly distance from l1 origin to l2 intersection
|
||||
b = n2 / d; // roughly distance from l2 origin to l1 intersection
|
||||
|
||||
var ia = a >= -0.0001 && a <= 1.0001,
|
||||
let ia = a >= -0.0001 && a <= 1.0001,
|
||||
ib = b >= -0.0001 && b <= 1.0001,
|
||||
segint = (ia && ib),
|
||||
rayint = (a >= 0 && b >= 0);
|
||||
|
|
@ -215,7 +212,7 @@ var gs_base = exports;
|
|||
if (test === keys.SEGINT && !segint) return null;
|
||||
if (test === keys.RAYINT && !rayint) return null;
|
||||
|
||||
var ip = BASE.newPoint(
|
||||
let ip = BASE.newPoint(
|
||||
p1x + (a * d1x), // x
|
||||
p1y + (a * d1y), // y
|
||||
p3.z || p4.z, // z
|
||||
|
|
@ -240,7 +237,7 @@ var gs_base = exports;
|
|||
* @returns {?Point}
|
||||
*/
|
||||
function intersectRayLine(ro, s1, p1, p2, infinite) {
|
||||
var keys = BASE.key,
|
||||
let keys = BASE.key,
|
||||
p1x = ro.x,
|
||||
p1y = ro.y,
|
||||
s1x = s1.dx,
|
||||
|
|
@ -253,7 +250,7 @@ var gs_base = exports;
|
|||
s2y = p4y - p3y,
|
||||
d = (s2y * s1x) - (s2x * s1y);
|
||||
|
||||
var a = p1y - p3y,
|
||||
let a = p1y - p3y,
|
||||
b = p1x - p3x,
|
||||
n1 = (s2x * a) - (s2y * b),
|
||||
n2 = (s1x * a) - (s1y * b);
|
||||
|
|
@ -267,7 +264,7 @@ var gs_base = exports;
|
|||
b = n2 / d;
|
||||
|
||||
if (infinite || (inCloseRange(b,0,1) && a >= 0)) {
|
||||
var ip = BASE.newPoint(
|
||||
let ip = BASE.newPoint(
|
||||
p1x + (a * s1x),
|
||||
p1y + (a * s1y),
|
||||
p2.z || ro.z,
|
||||
|
|
@ -289,7 +286,7 @@ var gs_base = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
function determinant(p1, p2, p3, p4) {
|
||||
var d1x = (p2.x - p1.x),
|
||||
let d1x = (p2.x - p1.x),
|
||||
d1y = (p2.y - p1.y),
|
||||
d2x = (p4.x - p3.x),
|
||||
d2y = (p4.y - p3.y);
|
||||
|
|
@ -2,11 +2,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var gs_base_bounds = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.Bounds) return;
|
||||
|
||||
/**
|
||||
|
|
@ -21,12 +18,9 @@ var gs_base_bounds = exports;
|
|||
this.leftMost = null;
|
||||
}
|
||||
|
||||
var BASE = self.base,
|
||||
const BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
CONF = BASE.config,
|
||||
ABS = Math.abs,
|
||||
MIN = Math.min,
|
||||
MAX = Math.max,
|
||||
PRO = Bounds.prototype;
|
||||
|
||||
BASE.Bounds = Bounds;
|
||||
|
|
@ -40,7 +34,7 @@ var gs_base_bounds = exports;
|
|||
* @returns {Bounds}
|
||||
*/
|
||||
PRO.clone = function() {
|
||||
var b = new Bounds();
|
||||
let b = new Bounds();
|
||||
b.minx = this.minx;
|
||||
b.miny = this.miny;
|
||||
b.maxx = this.maxx;
|
||||
|
|
@ -60,20 +54,20 @@ var gs_base_bounds = exports;
|
|||
* @param {Bounds} b
|
||||
*/
|
||||
PRO.merge = function(b) {
|
||||
this.minx = MIN(this.minx, b.minx);
|
||||
this.maxx = MAX(this.maxx, b.maxx);
|
||||
this.miny = MIN(this.miny, b.miny);
|
||||
this.maxy = MAX(this.maxy, b.maxy);
|
||||
this.minx = Math.min(this.minx, b.minx);
|
||||
this.maxx = Math.max(this.maxx, b.maxx);
|
||||
this.miny = Math.min(this.miny, b.miny);
|
||||
this.maxy = Math.max(this.maxy, b.maxy);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Point} p
|
||||
*/
|
||||
PRO.update = function(p) {
|
||||
this.minx = MIN(this.minx, p.x);
|
||||
this.maxx = MAX(this.maxx, p.x);
|
||||
this.miny = MIN(this.miny, p.y);
|
||||
this.maxy = MAX(this.maxy, p.y);
|
||||
this.minx = Math.min(this.minx, p.x);
|
||||
this.maxx = Math.max(this.maxx, p.x);
|
||||
this.miny = Math.min(this.miny, p.y);
|
||||
this.maxy = Math.max(this.maxy, p.y);
|
||||
if (this.minx === p.x) this.leftMost = p;
|
||||
};
|
||||
|
||||
|
|
@ -109,8 +103,8 @@ var gs_base_bounds = exports;
|
|||
*/
|
||||
PRO.overlaps = function(b, precision) {
|
||||
return (
|
||||
ABS(this.centerx() - b.centerx()) * 2 - precision < this.width() + b.width() &&
|
||||
ABS(this.centery() - b.centery()) * 2 - precision < this.height() + b.height()
|
||||
Math.abs(this.centerx() - b.centerx()) * 2 - precision < this.width() + b.width() &&
|
||||
Math.abs(this.centery() - b.centery()) * 2 - precision < this.height() + b.height()
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -2,21 +2,19 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var gs_base_debug = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.debug) return;
|
||||
|
||||
var base = self.base,
|
||||
enabled = false,
|
||||
const base = self.base,
|
||||
flags = {},
|
||||
stash = [],
|
||||
size = 20,
|
||||
next_debug_color = 0,
|
||||
debug_colors = [0xff0000, 0x00ff00, 0x0000ff, 0x00ffff, 0xff00ff, 0xffff00];
|
||||
|
||||
let size = 20,
|
||||
enabled = false,
|
||||
next_debug_color = 0;
|
||||
|
||||
/** ******************************************************************
|
||||
* Debug Functions
|
||||
******************************************************************* */
|
||||
|
|
@ -69,7 +67,7 @@ var gs_base_debug = exports;
|
|||
|
||||
function set(f, value) {
|
||||
if (Array.isArray(f)) {
|
||||
for (var i=0; i<f.length; i++) flags[f[i]] = (value || 1);
|
||||
for (let i=0; i<f.length; i++) flags[f[i]] = (value || 1);
|
||||
} else {
|
||||
flags[f] = (value || 1);
|
||||
}
|
||||
|
|
@ -77,14 +75,14 @@ var gs_base_debug = exports;
|
|||
|
||||
function clear(f) {
|
||||
if (Array.isArray(f)) {
|
||||
for (var i = 0; i < f.length; i++) delete flags[f[i]];
|
||||
for (let i = 0; i < f.length; i++) delete flags[f[i]];
|
||||
} else {
|
||||
delete flags[f];
|
||||
}
|
||||
}
|
||||
|
||||
function test(isSet, isNotSet) {
|
||||
var i;
|
||||
let i;
|
||||
if (isNotSet) {
|
||||
if (Array.isArray(isNotSet)) {
|
||||
for (i=0; i<isNotSet.length; i++) {
|
||||
|
|
@ -154,7 +152,7 @@ var gs_base_debug = exports;
|
|||
* @param {boolean} [creep]
|
||||
*/
|
||||
function xray(poly, z, v, deep, creep) {
|
||||
var colors = [
|
||||
let colors = [
|
||||
0xaa0000,
|
||||
0x0,
|
||||
0xaaaa00,
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_gyroid = exports;
|
||||
|
||||
(function() {
|
||||
if (!self.base) self.base = {};
|
||||
|
||||
if (self.base.gyroid) return;
|
||||
|
||||
var base = self.base;
|
||||
|
||||
let PI2 = Math.PI * 2;
|
||||
const base = self.base,
|
||||
PI2 = Math.PI * 2;
|
||||
|
||||
/**
|
||||
* @param off {number} z offset value from 0-1
|
||||
|
|
@ -1,14 +1,17 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_line = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.Line) return;
|
||||
|
||||
const BASE = self.base, PRO = Line.prototype;
|
||||
|
||||
BASE.Line = Line;
|
||||
BASE.newLine = newLine;
|
||||
BASE.newOrderedLine = newOrderedLine;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Point} p1
|
||||
|
|
@ -26,13 +29,6 @@ var gs_base_line = exports;
|
|||
this.del = false;
|
||||
}
|
||||
|
||||
var BASE = self.base,
|
||||
PRO = Line.prototype;
|
||||
|
||||
BASE.Line = Line;
|
||||
BASE.newLine = newLine;
|
||||
BASE.newOrderedLine = newOrderedLine;
|
||||
|
||||
/** ******************************************************************
|
||||
* Line Prototype Functions
|
||||
******************************************************************* */
|
||||
|
|
@ -62,7 +58,7 @@ var gs_base_line = exports;
|
|||
* @returns {Line}
|
||||
*/
|
||||
PRO.reverse = function() {
|
||||
var t = this.p1;
|
||||
let t = this.p1;
|
||||
this.p1 = this.p2;
|
||||
this.p2 = t;
|
||||
return this;
|
||||
|
|
@ -80,7 +76,7 @@ var gs_base_line = exports;
|
|||
* @returns {boolean}
|
||||
*/
|
||||
PRO.isCollinear = function(line) {
|
||||
var p1 = this.p1,
|
||||
let p1 = this.p1,
|
||||
p2 = this.p2,
|
||||
p3 = line.p1,
|
||||
p4 = line.p2,
|
||||
|
|
@ -1,14 +1,21 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_point = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.Point) return;
|
||||
|
||||
const BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
CONF = BASE.config,
|
||||
KEYS = BASE.key,
|
||||
ROUND = UTIL.round,
|
||||
PRO = Point.prototype;
|
||||
|
||||
BASE.Point = Point;
|
||||
BASE.newPoint = newPoint;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} x
|
||||
|
|
@ -44,16 +51,6 @@ var gs_base_point = exports;
|
|||
this.group = null; // for grouping in slice intersect, offset lines in trace
|
||||
}
|
||||
|
||||
var BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
CONF = BASE.config,
|
||||
KEYS = BASE.key,
|
||||
ROUND = UTIL.round,
|
||||
PRO = Point.prototype;
|
||||
|
||||
BASE.Point = Point;
|
||||
BASE.newPoint = newPoint;
|
||||
|
||||
/** ******************************************************************
|
||||
* Point Prototype Functions
|
||||
******************************************************************* */
|
||||
|
|
@ -64,14 +61,14 @@ var gs_base_point = exports;
|
|||
}
|
||||
|
||||
PRO.swapXZ = function() {
|
||||
var p = this,
|
||||
let p = this,
|
||||
t = p.x;
|
||||
p.x = p.z;
|
||||
p.z = t;
|
||||
};
|
||||
|
||||
PRO.swapYZ = function() {
|
||||
var p = this,
|
||||
let p = this,
|
||||
t = p.y;
|
||||
p.y = p.z;
|
||||
p.z = t;
|
||||
|
|
@ -163,10 +160,10 @@ var gs_base_point = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
PRO.distToLineSq = function(p1, p2) {
|
||||
var p = this,
|
||||
let p = this,
|
||||
d = UTIL.distSq(p1, p2);
|
||||
|
||||
var t = ((p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y)) / d;
|
||||
let t = ((p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y)) / d;
|
||||
|
||||
if (t < 0) return UTIL.distSq(p, p1);
|
||||
if (t > 1) return UTIL.distSq(p, p2);
|
||||
|
|
@ -189,16 +186,16 @@ var gs_base_point = exports;
|
|||
}
|
||||
|
||||
function p2l(p, l1, l2) {
|
||||
var v = {x: l2.x - l1.x, y: l2.y - l1.y};
|
||||
var w = {x: p.x - l1.x, y: p.y - l1.y};
|
||||
var c1 = dot(w, v);
|
||||
var c2 = dot(v, v);
|
||||
var b = c1 / c2;
|
||||
let v = {x: l2.x - l1.x, y: l2.y - l1.y};
|
||||
let w = {x: p.x - l1.x, y: p.y - l1.y};
|
||||
let c1 = dot(w, v);
|
||||
let c2 = dot(v, v);
|
||||
let b = c1 / c2;
|
||||
if (isNaN(b)) {
|
||||
// console.log('nan', {p, l1, l2, v, w, c1, c2});
|
||||
b = 0;
|
||||
}
|
||||
var pb = {x: l1.x + b * v.x, y: l1.y + b * v.y};
|
||||
let pb = {x: l1.x + b * v.x, y: l1.y + b * v.y};
|
||||
return d(p, pb);
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +209,7 @@ var gs_base_point = exports;
|
|||
* @returns {boolean}
|
||||
*/
|
||||
PRO.withinDist2 = function(p1, p2, dist2) {
|
||||
var ll2 = p1.distToSq2D(p2),
|
||||
let ll2 = p1.distToSq2D(p2),
|
||||
dp1 = this.distToSq2D(p1),
|
||||
dp2 = this.distToSq2D(p2);
|
||||
// if the line segment described is less than dist2
|
||||
|
|
@ -277,7 +274,7 @@ var gs_base_point = exports;
|
|||
* @param dist
|
||||
*/
|
||||
PRO.offsetPointFrom = function(p2, dist) {
|
||||
var p1 = this,
|
||||
let p1 = this,
|
||||
dx = p2.x - p1.x,
|
||||
dy = p2.y - p1.y,
|
||||
ls = dist / Math.sqrt(dx * dx + dy * dy),
|
||||
|
|
@ -313,7 +310,7 @@ var gs_base_point = exports;
|
|||
* @returns {Line}
|
||||
*/
|
||||
PRO.offsetLineTo = function(p2, offset) {
|
||||
var p1 = this,
|
||||
let p1 = this,
|
||||
dx = p2.x - p1.x,
|
||||
dy = p2.y - p1.y,
|
||||
ls = offset / Math.sqrt(dx * dx + dy * dy),
|
||||
|
|
@ -340,7 +337,7 @@ var gs_base_point = exports;
|
|||
PRO.inPolygon = function(poly) {
|
||||
if (!poly.bounds.containsXY(this.x, this.y)) return false;
|
||||
|
||||
var p = poly.points, pl = p.length, p1, p2, i, inside = false;
|
||||
let p = poly.points, pl = p.length, p1, p2, i, inside = false;
|
||||
|
||||
for (i=0; i<pl; i++) {
|
||||
p1 = p[i];
|
||||
|
|
@ -363,14 +360,14 @@ var gs_base_point = exports;
|
|||
* @return {boolean} true if inside outer but not inner
|
||||
*/
|
||||
PRO.isInPolygon = function(poly) {
|
||||
var point = this, i;
|
||||
let point = this, i;
|
||||
if (Array.isArray(poly)) {
|
||||
for (i=0; i<poly.length; i++) {
|
||||
if (point.isInPolygon(poly[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var holes = poly.inner;
|
||||
let holes = poly.inner;
|
||||
if (point.inPolygon(poly) || point.nearPolygon(poly, CONF.precision_merge_sq)) {
|
||||
for (i=0; holes && i < holes.length; i++) {
|
||||
if (point.inPolygon(holes[i]) && !point.nearPolygon(holes[i], CONF.precision_merge_sq)) return false;
|
||||
|
|
@ -388,14 +385,14 @@ var gs_base_point = exports;
|
|||
* @return {boolean} true if inside outer but not inner
|
||||
*/
|
||||
PRO.isInPolygonOnly = function(poly) {
|
||||
var point = this, i;
|
||||
let point = this, i;
|
||||
if (Array.isArray(poly)) {
|
||||
for (i=0; i<poly.length; i++) {
|
||||
if (point.isInPolygonOnly(poly[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var holes = poly.inner;
|
||||
let holes = poly.inner;
|
||||
if (point.inPolygon(poly)) {
|
||||
for (i=0; holes && i < holes.length; i++) {
|
||||
if (point.inPolygon(holes[i])) return false;
|
||||
|
|
@ -415,13 +412,13 @@ var gs_base_point = exports;
|
|||
*/
|
||||
PRO.nearPolygon = function(poly, dist2, inner) {
|
||||
// throw new Error("nearPolygon");
|
||||
for (var i=0, p=poly.points, pl=p.length ; i<pl; i++) {
|
||||
for (let i=0, p=poly.points, pl=p.length ; i<pl; i++) {
|
||||
if (this.withinDist2(p[i], p[(i+1)%pl], dist2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (inner && poly.inner) {
|
||||
for (var i=0; i<poly.inner.length; i++) {
|
||||
for (let i=0; i<poly.inner.length; i++) {
|
||||
if (this.nearPolygon(poly.inner[i], dist2)) return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -449,7 +446,7 @@ var gs_base_point = exports;
|
|||
* @returns {Point}
|
||||
*/
|
||||
PRO.follow = function(slope, distance) {
|
||||
var ls = distance / Math.sqrt(slope.dx * slope.dx + slope.dy * slope.dy);
|
||||
let ls = distance / Math.sqrt(slope.dx * slope.dx + slope.dy * slope.dy);
|
||||
return newPoint(this.x + slope.dx * ls, this.y + slope.dy * ls, this.z);
|
||||
};
|
||||
|
||||
|
|
@ -461,7 +458,7 @@ var gs_base_point = exports;
|
|||
* @returns {Point}
|
||||
*/
|
||||
PRO.intersectZ = function(p, z) {
|
||||
var dx = p.x - this.x,
|
||||
let dx = p.x - this.x,
|
||||
dy = p.y - this.y,
|
||||
dz = p.z - this.z,
|
||||
pct = 1 - ((p.z - z) / dz);
|
||||
|
|
@ -525,7 +522,7 @@ var gs_base_point = exports;
|
|||
* @param {number} [threshold] stop looking if under threshold
|
||||
*/
|
||||
PRO.distToPolySegments = function(poly, threshold) {
|
||||
var point = this,
|
||||
let point = this,
|
||||
mindist = Infinity;
|
||||
poly.forEachSegment(function(p1, p2) {
|
||||
const nextdist = Math.min(mindist, point.distToLine(p1, p2));
|
||||
|
|
@ -541,7 +538,7 @@ var gs_base_point = exports;
|
|||
* @param {number} [threshold] stop looking if under threshold
|
||||
*/
|
||||
PRO.distToPolyPoints = function(poly, threshold) {
|
||||
var point = this, mindist = Infinity;
|
||||
let point = this, mindist = Infinity;
|
||||
poly.forEachPoint(function(pp) {
|
||||
mindist = Math.min(mindist, point.distTo2D(pp));
|
||||
if (mindist < threshold) return true;
|
||||
|
|
@ -556,7 +553,7 @@ var gs_base_point = exports;
|
|||
*/
|
||||
PRO.nearestTo = function(points, max) {
|
||||
if (!max) throw "missing max";
|
||||
var mind = Infinity,
|
||||
let mind = Infinity,
|
||||
minp = null,
|
||||
i, p, d;
|
||||
for (i=0; i<points.length; i++) {
|
||||
|
|
@ -576,7 +573,7 @@ var gs_base_point = exports;
|
|||
* @return {number} average square dist to cloud of points
|
||||
*/
|
||||
PRO.averageDistTo = function(points) {
|
||||
var sum = 0.0, count = 0, i;
|
||||
let sum = 0.0, count = 0, i;
|
||||
for (i = 0; i < points.length; i++) {
|
||||
if (points[i] != this) {
|
||||
sum += this.distToSq2D(points[i]);
|
||||
|
|
@ -593,7 +590,7 @@ var gs_base_point = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
PRO.distTo2D = function(p) {
|
||||
var dx = this.x - p.x,
|
||||
let dx = this.x - p.x,
|
||||
dy = this.y - p.y;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
};
|
||||
|
|
@ -605,13 +602,13 @@ var gs_base_point = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
PRO.distToSq2D = function(p) {
|
||||
var dx = this.x - p.x,
|
||||
let dx = this.x - p.x,
|
||||
dy = this.y - p.y;
|
||||
return dx * dx + dy * dy;
|
||||
};
|
||||
|
||||
PRO.distTo3D = function(p) {
|
||||
var dx = this.x - p.x,
|
||||
let dx = this.x - p.x,
|
||||
dy = this.y - p.y,
|
||||
dz = this.z - p.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
|
|
@ -624,7 +621,7 @@ var gs_base_point = exports;
|
|||
* @returns {number}
|
||||
*/
|
||||
PRO.distToSq3D = function(p) {
|
||||
var dx = this.x - p.x,
|
||||
let dx = this.x - p.x,
|
||||
dy = this.y - p.y,
|
||||
dz = this.z - p.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
|
|
@ -639,7 +636,7 @@ var gs_base_point = exports;
|
|||
* @returns {boolean}
|
||||
*/
|
||||
PRO.inTriangle = function(a, b, c) {
|
||||
var as_x = this.x - a.x,
|
||||
let as_x = this.x - a.x,
|
||||
as_y = this.y - a.y,
|
||||
s_ab = (b.x - a.x) * as_y - (b.y - a.y) * as_x > 0;
|
||||
if ((c.x - a.x) * as_y - (c.y - a.y) * as_x > 0 == s_ab) return false;
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_polygon = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.Polygon) return;
|
||||
|
||||
var BASE = self.base,
|
||||
const BASE = self.base,
|
||||
CONF = BASE.config,
|
||||
UTIL = BASE.util,
|
||||
DBUG = BASE.debug,
|
||||
|
|
@ -21,12 +18,11 @@ var gs_base_polygon = exports;
|
|||
MAX = Math.max,
|
||||
PI = Math.PI,
|
||||
DEG2RAD = PI / 180,
|
||||
Bounds = BASE.Bounds,
|
||||
newPoint = BASE.newPoint,
|
||||
PRO = Polygon.prototype,
|
||||
nest_test_slope = BASE.newSlope(newPoint(0,0,0,KEYS.NONE), newPoint(1,0,0,KEYS.NONE)),
|
||||
min_area_mult = 2.0,
|
||||
seqid = 1;
|
||||
Bounds = BASE.Bounds,
|
||||
PRO = Polygon.prototype;
|
||||
|
||||
let seqid = 1;
|
||||
|
||||
BASE.Polygon = Polygon;
|
||||
BASE.newPolygon = newPolygon;
|
||||
|
|
@ -97,9 +93,9 @@ var gs_base_polygon = exports;
|
|||
|
||||
Polygon.filterChain = function(filters) {
|
||||
return function() {
|
||||
var f = filters;
|
||||
let f = filters;
|
||||
return function(p) {
|
||||
var len = f.length,
|
||||
let len = f.length,
|
||||
idx = 0;
|
||||
while (idx < len && (p = f[idx++](p)))
|
||||
;
|
||||
|
|
@ -213,8 +209,8 @@ var gs_base_polygon = exports;
|
|||
|
||||
PRO.createConvexHull = function(points) {
|
||||
function removeMiddle(a, b, c) {
|
||||
var cross = (a.x - b.x) * (c.y - b.y) - (a.y - b.y) * (c.x - b.x);
|
||||
var dot = (a.x - b.x) * (c.x - b.x) + (a.y - b.y) * (c.y - b.y);
|
||||
let cross = (a.x - b.x) * (c.y - b.y) - (a.y - b.y) * (c.x - b.x);
|
||||
let dot = (a.x - b.x) * (c.x - b.x) + (a.y - b.y) * (c.y - b.y);
|
||||
return cross < 0 || cross == 0 && dot <= 0;
|
||||
}
|
||||
|
||||
|
|
@ -222,11 +218,11 @@ var gs_base_polygon = exports;
|
|||
return a.x != b.x ? a.x - b.x : a.y - b.y;
|
||||
});
|
||||
|
||||
var n = points.length;
|
||||
var hull = [];
|
||||
let n = points.length;
|
||||
let hull = [];
|
||||
|
||||
for (var i = 0; i < 2 * n; i++) {
|
||||
var j = i < n ? i : 2 * n - 1 - i;
|
||||
for (let i = 0; i < 2 * n; i++) {
|
||||
let j = i < n ? i : 2 * n - 1 - i;
|
||||
while (hull.length >= 2 && removeMiddle(hull[hull.length - 2], hull[hull.length - 1], points[j]))
|
||||
hull.pop();
|
||||
hull.push(points[j]);
|
||||
|
|
@ -239,7 +235,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.stepsFromRoot = function() {
|
||||
var p = this.parent, steps = 0;
|
||||
let p = this.parent, steps = 0;
|
||||
while (p) {
|
||||
if (p.inner && p.inner.length > 1) steps++;
|
||||
p = p.parent;
|
||||
|
|
@ -256,11 +252,11 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.swap = function(x,y) {
|
||||
var poly = this,
|
||||
let poly = this,
|
||||
points = poly.points,
|
||||
length = points.length;
|
||||
poly.bounds = new Bounds();
|
||||
for (var i=0; i<length; i++) {
|
||||
for (let i=0; i<length; i++) {
|
||||
let p = points[i];
|
||||
if (x) p.swapXZ();
|
||||
else if (y) p.swapYZ();
|
||||
|
|
@ -291,7 +287,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Polygon|Point} a new polygon centered on x=0, y=0, z=0
|
||||
*/
|
||||
PRO.center = function(point) {
|
||||
var ap = newPoint(0,0,0,null), np = newPolygon(), pa = this.points;
|
||||
let ap = newPoint(0,0,0,null), np = newPolygon(), pa = this.points;
|
||||
pa.forEach(function(p) {
|
||||
ap.x += p.x;
|
||||
ap.y += p.y;
|
||||
|
|
@ -315,7 +311,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Point} center of a polygon assuming it's a circle
|
||||
*/
|
||||
PRO.circleCenter = function() {
|
||||
var points = this.points,
|
||||
let points = this.points,
|
||||
length = points.length,
|
||||
incr = Math.floor(length / 3),
|
||||
A = points[0],
|
||||
|
|
@ -387,7 +383,7 @@ var gs_base_polygon = exports;
|
|||
* @param {boolean} clockwise
|
||||
*/
|
||||
PRO.centerCircle = function(center, radius, points, clockwise) {
|
||||
var angle = 0, add = 360 / points;
|
||||
let angle = 0, add = 360 / points;
|
||||
if (clockwise) add = -add;
|
||||
while (points-- > 0) {
|
||||
this.push(newPoint(
|
||||
|
|
@ -406,7 +402,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Polygon}
|
||||
*/
|
||||
PRO.move = function(offset) {
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
bounds = scope.bounds = new Bounds();
|
||||
scope.points.forEach(function(p) {
|
||||
p.move(offset);
|
||||
|
|
@ -417,7 +413,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.scale = function(scale, round) {
|
||||
var scope = this,
|
||||
let scope = this,
|
||||
bounds = scope.bounds = new Bounds();
|
||||
scope.points.forEach(function(p) {
|
||||
p.x *= scale;
|
||||
|
|
@ -437,7 +433,7 @@ var gs_base_polygon = exports;
|
|||
* hint fill angle hinting from longest segment
|
||||
*/
|
||||
PRO.hintFillAngle = function() {
|
||||
var index = 0,
|
||||
let index = 0,
|
||||
points = this.points,
|
||||
length = points.length,
|
||||
prev,
|
||||
|
|
@ -471,7 +467,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Polygon}
|
||||
*/
|
||||
PRO.clone = function(deep) {
|
||||
var np = newPolygon(),
|
||||
let np = newPolygon(),
|
||||
ln = this.length,
|
||||
i = 0;
|
||||
|
||||
|
|
@ -495,7 +491,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Polygon} this
|
||||
*/
|
||||
PRO.setZ = function(z) {
|
||||
var ar = this.points,
|
||||
let ar = this.points,
|
||||
ln = ar.length,
|
||||
i = 0;
|
||||
while (i < ln) ar[i++].z = z;
|
||||
|
|
@ -545,7 +541,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {Polygon}
|
||||
*/
|
||||
PRO.addPoints = function(points) {
|
||||
var poly = this,
|
||||
let poly = this,
|
||||
length = points.length,
|
||||
i = 0;
|
||||
while (i < length) {
|
||||
|
|
@ -667,7 +663,7 @@ var gs_base_polygon = exports;
|
|||
*/
|
||||
PRO.isNested = function(parent) {
|
||||
if (parent.bounds.contains(this.bounds)) {
|
||||
//var int = POLY().rayIntersect(this.bounds.leftMost, nest_test_slope, [parent], false);
|
||||
//let int = POLY().rayIntersect(this.bounds.leftMost, nest_test_slope, [parent], false);
|
||||
//return int.length % 2 === 1 || this.isInside(parent, CONF.precision_nested_sq);
|
||||
return this.isInside(parent, CONF.precision_nested_sq);
|
||||
}
|
||||
|
|
@ -675,7 +671,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.forEachPointEaseDown = function(fn, fromPoint) {
|
||||
var index = this.findClosestPointTo(fromPoint).index,
|
||||
let index = this.findClosestPointTo(fromPoint).index,
|
||||
fromZ = fromPoint.z,
|
||||
offset = 0,
|
||||
points = this.points,
|
||||
|
|
@ -690,7 +686,7 @@ var gs_base_polygon = exports;
|
|||
while (true) {
|
||||
next = points[index % length];
|
||||
if (last && next.z < fromZ) {
|
||||
var deltaZ = fromZ - next.z;
|
||||
let deltaZ = fromZ - next.z;
|
||||
dist2next = last.distTo2D(next);
|
||||
if (dist2next > deltaZ * 2) {
|
||||
// too long: synth intermediate
|
||||
|
|
@ -716,7 +712,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.forEachPoint = function(fn, close, start) {
|
||||
var index = start || 0,
|
||||
let index = start || 0,
|
||||
points = this.points,
|
||||
length = points.length,
|
||||
count = close ? length + 1 : length,
|
||||
|
|
@ -731,7 +727,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.forEachSegment = function(fn, open, start) {
|
||||
var index = start || 0,
|
||||
let index = start || 0,
|
||||
points = this.points,
|
||||
length = points.length,
|
||||
count = open ? length - 1 : length,
|
||||
|
|
@ -749,9 +745,9 @@ var gs_base_polygon = exports;
|
|||
* returns intersections sorted by closest to lp1
|
||||
*/
|
||||
PRO.intersections = function(lp1, lp2) {
|
||||
var list = [];
|
||||
let list = [];
|
||||
this.forEachSegment(function(pp1, pp2, ip1, ip2) {
|
||||
var int = UTIL.intersect(lp1, lp2, pp1, pp2, BASE.key.SEGINT, false);
|
||||
let int = UTIL.intersect(lp1, lp2, pp1, pp2, BASE.key.SEGINT, false);
|
||||
if (int) {
|
||||
list.push(int);
|
||||
pp1.pos = ip1;
|
||||
|
|
@ -771,9 +767,9 @@ var gs_base_polygon = exports;
|
|||
PRO.bisect = function(p1, p2) {
|
||||
if (this.isOpen()) return null;
|
||||
|
||||
var copy = this.clone().setClockwise();
|
||||
let copy = this.clone().setClockwise();
|
||||
|
||||
var int = copy.intersections(p1, p2);
|
||||
let int = copy.intersections(p1, p2);
|
||||
if (!int || int.length !== 2) return null;
|
||||
|
||||
return [ copy.emitSegment(int[0], int[1]), copy.emitSegment(int[1], int[0]).reverse() ];
|
||||
|
|
@ -784,7 +780,7 @@ var gs_base_polygon = exports;
|
|||
* used in cam tabs and fdm output perimeter traces on infill
|
||||
*/
|
||||
PRO.emitSegment = function(i1, i2) {
|
||||
var poly = newPolygon(),
|
||||
let poly = newPolygon(),
|
||||
start = i1.p2.pos,
|
||||
end = i2.p1.pos;
|
||||
poly.setOpen();
|
||||
|
|
@ -805,7 +801,7 @@ var gs_base_polygon = exports;
|
|||
PRO.hasPointsInside = function(poly, tolerance) {
|
||||
if (!poly.overlaps(this)) return false;
|
||||
|
||||
var mid, exit = false;
|
||||
let mid, exit = false;
|
||||
|
||||
this.forEachSegment(function(prev, next) {
|
||||
// check midpoint on long lines
|
||||
|
|
@ -837,7 +833,7 @@ var gs_base_polygon = exports;
|
|||
this.bounds.isNested(poly.bounds)
|
||||
)) return false;
|
||||
|
||||
var mid,
|
||||
let mid,
|
||||
midcheck,
|
||||
exit = true;
|
||||
|
||||
|
|
@ -875,7 +871,7 @@ var gs_base_polygon = exports;
|
|||
*/
|
||||
PRO.containedBySet = function(polys) {
|
||||
if (!polys) return false;
|
||||
for (var i=0; i<polys.length; i++) {
|
||||
for (let i=0; i<polys.length; i++) {
|
||||
if (polys[i].contains(this)) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -919,7 +915,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.newUndeleted = function() {
|
||||
var poly = newPolygon();
|
||||
let poly = newPolygon();
|
||||
this.forEachPoint(function(p) {
|
||||
if (!p.del) poly.push(p);
|
||||
});
|
||||
|
|
@ -946,7 +942,7 @@ var gs_base_polygon = exports;
|
|||
return this.perim;
|
||||
}
|
||||
|
||||
var len = 0.0;
|
||||
let len = 0.0;
|
||||
|
||||
this.forEachSegment(function(prev,next) {
|
||||
len += SQRT(prev.distToSq2D(next));
|
||||
|
|
@ -956,7 +952,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.perimeterDeep = function() {
|
||||
var len = this.perimeter();
|
||||
let len = this.perimeter();
|
||||
if (this.inner) this.inner.forEach(function(p) { len += p.perimeter() });
|
||||
return len;
|
||||
};
|
||||
|
|
@ -972,7 +968,7 @@ var gs_base_polygon = exports;
|
|||
PRO.area = function(raw) {
|
||||
if (this.length < 3) return 0;
|
||||
if (this.area2 === 0.0) {
|
||||
for (var p=this.points,pl=p.length,pi=0,p1,p2; pi<pl; pi++) {
|
||||
for (let p=this.points,pl=p.length,pi=0,p1,p2; pi<pl; pi++) {
|
||||
p1 = p[pi];
|
||||
p2 = p[(pi+1)%pl];
|
||||
this.area2 += (p2.x - p1.x) * (p2.y + p1.y);
|
||||
|
|
@ -989,7 +985,7 @@ var gs_base_polygon = exports;
|
|||
*/
|
||||
PRO.areaDeep = function() {
|
||||
if (!this.inner) return this.area();
|
||||
var i, c = this.inner, a = this.area();
|
||||
let i, c = this.inner, a = this.area();
|
||||
for (i=0; i<c.length; i++) {
|
||||
a -= c[i].area();
|
||||
}
|
||||
|
|
@ -1011,7 +1007,7 @@ var gs_base_polygon = exports;
|
|||
* @param {number} [z]
|
||||
*/
|
||||
PRO.fromXYArray = function(arr,z) {
|
||||
var i = 0;
|
||||
let i = 0;
|
||||
while (i < arr.length) {
|
||||
this.add(arr[i++], arr[i++], z || 0);
|
||||
}
|
||||
|
|
@ -1019,7 +1015,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
function fromClipperPath(path,z) {
|
||||
var poly = newPolygon(), i = 0, l = path.length;
|
||||
let poly = newPolygon(), i = 0, l = path.length;
|
||||
while (i < l) poly.push(newPoint(null,null,z,null,path[i++]));
|
||||
return poly;
|
||||
};
|
||||
|
|
@ -1042,11 +1038,11 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.toClipper = function(inout,debug) {
|
||||
var poly = this,
|
||||
let poly = this,
|
||||
cur = [],
|
||||
out = inout || [];
|
||||
if (debug) {
|
||||
var d = [],
|
||||
let d = [],
|
||||
points = poly.points,
|
||||
len = points.length,
|
||||
i = 0,
|
||||
|
|
@ -1101,14 +1097,14 @@ var gs_base_polygon = exports;
|
|||
this.bounds.equals(poly.bounds, precision || CONF.precision_poly_bounds))
|
||||
{
|
||||
// use circularity near 1 to eliminate the extensive check below
|
||||
var c1 = this.circularity(),
|
||||
let c1 = this.circularity(),
|
||||
c2 = poly.circularity();
|
||||
if (ABS(c1-c2) < CONF.precision_circularity && ((1-c1) < CONF.precision_circularity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (recurse) {
|
||||
var i, ai = this.inner, bi = poly.inner;
|
||||
let i, ai = this.inner, bi = poly.inner;
|
||||
if (ai !== bi) {
|
||||
if (ai === null || bi === null || ai.length != bi.length) return false;
|
||||
for (i=0; i < ai.length; i++) {
|
||||
|
|
@ -1117,7 +1113,7 @@ var gs_base_polygon = exports;
|
|||
}
|
||||
}
|
||||
|
||||
var exit = true,
|
||||
let exit = true,
|
||||
pointok,
|
||||
dist,
|
||||
min;
|
||||
|
|
@ -1153,7 +1149,7 @@ var gs_base_polygon = exports;
|
|||
* @return {Object} {point:point, distance:distance}
|
||||
*/
|
||||
PRO.findClosestPointTo = function(target) {
|
||||
var dist,
|
||||
let dist,
|
||||
index,
|
||||
closest,
|
||||
mindist = Infinity;
|
||||
|
|
@ -1181,7 +1177,7 @@ var gs_base_polygon = exports;
|
|||
};
|
||||
|
||||
PRO.shortestSegmentLength = function() {
|
||||
var len = Infinity;
|
||||
let len = Infinity;
|
||||
this.forEachSegment(function(p1, p2) {
|
||||
len = Math.min(len, p1.distTo2D(p2));
|
||||
});
|
||||
|
|
@ -1193,7 +1189,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {?Polygon[]}
|
||||
*/
|
||||
PRO.diff = function(poly) {
|
||||
var fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
clib = self.ClipperLib,
|
||||
ctyp = clib.ClipType,
|
||||
ptyp = clib.PolyType,
|
||||
|
|
@ -1222,7 +1218,7 @@ var gs_base_polygon = exports;
|
|||
* @returns {?Polygon[]}
|
||||
*/
|
||||
PRO.mask = function(poly) {
|
||||
var fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
clib = self.ClipperLib,
|
||||
ctyp = clib.ClipType,
|
||||
ptyp = clib.PolyType,
|
||||
|
|
@ -1287,7 +1283,7 @@ var gs_base_polygon = exports;
|
|||
PRO.union = function(poly, min) {
|
||||
if (!this.overlaps(poly)) return null;
|
||||
|
||||
var fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
let fillang = this.fillang && this.area() > poly.area() ? this.fillang : poly.fillang,
|
||||
clib = self.ClipperLib,
|
||||
ctyp = clib.ClipType,
|
||||
ptyp = clib.PolyType,
|
||||
|
|
@ -1318,7 +1314,7 @@ var gs_base_polygon = exports;
|
|||
* furthest apart and lowest when there is a tie breaker
|
||||
*/
|
||||
PRO.spread = function() {
|
||||
var poly = this,
|
||||
let poly = this,
|
||||
points = poly.points,
|
||||
plen = points.length,
|
||||
i, pp, np, p, mdelta, newmax, max, shift, maxd;
|
||||
|
|
@ -1,15 +1,13 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_polygons = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.polygons) return;
|
||||
|
||||
var BASE = self.base,
|
||||
const BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
CONF = BASE.config,
|
||||
DEG2RAD = Math.PI / 180,
|
||||
|
|
@ -30,6 +28,7 @@ var gs_base_polygons = exports;
|
|||
trimTo : trimTo,
|
||||
expand2 : expand2,
|
||||
expand : expand,
|
||||
expand_lines: expand_lines,
|
||||
union : union,
|
||||
nest : nest,
|
||||
diff : doDiff,
|
||||
|
|
@ -48,13 +47,13 @@ var gs_base_polygons = exports;
|
|||
******************************************************************* */
|
||||
|
||||
function toClipper(polys,debug) {
|
||||
var out = [];
|
||||
let out = [];
|
||||
polys.forEach(function(poly) { poly.toClipper(out,debug) });
|
||||
return out;
|
||||
}
|
||||
|
||||
function fromClipperNode(tnode, z) {
|
||||
var poly = BASE.newPolygon();
|
||||
let poly = BASE.newPolygon();
|
||||
tnode.m_polygon.forEach(function(p) {
|
||||
poly.push(newPoint(null, null, z, null, p));
|
||||
});
|
||||
|
|
@ -63,7 +62,7 @@ var gs_base_polygons = exports;
|
|||
};
|
||||
|
||||
function fromClipperTree(tnode, z, tops, parent, minarea) {
|
||||
var polys = tops || [],
|
||||
let polys = tops || [],
|
||||
poly,
|
||||
min = minarea || 0.1;
|
||||
|
||||
|
|
@ -108,7 +107,7 @@ var gs_base_polygons = exports;
|
|||
};
|
||||
|
||||
function cleanClipperTree(tree) {
|
||||
var clib = self.ClipperLib,
|
||||
let clib = self.ClipperLib,
|
||||
clip = clib.Clipper;
|
||||
|
||||
if (tree.m_Childs) tree.m_Childs.forEach(function(child) {
|
||||
|
|
@ -151,7 +150,7 @@ var gs_base_polygons = exports;
|
|||
polygons.sort(function (a, b) {
|
||||
return a.area() - b.area();
|
||||
});
|
||||
var i, poly;
|
||||
let i, poly;
|
||||
// clear parent/child links if they exist
|
||||
for (i = 0; i < polygons.length; i++) {
|
||||
poly = polygons[i];
|
||||
|
|
@ -162,8 +161,8 @@ var gs_base_polygons = exports;
|
|||
for (i = 0; i < polygons.length - 1; i++) {
|
||||
poly = polygons[i];
|
||||
// find the smallest suitable parent
|
||||
for (var j = i + 1; j < polygons.length; j++) {
|
||||
var parent = polygons[j];
|
||||
for (let j = i + 1; j < polygons.length; j++) {
|
||||
let parent = polygons[j];
|
||||
// prevent open polys from having inners
|
||||
if (opentop && parent.isOpen()) continue;
|
||||
if (poly.isNested(parent)) {
|
||||
|
|
@ -173,7 +172,7 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
}
|
||||
// tops have an even # depth
|
||||
var tops = [],
|
||||
let tops = [],
|
||||
p;
|
||||
// assign a depth level to each group
|
||||
for (i = 0; i < polygons.length; i++) {
|
||||
|
|
@ -207,7 +206,7 @@ var gs_base_polygons = exports;
|
|||
*/
|
||||
function setWinding(array, CW, recurse) {
|
||||
if (!array) return;
|
||||
var poly, i = 0;
|
||||
let poly, i = 0;
|
||||
while (i < array.length) {
|
||||
poly = array[i++];
|
||||
if (poly.isClockwise() !== CW) poly.reverse();
|
||||
|
|
@ -223,7 +222,7 @@ var gs_base_polygons = exports;
|
|||
* @return {boolean} true if aligned clockwise
|
||||
*/
|
||||
function alignWindings(polys) {
|
||||
var len = polys.length,
|
||||
let len = polys.length,
|
||||
fwd = 0,
|
||||
pts = 0,
|
||||
i = 0,
|
||||
|
|
@ -244,7 +243,7 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
|
||||
function setContains(setA, poly) {
|
||||
for (var i=0; i<setA.length; i++) {
|
||||
for (let i=0; i<setA.length; i++) {
|
||||
if (setA[i].contains(poly)) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -272,7 +271,7 @@ var gs_base_polygons = exports;
|
|||
* @returns {Polygon[]} out
|
||||
*/
|
||||
function subtract(setA, setB, outA, outB, z, minArea) {
|
||||
var clib = self.ClipperLib,
|
||||
let clib = self.ClipperLib,
|
||||
ctyp = clib.ClipType,
|
||||
ptyp = clib.PolyType,
|
||||
cfil = clib.PolyFillType,
|
||||
|
|
@ -333,7 +332,7 @@ var gs_base_polygons = exports;
|
|||
function union(polys, minarea) {
|
||||
if (polys.length < 2) return polys;
|
||||
|
||||
var out = polys.slice(), i, j, union, uset = [];
|
||||
let out = polys.slice(), i, j, union, uset = [];
|
||||
|
||||
outer: for (i=0; i<out.length; i++) {
|
||||
if (!out[i]) continue;
|
||||
|
|
@ -361,7 +360,7 @@ var gs_base_polygons = exports;
|
|||
* @returns {?Polygon[]}
|
||||
*/
|
||||
function doDiff(setA, setB, z) {
|
||||
var clib = self.ClipperLib,
|
||||
let clib = self.ClipperLib,
|
||||
ctyp = clib.ClipType,
|
||||
ptyp = clib.PolyType,
|
||||
cfil = clib.PolyFillType,
|
||||
|
|
@ -391,7 +390,7 @@ var gs_base_polygons = exports;
|
|||
// handle null/empty slices
|
||||
if (setA === setB || setA === null || setB === null) return null;
|
||||
|
||||
var out = [], tmp;
|
||||
let out = [], tmp;
|
||||
UTIL.doCombinations(setA, setB, {}, function(a, b) {
|
||||
if (tmp = a.mask(b)) {
|
||||
out.appendAll(tmp);
|
||||
|
|
@ -402,13 +401,32 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
|
||||
function sumCirc(polys) {
|
||||
var sum = 0.0;
|
||||
let sum = 0.0;
|
||||
polys.forEach(function(poly) {
|
||||
sum += poly.circularityDeep();
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Polygon[]} polys
|
||||
* @param {number} distance offset
|
||||
* @param {number} [z] defaults to 0
|
||||
*/
|
||||
function expand_lines(poly, distance, z) {
|
||||
let fact = CONF.clipper,
|
||||
clib = self.ClipperLib,
|
||||
cjnt = clib.JoinType,
|
||||
cety = clib.EndType,
|
||||
coff = new clib.ClipperOffset(),
|
||||
ctre = new clib.PolyTree();
|
||||
|
||||
coff.AddPaths(poly.toClipper(), cjnt.jtMiter, cety.etOpenSquare);
|
||||
coff.Execute(ctre, distance * fact);
|
||||
|
||||
return fromClipperTree(ctre, z, null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Polygon[]} polys
|
||||
* @param {number} distance offset
|
||||
|
|
@ -426,7 +444,7 @@ var gs_base_polygons = exports;
|
|||
if (poly.inner) setWinding(poly.inner, !poly.isClockwise());
|
||||
});
|
||||
|
||||
var fact = CONF.clipper,
|
||||
let fact = CONF.clipper,
|
||||
clib = self.ClipperLib,
|
||||
clip = clib.Clipper,
|
||||
cpft = clib.PolyFillType,
|
||||
|
|
@ -437,8 +455,8 @@ var gs_base_polygons = exports;
|
|||
circ = sumCirc(polys);
|
||||
|
||||
polys.forEach(function(poly) {
|
||||
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
var simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
let clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
let simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
coff.AddPaths(simple, cjnt.jtMiter, cety.etClosedPolygon);
|
||||
});
|
||||
|
||||
|
|
@ -476,7 +494,7 @@ var gs_base_polygons = exports;
|
|||
if (poly.inner) setWinding(poly.inner, !poly.isClockwise());
|
||||
});
|
||||
|
||||
var fact = CONF.clipper,
|
||||
let fact = CONF.clipper,
|
||||
clib = self.ClipperLib,
|
||||
clip = clib.Clipper,
|
||||
cpft = clib.PolyFillType,
|
||||
|
|
@ -489,8 +507,8 @@ var gs_base_polygons = exports;
|
|||
|
||||
// inset
|
||||
polys.forEach(function(poly) {
|
||||
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
var simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
let clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
let simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
coff.AddPaths(simple, cjnt.jtMiter, cety.etClosedPolygon);
|
||||
});
|
||||
|
||||
|
|
@ -501,8 +519,8 @@ var gs_base_polygons = exports;
|
|||
coff = new clib.ClipperOffset();
|
||||
ctre = new clib.PolyTree();
|
||||
polys.forEach(function(poly) {
|
||||
var clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
var simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
let clean = clip.CleanPolygons(poly.toClipper(), CONF.clipperClean);
|
||||
let simple = clip.SimplifyPolygons(clean, cpft.pftNonZero);
|
||||
coff.AddPaths(simple, cjnt.jtMiter, cety.etClosedPolygon);
|
||||
});
|
||||
coff.Execute(ctre, -over * fact);
|
||||
|
|
@ -510,7 +528,7 @@ var gs_base_polygons = exports;
|
|||
|
||||
// detect possible thin walls
|
||||
if (thins) {
|
||||
var circ1 = sumCirc(orig),
|
||||
let circ1 = sumCirc(orig),
|
||||
circ2 = sumCirc(polys),
|
||||
diff = Math.abs(1 - (circ1 / circ2));
|
||||
|
||||
|
|
@ -545,7 +563,7 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
|
||||
// offset polygon to outer traces array
|
||||
var calcoff = depth === 0 && last ? offset / 2 : offset,
|
||||
let calcoff = depth === 0 && last ? offset / 2 : offset,
|
||||
outer = poly.offset(calcoff, []),
|
||||
inner = [],
|
||||
j;
|
||||
|
|
@ -563,7 +581,7 @@ var gs_base_polygons = exports;
|
|||
});
|
||||
}
|
||||
|
||||
var newouter = [], newinner = [];
|
||||
let newouter = [], newinner = [];
|
||||
subtract(outer, inner, newouter, newinner, poly.getZ());
|
||||
|
||||
if (newouter.length > 0) {
|
||||
|
|
@ -596,7 +614,7 @@ var gs_base_polygons = exports;
|
|||
function fillArea(polys, angle, spacing, output, minLen, maxLen) {
|
||||
if (polys.length === 0) return;
|
||||
|
||||
var i = 1,
|
||||
let i = 1,
|
||||
p0 = polys[0],
|
||||
zpos = p0.getZ(),
|
||||
bounds = p0.bounds.clone(),
|
||||
|
|
@ -616,7 +634,7 @@ var gs_base_polygons = exports;
|
|||
while (i < polys.length) bounds.merge(polys[i++].bounds);
|
||||
|
||||
// ray stepping is an axis from the line perpendicular to the ray
|
||||
var rayint = output || [],
|
||||
let rayint = output || [],
|
||||
stepX = -raySlope.dy,
|
||||
stepY = raySlope.dx,
|
||||
iterX = ABS(ABS(stepX) > 0 ? bounds.width() / stepX : 0),
|
||||
|
|
@ -639,7 +657,7 @@ var gs_base_polygons = exports;
|
|||
rayint.origin = newPoint(start.x, start.y, start.z);
|
||||
|
||||
for (i = 0; i < steps; i++) {
|
||||
var p1 = newPoint(start.x - raySlope.dx * 1000, start.y - raySlope.dy * 1000, zpos, NOKEY),
|
||||
let p1 = newPoint(start.x - raySlope.dx * 1000, start.y - raySlope.dy * 1000, zpos, NOKEY),
|
||||
p2 = newPoint(start.x + raySlope.dx * 1000, start.y + raySlope.dy * 1000, zpos, NOKEY);
|
||||
|
||||
lines.push([p1,p2]);
|
||||
|
|
@ -655,13 +673,13 @@ var gs_base_polygons = exports;
|
|||
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) {
|
||||
ctre.m_AllPolys.forEach(function(poly) {
|
||||
if (minlen || maxlen) {
|
||||
var plen = clib.JS.PerimeterOfPath(poly.m_polygon, false, 1);
|
||||
let plen = clib.JS.PerimeterOfPath(poly.m_polygon, false, 1);
|
||||
if (minlen && plen < minlen) return;
|
||||
if (maxlen && plen > maxlen) return;
|
||||
}
|
||||
var p1 = newPoint(null,null,zpos,null,poly.m_polygon[0]);
|
||||
var p2 = newPoint(null,null,zpos,null,poly.m_polygon[1]);
|
||||
var od = rayint.origin.distToLineNew(p1,p2) / spacing;
|
||||
let p1 = newPoint(null,null,zpos,null,poly.m_polygon[0]);
|
||||
let p2 = newPoint(null,null,zpos,null,poly.m_polygon[1]);
|
||||
let od = rayint.origin.distToLineNew(p1,p2) / spacing;
|
||||
lines.push([p1, p2, od]);
|
||||
});
|
||||
}
|
||||
|
|
@ -671,7 +689,7 @@ var gs_base_polygons = exports;
|
|||
})
|
||||
|
||||
lines.forEach(function(line) {
|
||||
var dist = Math.round(line[2]);
|
||||
let dist = Math.round(line[2]);
|
||||
line[0].index = dist;
|
||||
line[1].index = dist;
|
||||
rayint.push(line[0]);
|
||||
|
|
@ -692,7 +710,7 @@ var gs_base_polygons = exports;
|
|||
* @returns {Point[]}
|
||||
*/
|
||||
function rayIntersect(start, slope, polygons, for_fill) {
|
||||
var i = 0,
|
||||
let i = 0,
|
||||
flat = [],
|
||||
points = [],
|
||||
conf = BASE.config,
|
||||
|
|
@ -703,13 +721,13 @@ var gs_base_polygons = exports;
|
|||
});
|
||||
polygons = flat;
|
||||
while (i < polygons.length) {
|
||||
var polygon = polygons[i++],
|
||||
let polygon = polygons[i++],
|
||||
pp = polygon.points,
|
||||
pl = pp.length,
|
||||
dbug = BASE.debug,
|
||||
debug = false;
|
||||
for (var j = 0; j < pl; j++) {
|
||||
var j2 = (j + 1) % pl,
|
||||
for (let j = 0; j < pl; j++) {
|
||||
let j2 = (j + 1) % pl,
|
||||
ip = UTIL.intersectRayLine(start, slope, pp[j], pp[j2]);
|
||||
if (ip) {
|
||||
// add group object to point for cull detection
|
||||
|
|
@ -732,12 +750,12 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
}
|
||||
if (points.length > 0) {
|
||||
var del = false;
|
||||
let del = false;
|
||||
// sort on distance from ray origin
|
||||
points.sort(function (p1, p2) {
|
||||
// handle passing through line-common end points
|
||||
if (!(p1.del || p2.del) && p1.isNear(p2, merge_dist)) {
|
||||
var line = [];
|
||||
let line = [];
|
||||
if (!p1.isNear(p1.p1, merge_dist)) line.push(p1.p1);
|
||||
if (!p1.isNear(p1.p2, merge_dist)) line.push(p1.p2);
|
||||
if (!p2.isNear(p2.p1, merge_dist)) line.push(p2.p1);
|
||||
|
|
@ -780,7 +798,7 @@ var gs_base_polygons = exports;
|
|||
* ok = diff level (even-odd)
|
||||
*/
|
||||
if (for_fill) {
|
||||
var p1, p2;
|
||||
let p1, p2;
|
||||
i = 0;
|
||||
pl = points.length;
|
||||
while (i < pl) {
|
||||
|
|
@ -789,7 +807,7 @@ var gs_base_polygons = exports;
|
|||
p2 = points[i++];
|
||||
while (p2 && p2.del && i < pl) p2 = points[i++];
|
||||
if (p1 && p2 && p1.group && p1.group) {
|
||||
var p1g = p1.group,
|
||||
let p1g = p1.group,
|
||||
p2g = p2.group,
|
||||
even = (p1g.depth % 2 === 0), // point is on an even depth group
|
||||
same = (p1g === p2g); // points intersect same group
|
||||
|
|
@ -803,7 +821,7 @@ var gs_base_polygons = exports;
|
|||
//}
|
||||
// check cull co-linear with group edge
|
||||
if (same && p1.mod && p2.mod) {
|
||||
var diff = ABS(p1.pos - p2.pos);
|
||||
let diff = ABS(p1.pos - p2.pos);
|
||||
if (diff === 1 || diff === p1.mod - 1) {
|
||||
p1.del = true;
|
||||
p2.del = true;
|
||||
|
|
@ -817,9 +835,9 @@ var gs_base_polygons = exports;
|
|||
}
|
||||
// handle deletions, if found
|
||||
if (del) {
|
||||
var np = [];
|
||||
let np = [];
|
||||
for (i = 0; i < points.length; i++) {
|
||||
var p = points[i];
|
||||
let p = points[i];
|
||||
if (!p.del) {
|
||||
np.push(p);
|
||||
}
|
||||
|
|
@ -1,17 +1,15 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_render = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.render) return;
|
||||
|
||||
var BASE = self.base,
|
||||
line_width = 1,
|
||||
materialCache = {};
|
||||
const BASE = self.base,
|
||||
materialCache = {},
|
||||
line_width = 1;
|
||||
|
||||
BASE.render = {
|
||||
wireframe : wireframe
|
||||
|
|
@ -32,11 +30,11 @@ var gs_base_render = exports;
|
|||
*/
|
||||
function wireframe(group, points, color) {
|
||||
if (points.length % 3 != 0) throw "invalid line : "+points.length;
|
||||
var lines = new THREE.Geometry(),
|
||||
let lines = new THREE.Geometry(),
|
||||
hash = {},
|
||||
added = 0;
|
||||
for (var i = 0; i < points.length; i += 3) {
|
||||
var p1 = points[i],
|
||||
for (let i = 0; i < points.length; i += 3) {
|
||||
let p1 = points[i],
|
||||
p2 = points[i + 1],
|
||||
p3 = points[i + 2],
|
||||
l1 = newOrderedLine(p1, p2),
|
||||
|
|
@ -59,7 +57,7 @@ var gs_base_render = exports;
|
|||
}
|
||||
}
|
||||
lines.verticesNeedUpdate = true;
|
||||
var mesh = new THREE.LineSegments(lines, getMaterial(color));
|
||||
let mesh = new THREE.LineSegments(lines, getMaterial(color));
|
||||
group.add(mesh);
|
||||
return mesh;
|
||||
}
|
||||
|
|
@ -73,7 +71,7 @@ var gs_base_render = exports;
|
|||
* @returns {THREE.LineBasicMaterial}
|
||||
*/
|
||||
function getMaterial(color) {
|
||||
var material = materialCache[color];
|
||||
let material = materialCache[color];
|
||||
if (!material) {
|
||||
material = new THREE.LineBasicMaterial({
|
||||
fog:false,
|
||||
|
|
@ -1,14 +1,27 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_base_slope = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.base) self.base = {};
|
||||
if (self.base.Slope) return;
|
||||
|
||||
const BASE = self.base,
|
||||
CONF = BASE.config,
|
||||
ABS = Math.abs,
|
||||
PRO = Slope.prototype,
|
||||
DEG2RAD = Math.PI / 180,
|
||||
RAD2DEG = 180 / Math.PI;
|
||||
|
||||
BASE.Slope = Slope;
|
||||
BASE.newSlope = newSlope;
|
||||
BASE.newSlopeFromAngle = function(angle) {
|
||||
return newSlope(0,0,
|
||||
Math.cos(angle * DEG2RAD),
|
||||
Math.sin(angle * DEG2RAD)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param p1
|
||||
|
|
@ -23,23 +36,6 @@ var gs_base_slope = exports;
|
|||
this.angle = Math.atan2(this.dy, this.dx) * RAD2DEG;
|
||||
}
|
||||
|
||||
var BASE = self.base,
|
||||
CONF = BASE.config,
|
||||
ABS = Math.abs,
|
||||
PRO = Slope.prototype,
|
||||
DEG2RAD = Math.PI / 180,
|
||||
RAD2DEG = 180 / Math.PI;
|
||||
|
||||
BASE.Slope = Slope;
|
||||
BASE.newSlope = newSlope;
|
||||
|
||||
BASE.newSlopeFromAngle = function(angle) {
|
||||
return newSlope(0,0,
|
||||
Math.cos(angle * DEG2RAD),
|
||||
Math.sin(angle * DEG2RAD)
|
||||
);
|
||||
};
|
||||
|
||||
/** ******************************************************************
|
||||
* Slope Prototype Functions
|
||||
******************************************************************* */
|
||||
|
|
@ -57,7 +53,7 @@ var gs_base_slope = exports;
|
|||
if (ABS(this.dx) <= CONF.precision_merge && ABS(s.dx) <= CONF.precision_merge) return true;
|
||||
if (ABS(this.dy) <= CONF.precision_merge && ABS(s.dy) <= CONF.precision_merge) return true;
|
||||
// check angle within a range
|
||||
var prec = Math.min(1/Math.sqrt(this.dx * this.dx + this.dy * this.dy), CONF.precision_slope_merge);
|
||||
let prec = Math.min(1/Math.sqrt(this.dx * this.dx + this.dy * this.dy), CONF.precision_slope_merge);
|
||||
return angleWithinDelta(this.angle, s.angle, prec || CONF.precision_slope);
|
||||
};
|
||||
|
||||
|
|
@ -67,7 +63,7 @@ var gs_base_slope = exports;
|
|||
* @returns {Slope}
|
||||
*/
|
||||
PRO.normal = function() {
|
||||
var t = this.dx;
|
||||
let t = this.dx;
|
||||
this.dx = -this.dy;
|
||||
this.dy = t;
|
||||
this.angle = Math.atan2(this.dy, this.dx) * RAD2DEG;
|
||||
|
|
@ -75,7 +71,7 @@ var gs_base_slope = exports;
|
|||
};
|
||||
|
||||
PRO.toUnit = function() {
|
||||
var max = Math.max(ABS(this.dx), ABS(this.dy));
|
||||
let max = Math.max(ABS(this.dx), ABS(this.dy));
|
||||
this.dx = this.dx / max;
|
||||
this.dy = this.dy / max;
|
||||
return this;
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_wasm = exports;
|
||||
|
||||
// only active in workers
|
||||
if (!self.window)
|
||||
(function() {
|
||||
if (!self.window) (function() {
|
||||
|
||||
if (!self.geo) self.geo = {};
|
||||
|
||||
3
src/ico/cnc.svg
Normal file
3
src/ico/cnc.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 170 170" width="75px" height="75px"><defs><path d="M15 38.33C15 38.33 15 38.33 15 38.33C15 25.45 25.45 15 38.33 15C44.56 15 75.67 15 131.67 15C131.67 15 131.67 15 131.67 15C137.85 15 143.79 17.46 148.17 21.83C152.54 26.21 155 32.15 155 38.33C155 47.67 155 122.33 155 131.67C155 144.55 144.55 155 131.67 155C122.33 155 47.67 155 38.33 155C25.45 155 15 144.55 15 131.67C15 119.22 15 88.11 15 38.33Z" id="e3irHaXr4"></path><path d="M65 15L105 15L105 125L65 125L65 15Z" id="c1YkLol10d"></path><path d="M105 25L65 55" id="b4hxjCK1zy"></path><path d="M105 55L65 85" id="apUaV8mZu"></path><path d="M105 85L65 115" id="bk21dIqOq"></path></defs><g><g><g><g><use xlink:href="#e3irHaXr4" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#e3irHaXr4" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#c1YkLol10d" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#c1YkLol10d" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#b4hxjCK1zy" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#apUaV8mZu" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#bk21dIqOq" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
3
src/ico/fdm.svg
Normal file
3
src/ico/fdm.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 170 170" width="75px" height="75px"><defs><path d="M15 38.33C15 38.33 15 38.33 15 38.33C15 25.45 25.45 15 38.33 15C44.56 15 75.67 15 131.67 15C131.67 15 131.67 15 131.67 15C137.85 15 143.79 17.46 148.17 21.83C152.54 26.21 155 32.15 155 38.33C155 47.67 155 122.33 155 131.67C155 144.55 144.55 155 131.67 155C122.33 155 47.67 155 38.33 155C25.45 155 15 144.55 15 131.67C15 119.22 15 88.11 15 38.33Z" id="a14Galv9UF"></path><path d="M45 15L125 15L125 75L45 75L45 15Z" id="c3q839LU3"></path><path d="M35 141.48C53.11 141.48 64.43 141.48 68.96 141.48C77.82 141.48 85 134.3 85 125.45C85 125.45 85 125.45 85 125.45" id="chE0t1xfL"></path><path d="M105 95L85 115L65 95L105 95Z" id="a6K998F3GT"></path><path d="M75 75L95 75L95 95L75 95L75 75Z" id="e1iiMERqAh"></path></defs><g><g><g><g><use xlink:href="#a14Galv9UF" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#a14Galv9UF" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#c3q839LU3" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#c3q839LU3" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#chE0t1xfL" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#a6K998F3GT" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><use xlink:href="#e1iiMERqAh" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#e1iiMERqAh" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2 KiB |
3
src/ico/laser.svg
Normal file
3
src/ico/laser.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 170 170" width="75px" height="75px"><defs><path d="M15 38.33C15 38.33 15 38.33 15 38.33C15 25.45 25.45 15 38.33 15C44.56 15 75.67 15 131.67 15C131.67 15 131.67 15 131.67 15C137.85 15 143.79 17.46 148.17 21.83C152.54 26.21 155 32.15 155 38.33C155 47.67 155 122.33 155 131.67C155 144.55 144.55 155 131.67 155C122.33 155 47.67 155 38.33 155C25.45 155 15 144.55 15 131.67C15 119.22 15 88.11 15 38.33Z" id="a4l00mnEny"></path><path d="M65 15L105 15L105 55L65 55L65 15Z" id="bq8oBWrfG"></path><path d="M85 125L85 65" id="aXzHtGbsD"></path><path d="M55 105L75 135" id="akSzh0QKx"></path><path d="M115 105L95 135" id="bloAs9giZ"></path><path d="M35 125L75 145" id="gk6ohj0JL"></path><path d="M135 123.96L95 145" id="e404eoj7L"></path></defs><g><g><g><g><use xlink:href="#a4l00mnEny" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#a4l00mnEny" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#bq8oBWrfG" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#bq8oBWrfG" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#aXzHtGbsD" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#akSzh0QKx" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#bloAs9giZ" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#gk6ohj0JL" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#e404eoj7L" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8.01" stroke-opacity="1"></use></g></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
3
src/ico/sla.svg
Normal file
3
src/ico/sla.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 170 170" width="75px" height="75px"><defs><path d="M15 38.33C15 38.33 15 38.33 15 38.33C15 25.45 25.45 15 38.33 15C44.56 15 75.67 15 131.67 15C131.67 15 131.67 15 131.67 15C137.85 15 143.79 17.46 148.17 21.83C152.54 26.21 155 32.15 155 38.33C155 47.67 155 122.33 155 131.67C155 144.55 144.55 155 131.67 155C122.33 155 47.67 155 38.33 155C25.45 155 15 144.55 15 131.67C15 119.22 15 88.11 15 38.33Z" id="b3TRNHybxX"></path><path d="M31.88 42.5L138.12 42.5L138.12 47.81L31.88 47.81L31.88 42.5Z" id="aNMkzLwb"></path><path d="M75 21.87L95 21.87L95 41.88L75 41.88L75 21.87Z" id="d1fKKg2Jru"></path><path d="M115.93 107.19C115.93 124.27 102.07 138.13 85 138.13C67.93 138.13 54.07 124.27 54.07 107.19C54.07 90.12 67.93 76.26 85 76.26C102.07 76.26 115.93 90.12 115.93 107.19Z" id="cnyrcTQMg"></path><path d="M53.87 47.81L53.87 107.08" id="a4G9Rr6VQL"></path><path d="M115.76 51.27L115.76 110.53" id="d4hytySQxZ"></path><path d="M69.06 79.69L69.06 47.81" id="b1WQ83ELAA"></path><path d="M100.94 79.69L100.94 47.81" id="f2kNHslaLa"></path><path d="M69.06 58.44L53.13 74.38" id="g67vFJwAFy"></path><path d="M114.68 58.44L100.94 69.06" id="aAcp3z5Kv"></path></defs><g><g><g><use xlink:href="#b3TRNHybxX" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#b3TRNHybxX" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#aNMkzLwb" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#aNMkzLwb" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#d1fKKg2Jru" opacity="1" fill="#000000" fill-opacity="0"></use><g><use xlink:href="#d1fKKg2Jru" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><use xlink:href="#cnyrcTQMg" opacity="1" fill="#1ea5e6" fill-opacity="0"></use><g><use xlink:href="#cnyrcTQMg" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#a4G9Rr6VQL" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#d4hytySQxZ" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#b1WQ83ELAA" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#f2kNHslaLa" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="8" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#g67vFJwAFy" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="6" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#aAcp3z5Kv" opacity="1" fill-opacity="0" stroke="currentColor" stroke-width="6" stroke-opacity="1"></use></g></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
11
src/kiri.js
Normal file
11
src/kiri.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
(function () {
|
||||
|
||||
if (self.kiri) return;
|
||||
|
||||
self.kiri = { };
|
||||
|
||||
})();
|
||||
|
|
@ -1,19 +1,14 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_kiri_codec = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.codec) return;
|
||||
|
||||
var base = self.base,
|
||||
kiri = self.kiri,
|
||||
handlers = {};
|
||||
const BASE = self.base, KIRI = self.kiri, handlers = {};
|
||||
|
||||
kiri.codec = {
|
||||
KIRI.codec = {
|
||||
encode: encode,
|
||||
decode: decode,
|
||||
registerDecoder: registerDecoder
|
||||
|
|
@ -24,7 +19,7 @@ var gs_kiri_codec = exports;
|
|||
if (o === null) return null;
|
||||
if (o === undefined) return undefined;
|
||||
if (Array.isArray(o)) {
|
||||
var arr = new Array(o.length), i=0;
|
||||
let arr = new Array(o.length), i=0;
|
||||
while (i < o.length) arr[i] = encode(o[i++], state);
|
||||
return arr;
|
||||
}
|
||||
|
|
@ -44,7 +39,7 @@ var gs_kiri_codec = exports;
|
|||
if (o === null) return null;
|
||||
if (o === undefined) return undefined;
|
||||
if (Array.isArray(o)) {
|
||||
for (var i=0; i < o.length; i++) o[i] = decode(o[i],state);
|
||||
for (let i=0; i < o.length; i++) o[i] = decode(o[i],state);
|
||||
return o;
|
||||
}
|
||||
switch (typeof(o)) {
|
||||
|
|
@ -64,8 +59,8 @@ var gs_kiri_codec = exports;
|
|||
|
||||
function genOEncode(o, state) {
|
||||
if (o instanceof Float32Array) return o;
|
||||
var out = {};
|
||||
for (var k in o) {
|
||||
let out = {};
|
||||
for (let k in o) {
|
||||
if (o.hasOwnProperty(k)) out[k] = encode(o[k], state);
|
||||
}
|
||||
return out;
|
||||
|
|
@ -73,8 +68,8 @@ var gs_kiri_codec = exports;
|
|||
|
||||
function genODecode(o, state) {
|
||||
if (o instanceof Float32Array) return o;
|
||||
var out = {};
|
||||
for (var k in o) {
|
||||
let out = {};
|
||||
for (let k in o) {
|
||||
if (o.hasOwnProperty(k)) out[k] = decode(o[k], state);
|
||||
}
|
||||
return out;
|
||||
|
|
@ -84,7 +79,7 @@ var gs_kiri_codec = exports;
|
|||
* Object CODEC Functions
|
||||
******************************************************************* */
|
||||
|
||||
kiri.Slice.prototype.encode = function(state) {
|
||||
KIRI.Slice.prototype.encode = function(state) {
|
||||
return {
|
||||
type: 'slice',
|
||||
z: this.z,
|
||||
|
|
@ -100,7 +95,7 @@ var gs_kiri_codec = exports;
|
|||
};
|
||||
|
||||
registerDecoder('slice', function(v, state) {
|
||||
var slice = kiri.newSlice(v.z, state.mesh ? state.mesh.newGroup() : null);
|
||||
let slice = KIRI.newSlice(v.z, state.mesh ? state.mesh.newGroup() : null);
|
||||
|
||||
slice.index = v.index;
|
||||
slice.camMode = v.camMode;
|
||||
|
|
@ -114,7 +109,7 @@ var gs_kiri_codec = exports;
|
|||
return slice;
|
||||
});
|
||||
|
||||
kiri.Top.prototype.encode = function(state) {
|
||||
KIRI.Top.prototype.encode = function(state) {
|
||||
return {
|
||||
type: 'top',
|
||||
poly: encode(this.poly, state),
|
||||
|
|
@ -129,7 +124,7 @@ var gs_kiri_codec = exports;
|
|||
};
|
||||
|
||||
registerDecoder('top', function(v, state) {
|
||||
var top = kiri.newTop(decode(v.poly, state));
|
||||
let top = KIRI.newTop(decode(v.poly, state));
|
||||
|
||||
top.traces = decode(v.traces, state);
|
||||
top.inner = decode(v.inner, state);
|
||||
|
|
@ -145,7 +140,7 @@ var gs_kiri_codec = exports;
|
|||
function encodePointArray(points, state) {
|
||||
if (!points) return null;
|
||||
|
||||
var array = new Float32Array(points.length * 3),
|
||||
let array = new Float32Array(points.length * 3),
|
||||
pos = 0;
|
||||
|
||||
points.forEach(function(point) {
|
||||
|
|
@ -174,21 +169,21 @@ var gs_kiri_codec = exports;
|
|||
function decodePointArray(array) {
|
||||
if (!array) return null;
|
||||
|
||||
var vid = 0,
|
||||
let vid = 0,
|
||||
pid = 0,
|
||||
points = new Array(array.length/3);
|
||||
|
||||
while (vid < array.length) {
|
||||
points[pid++] = base.newPoint(array[vid++], array[vid++], array[vid++]);
|
||||
points[pid++] = BASE.newPoint(array[vid++], array[vid++], array[vid++]);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
base.Polygon.prototype.encode = function(state) {
|
||||
BASE.Polygon.prototype.encode = function(state) {
|
||||
if (!state.poly) state.poly = {};
|
||||
|
||||
var cached = state.poly[this.id];
|
||||
let cached = state.poly[this.id];
|
||||
|
||||
if (cached) {
|
||||
return {
|
||||
|
|
@ -216,11 +211,11 @@ var gs_kiri_codec = exports;
|
|||
|
||||
if (v.ref) return state.poly[v.ref];
|
||||
|
||||
var poly = base.newPolygon(),
|
||||
let poly = BASE.newPolygon(),
|
||||
vid = 0;
|
||||
|
||||
while (vid < v.array.length) {
|
||||
poly.push(base.newPoint(v.array[vid++], v.array[vid++], v.array[vid++]));
|
||||
poly.push(BASE.newPoint(v.array[vid++], v.array[vid++], v.array[vid++]));
|
||||
}
|
||||
|
||||
poly.id = v.id;
|
||||
|
|
@ -1,17 +1,12 @@
|
|||
/** Copyright Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_conf = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.conf) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
CVER = 185,
|
||||
clone = Object.clone;
|
||||
const KIRI = self.kiri, CVER = 185, clone = Object.clone;
|
||||
|
||||
function genID() {
|
||||
while (true) {
|
||||
|
|
@ -352,6 +347,7 @@ let gs_kiri_conf = exports;
|
|||
p:{
|
||||
processName: "default",
|
||||
camFastFeed: 6000,
|
||||
camFastFeedZ: 300,
|
||||
roughingTool: 1000,
|
||||
roughingSpindle: 1000,
|
||||
roughingDown: 2,
|
||||
|
|
@ -542,14 +538,17 @@ let gs_kiri_conf = exports;
|
|||
view: null,
|
||||
dark: false,
|
||||
expert: false,
|
||||
compact: false,
|
||||
zoomSpeed: 1.0,
|
||||
thinRender: false,
|
||||
reverseZoom: true,
|
||||
showOrigin: false,
|
||||
freeLayout: true,
|
||||
autoLayout: true,
|
||||
alignTop: true,
|
||||
units: "mm"
|
||||
units: "mm",
|
||||
exportOcto: true,
|
||||
exportGhost: false,
|
||||
exportLocal: false
|
||||
},
|
||||
// for passing temporary slice hints (topo currently)
|
||||
synth: {},
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_kiri_db = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = { };
|
||||
const KIRI = self.kiri, DP = Catalog.prototype;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Catalog(motodb, decimate) {
|
||||
var store = this;
|
||||
let store = this;
|
||||
store.db = motodb;
|
||||
store.files = {};
|
||||
store.listeners = [];
|
||||
|
|
@ -21,15 +19,12 @@ var gs_kiri_db = exports;
|
|||
store.refresh();
|
||||
}
|
||||
|
||||
var kiri = self.kiri,
|
||||
DP = Catalog.prototype;
|
||||
|
||||
kiri.openCatalog = function(motodb,decimate) {
|
||||
KIRI.openCatalog = function(motodb,decimate) {
|
||||
return new Catalog(motodb,decimate);
|
||||
};
|
||||
|
||||
DP.refresh = function() {
|
||||
var store = this;
|
||||
let store = this;
|
||||
store.db.get('files', function(files) {
|
||||
if (files) {
|
||||
store.files = files;
|
||||
|
|
@ -39,7 +34,7 @@ var gs_kiri_db = exports;
|
|||
};
|
||||
|
||||
DP.wipe = function() {
|
||||
var key, files = this.files;
|
||||
let key, files = this.files;
|
||||
for (key in files) {
|
||||
if (files.hasOwnProperty(key)) this.deleteFile(key);
|
||||
}
|
||||
|
|
@ -66,14 +61,14 @@ var gs_kiri_db = exports;
|
|||
}
|
||||
|
||||
function notifyFileListeners(store) {
|
||||
for (var i=0; i<store.listeners.length; i++) {
|
||||
for (let i=0; i<store.listeners.length; i++) {
|
||||
store.listeners[i](store.files);
|
||||
}
|
||||
}
|
||||
|
||||
DP.decimate = function(vertices, callback) {
|
||||
if (vertices.length < 500000) return callback(vertices);
|
||||
kiri.work.decimate(vertices, function(reply) {
|
||||
KIRI.work.decimate(vertices, function(reply) {
|
||||
callback(reply);
|
||||
});
|
||||
};
|
||||
|
|
@ -96,7 +91,7 @@ var gs_kiri_db = exports;
|
|||
* @param {Function} [callback]
|
||||
*/
|
||||
DP.putFile = function(name, vertices, callback) {
|
||||
var store = this;
|
||||
let store = this;
|
||||
store.db.put('file-'+name, vertices, function(ok) {
|
||||
if (ok) {
|
||||
store.files[name] = {
|
||||
|
|
@ -114,12 +109,39 @@ var gs_kiri_db = exports;
|
|||
});
|
||||
};
|
||||
|
||||
DP.rename = function(name, newname, callback) {
|
||||
if (!this.files[name]) return callback({error: 'no such file'});
|
||||
if (!newname || newname == name) return callback({error: 'invalid new name'});
|
||||
let done = 0;
|
||||
let error = [];
|
||||
let store = this;
|
||||
function complete(ok, err) {
|
||||
if (err) error.push(err);
|
||||
if (++done === 2) {
|
||||
store.files[newname] = store.files[name];
|
||||
delete store.files[name];
|
||||
saveFileList(store);
|
||||
store.db.remove(`fdec-${name}`);
|
||||
store.db.remove(`file-${name}`);
|
||||
callback(error.length ? {error} : {});
|
||||
}
|
||||
}
|
||||
store.db.get(`fdec-${name}`, (vertices) => {
|
||||
if (!vertices) return complete(false, 'no decimation');
|
||||
store.db.put(`fdec-${newname}`, vertices, complete);
|
||||
});
|
||||
store.db.get(`file-${name}`, (vertices) => {
|
||||
if (!vertices) return complete(false, 'no raw file');
|
||||
store.db.put(`file-${newname}`, vertices, complete);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {Function} callback
|
||||
*/
|
||||
DP.getFile = function(name, callback) {
|
||||
var store = this,
|
||||
let store = this,
|
||||
rec = store.files[name];
|
||||
if (rec && rec.deferred) {
|
||||
if (store.deferredHandler) return store.deferredHandler(rec.deferred, name, callback);
|
||||
|
|
@ -152,7 +174,7 @@ var gs_kiri_db = exports;
|
|||
* @param {Function} callback
|
||||
*/
|
||||
DP.deleteFile = function(name, callback) {
|
||||
var store = this;
|
||||
let store = this;
|
||||
if (store.files[name]) {
|
||||
delete store.files[name];
|
||||
store.db.remove('fdec-'+name);
|
||||
|
|
@ -1,26 +1,24 @@
|
|||
/** Copyright Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_export = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = { };
|
||||
if (self.kiri.export) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
API = KIRI.api,
|
||||
SDB = API.sdb,
|
||||
UI = API.ui,
|
||||
STATS = API.stats,
|
||||
MODES = API.const.MODES,
|
||||
printSeq = parseInt(SDB['kiri-print-seq'] || SDB['print-seq'] || "0") + 1;
|
||||
MODES = API.const.MODES;
|
||||
|
||||
KIRI.export = exportPrint;
|
||||
|
||||
let printSeq = parseInt(SDB['kiri-print-seq'] || SDB['print-seq'] || "0") + 1;
|
||||
|
||||
function exportPrint() {
|
||||
let currentPrint = API.print.get();
|
||||
if (currentPrint) {
|
||||
|
|
@ -56,8 +54,12 @@ let gs_kiri_export = exports;
|
|||
}
|
||||
segment = line.message;
|
||||
}
|
||||
if (line.progress) API.show.progress(line.progress, "exporting");
|
||||
if (line.data) lines.push(line.data);
|
||||
if (line.progress) {
|
||||
API.show.progress(line.progress, "exporting");
|
||||
}
|
||||
if (line.data) {
|
||||
lines.push(line.data);
|
||||
}
|
||||
}, function(done) {
|
||||
currentPrint.exported = true;
|
||||
times[`${seq++}_${segment}`] = Date.now() - mark;
|
||||
|
|
@ -115,7 +117,6 @@ let gs_kiri_export = exports;
|
|||
UI.print.innerHTML = html;
|
||||
$('print-filename').value = filename;
|
||||
$('print-lines').value = UTIL.comma(segments);
|
||||
$('print-close').onclick = API.modal.hide;
|
||||
$('print-svg').onclick = download_svg;
|
||||
$('print-dxf').onclick = download_dxf;
|
||||
$('print-lg').onclick = download_gcode;
|
||||
|
|
@ -183,6 +184,7 @@ let gs_kiri_export = exports;
|
|||
} else {
|
||||
API.show.alert("octoprint error\nstatus: "+status+"\nmessage: "+ajax.responseText);
|
||||
}
|
||||
API.show.progress(0);
|
||||
}
|
||||
API.show.progress(0);
|
||||
};
|
||||
|
|
@ -216,7 +218,15 @@ let gs_kiri_export = exports;
|
|||
let dev = devs[uuid];
|
||||
html.push(`<option id="gl-${uuid}" value="${uuid}">${dev.stat.device.name}</option>`);
|
||||
}
|
||||
$('grid-local').innerHTML = html.join('\n');
|
||||
|
||||
if (html.length) {
|
||||
$('grid-local').innerHTML = html.join('\n');
|
||||
$('send-to-gridhead').style.display = 'flex';
|
||||
$('send-to-gridspool').style.display = 'flex';
|
||||
} else {
|
||||
$('send-to-gridhead').style.display = '';
|
||||
$('send-to-gridspool').style.display = '';
|
||||
}
|
||||
}
|
||||
|
||||
function sendto_gridlocal() {
|
||||
|
|
@ -415,54 +425,78 @@ let gs_kiri_export = exports;
|
|||
mins = floor(newtime / 60),
|
||||
secs = newtime - mins * 60;
|
||||
|
||||
$('mill-time').value = $('print-time').value = [pad(hours),pad(mins),pad(secs)].join(':');
|
||||
$('output-time').value = [pad(hours),pad(mins),pad(secs)].join(':');
|
||||
}
|
||||
|
||||
API.ajax("/kiri/output-gcode.html", function(html) {
|
||||
fetch("/kiri/output-gcode.html").then(r => r.text()).then(html => {
|
||||
UI.print.innerHTML = html;
|
||||
$('print-close').onclick = API.modal.hide;
|
||||
let set = API.conf.get();
|
||||
let fdm = MODE === MODES.FDM;
|
||||
let octo = set.controller.exportOcto && MODE !== MODES.CAM;
|
||||
let ghost = set.controller.exportGhost;
|
||||
let local = set.controller.exportLocal;
|
||||
$('print-download').onclick = download;
|
||||
$('print-octoprint').onclick = sendto_octoprint;
|
||||
$('print-gridhost').onclick = sendto_gridhost;
|
||||
$('print-gridlocal').onclick = sendto_gridlocal;
|
||||
$('admin-gridlocal').onclick = admin_gridlocal;
|
||||
$('print-filament-row').style.display = MODE === MODES.FDM ? '' : 'none';
|
||||
$('mill-info').style.display = MODE === MODES.CAM ? '' : 'none';
|
||||
$('print-filament-head').style.display = fdm ? '' : 'none';
|
||||
$('print-filament-info').style.display = fdm ? '' : 'none';
|
||||
$('print-filename').value = filename;
|
||||
$('print-filesize').value = UTIL.comma(currentPrint.bytes);
|
||||
$('print-filament').value = Math.round(currentPrint.distance);
|
||||
$('grid-host').onkeyup = gridhost_probe;
|
||||
$('grid-apik').onkeyup = gridhost_probe;
|
||||
calcTime();
|
||||
if (MODE === MODES.FDM) {
|
||||
if (fdm) {
|
||||
calcWeight();
|
||||
}
|
||||
octo_host = $('octo-host');
|
||||
octo_apik = $('octo-apik');
|
||||
if (MODE === MODES.CAM) {
|
||||
$('send-to-octoprint').style.display = 'none';
|
||||
} else {
|
||||
$('send-to-octoprint').style.display = '';
|
||||
}
|
||||
// hide octoprint when hard-coded in the url
|
||||
if (API.const.OCTO) {
|
||||
$('ophost').style.display = 'none';
|
||||
$('opapik').style.display = 'none';
|
||||
$('ophint').style.display = 'none';
|
||||
$('send-to-gridhost').style.display = 'none';
|
||||
}
|
||||
octo_host.value = SDB['octo-host'] || '';
|
||||
octo_apik.value = SDB['octo-apik'] || '';
|
||||
grid_host = $('grid-host');
|
||||
grid_apik = $('grid-apik');
|
||||
grid_target = $('grid-target');
|
||||
grid_target.onchange = function(ev) {
|
||||
SDB['grid-target'] = grid_targets[grid_target.selectedIndex];
|
||||
};
|
||||
grid_host.value = SDB['grid-host'] || '';
|
||||
grid_apik.value = SDB['grid-apik'] || '';
|
||||
gridhost_probe();
|
||||
gridlocal_probe();
|
||||
|
||||
// octoprint setup
|
||||
$('send-to-octohead').style.display = octo ? '' : 'none';
|
||||
$('send-to-octoprint').style.display = octo ? '' : 'none';
|
||||
if (octo) try {
|
||||
$('print-octoprint').onclick = sendto_octoprint;
|
||||
octo_host = $('octo-host');
|
||||
octo_apik = $('octo-apik');
|
||||
if (MODE === MODES.CAM) {
|
||||
$('send-to-octohead').style.display = 'none';
|
||||
$('send-to-octoprint').style.display = 'none';
|
||||
} else {
|
||||
$('send-to-octohead').style.display = '';
|
||||
$('send-to-octoprint').style.display = '';
|
||||
}
|
||||
// hide octoprint when hard-coded in the url
|
||||
if (API.const.OCTO) {
|
||||
$('ophost').style.display = 'none';
|
||||
$('opapik').style.display = 'none';
|
||||
$('ophint').style.display = 'none';
|
||||
$('send-to-gridhost').style.display = 'none';
|
||||
}
|
||||
octo_host.value = SDB['octo-host'] || '';
|
||||
octo_apik.value = SDB['octo-apik'] || '';
|
||||
} catch (e) { console.log(e) }
|
||||
|
||||
// grid:host setup
|
||||
$('send-to-hosthead').style.display = ghost ? '' : 'none';
|
||||
$('send-to-gridhost').style.display = ghost ? '' : 'none';
|
||||
if (ghost) try {
|
||||
$('print-gridhost').onclick = sendto_gridhost;
|
||||
$('grid-host').onkeyup = gridhost_probe;
|
||||
$('grid-apik').onkeyup = gridhost_probe;
|
||||
grid_host = $('grid-host');
|
||||
grid_apik = $('grid-apik');
|
||||
grid_target = $('grid-target');
|
||||
grid_target.onchange = function(ev) {
|
||||
SDB['grid-target'] = grid_targets[grid_target.selectedIndex];
|
||||
};
|
||||
grid_host.value = SDB['grid-host'] || '';
|
||||
grid_apik.value = SDB['grid-apik'] || '';
|
||||
gridhost_probe();
|
||||
} catch (e) { console.log(e) }
|
||||
|
||||
// grid:local setup
|
||||
if (local) try {
|
||||
gridlocal_probe();
|
||||
$('print-gridlocal').onclick = sendto_gridlocal;
|
||||
$('admin-gridlocal').onclick = admin_gridlocal;
|
||||
} catch (e) { console.log(e) }
|
||||
|
||||
// show dialog
|
||||
API.modal.show('print');
|
||||
});
|
||||
}
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gs_kiri_fill = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.fill) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
ROUND = UTIL.round,
|
||||
File diff suppressed because it is too large
Load diff
1
src/kiri/lang-en.js
Symbolic link
1
src/kiri/lang-en.js
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../web/kiri/lang/en.js
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_lang = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.lang) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
LANG = self.kiri.lang = { current: {} },
|
||||
lset = navigator.language.toLocaleLowerCase();
|
||||
const KIRI = self.kiri, LANG = self.kiri.lang = { current: {} };
|
||||
|
||||
let lset = navigator.language.toLocaleLowerCase();
|
||||
|
||||
LANG.get = function() {
|
||||
return lset;
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_layer = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.Layer) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
POLY = self.base.polygons,
|
||||
LP = Layer.prototype,
|
||||
mcache = {};
|
||||
|
|
@ -82,30 +79,35 @@ let gs_kiri_layer = exports;
|
|||
this.view = view;
|
||||
this.bycolor = {};
|
||||
this.opacity = 0.15,
|
||||
this.specular = 0x181818,
|
||||
this.shininess = 100,
|
||||
this.specular = 0x181818;
|
||||
this.shininess = 100;
|
||||
this.transparent = true;
|
||||
};
|
||||
|
||||
LP.setOpacity = function(v) {
|
||||
this.opacity = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.setSpecular = function(v) {
|
||||
this.specular = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.setShininess = function(v) {
|
||||
this.shininess = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.setTransparent = function(b) {
|
||||
this.transparent = b;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.setVisible = function(vis) {
|
||||
if (this.group) this.group.visible = vis;
|
||||
if (this.solids) this.solids.visible = vis;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.clear = function() {
|
||||
|
|
@ -117,6 +119,7 @@ let gs_kiri_layer = exports;
|
|||
let ca = this.bycolor[color];
|
||||
if (!ca) ca = this.bycolor[color] = [];
|
||||
ca.push(obj);
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.poly = function(poly, color, deep, open) {
|
||||
|
|
@ -127,14 +130,17 @@ let gs_kiri_layer = exports;
|
|||
this.add(color, {poly:poly, deep:deep, open:open});
|
||||
this.changed = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.solid = function(poly, color) {
|
||||
this.add(color, {solid: poly});
|
||||
this.changed = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.noodle = function(poly, offset, color, traceColor, open) {
|
||||
if (!poly) return;
|
||||
if (Array.isArray(poly)) {
|
||||
poly = POLY.flatten(poly, [], true);
|
||||
} else {
|
||||
|
|
@ -148,11 +154,38 @@ let gs_kiri_layer = exports;
|
|||
POLY.expand([p], -offset, z-0.01, exp, 1);
|
||||
POLY.nest(exp).forEach((p,i) => {
|
||||
this.add(color, {solid: p});
|
||||
p = p.clone(true).setZ(z + 0.01);
|
||||
this.add(traceColor, {poly: p, deep: true, open});
|
||||
this.add(traceColor, {poly: p.clone(true).setZ(z + 0.01), deep: true, open});
|
||||
});
|
||||
})
|
||||
this.changed = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.noodle_open = function(poly, offset, color, traceColor, z) {
|
||||
poly = POLY.expand_lines(poly, offset, z);
|
||||
poly.forEach(p => {
|
||||
this.add(color, {solid: p});
|
||||
this.add(traceColor, {poly: p.clone().setZ(z + 0.01), deep: false, open: false});
|
||||
})
|
||||
this.changed = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.noodle_lines = function(points, offset, color, traceColor, z) {
|
||||
if (!(points && points.length)) return;
|
||||
for (let i=0; i<points.length; i += 2) {
|
||||
let p1 = points[i];
|
||||
let p2 = points[i+1];
|
||||
let l1 = p1.offsetLineTo(p2, offset);
|
||||
let l2 = p2.offsetLineTo(p1, offset);
|
||||
let poly = base.newPolygon().addPoints([
|
||||
l1.p1, l1.p2, l2.p1, l2.p2
|
||||
]);
|
||||
this.add(color, {solid: poly});
|
||||
this.add(traceColor, {poly: poly.clone().setZ(z + 0.01), deep: false, open: false});
|
||||
}
|
||||
this.changed = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.points = function(points, color, size, opacity) {
|
||||
|
|
@ -188,11 +221,13 @@ let gs_kiri_layer = exports;
|
|||
toVector({x:p.x-sz, y:p.y-sz, z:p.z-sz}),
|
||||
], color);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.lines = function(points, color) {
|
||||
this.add(color, {lines:points});
|
||||
this.changed = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
LP.renderAll = function() {
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
/** Copyright Stewart Allen -- All Rights Reserved */
|
||||
"use strict";
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
self.kiri = (self.kiri || {});
|
||||
self.kiri.version = exports.VERSION;
|
||||
self.kiri.license = exports.LICENSE;
|
||||
self.kiri.copyright = exports.COPYRIGHT;
|
||||
"use strict";
|
||||
|
||||
(function () {
|
||||
|
||||
|
|
@ -43,8 +39,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
newWidget = kiri.newWidget,
|
||||
// ---------------
|
||||
UI = {},
|
||||
UC = MOTO.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
|
||||
UC = KIRI.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
|
||||
MODE = MODES.FDM,
|
||||
DRIVER = undefined,
|
||||
onEvent = {},
|
||||
currentPrint = null,
|
||||
selectedMeshes = [],
|
||||
|
|
@ -180,18 +177,17 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
SECURE
|
||||
},
|
||||
var: {
|
||||
layer_at: Infinity,
|
||||
layer_max: 0,
|
||||
layer_range: 0
|
||||
layer_lo: 0,
|
||||
layer_hi: 0,
|
||||
layer_max: 0
|
||||
},
|
||||
device: {
|
||||
get: currentDeviceName,
|
||||
set: undefined // set during init
|
||||
},
|
||||
dialog: {
|
||||
show: showDialog,
|
||||
hide: hideDialog,
|
||||
update: updateDialogLeft
|
||||
show: showModal,
|
||||
hide: hideModal
|
||||
},
|
||||
help: {
|
||||
show: showHelp,
|
||||
|
|
@ -212,7 +208,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
clear: clearWidgetCache
|
||||
},
|
||||
hide: {
|
||||
import: function() { UI.import.style.display = 'none' }
|
||||
import: function() { }
|
||||
},
|
||||
language: KIRI.lang,
|
||||
lists,
|
||||
|
|
@ -262,6 +258,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
view: {
|
||||
get: function() { return viewMode },
|
||||
set: setViewMode,
|
||||
update_slider: updateSlider,
|
||||
update_fields: updateFields,
|
||||
wireframe: toggleWireframe,
|
||||
snapshot: null
|
||||
|
|
@ -466,8 +463,21 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
return Math.max(min,Math.min(max,v));
|
||||
}
|
||||
|
||||
function setVisibleLayer(v) {
|
||||
showSlices(API.var.layer_at = bound(v, 0, API.var.layer_max));
|
||||
function updateSlider() {
|
||||
API.event.emit("slider.set", {
|
||||
start: 1 - (API.var.layer_hi / API.var.layer_max),
|
||||
end: 1 - (API.var.layer_lo / API.var.layer_max)
|
||||
});
|
||||
}
|
||||
|
||||
function setVisibleLayer(h, l) {
|
||||
h = h >= 0 ? h : API.var.layer_hi;
|
||||
l = l >= 0 ? l : API.var.layer_lo;
|
||||
API.var.layer_hi = bound(h, 0, API.var.layer_max);
|
||||
API.var.layer_lo = bound(l, 0, h);
|
||||
API.event.emit("slider.label");
|
||||
updateSlider();
|
||||
showSlices();
|
||||
}
|
||||
|
||||
function meshArray() {
|
||||
|
|
@ -494,9 +504,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
});
|
||||
}
|
||||
|
||||
function forSelectedWidgets(f) {
|
||||
function forSelectedWidgets(f,noauto) {
|
||||
let m = selectedMeshes;
|
||||
if (m.length === 0 && WIDGETS.length === 1) m = [ WIDGETS[0].mesh ];
|
||||
if (m.length === 0 && WIDGETS.length === 1) {
|
||||
m = noauto ? [] : [ WIDGETS[0].mesh ];
|
||||
}
|
||||
m.slice().forEach(function (mesh) { f(mesh.widget) });
|
||||
}
|
||||
|
||||
|
|
@ -520,16 +532,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
});
|
||||
}
|
||||
max = Math.max(0, max - 1);
|
||||
API.var.layer_max = max;
|
||||
if (UI.layerID.convert() > max || API.var.layer_at > max) {
|
||||
API.var.layer_at = max;
|
||||
UI.layerID.value = max;
|
||||
UI.layerSlider.value = API.var.layer_max;
|
||||
}
|
||||
UI.layerSlider.max = max;
|
||||
if (set) {
|
||||
API.var.layer_at = API.var.layer_max;
|
||||
UI.layerSlider.value = API.var.layer_max;
|
||||
API.var.layer_max = UI.sliderMax.innerText = max;
|
||||
if (set || max < API.var.layer_hi) {
|
||||
API.var.layer_hi = API.var.layer_max;
|
||||
API.event.emit("slider.label");
|
||||
updateSlider();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -544,85 +551,69 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
return showing;
|
||||
}
|
||||
|
||||
function showSlice(index, range, layer) {
|
||||
if (range) {
|
||||
return index <= layer && index > layer-range;
|
||||
} else {
|
||||
return index <= layer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hide or show slice-layers and their sub-elements
|
||||
*
|
||||
* @param {number} [layer]
|
||||
*/
|
||||
function showSlices(layer) {
|
||||
if (viewMode === VIEWS.ARRANGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
showSlider();
|
||||
|
||||
if (typeof(layer) === 'string' || typeof(layer) === 'number') {
|
||||
layer = parseInt(layer);
|
||||
} else {
|
||||
layer = API.var.layer_at;
|
||||
layer = API.var.layer_hi;
|
||||
}
|
||||
|
||||
layer = bound(layer, 0, API.var.layer_max);
|
||||
API.var.layer_hi = layer;
|
||||
API.event.emit("slider.label");
|
||||
|
||||
UI.layerID.value = layer;
|
||||
UI.layerSlider.value = layer;
|
||||
let print = UI.layerPrint.checked,
|
||||
moves = UI.layerMoves.checked,
|
||||
cam = MODE === MODES.CAM,
|
||||
hi = cam ? API.var.layer_max - API.var.layer_lo : API.var.layer_hi,
|
||||
lo = cam ? API.var.layer_max - API.var.layer_hi : API.var.layer_lo;
|
||||
|
||||
let j,
|
||||
slice,
|
||||
slices,
|
||||
layers,
|
||||
range = UI.layerRange.checked ? UI.layerSpan.convert() || 1 : 0,
|
||||
print = UI.layerPrint.checked,
|
||||
moves = UI.layerMoves.checked;
|
||||
|
||||
if (MODE === MODES.CAM && API.var.layer_range !== range && range && layer === API.var.layer_max) {
|
||||
layer = 0;
|
||||
}
|
||||
|
||||
API.var.layer_range = range;
|
||||
API.var.layer_at = layer;
|
||||
updateSlider();
|
||||
|
||||
forAllWidgets(function(widget) {
|
||||
if (print) return widget.hideSlices();
|
||||
|
||||
slices = widget.slices;
|
||||
let slices = widget.slices;
|
||||
if (!slices) return;
|
||||
|
||||
for (j = 0; j < slices.length; j++) {
|
||||
slice = slices[j];
|
||||
slice.view.visible = showSlice(j, range, layer);
|
||||
layers = slice.layers;
|
||||
layers.outline.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerOutline.checked && LOCAL :
|
||||
UI.layerOutline.checked
|
||||
for (let j = 0; j < slices.length; j++) {
|
||||
let slice = slices[j];
|
||||
slice.view.visible = j >= lo && j <= hi;
|
||||
let layers = slice.layers;
|
||||
layers.outline.setVisible(cam ?
|
||||
UI.layerOutline.checked :
|
||||
UI.layerOutline.checked
|
||||
);
|
||||
layers.trace.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerRough.checked :
|
||||
UI.layerTrace.checked
|
||||
layers.trace.setVisible(cam ?
|
||||
UI.layerRough.checked :
|
||||
UI.layerTrace.checked
|
||||
);
|
||||
layers.bridge.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerFinishX.checked :
|
||||
UI.layerDelta.checked
|
||||
layers.bridge.setVisible(cam ?
|
||||
UI.layerFinishX.checked :
|
||||
UI.layerDelta.checked
|
||||
);
|
||||
layers.flat.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerFinishY.checked :
|
||||
UI.layerDelta.checked
|
||||
layers.flat.setVisible(cam ?
|
||||
UI.layerFinishY.checked :
|
||||
UI.layerDelta.checked
|
||||
);
|
||||
layers.solid.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerFinish.checked :
|
||||
UI.layerSolid.checked
|
||||
layers.solid.setVisible(cam ?
|
||||
UI.layerFinish.checked :
|
||||
UI.layerSolid.checked
|
||||
);
|
||||
layers.fill.setVisible(
|
||||
MODE === MODES.CAM ?
|
||||
UI.layerFacing.checked :
|
||||
UI.layerFill.checked
|
||||
layers.fill.setVisible(cam ?
|
||||
UI.layerFacing.checked :
|
||||
UI.layerFill.checked
|
||||
);
|
||||
layers.sparse.setVisible(UI.layerSparse.checked);
|
||||
layers.support.setVisible(UI.layerSupport.checked);
|
||||
|
|
@ -631,10 +622,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
|
||||
if (currentPrint) {
|
||||
let len = currentPrint.getLayerCount();
|
||||
for (j = 0; j < len; j++) {
|
||||
currentPrint.showLayer(j, print && showSlice(j, range, layer), moves);
|
||||
for (let j = 0; j < len; j++) {
|
||||
currentPrint.showLayer(j, print && j >= lo && j <= hi, moves);
|
||||
}
|
||||
}
|
||||
|
||||
UI.layerPrint.parentNode.style.display = currentPrint ? '' : 'none';
|
||||
UI.layerMoves.parentNode.style.display = currentPrint ? '' : 'none';
|
||||
|
||||
|
|
@ -671,6 +663,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
|
||||
function preparePrint(callback) {
|
||||
if (viewMode === VIEWS.PREVIEW) return;
|
||||
hideSlider(true);
|
||||
|
||||
// kick off slicing it hasn't been done already
|
||||
for (let i=0; i < WIDGETS.length; i++) {
|
||||
|
|
@ -746,6 +739,18 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
});
|
||||
}
|
||||
|
||||
function showSlider() {
|
||||
UI.layers.style.display = 'flex';
|
||||
UI.slider.style.display = 'flex';
|
||||
UI.setMenu.style.display = 'none';
|
||||
}
|
||||
|
||||
function hideSlider(andmenu) {
|
||||
UI.layers.style.display = 'none';
|
||||
UI.slider.style.display = 'none';
|
||||
UI.setMenu.style.display = andmenu ? 'none' : 'flex';
|
||||
}
|
||||
|
||||
/**
|
||||
* incrementally slice all meshes then incrementally update them
|
||||
*
|
||||
|
|
@ -757,7 +762,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
API.view.snapshot = snap.substring(snap.indexOf(",")+1);
|
||||
KIRI.work.snap(API.view.snapshot);
|
||||
}
|
||||
if (MODE === MODES.SLA && !callback) {
|
||||
callback = preparePrint;
|
||||
}
|
||||
|
||||
hideSlider(true);
|
||||
clearPrint();
|
||||
platform.deselect();
|
||||
setViewMode(VIEWS.SLICE);
|
||||
|
|
@ -766,7 +775,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
let firstMesh = true,
|
||||
countdown = WIDGETS.length,
|
||||
preserveMax = API.var.layer_max,
|
||||
preserveLayer = API.var.layer_at,
|
||||
preserveLayer = API.var.layer_hi,
|
||||
totalProgress,
|
||||
track = {},
|
||||
now = UTIL.time();
|
||||
|
|
@ -789,7 +798,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
widget.slice(settings, function(sliced, error) {
|
||||
let mark = UTIL.time();
|
||||
// on done
|
||||
widget.render(renderMode, MODE === MODES.CAM);
|
||||
widget.render();
|
||||
// clear wireframe
|
||||
widget.setWireframe(false, color.wireframe, color.wireframe_opacity);
|
||||
widget.setOpacity(settings.mode === 'CAM' ? color.cam_sliced_opacity : color.sliced_opacity);
|
||||
|
|
@ -816,8 +825,6 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
callback();
|
||||
}
|
||||
}
|
||||
// update slider window
|
||||
API.dialog.update();
|
||||
// handle slicing errors
|
||||
if (error && !errored) {
|
||||
errored = true;
|
||||
|
|
@ -880,7 +887,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
|
||||
function setOpacity(value) {
|
||||
forAllWidgets(function (w) { w.setOpacity(value) });
|
||||
UI.modelOpacity.value = value * 100;
|
||||
// UI.modelOpacity.value = value * 100;
|
||||
SPACE.update();
|
||||
}
|
||||
|
||||
|
|
@ -998,7 +1005,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function platformSelect(widget, shift) {
|
||||
if (viewMode !== VIEWS.ARRANGE) return;
|
||||
if (viewMode !== VIEWS.ARRANGE) {
|
||||
return;
|
||||
}
|
||||
let mesh = widget.mesh,
|
||||
sel = (selectedMeshes.indexOf(mesh) >= 0);
|
||||
if (sel) {
|
||||
|
|
@ -1026,19 +1035,24 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function platformUpdateSelected() {
|
||||
UI.selection.style.display = platform.selected_count() ? 'inline' : 'none';
|
||||
$('ext-sel').style.display = (MODE === MODES.FDM) ? 'inline-block' : 'none';
|
||||
let extruders = settings.device.extruders;
|
||||
let menu_show = platform.selected_count() ? 'flex': '';
|
||||
let ext_show = platform.selected_count() && MODE === 'FDM' ? 'flex': '';
|
||||
UI.scale.style.display = menu_show;
|
||||
UI.rotate.style.display = menu_show;
|
||||
UI.nozzle.style.display = extruders && extruders.length > 1 ? menu_show : '';
|
||||
UI.menusep.style.display = menu_show;
|
||||
if (extruders) {
|
||||
for (let i=0; i<extruders.length; i++) {
|
||||
let b = $(`sel-ext-${i}`);
|
||||
if (b) b.classList.remove('buton');
|
||||
if (b) b.classList.remove('pop-sel');
|
||||
}
|
||||
forSelectedWidgets(w => {
|
||||
w.setColor(color.selected, settings);
|
||||
let ext = (settings.widget[w.id] || {}).extruder || 0;
|
||||
let b = $(`sel-ext-${ext}`);
|
||||
if (b) b.classList.add('buton');
|
||||
});
|
||||
if (b) b.classList.add('pop-sel');
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1233,7 +1247,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
camTopZ = topZ;
|
||||
// create/inject cam stock if stock size other than default
|
||||
if (MODE === MODES.CAM && stockSet && WIDGETS.length) {
|
||||
UI.stock.style.display = offset ? 'inline-block' : 'none';
|
||||
// UI.stock.style.display = offset ? 'inline-block' : 'none';
|
||||
let csx = sd.camStockX * scale;
|
||||
let csy = sd.camStockY * scale;
|
||||
let csz = sd.camStockZ * scale;
|
||||
|
|
@ -1261,9 +1275,9 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
csz += max.z - min.z;
|
||||
csox = min.x + ((max.x - min.x) / 2);
|
||||
csoy = min.y + ((max.y - min.y) / 2);
|
||||
$('stock-width').innerText = (csx/scale).toFixed(2);
|
||||
$('stock-depth').innerText = (csy/scale).toFixed(2);
|
||||
$('stock-height').innerText = (csz/scale).toFixed(2);
|
||||
// $('stock-width').innerText = (csx/scale).toFixed(2);
|
||||
// $('stock-depth').innerText = (csy/scale).toFixed(2);
|
||||
// $('stock-height').innerText = (csz/scale).toFixed(2);
|
||||
}
|
||||
if (!camStock) {
|
||||
let geo = new THREE.BoxGeometry(1, 1, 1);
|
||||
|
|
@ -1286,7 +1300,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
camStock.material.visible = settings.mode === 'CAM';
|
||||
camTopZ = csz;
|
||||
} else if (camStock) {
|
||||
UI.stock.style.display = 'none';
|
||||
// UI.stock.style.display = 'none';
|
||||
SPACE.platform.remove(camStock);
|
||||
camStock = null;
|
||||
camTopZ = topZ;
|
||||
|
|
@ -1435,6 +1449,8 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
API.conf.save();
|
||||
platform.update_stock();
|
||||
$('mode-device').innerText = settings.device.deviceName;
|
||||
$('mode-profile').innerText = settings.process.processName;
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
|
|
@ -1626,36 +1642,53 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function modalShowing() {
|
||||
let showing = $('modal').style.display !== 'none';
|
||||
return showing || UC.isPopped();
|
||||
return UI.modal.style.display === 'flex';
|
||||
}
|
||||
|
||||
function showModal(which) {
|
||||
UI.modal.style.display = 'block';
|
||||
["print","help","local"].forEach(function(modal) {
|
||||
UI[modal].style.display = (modal === which ? 'block' : 'none');
|
||||
let mod = UI.modal,
|
||||
style = mod.style,
|
||||
visible = modalShowing(),
|
||||
info = { pct: 0 };
|
||||
|
||||
["help","setup","tools","prefs","saves","files","print","local"].forEach(function(name) {
|
||||
UI[name].style.display = name === which ? 'flex' : '';
|
||||
});
|
||||
if (which) API.event.emit('modal.show', which);
|
||||
|
||||
function ondone() {
|
||||
API.event.emit('modal.show', which);
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
return ondone();
|
||||
}
|
||||
|
||||
style.height = '0';
|
||||
style.display = 'flex';
|
||||
|
||||
new TWEEN.Tween(info).
|
||||
easing(TWEEN.Easing.Quadratic.InOut).
|
||||
to({ pct: 100 }, 100).
|
||||
onUpdate(() => { style.height = `${info.pct}%` }).
|
||||
onComplete(ondone).
|
||||
start();
|
||||
}
|
||||
|
||||
function hideDialog() {
|
||||
showDialog(null);
|
||||
}
|
||||
|
||||
function showDialog(which, force) {
|
||||
if (UC.isPopped()) {
|
||||
UC.hidePop();
|
||||
function hideModal() {
|
||||
if (!modalShowing()) {
|
||||
return;
|
||||
}
|
||||
["catalog","devices","tools","settings"].forEach(function(dialog) {
|
||||
let style = UI[dialog].style;
|
||||
style.display = (dialog === which && (force || style.display !== 'flex') ? 'flex' : 'none');
|
||||
});
|
||||
if (which) API.event.emit('dialog.show', which);
|
||||
let mod = UI.modal, style = mod.style, info={pct:100};
|
||||
new TWEEN.Tween(info).
|
||||
easing(TWEEN.Easing.Quadratic.InOut).
|
||||
to({pct:0}, 100).
|
||||
onUpdate(() => { style.height = `${info.pct}%` }).
|
||||
onComplete(() => { style.display = '' }).
|
||||
start();
|
||||
}
|
||||
|
||||
function showCatalog() {
|
||||
showDialog("catalog");
|
||||
showModal("files");
|
||||
}
|
||||
|
||||
function getSettings() {
|
||||
|
|
@ -1691,7 +1724,6 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
let mode = getMode(),
|
||||
name = e ? e.target.getAttribute("load") : named || settings.cproc[mode],
|
||||
load = settings.sproc[mode][name];
|
||||
|
||||
if (!load) return;
|
||||
|
||||
settings.process = clone(load);
|
||||
|
|
@ -1701,20 +1733,11 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
// associate named process with the current device
|
||||
settings.devproc[currentDeviceName()] = name;
|
||||
|
||||
// update selection display
|
||||
$('selected-mode').innerHTML = API.mode.get();
|
||||
$('selected-device').innerHTML = API.device.get();
|
||||
$('selected-process').innerHTML = name;
|
||||
|
||||
// FDM process settings overridden by device
|
||||
if (mode == "FDM") {
|
||||
settings.process.outputOriginCenter = (settings.device.originCenter || false);
|
||||
}
|
||||
|
||||
if (!named) {
|
||||
hideDialog();
|
||||
}
|
||||
|
||||
updateFields();
|
||||
API.conf.update();
|
||||
if (e) triggerSettingsEvent();
|
||||
|
|
@ -1742,7 +1765,10 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
name = sk;
|
||||
|
||||
load.setAttribute('load', sk);
|
||||
load.onclick = API.conf.load;
|
||||
load.onclick = (ev) => {
|
||||
API.conf.load(undefined, sk);
|
||||
updateSettingsList();
|
||||
}
|
||||
load.appendChild(DOC.createTextNode(sk));
|
||||
if (sk == settings.process.processName) {
|
||||
load.setAttribute('class', 'selected')
|
||||
|
|
@ -1764,15 +1790,15 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
row.appendChild(del);
|
||||
table.appendChild(row);
|
||||
});
|
||||
API.dialog.update();
|
||||
}
|
||||
|
||||
function showSettings() {
|
||||
updateSettingsList();
|
||||
showDialog("settings");
|
||||
showModal("saves");
|
||||
}
|
||||
|
||||
function updateDialogLeft() {
|
||||
return console.log('TODO updateDialogLeft');
|
||||
let left = UI.ctrlLeft.getBoundingClientRect();
|
||||
let right = UI.ctrlRight.getBoundingClientRect();
|
||||
UI.catalog.style.left = (left.width + 5) + 'px';
|
||||
|
|
@ -1781,35 +1807,31 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
UI.settings.style.right = (right.width + 5) + 'px';
|
||||
}
|
||||
|
||||
function hideModal() {
|
||||
UI.modal.style.display = 'none';
|
||||
}
|
||||
|
||||
function showHelp() {
|
||||
showHelpFile(`/kiri/lang/${KIRI.lang.get()}-help.html?${KIRI.version}`);
|
||||
}
|
||||
|
||||
function showHelpFile(local) {
|
||||
hideDialog();
|
||||
if (!local) {
|
||||
WIN.open("//wiki.grid.space/wiki/Kiri:Moto", "_help");
|
||||
return;
|
||||
}
|
||||
ajax(local, function(html) {
|
||||
UI.help.innerHTML = html;
|
||||
try { $('help-close').onclick = hideModal; } catch (e) { console.log(e, html) }
|
||||
try { $('kiri-version').innerHTML = `<i>${LANG.version} ${KIRI.version}</i>`; } catch (e) { }
|
||||
try {
|
||||
$('kiri-version').innerHTML = `${LANG.version} ${KIRI.version}`;
|
||||
} catch (e) { }
|
||||
showModal('help');
|
||||
});
|
||||
API.event.emit('help.show', local);
|
||||
}
|
||||
|
||||
function showLocal() {
|
||||
$('local-close').onclick = hideModal;
|
||||
showModal('local');
|
||||
fetch("/api/grid_local")
|
||||
.then(r => r.json())
|
||||
.then(j => {
|
||||
let devc = 0;
|
||||
let bind = [];
|
||||
let html = ['<table>'];
|
||||
html.push(`<thead><tr><th>device</th><th>type</th><th>status</th><th></th></tr></thead>`);
|
||||
|
|
@ -1823,10 +1845,15 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
html.push(`<td>${r.state}</td>`);
|
||||
html.push(`<td><button id="${r.device.uuid}">admin</button></td>`);
|
||||
html.push(`</tr>`);
|
||||
devc++;
|
||||
}
|
||||
html.push(`</tbody>`);
|
||||
html.push(`</table>`);
|
||||
$('local-dev').innerHTML = html.join('');
|
||||
if (devc) {
|
||||
$('mod-local').innerHTML = html.join('');
|
||||
} else {
|
||||
$('mod-local').innerHTML = `<br><b>no local devices</b>`;
|
||||
}
|
||||
bind.forEach(rec => {
|
||||
$(rec.uuid).onclick = () => {
|
||||
window.open(`http://${rec.host}:${rec.port||4080}/`);
|
||||
|
|
@ -1836,7 +1863,7 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function setFocus(el) {
|
||||
el = [ el || UI.load, UI.import, UI.ctrlLeft, UI.container, UI.assets, UI.control, UI.modeFDM, UI.reverseZoom, UI.modelOpacity, DOC.body ];
|
||||
el = [ el || UI.focuser, UI.load, UI.sizeX, DOC.body ];
|
||||
for (let es, i=0; i<el.length; i++) {
|
||||
es = el[i];
|
||||
es.focus();
|
||||
|
|
@ -1853,20 +1880,18 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
updateSelectedInfo();
|
||||
switch (mode) {
|
||||
case VIEWS.ARRANGE:
|
||||
$('lt-back').style.display = '';
|
||||
KIRI.work.clear();
|
||||
hideSlider();
|
||||
clearWidgetCache();
|
||||
showLayerView(false);
|
||||
updateSliderMax();
|
||||
showModeActive(UI.modeArrange);
|
||||
break;
|
||||
case VIEWS.SLICE:
|
||||
showLayerView(true);
|
||||
$('lt-back').style.display = 'flex';
|
||||
updateSliderMax();
|
||||
showModeActive(UI.modeSlice);
|
||||
break;
|
||||
case VIEWS.PREVIEW:
|
||||
showLayerView(true);
|
||||
showModeActive(UI.modePreview);
|
||||
$('lt-back').style.display = 'flex';
|
||||
break;
|
||||
default:
|
||||
DBUG.log("invalid view mode: "+mode);
|
||||
|
|
@ -1875,22 +1900,10 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
DOC.activeElement.blur();
|
||||
}
|
||||
|
||||
function showModeActive(el) {
|
||||
[ UI.modeArrange, UI.modeSlice, UI.modePreview, UI.modeExport ].forEach(function(b) {
|
||||
if (b === el) {
|
||||
b.classList.add('buton');
|
||||
} else {
|
||||
b.classList.remove('buton');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showLayerView(bool) {
|
||||
UI.layerView.style.display = bool ? 'flex' : 'none';
|
||||
}
|
||||
|
||||
function setExpert(bool) {
|
||||
UC.setExpert(UI.expert.checked = control.expert = bool);
|
||||
UC.setExpert(UI.expert.checked = settings.controller.expert = bool);
|
||||
$('lt-sep-help').style.display = bool ? 'none' : '';
|
||||
$('set-help').style.display = bool ? 'none' : '';
|
||||
}
|
||||
|
||||
function getMode() {
|
||||
|
|
@ -1906,51 +1919,54 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function setMode(mode, lock, then) {
|
||||
hideModal();
|
||||
hideDialog();
|
||||
if (!MODES[mode]) {
|
||||
DBUG.log("invalid mode: "+mode);
|
||||
mode = 'FDM';
|
||||
}
|
||||
// change mode constants
|
||||
settings.mode = mode;
|
||||
MODE = MODES[mode];
|
||||
DRIVER = KIRI.driver[mode];
|
||||
// update mode display
|
||||
$('app-mode-name').innerHTML = mode;
|
||||
// highlight relevant device mode button
|
||||
["fdm","sla","cam","laser"].forEach(dev => {
|
||||
let cl = $(`mode-${dev}`).classList;
|
||||
if (dev === mode.toLowerCase()) {
|
||||
cl.add("dev-sel");
|
||||
} else {
|
||||
cl.remove("dev-sel");
|
||||
}
|
||||
});
|
||||
// restore cached device profile for this mode
|
||||
if (settings.cdev[mode]) {
|
||||
settings.device = clone(settings.cdev[mode]);
|
||||
API.event.emit('device.set', currentDeviceName());
|
||||
}
|
||||
if (MODE === MODES.CAM) {
|
||||
SPACE.platform.setColor(0xeeeeee);
|
||||
} else {
|
||||
SPACE.platform.setColor(0xcccccc);
|
||||
}
|
||||
MODE = MODES[mode];
|
||||
// updates right-hand menu by enabling/disabling fields
|
||||
setViewMode(VIEWS.ARRANGE);
|
||||
UC.setMode(MODE);
|
||||
API.conf.load();
|
||||
API.conf.save();
|
||||
clearWidgetCache();
|
||||
SPACE.update();
|
||||
UI.modeFDM.setAttribute('class', MODE === MODES.FDM ? 'buton' : '');
|
||||
UI.modeSLA.setAttribute('class', MODE === MODES.SLA ? 'buton' : '');
|
||||
UI.modeCAM.setAttribute('class', MODE === MODES.CAM ? 'buton' : '');
|
||||
UI.modeLASER.setAttribute('class', MODE === MODES.LASER ? 'buton' : '');
|
||||
UI.mode.style.display = lock ? 'none' : '';
|
||||
UI.modeTable.style.display = lock ? 'none' : '';
|
||||
UI.modelOpacity.style.display = MODE === MODES.SLA ? 'none' : '';
|
||||
UI.modePreview.style.display = MODE === MODES.SLA ? 'none' : '';
|
||||
// really belongs in CAM driver (lots of work / abstraction needed)
|
||||
if (camStock) {
|
||||
camStock.material.visible = settings.mode === 'CAM';
|
||||
}
|
||||
API.space.restore(null, true);
|
||||
if (then) then();
|
||||
// updates right-hand menu by enabling/disabling fields
|
||||
setViewMode(VIEWS.ARRANGE);
|
||||
UC.setMode(MODE);
|
||||
// sanitize and persist settings
|
||||
API.conf.load();
|
||||
API.conf.save();
|
||||
// other housekeeping
|
||||
clearWidgetCache();
|
||||
triggerSettingsEvent();
|
||||
platformUpdateSelected();
|
||||
updateFields();
|
||||
if (settings.device.new) {
|
||||
// because device dialog, if showing, needs to be updated
|
||||
if (modalShowing()) {
|
||||
API.show.devices();
|
||||
}
|
||||
API.space.restore(null, true);
|
||||
API.event.emit("mode.set", mode);
|
||||
if (then) {
|
||||
then();
|
||||
}
|
||||
}
|
||||
|
||||
function currentDeviceName() {
|
||||
|
|
@ -1958,8 +1974,8 @@ self.kiri.copyright = exports.COPYRIGHT;
|
|||
}
|
||||
|
||||
function setControlsVisible(show) {
|
||||
UI.ctrlLeft.style.display = show ? 'block' : 'none';
|
||||
UI.ctrlRight.style.display = show ? 'block' : 'none';
|
||||
$('mid-lcol').style.display = show ? 'flex' : 'none';
|
||||
$('mid-rcol').style.display = show ? 'flex' : 'none';
|
||||
}
|
||||
|
||||
// prevent safari from exiting full screen mode
|
||||
|
|
@ -1,14 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_print = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.newPrint) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
DRIVERS = KIRI.driver,
|
||||
LASER = DRIVERS.LASER,
|
||||
CAM = DRIVERS.CAM,
|
||||
|
|
@ -22,8 +20,9 @@ let gs_kiri_print = exports;
|
|||
PI = Math.PI,
|
||||
PRO = Print.prototype,
|
||||
Polygon = BASE.Polygon,
|
||||
newPoint = BASE.newPoint,
|
||||
lastPoint = null,
|
||||
newPoint = BASE.newPoint;
|
||||
|
||||
let lastPoint = null,
|
||||
lastEmit = null;
|
||||
|
||||
KIRI.newPrint = function(settings, widgets, id) {
|
||||
|
|
@ -51,6 +50,8 @@ let gs_kiri_print = exports;
|
|||
this.distance = 0;
|
||||
this.bounds = null;
|
||||
this.imported = null;
|
||||
|
||||
this.hsv2rgb = hsv2rgb;
|
||||
}
|
||||
|
||||
PRO.addOutput = addOutput;
|
||||
|
|
@ -228,6 +229,8 @@ let gs_kiri_print = exports;
|
|||
} else {
|
||||
|
||||
// executed from kiri-worker.js
|
||||
// uses encodeOutput in this class to produce scope.output above
|
||||
// this encoding could be made vastly more efficient
|
||||
let driver = KIRI.driver[mode];
|
||||
if (driver) driver.printSetup(scope, onupdate);
|
||||
else console.log({missing_print_driver: mode});
|
||||
|
|
@ -317,7 +320,8 @@ let gs_kiri_print = exports;
|
|||
emit: out.emit,
|
||||
speed: out.speed * 60,
|
||||
retract: out.retract,
|
||||
point: {x: out.point.x, y: out.point.y, z: out.point.z}
|
||||
point: {x: out.point.x, y: out.point.y, z: out.point.z},
|
||||
tool: out.tool
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -327,25 +331,17 @@ let gs_kiri_print = exports;
|
|||
};
|
||||
|
||||
PRO.render = function() {
|
||||
let scope = this,
|
||||
settings = scope.settings,
|
||||
process = settings.process,
|
||||
let settings = this.settings,
|
||||
origin = settings.origin,
|
||||
mode = settings.mode,
|
||||
tools = [],
|
||||
driver = KIRI.driver[mode];
|
||||
|
||||
switch (mode) {
|
||||
case 'SLA':
|
||||
driver.printRender(scope);
|
||||
break;
|
||||
case 'CAM':
|
||||
case 'FDM':
|
||||
scope.renderMoves(true, 0x888888);
|
||||
break;
|
||||
case 'LASER':
|
||||
scope.renderMoves(false, 0x0088aa);
|
||||
break;
|
||||
if (mode === 'FDM') {
|
||||
tools = settings.device.extruders || [];
|
||||
}
|
||||
|
||||
driver.printRender(this, {tools});
|
||||
};
|
||||
|
||||
function pref(a,b) {
|
||||
|
|
@ -425,69 +421,6 @@ let gs_kiri_print = exports;
|
|||
return out;
|
||||
}
|
||||
|
||||
PRO.renderMoves = function(showMoves, moveColor, firstPoint) {
|
||||
let debug = KIRI.api.const.LOCAL;
|
||||
let scope = this, emits, moves, last = firstPoint;
|
||||
// render layered output
|
||||
scope.lines = 0;
|
||||
scope.output.forEach(function(layerout) {
|
||||
let move = [], print = {}, z;
|
||||
layerout.forEach(function(out, index) {
|
||||
let point = out.point;
|
||||
if (last) {
|
||||
if (UTIL.distSq(last, point) < 0.001 && point.z === last.z) {
|
||||
return;
|
||||
}
|
||||
if (out.emit > 0) {
|
||||
let spd = out.speed || 4000;
|
||||
let arr = print[spd] || [];
|
||||
print[spd] = arr;
|
||||
arr.push(last);
|
||||
arr.push(point);
|
||||
} else {
|
||||
move.push(last);
|
||||
move.push(point);
|
||||
}
|
||||
if (debug && showMoves && last.z == point.z) {
|
||||
let rs = BASE.newSlope(
|
||||
{x: point.x, y: point.y},
|
||||
{x: last.x, y: last.y}
|
||||
);
|
||||
let ao1 = BASE.newSlopeFromAngle(rs.angle + 25);
|
||||
let ao2 = BASE.newSlopeFromAngle(rs.angle - 25);
|
||||
let sp = BASE.newPoint(point.x, point.y, point.z);
|
||||
move.push(sp);
|
||||
move.push(sp.projectOnSlope(ao1, 0.5));
|
||||
move.push(sp);
|
||||
move.push(sp.projectOnSlope(ao2, 0.5));
|
||||
}
|
||||
} else {
|
||||
z = point.z;
|
||||
}
|
||||
last = point;
|
||||
});
|
||||
emits = KIRI.newLayer(scope.group);
|
||||
scope.printView.push(emits);
|
||||
if (showMoves) {
|
||||
moves = KIRI.newLayer(scope.group);
|
||||
moves.lines(move, moveColor);
|
||||
scope.movesView.push(moves);
|
||||
moves.render();
|
||||
}
|
||||
for (let speed in print) {
|
||||
let sint = Math.min(6000, parseInt(speed));
|
||||
let rgb = hsv2rgb({h:sint/6000, s:1, v:0.6});
|
||||
emits.lines(print[speed],
|
||||
((rgb.r * 0xff) << 16) |
|
||||
((rgb.g * 0xff) << 8) |
|
||||
((rgb.b * 0xff) << 0)
|
||||
);
|
||||
}
|
||||
emits.render();
|
||||
scope.lines += print.length;
|
||||
});
|
||||
}
|
||||
|
||||
PRO.getLayerCount = function() {
|
||||
return this.output.length;
|
||||
}
|
||||
|
|
@ -1,26 +1,21 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_slice = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.Slice) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
FILL = KIRI.fill,
|
||||
FILLFIXED = KIRI.fill_fixed,
|
||||
PRO = Slice.prototype,
|
||||
BASE = self.base,
|
||||
UTIL = BASE.util,
|
||||
POLY = BASE.polygons,
|
||||
PRO = Slice.prototype,
|
||||
NOKEY = BASE.key.NONE,
|
||||
fillArea = POLY.fillArea,
|
||||
newPoint = BASE.newPoint,
|
||||
MIN = Math.min,
|
||||
MAX = Math.max,
|
||||
NOKEY = BASE.key.NONE,
|
||||
outline_colors = [
|
||||
0xeeee00,
|
||||
0xeebb00,
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_slicer = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.slicer) return;
|
||||
|
||||
let slicer = self.kiri.slicer = {
|
||||
self.kiri.slicer = {
|
||||
slice: slice,
|
||||
sliceWidget: sliceWidget,
|
||||
connectLines: connectLines
|
||||
|
|
@ -271,6 +268,7 @@ let gs_kiri_slicer = exports;
|
|||
// copy to store original z
|
||||
zHeights = zIndexes.slice();
|
||||
} else if (zIncMin) {
|
||||
// console.log('adaptive slicing', zIncMin, ':', zInc, 'from', zMin, 'to', zMax);
|
||||
// FDM adaptive slicing
|
||||
let zPos = zMin + zIncFirst,
|
||||
zOI = 0,
|
||||
|
|
@ -311,6 +309,7 @@ let gs_kiri_slicer = exports;
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// console.log('fixed slicing', zInc, 'from', zMin, 'to', zMax);
|
||||
// FDM fixed slicing
|
||||
if (options.firstHeight) {
|
||||
zIndexes.push(options.firstHeight / 2);
|
||||
|
|
@ -322,6 +321,7 @@ let gs_kiri_slicer = exports;
|
|||
zHeights.push(zInc);
|
||||
}
|
||||
}
|
||||
|
||||
// create a Slice for each z offset in the zIndexes array
|
||||
for (let i = 0; i < zIndexes.length; i++) {
|
||||
let ik = zIndexes[i].toFixed(5),
|
||||
586
src/kiri/ui.js
Normal file
586
src/kiri/ui.js
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
|
||||
if (kiri.ui) return;
|
||||
|
||||
let SELF = self,
|
||||
KIRI = self.kiri,
|
||||
lastGroup = null,
|
||||
lastDiv = null,
|
||||
addTo = null,
|
||||
hideAction = null,
|
||||
inputAction = null,
|
||||
groups = {},
|
||||
groupShow = {},
|
||||
groupName = undefined,
|
||||
poppable = {},
|
||||
hasModes = [],
|
||||
isExpert = [],
|
||||
letMode = null,
|
||||
letExpert = false,
|
||||
DOC = SELF.document,
|
||||
state = {},
|
||||
prefix = "tab",
|
||||
NOMODE = "nomode",
|
||||
exitimer = undefined;
|
||||
|
||||
SELF.$ = (SELF.$ || function (id) { return DOC.getElementById(id) } );
|
||||
|
||||
KIRI.ui = {
|
||||
prefix: function(pre) { prefix = pre; return kiri.ui },
|
||||
hideAction: function(fn) { hideAction = fn; return kiri.ui },
|
||||
inputAction: function(fn) { inputAction = fn; return kiri.ui },
|
||||
setMode: setMode,
|
||||
setExpert: setExpert,
|
||||
bound: bound,
|
||||
toInt: toInt,
|
||||
toFloat: toFloat,
|
||||
hidePop: hidePop,
|
||||
isPopped: isPopped,
|
||||
newText: newTextArea,
|
||||
newLabel: newLabel,
|
||||
newRange: newRange,
|
||||
newInput: newInputField,
|
||||
newButton: newButton,
|
||||
newBoolean: newBooleanField,
|
||||
newSelect: newSelect,
|
||||
newTable: newTables,
|
||||
newTableRow: newTableRow,
|
||||
newRow: newRow,
|
||||
newBlank: newBlank,
|
||||
newGroup: newGroup,
|
||||
setGroup: setGroup,
|
||||
hidePoppers: hidePoppers,
|
||||
checkpoint,
|
||||
restore
|
||||
};
|
||||
|
||||
function setMode(mode) {
|
||||
Object.keys(groupShow).forEach(group => {
|
||||
updateGroupShow(group);
|
||||
});
|
||||
letMode = mode;
|
||||
hasModes.forEach(function(div) {
|
||||
div.setMode(div._group && !groupShow[div._group] ? NOMODE : mode);
|
||||
});
|
||||
hidePoppers();
|
||||
}
|
||||
|
||||
function setExpert(bool) {
|
||||
letExpert = bool;
|
||||
setMode(letMode);
|
||||
}
|
||||
|
||||
function checkpoint() {
|
||||
return { addTo, lastDiv, lastGroup, groupName };
|
||||
}
|
||||
|
||||
function restore(opt) {
|
||||
if (opt) {
|
||||
addTo = opt.addTo;
|
||||
lastDiv = opt.lastDiv;
|
||||
lastGroup = opt.lastGroup;
|
||||
groupName = opt.groupName;
|
||||
}
|
||||
}
|
||||
|
||||
// at present only used by the layers popup menu
|
||||
function setGroup(div) {
|
||||
addTo = lastDiv = div;
|
||||
groupName = undefined;
|
||||
lastGroup = [];
|
||||
return div;
|
||||
}
|
||||
|
||||
function newGroup(label, div, options) {
|
||||
lastDiv = div || lastDiv;
|
||||
return addCollapsableGroup(label, lastDiv, options);
|
||||
}
|
||||
|
||||
function addCollapsableGroup(label, div, options) {
|
||||
let opt = options || {};
|
||||
let group = opt.group || label;
|
||||
poppable[group] = opt.inline === true ? false : true;
|
||||
|
||||
let row = DOC.createElement('div'),
|
||||
a = DOC.createElement('a'),
|
||||
dbkey = `beta-${prefix}-show-${group}`,
|
||||
popper = !opt.inline;
|
||||
|
||||
if (popper) {
|
||||
let pop = DOC.createElement('div');
|
||||
pop.classList.add('set-pop');
|
||||
row.appendChild(pop);
|
||||
row.setAttribute("class", "set-group noselect");
|
||||
addTo = pop;
|
||||
} else {
|
||||
row.setAttribute("class", "set-header col");
|
||||
addTo = lastDiv;
|
||||
}
|
||||
|
||||
div.appendChild(row);
|
||||
row.appendChild(a);
|
||||
a.appendChild(DOC.createTextNode(label));
|
||||
addModeControls(row, opt);
|
||||
lastGroup = groups[group] = [];
|
||||
lastGroup.key = dbkey;
|
||||
groupName = group;
|
||||
groupShow[group] = popper ? state[dbkey] === 'true' : state[dbkey] !== 'false';
|
||||
row.onclick = function(ev) {
|
||||
if (ev.target !== a && ev.target !== row) {
|
||||
return;
|
||||
}
|
||||
toggleGroup(group, dbkey);
|
||||
};
|
||||
if (popper) {
|
||||
row.onmouseenter = function(ev) {
|
||||
if (ev.target !== a && ev.target !== row) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(exitimer);
|
||||
showGroup(group);
|
||||
};
|
||||
row.onmouseleave = function(ev) {
|
||||
if (ev.target !== a && ev.target !== row) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(exitimer);
|
||||
exitimer = setTimeout(showGroup, 1000);
|
||||
};
|
||||
addTo._group = group;
|
||||
addModeControls(addTo, opt);
|
||||
lastGroup.push(addTo);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
function hidePoppers() {
|
||||
showGroup(undefined);
|
||||
}
|
||||
|
||||
function showGroup(groupname) {
|
||||
Object.keys(groups).forEach(name => {
|
||||
let group = groups[name];
|
||||
groupShow[name] = state[group.key] = (groupname === name);
|
||||
updateGroupShow(name);
|
||||
});
|
||||
}
|
||||
|
||||
function toggleGroup(groupname, dbkey) {
|
||||
let show = state[dbkey] === 'false';
|
||||
groupShow[groupname] = poppable[groupname] ? state[dbkey] = show : true;
|
||||
updateGroupShow(groupname);
|
||||
}
|
||||
|
||||
function updateGroupShow(groupname) {
|
||||
let show = groupShow[groupname] || !poppable[groupname];
|
||||
let group = groups[groupname];
|
||||
group.forEach(div => {
|
||||
if (show) div.setMode(letMode);
|
||||
else div.setMode(NOMODE);
|
||||
});
|
||||
}
|
||||
|
||||
function toInt() {
|
||||
let nv = this.value !== '' ? parseInt(this.value) : null;
|
||||
if (isNaN(nv)) nv = 0;
|
||||
if (nv !== null && this.bound) nv = this.bound(nv);
|
||||
this.value = nv;
|
||||
return nv;
|
||||
}
|
||||
|
||||
function toFloat() {
|
||||
let nv = this.value !== '' ? parseFloat(this.value) : null;
|
||||
if (nv !== null && this.bound) nv = this.bound(nv);
|
||||
this.value = nv;
|
||||
return nv;
|
||||
}
|
||||
|
||||
function bound(low,high) {
|
||||
return function(v) {
|
||||
if (isNaN(v)) return low;
|
||||
return v < low ? low : v > high ? high : v;
|
||||
};
|
||||
}
|
||||
|
||||
function raw() {
|
||||
return this.value !== '' ? this.value : null;
|
||||
}
|
||||
|
||||
function newLabel(text) {
|
||||
let label = DOC.createElement('label');
|
||||
label.appendChild(DOC.createTextNode(text));
|
||||
label.setAttribute("class", "noselect");
|
||||
return label;
|
||||
}
|
||||
|
||||
function addId(el, options) {
|
||||
if (options && options.id) {
|
||||
el.setAttribute("id", options.id);
|
||||
}
|
||||
}
|
||||
|
||||
function addModeControls(el, options) {
|
||||
options = options || {};
|
||||
el.__show = true;
|
||||
el.__modeSave = null;
|
||||
el.showMe = function() {
|
||||
if (el.__show) return;
|
||||
el.style.display = el.__modeSave;
|
||||
el.__show = true;
|
||||
el.__modeSave = null;
|
||||
};
|
||||
el.hideMe = function() {
|
||||
if (!el.__show) return;
|
||||
el.__show = false;
|
||||
el.__modeSave = el.style.display;
|
||||
el.style.display = 'none';
|
||||
};
|
||||
el.setVisible = function(show) {
|
||||
if (show) el.showMe();
|
||||
else el.hideMe();
|
||||
};
|
||||
el.setMode = function(mode) {
|
||||
let show = options.expert === undefined || (options.expert === letExpert);
|
||||
el.setVisible(el.hasMode(mode) && show);
|
||||
}
|
||||
el.hasMode = function(mode) {
|
||||
if (mode === NOMODE) return false;
|
||||
if (!el.modes) return true;
|
||||
return el.modes.contains(mode);
|
||||
}
|
||||
if (options.modes) {
|
||||
el.modes = options.modes;
|
||||
hasModes.push(el);
|
||||
}
|
||||
}
|
||||
|
||||
function newDiv(options) {
|
||||
let div = DOC.createElement('div');
|
||||
addModeControls(div, options);
|
||||
addTo.appendChild(div);
|
||||
lastGroup.push(div);
|
||||
div._group = groupName;
|
||||
return div;
|
||||
}
|
||||
|
||||
let lastTxt = null;
|
||||
let lastPop = null;
|
||||
let savePop = null;
|
||||
|
||||
function hidePop() {
|
||||
if (lastPop) {
|
||||
lastPop.style.display = "none";
|
||||
}
|
||||
if (savePop) {
|
||||
savePop();
|
||||
savePop = null;
|
||||
}
|
||||
lastPop = null;
|
||||
}
|
||||
|
||||
function isPopped() {
|
||||
return lastPop !== null;
|
||||
}
|
||||
|
||||
function newTextArea(label, options) {
|
||||
let opt = options || {},
|
||||
row = newDiv(options),
|
||||
btn = DOC.createElement("button"),
|
||||
pop = DOC.createElement("div"),
|
||||
txt = DOC.createElement("textarea"),
|
||||
area = opt.area;
|
||||
|
||||
txt.setAttribute("wrap", "off");
|
||||
txt.setAttribute("spellcheck", "false");
|
||||
txt.setAttribute("style", "resize: none");
|
||||
txt.onblur = inputAction;
|
||||
|
||||
btn.appendChild(DOC.createTextNode("edit"));
|
||||
|
||||
btn.onclick = function(ev) {
|
||||
ev.stopPropagation();
|
||||
if (ev.target === txt) {
|
||||
// drop clicks on TextArea
|
||||
ev.target.focus();
|
||||
} else {
|
||||
let fc = area.firstChild;
|
||||
if (fc) area.removeChild(fc);
|
||||
area.appendChild(txt);
|
||||
// first time, button click / show
|
||||
btn.parentNode.onclick = btn.onclick;
|
||||
txt.scrollTop = 0;
|
||||
txt.scrollLeft = 0;
|
||||
txt.selectionEnd = 0;
|
||||
let rows = txt.value.split('\n');
|
||||
let cols = 0;
|
||||
rows.forEach(row => {
|
||||
cols = Math.max(cols, row.length);
|
||||
});
|
||||
txt.setAttribute("cols", Math.max(30, cols + 1));
|
||||
txt.setAttribute("rows", Math.max(10, rows.length + 1));
|
||||
|
||||
let showing = pop === lastPop;
|
||||
hidePop();
|
||||
if (!showing) {
|
||||
if (lastTxt) {
|
||||
lastTxt.classList.remove('txt-sel');
|
||||
}
|
||||
row.classList.add('txt-sel');
|
||||
savePop = inputAction;
|
||||
pop.style.display = "flex";
|
||||
lastPop = pop;
|
||||
lastTxt = row;
|
||||
txt.focus();
|
||||
} else {
|
||||
inputAction();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addModeControls(btn, opt);
|
||||
addId(btn, opt);
|
||||
|
||||
row.appendChild(newLabel(label));
|
||||
row.appendChild(btn);
|
||||
row.setAttribute("class", "var-row");
|
||||
if (opt.title) row.setAttribute("title", options.title);
|
||||
btn.setVisible = row.setVisible;
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
function newInputField(label, options) {
|
||||
let opt = options || {},
|
||||
row = newDiv(opt),
|
||||
hide = opt && opt.hide,
|
||||
size = opt ? opt.size || 5 : 5,
|
||||
height = opt ? opt.height : 0,
|
||||
ip = height > 1 ? DOC.createElement('textarea') : DOC.createElement('input'),
|
||||
action = opt.action || inputAction;
|
||||
|
||||
row.appendChild(newLabel(label));
|
||||
row.appendChild(ip);
|
||||
row.setAttribute("class", "var-row");
|
||||
if (height > 1) {
|
||||
ip.setAttribute("cols", size);
|
||||
ip.setAttribute("rows", height);
|
||||
ip.setAttribute("wrap", "off");
|
||||
} else {
|
||||
if (Number.isInteger(size)) {
|
||||
ip.setAttribute("size", size);
|
||||
} else {
|
||||
ip.setAttribute("style", `width:${size}`);
|
||||
}
|
||||
}
|
||||
ip.setAttribute("type", "text");
|
||||
ip.setAttribute("spellcheck", "false");
|
||||
row.style.display = hide ? 'none' : '';
|
||||
if (opt) {
|
||||
if (opt.disabled) ip.setAttribute("disabled", "true");
|
||||
if (opt.title) row.setAttribute("title", opt.title);
|
||||
if (opt.convert) ip.convert = opt.convert.bind(ip);
|
||||
if (opt.bound) ip.bound = opt.bound;
|
||||
if (opt.action) action = opt.action;
|
||||
}
|
||||
ip.addEventListener('focus', function(event) {
|
||||
hidePop();
|
||||
});
|
||||
if (action) {
|
||||
ip.addEventListener('keydown', function(event) {
|
||||
let key = event.key;
|
||||
if (
|
||||
opt.text ||
|
||||
(key >= '0' && key <= '9') ||
|
||||
key === '.' ||
|
||||
key === '-' ||
|
||||
key === 'Backspace' ||
|
||||
key === 'Delete' ||
|
||||
key === 'ArrowLeft' ||
|
||||
key === 'ArrowRight' ||
|
||||
key === 'Tab' ||
|
||||
event.metaKey ||
|
||||
event.ctrlKey ||
|
||||
(key === ',' && options.comma)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
ip.addEventListener('keyup', function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
// action(event);
|
||||
ip.blur();
|
||||
}
|
||||
});
|
||||
ip.addEventListener('blur', function(event) {
|
||||
action(event);
|
||||
});
|
||||
}
|
||||
if (!ip.convert) ip.convert = raw.bind(ip);
|
||||
ip.setVisible = row.setVisible;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function newRange(label, options) {
|
||||
let row = newDiv(options),
|
||||
ip = DOC.createElement('input'),
|
||||
hide = options && options.hide,
|
||||
action = inputAction;
|
||||
|
||||
if (label) row.appendChild(newLabel(label));
|
||||
row.appendChild(ip);
|
||||
row.setAttribute("class", "var-row");
|
||||
ip.setAttribute("type", "range");
|
||||
ip.setAttribute("min", (options && options.min ? options.min : 0));
|
||||
ip.setAttribute("max", (options && options.max ? options.max : 100));
|
||||
ip.setAttribute("value", 0);
|
||||
row.style.display = hide ? 'none' : '';
|
||||
if (options) {
|
||||
if (options.title) {
|
||||
ip.setAttribute("title", options.title);
|
||||
row.setAttribute("title", options.title);
|
||||
}
|
||||
if (options.action) action = options.action;
|
||||
}
|
||||
ip.setVisible = row.setVisible;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function newSelect(label, options, source) {
|
||||
let row = newDiv(options),
|
||||
ip = DOC.createElement('select'),
|
||||
hide = options && options.hide,
|
||||
action = inputAction;
|
||||
|
||||
row.appendChild(newLabel(label));
|
||||
row.appendChild(ip);
|
||||
row.setAttribute("source", source || "tools");
|
||||
row.setAttribute("class", "var-row");
|
||||
row.style.display = hide ? 'none' : '';
|
||||
if (options) {
|
||||
if (options.convert) ip.convert = options.convert.bind(ip);
|
||||
if (options.disabled) ip.setAttribute("disabled", "true");
|
||||
if (options.title) row.setAttribute("title", options.title);
|
||||
if (options.action) action = options.action;
|
||||
}
|
||||
ip.onchange = function() { action() };
|
||||
ip.setVisible = row.setVisible;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function newBooleanField(label, action, options) {
|
||||
let row = newDiv(options),
|
||||
ip = DOC.createElement('input'),
|
||||
hide = options && options.hide;
|
||||
|
||||
if (label) {
|
||||
row.appendChild(newLabel(label));
|
||||
}
|
||||
row.appendChild(ip);
|
||||
row.setAttribute("class", "var-row");
|
||||
row.style.display = hide ? 'none' : '';
|
||||
ip.setAttribute("type", "checkbox");
|
||||
ip.checked = false;
|
||||
if (options) {
|
||||
if (options.disabled) ip.setAttribute("disabled", "true");
|
||||
if (options.title) {
|
||||
ip.setAttribute("title", options.title);
|
||||
row.setAttribute("title", options.title);
|
||||
}
|
||||
}
|
||||
if (action) ip.onclick = function() { action() };
|
||||
ip.setVisible = row.setVisible;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function newBlank(options) {
|
||||
let row = newDiv(options),
|
||||
hide = options && options.hide;
|
||||
|
||||
row.setAttribute("class", "var-row");
|
||||
row.style.display = hide ? 'none' : '';
|
||||
ip.setVisible = row.setVisible;
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function newButton(label, action, options) {
|
||||
let opt = options || {},
|
||||
b = DOC.createElement('button');
|
||||
|
||||
b.onclick = function() {
|
||||
hidePoppers();
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
if (opt.class) {
|
||||
opt.class.split(' ').forEach(ce => {
|
||||
b.classList.add(ce);
|
||||
});
|
||||
}
|
||||
if (opt.icon) {
|
||||
let d = DOC.createElement('div');
|
||||
d.innerHTML = opt.icon;
|
||||
b.appendChild(d);
|
||||
}
|
||||
if (label) {
|
||||
b.appendChild(DOC.createTextNode(label));
|
||||
}
|
||||
|
||||
addModeControls(b, options);
|
||||
addId(b, options);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
function newTableRow(arrayOfArrays, options) {
|
||||
return newRow(newTables(arrayOfArrays), options);
|
||||
}
|
||||
|
||||
function newTables(arrayOfArrays) {
|
||||
let array = [];
|
||||
for (let i=0; i<arrayOfArrays.length; i++) {
|
||||
array.push(newRowTable(arrayOfArrays[i]));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function newRowTable(array) {
|
||||
let div = newDiv();
|
||||
div.setAttribute("class", "table-row");
|
||||
array.forEach(function(c) {
|
||||
div.appendChild(c);
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
function newRow(children, options) {
|
||||
let row = addCollapsableElement((options && options.noadd) ? null : addTo);
|
||||
if (children) children.forEach(function (c) { row.appendChild(c) });
|
||||
addModeControls(row, options);
|
||||
if (options && options.class) {
|
||||
options.class.split(' ').forEach(ce => {
|
||||
row.classList.add(ce);
|
||||
});
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
function addCollapsableElement(parent) {
|
||||
let row = newDiv();
|
||||
if (parent) parent.appendChild(row);
|
||||
if (lastGroup) lastGroup.push(row);
|
||||
return row;
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
||||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
let gs_kiri_widget = exports;
|
||||
|
||||
(function() {
|
||||
|
||||
if (!self.kiri) self.kiri = {};
|
||||
if (self.kiri.Widget) return;
|
||||
|
||||
let KIRI = self.kiri,
|
||||
const KIRI = self.kiri,
|
||||
DRIVERS = KIRI.driver,
|
||||
BASE = self.base,
|
||||
CONF = BASE.config,
|
||||
|
|
@ -20,8 +17,9 @@ let gs_kiri_widget = exports;
|
|||
SQRT = MATH.sqrt,
|
||||
PRO = Widget.prototype,
|
||||
time = UTIL.time,
|
||||
solid_opacity = 1.0,
|
||||
nextId = 0,
|
||||
solid_opacity = 1.0;
|
||||
|
||||
let nextId = 0,
|
||||
groups = [];
|
||||
|
||||
KIRI.Widget = Widget;
|
||||
|
|
@ -713,34 +711,9 @@ let gs_kiri_widget = exports;
|
|||
|
||||
/**
|
||||
* render all slice and processed data
|
||||
* @param {number} renderMode
|
||||
* @param {boolean} cam mode
|
||||
*/
|
||||
PRO.render = function(renderMode, cam) {
|
||||
let slices = this.slices;
|
||||
if (!slices) return;
|
||||
|
||||
let settings = this.settings,
|
||||
driver = DRIVERS[settings.mode.toUpperCase()];
|
||||
|
||||
// allow driver to override widget slice rendering (new in SLA)
|
||||
if (driver.sliceRender) return driver.sliceRender(this);
|
||||
|
||||
let extruder = this.getExtruder(settings);
|
||||
// render outline
|
||||
slices.forEach(function(s) { s.renderOutline(renderMode,extruder) });
|
||||
// render shells
|
||||
slices.forEach(function(s) { s.renderShells(renderMode) });
|
||||
// render diff
|
||||
if (!cam) slices.forEach(function(s) { s.renderDiff() });
|
||||
// render solid fill (include solid flats/bridges)
|
||||
slices.forEach(function(s) { s.renderSolidFill() });
|
||||
// render solid fill outlines
|
||||
if (!cam) slices.forEach(function(s) { s.renderSolidOutlines() });
|
||||
// render sparse fill
|
||||
if (!cam) slices.forEach(function(s) { s.renderSparseFill() });
|
||||
// render supports
|
||||
if (!cam) slices.forEach(function(s) { s.renderSupport() });
|
||||
PRO.render = function() {
|
||||
DRIVERS[this.settings.mode.toUpperCase()].sliceRender(this);
|
||||
};
|
||||
|
||||
PRO.hideSlices = function() {
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue