commit
365427ede7
76 changed files with 7225 additions and 2047 deletions
201
app.js
201
app.js
|
|
@ -21,10 +21,10 @@ const load = [];
|
||||||
const synth = {};
|
const synth = {};
|
||||||
const api = {};
|
const api = {};
|
||||||
|
|
||||||
let level;
|
|
||||||
let setupFn;
|
let setupFn;
|
||||||
let cacheDir;
|
let cacheDir;
|
||||||
let startTime;
|
let startTime;
|
||||||
|
let oversion;
|
||||||
let lastmod;
|
let lastmod;
|
||||||
let logger;
|
let logger;
|
||||||
let debug;
|
let debug;
|
||||||
|
|
@ -43,25 +43,8 @@ function init(mod) {
|
||||||
dir = mod.dir;
|
dir = mod.dir;
|
||||||
log = mod.log;
|
log = mod.log;
|
||||||
|
|
||||||
if (mod.util.globdir) {
|
|
||||||
// when globdir available, look for shared kvstore
|
|
||||||
// and if not present, create and share in through env
|
|
||||||
if (mod.env._level) {
|
|
||||||
level = mod.env._level;
|
|
||||||
logger.log("using shared kvstore");
|
|
||||||
} else {
|
|
||||||
level = require('level')(mod.util.globdir("kvstore"), {valueEncoding:"json"});
|
|
||||||
mod.env._level = level;
|
|
||||||
logger.log("creating shared kvstore");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log("fallback to local kvstore");
|
|
||||||
level = require('level')(mod.util.datadir("kvstore"), {valueEncoding:"json"});
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheDir = mod.util.datadir("cache");
|
cacheDir = mod.util.datadir("cache");
|
||||||
|
|
||||||
mod.on.reload(() => level.close());
|
|
||||||
mod.on.test((req) => {
|
mod.on.test((req) => {
|
||||||
let cookie = cookieValue(req.headers.cookie, "version") || undefined;
|
let cookie = cookieValue(req.headers.cookie, "version") || undefined;
|
||||||
let vmatch = mod.meta.version || "*";
|
let vmatch = mod.meta.version || "*";
|
||||||
|
|
@ -85,7 +68,6 @@ function init(mod) {
|
||||||
mod.add(handleVersion);
|
mod.add(handleVersion);
|
||||||
mod.add(prepath([
|
mod.add(prepath([
|
||||||
[ "/code/", handleCode ],
|
[ "/code/", handleCode ],
|
||||||
[ "/data/", handleData ],
|
|
||||||
[ "/wasm/", handleWasm ]
|
[ "/wasm/", handleWasm ]
|
||||||
]));
|
]));
|
||||||
mod.add(fixedmap("/api/", api));
|
mod.add(fixedmap("/api/", api));
|
||||||
|
|
@ -144,7 +126,8 @@ function initModule(mod, file, dir) {
|
||||||
require_fresh(file)({
|
require_fresh(file)({
|
||||||
api: api,
|
api: api,
|
||||||
adm: {
|
adm: {
|
||||||
reload: prepareScripts
|
reload: prepareScripts,
|
||||||
|
setver: (ver) => { oversion = ver }
|
||||||
},
|
},
|
||||||
const: {
|
const: {
|
||||||
args: {},
|
args: {},
|
||||||
|
|
@ -166,6 +149,8 @@ function initModule(mod, file, dir) {
|
||||||
time: time,
|
time: time,
|
||||||
guid: guid,
|
guid: guid,
|
||||||
mkdirs: util.mkdir,
|
mkdirs: util.mkdir,
|
||||||
|
isfile: util.isfile,
|
||||||
|
confdir: util.confdir,
|
||||||
datadir: util.datadir,
|
datadir: util.datadir,
|
||||||
lastmod: lastmod,
|
lastmod: lastmod,
|
||||||
obj2string: obj2string,
|
obj2string: obj2string,
|
||||||
|
|
@ -173,10 +158,6 @@ function initModule(mod, file, dir) {
|
||||||
getCookieValue: cookieValue,
|
getCookieValue: cookieValue,
|
||||||
logger: log.new
|
logger: log.new
|
||||||
},
|
},
|
||||||
db: {
|
|
||||||
api: db,
|
|
||||||
level: level
|
|
||||||
},
|
|
||||||
inject: (code, file, options) => {
|
inject: (code, file, options) => {
|
||||||
if (!script[code]) {
|
if (!script[code]) {
|
||||||
return logger.log(`inject missing target "${code}"`);
|
return logger.log(`inject missing target "${code}"`);
|
||||||
|
|
@ -239,11 +220,13 @@ const script = {
|
||||||
kiri : [
|
kiri : [
|
||||||
"kiri",
|
"kiri",
|
||||||
"ext/three",
|
"ext/three",
|
||||||
|
"ext/three-bgu",
|
||||||
"license",
|
"license",
|
||||||
"ext/clip2", // work.test
|
"ext/clip2", // work.test
|
||||||
"ext/tween",
|
"ext/tween",
|
||||||
"ext/fsave",
|
"ext/fsave",
|
||||||
"ext/earcut", // work.test
|
"ext/earcut", // work.test
|
||||||
|
"ext/base64",
|
||||||
"add/array",
|
"add/array",
|
||||||
"add/three",
|
"add/three",
|
||||||
"geo/base",
|
"geo/base",
|
||||||
|
|
@ -267,11 +250,11 @@ const script = {
|
||||||
"kiri/ui",
|
"kiri/ui",
|
||||||
"kiri/lang",
|
"kiri/lang",
|
||||||
"kiri/lang-en",
|
"kiri/lang-en",
|
||||||
"kiri/fill",
|
|
||||||
"kiri/db",
|
"kiri/db",
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
"kiri/client",
|
"kiri/client",
|
||||||
|
"mode/fdm/fill",
|
||||||
"mode/fdm/driver",
|
"mode/fdm/driver",
|
||||||
"mode/fdm/client",
|
"mode/fdm/client",
|
||||||
"mode/sla/driver",
|
"mode/sla/driver",
|
||||||
|
|
@ -297,6 +280,7 @@ const script = {
|
||||||
"kiri",
|
"kiri",
|
||||||
"ext/three",
|
"ext/three",
|
||||||
"ext/pngjs",
|
"ext/pngjs",
|
||||||
|
"ext/jszip",
|
||||||
"license",
|
"license",
|
||||||
"ext/clip2",
|
"ext/clip2",
|
||||||
"ext/earcut",
|
"ext/earcut",
|
||||||
|
|
@ -315,11 +299,11 @@ const script = {
|
||||||
"geo/polygons",
|
"geo/polygons",
|
||||||
"geo/gyroid",
|
"geo/gyroid",
|
||||||
"moto/pack",
|
"moto/pack",
|
||||||
"kiri/fill",
|
|
||||||
"kiri/slice",
|
"kiri/slice",
|
||||||
"kiri/slicer",
|
"kiri/slicer",
|
||||||
"kiri/slicer2",
|
"kiri/slicer2",
|
||||||
"kiri/layers",
|
"kiri/layers",
|
||||||
|
"mode/fdm/fill",
|
||||||
"mode/fdm/driver",
|
"mode/fdm/driver",
|
||||||
"mode/fdm/slice",
|
"mode/fdm/slice",
|
||||||
"mode/fdm/prepare",
|
"mode/fdm/prepare",
|
||||||
|
|
@ -404,40 +388,6 @@ const script = {
|
||||||
// prevent caching of specified modules
|
// prevent caching of specified modules
|
||||||
const cachever = {};
|
const cachever = {};
|
||||||
|
|
||||||
const db = {
|
|
||||||
// --------
|
|
||||||
key: arr => arr.join("/"),
|
|
||||||
// --------
|
|
||||||
get: key => {
|
|
||||||
if (Array.isArray(key)) key = db.key(key);
|
|
||||||
return promise((resolve,reject) => {
|
|
||||||
level.get(key,(err,record) => {
|
|
||||||
resolve(record,err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// --------
|
|
||||||
put: (key, value) => {
|
|
||||||
if (Array.isArray(key)) key = db.key(key);
|
|
||||||
return promise((resolve,reject) => {
|
|
||||||
level.put(key,value,(err) => {
|
|
||||||
if (err) reject(err);
|
|
||||||
else resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// --------
|
|
||||||
del: key => {
|
|
||||||
return promise((resolve,reject) => {
|
|
||||||
level.del(key, (err) => {
|
|
||||||
if (err) reject(err);
|
|
||||||
else resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function promise(resolve, reject) {
|
function promise(resolve, reject) {
|
||||||
return new Promise(resolve, reject);
|
return new Promise(resolve, reject);
|
||||||
}
|
}
|
||||||
|
|
@ -471,11 +421,12 @@ function handleSetup(req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleVersion(req, res, next) {
|
function handleVersion(req, res, next) {
|
||||||
if (req.app.path === "/kiri/" && req.url.indexOf(version) < 0) {
|
let vstr = oversion || version;
|
||||||
|
if (req.app.path === "/kiri/" && req.url.indexOf(vstr) < 0) {
|
||||||
if (req.url.indexOf("?") > 0) {
|
if (req.url.indexOf("?") > 0) {
|
||||||
return http.redirect(res, `${req.url},ver:${version}`);
|
return http.redirect(res, `${req.url},ver:${vstr}`);
|
||||||
} else {
|
} else {
|
||||||
return http.redirect(res, `${req.url}?ver:${version}`);
|
return http.redirect(res, `${req.url}?ver:${vstr}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
|
|
@ -496,118 +447,6 @@ function handleOptions(req, res, next) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleData(req, res, next) {
|
|
||||||
addCorsHeaders(req, res);
|
|
||||||
res.setHeader('Cache-Control', 'private, no-cache, max-age=0');
|
|
||||||
|
|
||||||
let tok = req.app.path.split('/'),
|
|
||||||
muid = req.headers['x-moto-ajax'],
|
|
||||||
space = tok[2] || null,
|
|
||||||
version = tok[3],
|
|
||||||
valid = space && space.length >= 4 && space.length <= 8;
|
|
||||||
|
|
||||||
function genKey() {
|
|
||||||
while (true) {
|
|
||||||
let k = Math.round(Math.random() * 9999999999).toString(36);
|
|
||||||
if (k.length >= 4 && k.length <= 8) return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function countKey(space) {
|
|
||||||
return db.key(['meta/counter',space]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ownerKey(space) {
|
|
||||||
return db.key(['meta/owner',muid,'space',space]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function recordKey(space, version) {
|
|
||||||
return db.key(["meta/space",space,version]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve latest space data
|
|
||||||
if (valid && req.method === 'GET' && valid) {
|
|
||||||
function send(rec, version) {
|
|
||||||
if (rec) {
|
|
||||||
res.write(obj2string({space:space,ver:version,rec:rec}));
|
|
||||||
res.end();
|
|
||||||
} else {
|
|
||||||
res.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function retrieve(version) {
|
|
||||||
return db.get(recordKey(space,version))
|
|
||||||
.then(record => {
|
|
||||||
send(record || null, version);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version) {
|
|
||||||
retrieve(version)
|
|
||||||
} else {
|
|
||||||
db.get(countKey(space)).then(version => retrieve(version));
|
|
||||||
}
|
|
||||||
} else if (valid && req.method === 'POST') {
|
|
||||||
let dbOwner = null,
|
|
||||||
dbVersion = null,
|
|
||||||
postBody = null,
|
|
||||||
spacein = space,
|
|
||||||
version = 0,
|
|
||||||
body = '';
|
|
||||||
|
|
||||||
function checkDone() {
|
|
||||||
if (!(dbVersion && postBody)) return;
|
|
||||||
// if not owner, assign new space id
|
|
||||||
if (dbVersion > 1) {
|
|
||||||
if (!dbOwner) {
|
|
||||||
space = genKey();
|
|
||||||
version = 1;
|
|
||||||
logger.log({forked:space,from:spacein,by:muid});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// log what we have
|
|
||||||
logger.log({
|
|
||||||
space: space,
|
|
||||||
ver: dbVersion,
|
|
||||||
uid: muid,
|
|
||||||
size: postBody.length
|
|
||||||
});
|
|
||||||
if (muid && muid.length > 0) {
|
|
||||||
level.put(recordKey(space, dbVersion), body);
|
|
||||||
level.put(ownerKey(space), {time: time(), ver: dbVersion});
|
|
||||||
level.put(countKey(space), dbVersion);
|
|
||||||
}
|
|
||||||
res.end(obj2string({space: space, ver: dbVersion}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// accumulate post body
|
|
||||||
req.on('data', data => { body += data });
|
|
||||||
req.on('end', () => {
|
|
||||||
postBody = body;
|
|
||||||
checkDone();
|
|
||||||
});
|
|
||||||
|
|
||||||
// fetch owner and version information
|
|
||||||
db.get(ownerKey(space))
|
|
||||||
.then(owner => {
|
|
||||||
dbOwner = owner;
|
|
||||||
return db.get(countKey(space));
|
|
||||||
})
|
|
||||||
.then(version => {
|
|
||||||
dbVersion = parseInt(version || "0") + 1;
|
|
||||||
checkDone();
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
next();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWasm(req, res, next) {
|
function handleWasm(req, res, next) {
|
||||||
let [root, file] = req.app.path.split('/').slice(1);
|
let [root, file] = req.app.path.split('/').slice(1);
|
||||||
let ext = (file || '').split('.')[1];
|
let ext = (file || '').split('.')[1];
|
||||||
|
|
@ -775,10 +614,14 @@ function getCachedFile(file, fn) {
|
||||||
let smod = lastmod(filePath),
|
let smod = lastmod(filePath),
|
||||||
cmod = cached.mtime;
|
cmod = cached.mtime;
|
||||||
|
|
||||||
if (!smod) throw "missing source file";
|
if (!smod) {
|
||||||
if (smod > cmod) cached = null;
|
throw "missing source file";
|
||||||
|
}
|
||||||
cached.lastcheck = now;
|
if (smod > cmod) {
|
||||||
|
cached = null;
|
||||||
|
} else {
|
||||||
|
cached.lastcheck = now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
65
notes.md
65
notes.md
|
|
@ -2,46 +2,49 @@
|
||||||
|
|
||||||
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
||||||
|
|
||||||
* `B` saved profile should be restored / defaulted when switching devices?
|
* `B` origin (and bed size) bug (Onshape?) when switching modes in 2.5 and 2.6
|
||||||
* `B` normals possibly inverted on faces in 2D to 3D conversion
|
|
||||||
* `B` normalize left, bottom, right pop menu time/click and value persistence
|
|
||||||
* `B` origin bug (Onshape?) when switching modes in 2.5 and 2.6
|
|
||||||
|
|
||||||
* `P` duplicate objects should share same slice data unless rotated or scaled
|
* `P` duplicate objects should share same slice data unless rotated or scaled
|
||||||
* `P` allow selection to me decimated on demand (context menu?)
|
* `P` allow selection to me decimated on demand (context menu?)
|
||||||
* `P` improve decimation speed: omit point conversion or use wasm
|
* `P` improve decimation speed: omit point conversion or use wasm
|
||||||
* `P` client/worker interface normalization
|
* `P` client/worker message interface normalization
|
||||||
* `P` explore widget vertex reloading / replacing
|
* `P` explore widget vertex reloading / replacing (Onshape) (issue #48)
|
||||||
|
|
||||||
* `F` SVG import to 3D part like images
|
* `F` SVG import to 3D part like images
|
||||||
|
* `F` show slider range values in workspace units (on hover?)
|
||||||
|
* `F` allow select of a range by typing in values in slices or workspace units
|
||||||
|
* `F` add % field type with conversion (like units)
|
||||||
|
* `F` complete G2/G3 arc output / input (85% now)
|
||||||
|
* `F` expose grouping feature
|
||||||
|
* `F` add svgnest-like arrange algorithm
|
||||||
|
|
||||||
# FDM
|
# FDM
|
||||||
|
|
||||||
* `B` large # linear points with linear infill (belt only?)
|
* `B` re-calibrate slicing progress weighting
|
||||||
* `B` fix adaptive slicing with multi-extruder
|
* `B` infill densities are inaccurate
|
||||||
* `B` fix supports with grouped parts
|
* `B` fix support projection/end with grouped parts
|
||||||
* `B` multi-extruder rendering of raft fails to offset the rest of the print
|
* `B` multi-extruder rendering of raft fails to offset the rest of the print
|
||||||
* `B` multi-extruder purge blocks fail to generate properly for rafts
|
* `B` multi-extruder purge blocks fail to generate properly for rafts
|
||||||
|
|
||||||
* `F` slicing controls per user-defined z-region
|
* `F` support pillar should conform to part
|
||||||
|
* `F` support pillar should have solid top/bottom
|
||||||
|
* `F` more explicit line width control with ranges and min/max adaptive
|
||||||
|
* `F` test outlining solid projected areas (internally)
|
||||||
* `F` control for size of purge block (with 0=disabled)
|
* `F` control for size of purge block (with 0=disabled)
|
||||||
* `F` add separate fill speed control
|
|
||||||
* `F` polishing and other non-planar work
|
* `F` polishing and other non-planar work
|
||||||
* `F` gradient infill https://www.youtube.com/watch?v=hq53gsYREHU&feature=emb_logo
|
* `F` gradient infill https://www.youtube.com/watch?v=hq53gsYREHU&feature=emb_logo
|
||||||
* `F` first layer segment large flat areas for better fill reliability
|
|
||||||
* `F` feather sharp tips by reducing extrusion in area of overlap
|
* `F` feather sharp tips by reducing extrusion in area of overlap
|
||||||
|
* `F` first layer segment large flat areas for better fill reliability
|
||||||
* `F` enable purge blocks when quick layers are detected
|
* `F` enable purge blocks when quick layers are detected
|
||||||
* `F` option to support interior bridges when 0% infill
|
* `F` option to support interior bridges when 0% infill
|
||||||
* `F` trim support offset from layer below
|
|
||||||
* `F` calculate filament use per extruder per print
|
* `F` calculate filament use per extruder per print
|
||||||
* `F` first layer support speed should be same as shell speed
|
|
||||||
* `F` apply finish speed to exposed top and underside flat areas
|
* `F` apply finish speed to exposed top and underside flat areas
|
||||||
* `F` expand internal supporting flats / solids before projection
|
* `F` expand internal supporting flats / solids before projection
|
||||||
|
|
||||||
|
* `P` extruder + filament max flow rate cap in planner
|
||||||
* `P` revisit path routing / optimization
|
* `P` revisit path routing / optimization
|
||||||
* `P` implement infill clipping in wasm
|
* `P` implement infill clipping in wasm
|
||||||
* `P` solid fill the tops of supports for down facing flats
|
* `P` solid fill the tops of supports for down facing flats
|
||||||
* `P` sparse infill should follow polys between intersect points
|
|
||||||
|
|
||||||
# FDM - SLA
|
# FDM - SLA
|
||||||
|
|
||||||
|
|
@ -51,27 +54,33 @@
|
||||||
|
|
||||||
# FDM - BELT
|
# FDM - BELT
|
||||||
|
|
||||||
* `B` fix supports for belt printing
|
* `B` auto bed resizing leaves the origin in the wrong place at first
|
||||||
|
* `B` ranges don't work with anchors
|
||||||
|
* `B` multiple parts with one angled against origin "floats" in preview
|
||||||
|
* `B` re-add progress calls for all work units
|
||||||
|
|
||||||
|
* `F` slightly angle supports to lean into the Z of the part
|
||||||
|
* `F` arrange should just align down Z, not side to side.
|
||||||
|
|
||||||
# CAM
|
# CAM
|
||||||
|
|
||||||
|
* `B` tabs are not cut to exact height
|
||||||
* `B` first rough step too far down in certain circumstances?
|
* `B` first rough step too far down in certain circumstances?
|
||||||
* `B` trace open polys are not wound consistently
|
* `B` trace open polys are not wound consistently
|
||||||
* `B` path routing with tabs sometimes makes no sense
|
* `B` path routing with tabs sometimes makes no sense
|
||||||
* `B` clicking on a pop-op should pin it until clicked or [esc]
|
* `B` clicking on a pop-op should pin it until clicked or [esc]
|
||||||
* `B` need to force cut line at synthetic z bottom (midlines, etc)
|
* `B` need to force cut line at synthetic z bottom (midlines, etc)
|
||||||
* `B` non-clear-voids duplicates thru-holes
|
|
||||||
* `B` failure to go *up* when moving between parts?
|
|
||||||
* `B` starting export during animation unleashes chaos
|
* `B` starting export during animation unleashes chaos
|
||||||
* `B` climb vs conventional not fully consistent after refactor
|
|
||||||
* `B` outside cutting direction in roughing mode inverted
|
|
||||||
|
|
||||||
|
* `F` limit cut depth to flute length of selected tool
|
||||||
|
* `F` add ease-down support to trace op
|
||||||
|
* `F` add linear clearing strategy
|
||||||
|
* `F` add adaptive clearing strategy
|
||||||
|
* `F` user-selectable origin (issue #28)
|
||||||
* `F` intelligently turn circle hole pocket clear into spiral down
|
* `F` intelligently turn circle hole pocket clear into spiral down
|
||||||
* `F` trace follow hole that matches endmill should turn into a drill op
|
* `F` trace follow hole that matches endmill should turn into a drill op
|
||||||
* `F` add climb/conventional into each operation
|
* `F` add climb/conventional into each operation
|
||||||
* `F` update analyzer to detect overhangs
|
* `F` update analyzer to detect overhangs
|
||||||
* `F` add linear clearing strategy option for roughing / pocket
|
|
||||||
* `F` adaptive clearing in roughing mode
|
|
||||||
* `F` extend acute roughing on inside polys to clear small voids
|
* `F` extend acute roughing on inside polys to clear small voids
|
||||||
* `F` option to use part / STL coordinate space to determine X,Y origin
|
* `F` option to use part / STL coordinate space to determine X,Y origin
|
||||||
* `F` validate muti-part layout and spacing exceeds largest outside tool diameter
|
* `F` validate muti-part layout and spacing exceeds largest outside tool diameter
|
||||||
|
|
@ -88,14 +97,13 @@
|
||||||
* `F` can animation clear the mesh in areas where the cuts go through the stock?
|
* `F` can animation clear the mesh in areas where the cuts go through the stock?
|
||||||
* `F` support lathe mode / A-axis / rotary
|
* `F` support lathe mode / A-axis / rotary
|
||||||
* `F` gcode output option as zip for multiple or flip ops or tool change
|
* `F` gcode output option as zip for multiple or flip ops or tool change
|
||||||
* `F` ease-down should be engaged in all descending cutting operations
|
* `F` maintain several part orientations + op chains in a single profile
|
||||||
* `F` entirely user-selectable origin
|
|
||||||
|
|
||||||
|
|
||||||
* `P` common part pre-analyze to speed up 'slice' and improve shadow (overhangs)
|
* `P` common part pre-analyze to speed up 'slice' and improve shadow (overhangs)
|
||||||
* `P` redo all path route / planning in prepare to account for terrain before camOut
|
* `P` redo all path route / planning in prepare to account for terrain before camOut
|
||||||
* `P` detect render message backlog and pause or warn
|
* `P` detect render message backlog and pause or warn?
|
||||||
* `P` allow faster z movements when contouring (not plunging)
|
* `P` allow faster z movements when contouring (not plunging)
|
||||||
|
* `P` common / faster shadow generator using vertices shared with ledges
|
||||||
|
|
||||||
# Laser
|
# Laser
|
||||||
|
|
||||||
|
|
@ -108,6 +116,7 @@
|
||||||
* http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools
|
* http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools
|
||||||
* http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html
|
* http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html
|
||||||
* http://photon.chrisgraf.de/
|
* http://photon.chrisgraf.de/
|
||||||
|
* https://github.com/Jack000/SVGnest
|
||||||
|
|
||||||
# More CNC
|
# More CNC
|
||||||
|
|
||||||
|
|
@ -118,3 +127,7 @@
|
||||||
* https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
|
* https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
|
||||||
* https://en.wikipedia.org/wiki/ZIP_(file_format)
|
* https://en.wikipedia.org/wiki/ZIP_(file_format)
|
||||||
* https://stuk.github.io/jszip/
|
* https://stuk.github.io/jszip/
|
||||||
|
|
||||||
|
# Meta
|
||||||
|
|
||||||
|
* free-space tetrahedron modeler with vertex mating
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "grid-apps",
|
"name": "grid-apps",
|
||||||
"version": "2.6.8D",
|
"version": "2.8.1D",
|
||||||
"description": "grid.space 3d slice & modeling tools",
|
"description": "grid.space 3d slice & modeling tools",
|
||||||
"author": "Stewart Allen <sa@grid.space>",
|
"author": "Stewart Allen <sa@grid.space>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -21,18 +21,17 @@
|
||||||
"slicer"
|
"slicer"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"base64-js": "^1.5.1",
|
||||||
"buffer-crc32": "^0.2.13",
|
"buffer-crc32": "^0.2.13",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"connect": "^3.7.0",
|
"connect": "^3.7.0",
|
||||||
"earcut": "^2.2.2",
|
"earcut": "^2.2.2",
|
||||||
"express-useragent": "^1.0.13",
|
"express-useragent": "^1.0.13",
|
||||||
"level": "^6.0.1",
|
"jszip": "^3.5.0",
|
||||||
"leveldown": "^5.6.0",
|
|
||||||
"levelup": "^4.4.0",
|
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"pixi.js": "^4.8.9",
|
"pixi.js": "^4.8.9",
|
||||||
"serve-static": "^1.14.1",
|
"serve-static": "^1.14.1",
|
||||||
"three": "^0.122.0",
|
"three": "^0.126.0",
|
||||||
"tween.js": "^0.14.0",
|
"tween.js": "^0.14.0",
|
||||||
"uglify-es": "3.3.9",
|
"uglify-es": "3.3.9",
|
||||||
"validator": "^8.2.0",
|
"validator": "^8.2.0",
|
||||||
|
|
|
||||||
26
readme.md
26
readme.md
|
|
@ -1,6 +1,6 @@
|
||||||
[](https://paypal.me/gridspace3d?locale.x=en_US)
|
[](https://paypal.me/gridspace3d?locale.x=en_US)
|
||||||
|
|
||||||
Contributions in all forms (code, bug reports, community engagenment, cash money, etc) are warmly welcomed. They all go to the bottom line of making better apps.
|
Contributions in all forms (code, bug reports, community engagement, localization, etc) are warmly welcomed.
|
||||||
|
|
||||||
[](https://discord.com/channels/688863523207774209/688863523211968535)
|
[](https://discord.com/channels/688863523207774209/688863523211968535)
|
||||||

|

|
||||||
|
|
@ -19,6 +19,8 @@ Contributions in all forms (code, bug reports, community engagenment, cash money
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
### Development Activity
|
### Development Activity
|
||||||
|
|
||||||
|
|
@ -54,6 +56,21 @@ to start a local instance of the apps. then open
|
||||||
[Kiri:Moto](http://localhost:8080/kiri) or
|
[Kiri:Moto](http://localhost:8080/kiri) or
|
||||||
[Meta:Moto](http://localhost:8080/meta) on your local host
|
[Meta:Moto](http://localhost:8080/meta) on your local host
|
||||||
|
|
||||||
|
Alternatively, if you are using a packaged version of npm that ships with
|
||||||
|
a Linux distribution, but still want to install in your home directory, you
|
||||||
|
can use
|
||||||
|
|
||||||
|
```
|
||||||
|
npm config set prefix ~/.local
|
||||||
|
```
|
||||||
|
|
||||||
|
If gs-app-server is not found, then perhaps ~/.local/bin is not in
|
||||||
|
your path. You can either add it to your path, or you can run:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/local/bin/gs-app-server --debug
|
||||||
|
```
|
||||||
|
|
||||||
### Windows Developers
|
### Windows Developers
|
||||||
|
|
||||||
this git repo requires symbolic link support. on Windows, this means you have to clone the repo in a command shell with Administrator privileges.
|
this git repo requires symbolic link support. on Windows, this means you have to clone the repo in a command shell with Administrator privileges.
|
||||||
|
|
@ -68,8 +85,9 @@ web site.
|
||||||
|
|
||||||
requires node.js 12+
|
requires node.js 12+
|
||||||
|
|
||||||
### Javascript Slicing API
|
### Javascript Slicing APIs
|
||||||
|
|
||||||
A script include that injects a web worker into the page that will asynchronously perform any of Kiri’s slicing and gcode generation functions.
|
A script include that injects a web worker into the page that will asynchronously perform any of Kiri’s slicing and gcode generation functions. And a frame messaging API for controlling Kiri:Moto inside an IFrame.
|
||||||
|
|
||||||
https://grid.space/kiri/engine.html
|
* https://grid.space/kiri/engine.html
|
||||||
|
* https://grid.space/kiri/frame.html
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,10 @@
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AP.uniq = function() {
|
||||||
|
return this.slice().sort().filter((x, i, a) => !i || x != a[i-1]);
|
||||||
|
};
|
||||||
|
|
||||||
/** ******************************************************************
|
/** ******************************************************************
|
||||||
* String prototype helpers
|
* String prototype helpers
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,18 @@
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var MP = THREE.Mesh.prototype,
|
var MP = THREE.Mesh.prototype,
|
||||||
GP = THREE.Geometry.prototype,
|
|
||||||
BP = THREE.BufferGeometry.prototype;
|
BP = THREE.BufferGeometry.prototype;
|
||||||
|
|
||||||
|
THREE.computeFaceNormal = function(vA,vB,vC) {
|
||||||
|
const ab = new THREE.Vector3();
|
||||||
|
const cb = new THREE.Vector3();
|
||||||
|
cb.subVectors( vC, vB );
|
||||||
|
ab.subVectors( vA, vB );
|
||||||
|
cb.cross( ab );
|
||||||
|
cb.normalize();
|
||||||
|
return cb;
|
||||||
|
};
|
||||||
|
|
||||||
MP.getBoundingBox = function(update) {
|
MP.getBoundingBox = function(update) {
|
||||||
return this.geometry.getBoundingBox(update);
|
return this.geometry.getBoundingBox(update);
|
||||||
};
|
};
|
||||||
|
|
@ -46,7 +55,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// center geometry on x,y,z coordinates (defaults to 0,0,0)
|
// center geometry on x,y,z coordinates (defaults to 0,0,0)
|
||||||
GP.center = function(x,y,z) {
|
BP.center = function(x,y,z) {
|
||||||
var box = this.getBoundingBox(),
|
var box = this.getBoundingBox(),
|
||||||
mid = box.dim.clone().multiplyScalar(0.5),
|
mid = box.dim.clone().multiplyScalar(0.5),
|
||||||
dif = mid.clone().add(box.min),
|
dif = mid.clone().add(box.min),
|
||||||
|
|
@ -69,14 +78,17 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// return cached or refreshed (when update = true) bounding box
|
// return cached or refreshed (when update = true) bounding box
|
||||||
GP.getBoundingBox = function(update) {
|
BP.getBoundingBox = function(update) {
|
||||||
if (update || !this.boundingBox) this.computeBoundingBox();
|
if (update || !this.boundingBox) {
|
||||||
|
this.boundingBox = null;
|
||||||
|
this.computeBoundingBox();
|
||||||
|
}
|
||||||
this.boundingBox.dim = this.boundingBox.max.clone().sub(this.boundingBox.min);
|
this.boundingBox.dim = this.boundingBox.max.clone().sub(this.boundingBox.min);
|
||||||
return this.boundingBox;
|
return this.boundingBox;
|
||||||
};
|
};
|
||||||
|
|
||||||
// uniformly scale any mesh to a max x/y/z dim of 'unit' (defaults to 1)
|
// uniformly scale any mesh to a max x/y/z dim of 'unit' (defaults to 1)
|
||||||
GP.unitScale = function(unit) {
|
BP.unitScale = function(unit) {
|
||||||
var bbox = this.getBoundingBox().clone(),
|
var bbox = this.getBoundingBox().clone(),
|
||||||
scale = (unit || 1) / Math.max(
|
scale = (unit || 1) / Math.max(
|
||||||
bbox.max.x - bbox.min.x,
|
bbox.max.x - bbox.min.x,
|
||||||
|
|
@ -89,20 +101,21 @@
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
BP.center = GP.center;
|
|
||||||
BP.getBoundingBox = GP.getBoundingBox;
|
|
||||||
BP.unitScale = GP.unitScale;
|
|
||||||
|
|
||||||
BP.fixNormals = function() {
|
BP.fixNormals = function() {
|
||||||
this.computeVertexNormals();
|
this.computeVertexNormals();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
THREE.Geometry.fromVertices = function(vertices) {
|
// may be faster than the equivalent matrix transform. to be tested
|
||||||
var geometry = new THREE.BufferGeometry();
|
// BP.translate = function(x,y,z) {
|
||||||
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
|
// let off = [x,y,z],
|
||||||
return geometry;
|
// arr = this.attributes.position.array,
|
||||||
};
|
// len = arr.length;
|
||||||
|
// for (let i=0; i<len; i++) {
|
||||||
|
// arr[i] += off[i%3];
|
||||||
|
// }
|
||||||
|
// return this;
|
||||||
|
// }
|
||||||
|
|
||||||
THREE.Object3D.prototype.newGroup = function() {
|
THREE.Object3D.prototype.newGroup = function() {
|
||||||
var group = new THREE.Group();
|
var group = new THREE.Group();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"M03 S20000 ; spindle on"
|
"M03 S20000 ; spindle on"
|
||||||
],
|
],
|
||||||
"post":[
|
"post":[
|
||||||
"M05 ; spindle off",
|
"M05 ; spindle off",
|
||||||
"M30 ; program end"
|
"M30 ; program end"
|
||||||
],
|
],
|
||||||
"tool-change":[
|
"tool-change":[
|
||||||
|
|
|
||||||
21
src/dev/cam/Roland.MDX-50
Normal file
21
src/dev/cam/Roland.MDX-50
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"file-ext": "rml",
|
||||||
|
"token-space": "",
|
||||||
|
"strip-comments": true,
|
||||||
|
"pre":[
|
||||||
|
"PA;PA;VS4;!VZ4;!PZ0,80;!MC1;"
|
||||||
|
],
|
||||||
|
"post":[
|
||||||
|
"PA;PA;!PZ0,2420;PU0,6096;!MC0;"
|
||||||
|
],
|
||||||
|
"dwell":[
|
||||||
|
"W{time};"
|
||||||
|
],
|
||||||
|
"spindle": [
|
||||||
|
"!RC{speed};"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"bed_width": 400,
|
||||||
|
"bed_depth": 305
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,8 +15,7 @@
|
||||||
"G1 X200 E50 F800 ; extruder purge line",
|
"G1 X200 E50 F800 ; extruder purge line",
|
||||||
"G1 Z0.3 ; shift belt away 0.3mm",
|
"G1 Z0.3 ; shift belt away 0.3mm",
|
||||||
"G1 X0 E100 ; extruder purge line",
|
"G1 X0 E100 ; extruder purge line",
|
||||||
"G1 Z2 E98 ; shift belt away 2mm, retract extruder",
|
"G92 Z0 E0 ; reset bed + extruder position",
|
||||||
"G92 Z0 E-2 ; reset bed + extruder position",
|
|
||||||
"M117 CR-30 Printing..."
|
"M117 CR-30 Printing..."
|
||||||
],
|
],
|
||||||
"post":[
|
"post":[
|
||||||
|
|
@ -54,12 +53,12 @@
|
||||||
"origin_center": false,
|
"origin_center": false,
|
||||||
"extrude_abs": true,
|
"extrude_abs": true,
|
||||||
"bed_belt": true,
|
"bed_belt": true,
|
||||||
"bed_width": 215,
|
"bed_width": 220,
|
||||||
"bed_depth": 300,
|
"bed_depth": 300,
|
||||||
"build_height": 170
|
"build_height": 170
|
||||||
},
|
},
|
||||||
"profiles":[{
|
"profiles":[{
|
||||||
"processName": "CR30",
|
"processName": "CR30 PLA",
|
||||||
"sliceHeight": 0.25,
|
"sliceHeight": 0.25,
|
||||||
"sliceShells": 3,
|
"sliceShells": 3,
|
||||||
"sliceShellOrder": "in-out",
|
"sliceShellOrder": "in-out",
|
||||||
|
|
@ -68,43 +67,100 @@
|
||||||
"sliceFillOverlap": 0.3,
|
"sliceFillOverlap": 0.3,
|
||||||
"sliceFillSparse": 0.2,
|
"sliceFillSparse": 0.2,
|
||||||
"sliceFillType": "hex",
|
"sliceFillType": "hex",
|
||||||
|
"sliceAdaptive": false,
|
||||||
|
"sliceMinHeight": 0,
|
||||||
"sliceSupportDensity": 0.25,
|
"sliceSupportDensity": 0.25,
|
||||||
"sliceSupportOffset": 1.0,
|
"sliceSupportOffset": 0.4,
|
||||||
"sliceSupportGap": 0.75,
|
"sliceSupportGap": 0,
|
||||||
"sliceSupportSize": 5,
|
"sliceSupportSize": 6,
|
||||||
"sliceSupportArea": 0.1,
|
"sliceSupportArea": 0.25,
|
||||||
"sliceSupportExtra": 0,
|
"sliceSupportExtra": 0,
|
||||||
"sliceSupportAngle": 50,
|
"sliceSupportAngle": 1,
|
||||||
"sliceSupportNozzle": 0,
|
"sliceSupportNozzle": 0,
|
||||||
"sliceSolidMinArea": 1,
|
"sliceSolidMinArea": 1,
|
||||||
"sliceSolidLayers": 3,
|
"sliceSolidLayers": 3,
|
||||||
"sliceBottomLayers": 3,
|
"sliceBottomLayers": 3,
|
||||||
"sliceTopLayers": 3,
|
"sliceTopLayers": 3,
|
||||||
"firstLayerRate": 15,
|
"firstLayerRate": 10,
|
||||||
"firstLayerPrintMult": 1.1,
|
"firstLayerPrintMult": 1.10,
|
||||||
"firstLayerYOffset": 0,
|
"firstLayerYOffset": 0,
|
||||||
"firstLayerBrim": 0,
|
"firstLayerBrim": 0,
|
||||||
|
"firstLayerBeltLead": 0,
|
||||||
|
"firstLayerFanSpeed": 0,
|
||||||
"outputTemp": 210,
|
"outputTemp": 210,
|
||||||
"outputFanMax": 255,
|
"outputFanMax": 255,
|
||||||
"outputBedTemp": 70,
|
"outputBedTemp": 70,
|
||||||
|
"outputFanSpeed": 255,
|
||||||
"outputFeedrate": 50,
|
"outputFeedrate": 50,
|
||||||
"outputFinishrate": 50,
|
"outputFinishrate": 40,
|
||||||
"outputSeekrate": 80,
|
"outputSeekrate": 80,
|
||||||
"outputShellMult": 1.25,
|
"outputShellMult": 1.2,
|
||||||
"outputFillMult": 1.25,
|
"outputFillMult": 1.2,
|
||||||
"outputSparseMult": 1.25,
|
"outputSparseMult": 1.2,
|
||||||
"outputFanLayer": 1,
|
"outputFanLayer": 0,
|
||||||
"outputRetractDist": 3,
|
"outputRetractDist": 5,
|
||||||
"outputRetractSpeed": 40,
|
"outputRetractSpeed": 40,
|
||||||
"outputRetractDwell": 30,
|
"outputRetractWipe": 1,
|
||||||
"outputShortPoly": 100.0,
|
"outputRetractDwell": 20,
|
||||||
|
"outputShortPoly": 60.0,
|
||||||
"outputMinSpeed": 10.0,
|
"outputMinSpeed": 10.0,
|
||||||
"outputCoastDist": 0,
|
"outputCoastDist": 0.1,
|
||||||
"outputWipeDistance": 0,
|
"outputWipeDistance": 1,
|
||||||
"outputLayerRetract": false,
|
"outputLayerRetract": false,
|
||||||
"detectThinWalls": true,
|
"detectThinWalls": true,
|
||||||
"sliceMinHeight": 0,
|
"zHopDistance": 0,
|
||||||
|
"antiBacklash": 0
|
||||||
|
},{
|
||||||
|
"processName": "CR30 PETG",
|
||||||
|
"sliceHeight": 0.25,
|
||||||
|
"sliceShells": 3,
|
||||||
|
"sliceShellOrder": "in-out",
|
||||||
|
"sliceLayerStart": "last",
|
||||||
|
"sliceFillAngle": 45,
|
||||||
|
"sliceFillOverlap": 0.3,
|
||||||
|
"sliceFillSparse": 0.2,
|
||||||
|
"sliceFillType": "hex",
|
||||||
"sliceAdaptive": false,
|
"sliceAdaptive": false,
|
||||||
|
"sliceMinHeight": 0,
|
||||||
|
"sliceSupportDensity": 0.25,
|
||||||
|
"sliceSupportOffset": 0.4,
|
||||||
|
"sliceSupportGap": 0,
|
||||||
|
"sliceSupportSize": 6,
|
||||||
|
"sliceSupportArea": 0.25,
|
||||||
|
"sliceSupportExtra": 0,
|
||||||
|
"sliceSupportAngle": 1,
|
||||||
|
"sliceSupportNozzle": 0,
|
||||||
|
"sliceSolidMinArea": 1,
|
||||||
|
"sliceSolidLayers": 3,
|
||||||
|
"sliceBottomLayers": 3,
|
||||||
|
"sliceTopLayers": 3,
|
||||||
|
"firstLayerRate": 10,
|
||||||
|
"firstLayerPrintMult": 1.15,
|
||||||
|
"firstLayerYOffset": 0,
|
||||||
|
"firstLayerBrim": 0,
|
||||||
|
"firstLayerBeltLead": 0,
|
||||||
|
"firstLayerFanSpeed": 0,
|
||||||
|
"outputTemp": 240,
|
||||||
|
"outputFanMax": 0,
|
||||||
|
"outputBedTemp": 70,
|
||||||
|
"outputFanSpeed": 0,
|
||||||
|
"outputFeedrate": 40,
|
||||||
|
"outputFinishrate": 30,
|
||||||
|
"outputSeekrate": 80,
|
||||||
|
"outputShellMult": 1.2,
|
||||||
|
"outputFillMult": 1.2,
|
||||||
|
"outputSparseMult": 1.2,
|
||||||
|
"outputFanLayer": 0,
|
||||||
|
"outputRetractDist": 5.5,
|
||||||
|
"outputRetractSpeed": 30,
|
||||||
|
"outputRetractWipe": 1,
|
||||||
|
"outputRetractDwell": 20,
|
||||||
|
"outputShortPoly": 60.0,
|
||||||
|
"outputMinSpeed": 10.0,
|
||||||
|
"outputCoastDist": 0.1,
|
||||||
|
"outputWipeDistance": 1,
|
||||||
|
"outputLayerRetract": false,
|
||||||
|
"detectThinWalls": true,
|
||||||
"zHopDistance": 0,
|
"zHopDistance": 0,
|
||||||
"antiBacklash": 0
|
"antiBacklash": 0
|
||||||
}]
|
}]
|
||||||
|
|
|
||||||
|
|
@ -39,5 +39,59 @@
|
||||||
"bed_width": 220,
|
"bed_width": 220,
|
||||||
"bed_depth": 220,
|
"bed_depth": 220,
|
||||||
"build_height": 300
|
"build_height": 300
|
||||||
}
|
},
|
||||||
|
"profiles":[{
|
||||||
|
"processName": "Ender3 PLA",
|
||||||
|
"sliceHeight": 0.25,
|
||||||
|
"sliceShells": 3,
|
||||||
|
"sliceShellOrder": "in-out",
|
||||||
|
"sliceLayerStart": "last",
|
||||||
|
"sliceFillAngle": 45,
|
||||||
|
"sliceFillOverlap": 0.3,
|
||||||
|
"sliceFillSparse": 0.2,
|
||||||
|
"sliceFillType": "hex",
|
||||||
|
"sliceAdaptive": false,
|
||||||
|
"sliceMinHeight": 0,
|
||||||
|
"sliceSupportDensity": 0.25,
|
||||||
|
"sliceSupportOffset": 0.4,
|
||||||
|
"sliceSupportGap": 0,
|
||||||
|
"sliceSupportSize": 6,
|
||||||
|
"sliceSupportArea": 0.25,
|
||||||
|
"sliceSupportExtra": 0,
|
||||||
|
"sliceSupportAngle": 1,
|
||||||
|
"sliceSupportNozzle": 0,
|
||||||
|
"sliceSolidMinArea": 1,
|
||||||
|
"sliceSolidLayers": 3,
|
||||||
|
"sliceBottomLayers": 3,
|
||||||
|
"sliceTopLayers": 3,
|
||||||
|
"firstLayerRate": 10,
|
||||||
|
"firstLayerPrintMult": 1.10,
|
||||||
|
"firstLayerYOffset": 0,
|
||||||
|
"firstLayerBrim": 0,
|
||||||
|
"firstLayerBeltLead": 0,
|
||||||
|
"firstLayerFanSpeed": 0,
|
||||||
|
"outputTemp": 210,
|
||||||
|
"outputFanMax": 255,
|
||||||
|
"outputBedTemp": 70,
|
||||||
|
"outputFanSpeed": 255,
|
||||||
|
"outputFeedrate": 50,
|
||||||
|
"outputFinishrate": 40,
|
||||||
|
"outputSeekrate": 80,
|
||||||
|
"outputShellMult": 1.2,
|
||||||
|
"outputFillMult": 1.2,
|
||||||
|
"outputSparseMult": 1.2,
|
||||||
|
"outputFanLayer": 0,
|
||||||
|
"outputRetractDist": 5,
|
||||||
|
"outputRetractSpeed": 40,
|
||||||
|
"outputRetractWipe": 1,
|
||||||
|
"outputRetractDwell": 20,
|
||||||
|
"outputShortPoly": 60.0,
|
||||||
|
"outputMinSpeed": 10.0,
|
||||||
|
"outputCoastDist": 0.1,
|
||||||
|
"outputWipeDistance": 1,
|
||||||
|
"outputLayerRetract": false,
|
||||||
|
"detectThinWalls": true,
|
||||||
|
"zHopDistance": 0,
|
||||||
|
"antiBacklash": 0
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
||||||
"G1 E15 F200 ; purge 15mm from extruder",
|
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"G1 F225 ; set feed speed"
|
"G1 F225 ; set feed speed"
|
||||||
],
|
],
|
||||||
|
|
@ -19,7 +18,6 @@
|
||||||
"M107 ; turn off filament cooling fan",
|
"M107 ; turn off filament cooling fan",
|
||||||
"M104 S0 T{tool} ; turn off right extruder",
|
"M104 S0 T{tool} ; turn off right extruder",
|
||||||
"M140 S0 T{tool} ; turn off bed",
|
"M140 S0 T{tool} ; turn off bed",
|
||||||
"G1 Z{z_max} F1200 ; drop bed",
|
|
||||||
"G28 X0 Y0 ; home XY axes",
|
"G28 X0 Y0 ; home XY axes",
|
||||||
"M84 ; disable stepper motors"
|
"M84 ; disable stepper motors"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
||||||
"G1 E15 F200 ; purge 15mm from extruder",
|
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"G1 F225 ; set feed speed"
|
"G1 F225 ; set feed speed"
|
||||||
],
|
],
|
||||||
|
|
@ -19,7 +18,6 @@
|
||||||
"M107 ; turn off filament cooling fan",
|
"M107 ; turn off filament cooling fan",
|
||||||
"M104 S0 T{tool} ; turn off right extruder",
|
"M104 S0 T{tool} ; turn off right extruder",
|
||||||
"M140 S0 T{tool} ; turn off bed",
|
"M140 S0 T{tool} ; turn off bed",
|
||||||
"G1 Z{z_max} F1200 ; drop bed",
|
|
||||||
"G28 X0 Y0 ; home XY axes",
|
"G28 X0 Y0 ; home XY axes",
|
||||||
"M84 ; disable stepper motors"
|
"M84 ; disable stepper motors"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
||||||
"G1 E15 F200 ; purge 15mm from extruder",
|
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"G1 F225 ; set feed speed"
|
"G1 F225 ; set feed speed"
|
||||||
],
|
],
|
||||||
|
|
@ -19,7 +18,6 @@
|
||||||
"M107 ; turn off filament cooling fan",
|
"M107 ; turn off filament cooling fan",
|
||||||
"M104 S0 T{tool} ; turn off right extruder",
|
"M104 S0 T{tool} ; turn off right extruder",
|
||||||
"M140 S0 T{tool} ; turn off bed",
|
"M140 S0 T{tool} ; turn off bed",
|
||||||
"G1 Z{z_max} F1200 ; drop bed",
|
|
||||||
"G28 X0 Y0 ; home XY axes",
|
"G28 X0 Y0 ; home XY axes",
|
||||||
"M84 ; disable stepper motors"
|
"M84 ; disable stepper motors"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
"G1 Z0.25 F180 ; move z to 0.25mm over bed",
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
"M109 S{temp} T{tool} ; wait for extruder to reach target temp",
|
||||||
"G1 E15 F200 ; purge 15mm from extruder",
|
|
||||||
"G92 E0 ; zero the extruded",
|
"G92 E0 ; zero the extruded",
|
||||||
"G1 F225 ; set feed speed"
|
"G1 F225 ; set feed speed"
|
||||||
],
|
],
|
||||||
|
|
@ -19,7 +18,6 @@
|
||||||
"M107 ; turn off filament cooling fan",
|
"M107 ; turn off filament cooling fan",
|
||||||
"M104 S0 T{tool} ; turn off right extruder",
|
"M104 S0 T{tool} ; turn off right extruder",
|
||||||
"M140 S0 T{tool} ; turn off bed",
|
"M140 S0 T{tool} ; turn off bed",
|
||||||
"G1 Z{z_max} F1200 ; drop bed",
|
|
||||||
"G28 X0 Y0 ; home XY axes",
|
"G28 X0 Y0 ; home XY axes",
|
||||||
"M84 ; disable stepper motors"
|
"M84 ; disable stepper motors"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@
|
||||||
"cmd":{
|
"cmd":{
|
||||||
"fan_power": "M106 S{fan_speed}"
|
"fan_power": "M106 S{fan_speed}"
|
||||||
},
|
},
|
||||||
"proc": "kiri_fdm_xyz_mini_w",
|
|
||||||
"file-ext": "3w",
|
|
||||||
"settings":{
|
"settings":{
|
||||||
"origin_center": false,
|
"origin_center": false,
|
||||||
"extrude_abs": true,
|
"extrude_abs": true,
|
||||||
|
|
|
||||||
1
src/ext/base64.js
Symbolic link
1
src/ext/base64.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../node_modules/base64-js/base64js.min.js
|
||||||
1
src/ext/jszip.js
Symbolic link
1
src/ext/jszip.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../node_modules/jszip/dist/jszip.js
|
||||||
1
src/ext/three-bgu.js
Symbolic link
1
src/ext/three-bgu.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../node_modules/three/examples/js/utils/BufferGeometryUtils.js
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
function time() { return Date.now() }
|
function time() { return Date.now() }
|
||||||
|
|
||||||
function lerp(from, to, maxInc) {
|
function lerp(from, to, maxInc, incFrom) {
|
||||||
let dir = Math.sign(to - from);
|
let dir = Math.sign(to - from);
|
||||||
let delta = Math.abs(to - from);
|
let delta = Math.abs(to - from);
|
||||||
let steps = Math.floor(delta / maxInc);
|
let steps = Math.floor(delta / maxInc);
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
steps++;
|
steps++;
|
||||||
per = delta / steps;
|
per = delta / steps;
|
||||||
}
|
}
|
||||||
let out = [];
|
let out = incFrom ? [from] : [];
|
||||||
while (steps-- > 0) {
|
while (steps-- > 0) {
|
||||||
from += per * dir;
|
from += per * dir;
|
||||||
out.push(from);
|
out.push(from);
|
||||||
|
|
@ -316,6 +316,94 @@
|
||||||
return (d2y * d1x) - (d2x * d1y);
|
return (d2y * d1x) - (d2x * d1y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return circle center given three points
|
||||||
|
* from https://math.stackexchange.com/questions/1076177/3d-coordinates-of-circle-center-given-three-point-on-the-circle
|
||||||
|
*/
|
||||||
|
function center3d(a,b,c) {
|
||||||
|
let ax = a.x,
|
||||||
|
ay = a.y,
|
||||||
|
az = a.z || 0,
|
||||||
|
bx = b.x,
|
||||||
|
by = b.y,
|
||||||
|
bz = b.z || 0,
|
||||||
|
cx = c.x,
|
||||||
|
cy = c.y,
|
||||||
|
cz = c.z || 0,
|
||||||
|
Cx = bx-ax,
|
||||||
|
Cy = by-ay,
|
||||||
|
Cz = bz-az,
|
||||||
|
Bx = cx-ax,
|
||||||
|
By = cy-ay,
|
||||||
|
Bz = cz-az,
|
||||||
|
B2 = (ax*ax)-(cx*cx)+(ay*ay)-(cy*cy)+(az*az)-(cz*cz),
|
||||||
|
C2 = (ax*ax)-(bx*bx)+(ay*ay)-(by*by)+(az*az)-(bz*bz),
|
||||||
|
CByz = Cy*Bz-Cz*By,
|
||||||
|
CBxz = Cx*Bz-Cz*Bx,
|
||||||
|
CBxy = Cx*By-Cy*Bx,
|
||||||
|
ZZ1 = -(Bz-Cz*Bx/Cx)/(By-Cy*Bx/Cx),
|
||||||
|
Z01 = -(B2-Bx/Cx*C2)/(2*(By-Cy*Bx/Cx)),
|
||||||
|
ZZ2 = -(ZZ1*Cy+Cz)/Cx,
|
||||||
|
Z02 = -(2*Z01*Cy+C2)/(2*Cx),
|
||||||
|
dz = -((Z02-ax)*CByz-(Z01-ay)*CBxz-az*CBxy)/(ZZ2*CByz-ZZ1*CBxz+CBxy),
|
||||||
|
dx = ZZ2*dz + Z02,
|
||||||
|
dy = ZZ1*dz + Z01;
|
||||||
|
|
||||||
|
return {x:dx, y:dy, z:dz};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return circle center given three points
|
||||||
|
* from https://stackoverflow.com/questions/4103405/what-is-the-algorithm-for-finding-the-center-of-a-circle-from-three-points
|
||||||
|
*/
|
||||||
|
function center2d(A,B,C,rad) {
|
||||||
|
// let yDelta_a = B.y - A.y,
|
||||||
|
// xDelta_a = B.x - A.x,
|
||||||
|
// yDelta_b = C.y - B.y,
|
||||||
|
// xDelta_b = C.x - B.x,
|
||||||
|
// aSlope = yDelta_a/xDelta_a,
|
||||||
|
// bSlope = yDelta_b/xDelta_b,
|
||||||
|
// center = {x:0, y:0, z:0};
|
||||||
|
// center.x = (aSlope*bSlope*(A.y - C.y) + bSlope*(A.x + B.x) - aSlope*(B.x+C.x) )/(2* (bSlope-aSlope) );
|
||||||
|
// center.y = -1*(center.x - (A.x+B.x)/2)/aSlope + (A.y+B.y)/2;
|
||||||
|
let center = center3d(A,B,C);
|
||||||
|
if (rad) {
|
||||||
|
let dx = center.x - A.x;
|
||||||
|
let dy = center.y - A.y;
|
||||||
|
center.r = Math.sqrt(dx*dx + dy*dy)
|
||||||
|
// if (isNaN(center.r)) console.log('NaN',{dx,dy,A,B,C,center,xDelta_a,xDelta_b,yDelta_a,yDelta_b,aSlope,bSlope});
|
||||||
|
}
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return two possible circle centers given two points and a radius
|
||||||
|
* https://stackoverflow.com/questions/36211171/finding-center-of-a-circle-given-two-points-and-radius
|
||||||
|
*/
|
||||||
|
function center2pr(p1, p2, r) {
|
||||||
|
let x1 = p1.x,
|
||||||
|
x2 = p2.x,
|
||||||
|
y1 = p1.y,
|
||||||
|
y2 = p2.y,
|
||||||
|
q = Math.sqrt(Math.pow((x2-x1),2) + Math.pow((y2-y1),2)),
|
||||||
|
y3 = (y1+y2)/2,
|
||||||
|
x3 = (x1+x2)/2,
|
||||||
|
basex = Math.sqrt(Math.pow(r,2)-Math.pow((q/2),2))*(y1-y2)/q, //calculate once
|
||||||
|
basey = Math.sqrt(Math.pow(r,2)-Math.pow((q/2),2))*(x2-x1)/q, //calculate once
|
||||||
|
centerx1 = x3 + basex, //center x of circle 1
|
||||||
|
centery1 = y3 + basey, //center y of circle 1
|
||||||
|
centerx2 = x3 - basex, //center x of circle 2
|
||||||
|
centery2 = y3 - basey; //center y of circle 2
|
||||||
|
return [{x:centerx1, y:centery1}, {x:centerx2, y:centery2}];
|
||||||
|
}
|
||||||
|
|
||||||
|
function thetaDiff(n1, n2, sign) {
|
||||||
|
let diff = n2 - n1;
|
||||||
|
while (diff < -Math.PI) diff += Math.PI * 2;
|
||||||
|
while (diff > Math.PI) diff -= Math.PI * 2;
|
||||||
|
return sign ? diff : Math.abs(diff);
|
||||||
|
}
|
||||||
|
|
||||||
/** ******************************************************************
|
/** ******************************************************************
|
||||||
* Connect to base
|
* Connect to base
|
||||||
******************************************************************* */
|
******************************************************************* */
|
||||||
|
|
@ -399,6 +487,10 @@
|
||||||
time,
|
time,
|
||||||
round,
|
round,
|
||||||
area2,
|
area2,
|
||||||
|
center2d,
|
||||||
|
center3d,
|
||||||
|
center2pr,
|
||||||
|
thetaDiff,
|
||||||
distSq : dist2,
|
distSq : dist2,
|
||||||
distSqv2 : dist2v2,
|
distSqv2 : dist2v2,
|
||||||
inRange,
|
inRange,
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,198 @@
|
||||||
return Math.abs(diff);
|
return Math.abs(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate center crossing point cloud
|
||||||
|
PRO.centers = function(step, z, min, max, opt = {}) {
|
||||||
|
let cloud = [],
|
||||||
|
bounds = this.bounds,
|
||||||
|
lines = opt.lines || false,
|
||||||
|
stepoff = step / 2,
|
||||||
|
set = [this.points];
|
||||||
|
|
||||||
|
if (this.inner) {
|
||||||
|
for (let inner of this.inner) {
|
||||||
|
set.push(inner.points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let y of UTIL.lerp(bounds.miny + stepoff, bounds.maxy - stepoff, step, true)) {
|
||||||
|
let ints = [];
|
||||||
|
for (let points of set) {
|
||||||
|
let length = points.length;
|
||||||
|
for (let i=0; i<length; i++) {
|
||||||
|
let p1 = points[i % length];
|
||||||
|
let p2 = points[(i+1) % length];
|
||||||
|
if (
|
||||||
|
(p1.y <= y && p2.y > y) ||
|
||||||
|
(p1.y > y && p2.y <= y)
|
||||||
|
) ints.push([p1,p2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let cntr = [];
|
||||||
|
if (ints.length && ints.length % 2 === 0) {
|
||||||
|
for (let int of ints) {
|
||||||
|
let [p1, p2] = int;
|
||||||
|
if (p2.y < p1.y) {
|
||||||
|
let tp = p1;
|
||||||
|
p1 = p2;
|
||||||
|
p2 = tp;
|
||||||
|
}
|
||||||
|
let minx = Math.min(p1.x, p2.x);
|
||||||
|
let maxx = Math.max(p1.x, p2.x);
|
||||||
|
let miny = Math.min(p1.y, p2.y);
|
||||||
|
let maxy = Math.max(p1.y, p2.y);
|
||||||
|
let dx = p2.x - p1.x;
|
||||||
|
let dy = maxy - miny;
|
||||||
|
let pct = (y - miny) / dy;
|
||||||
|
let xpo = p1.x + pct * dx;
|
||||||
|
cntr.push(xpo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cntr.sort((a, b) => {
|
||||||
|
return b - a;
|
||||||
|
});
|
||||||
|
let lp, eo = 0;
|
||||||
|
for (let x of cntr) {
|
||||||
|
let p = BASE.newPoint(x, y, z);
|
||||||
|
if (eo++ % 2) {
|
||||||
|
let d = lp.distTo2D(p);
|
||||||
|
if (d >= min && d <= max) {
|
||||||
|
if (lines) {
|
||||||
|
cloud.push(lp);
|
||||||
|
cloud.push(p);
|
||||||
|
} else {
|
||||||
|
cloud.push(BASE.newPoint(
|
||||||
|
(lp.x + p.x) / 2, y, z
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lp = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let x of UTIL.lerp(bounds.minx + stepoff, bounds.maxx - stepoff, step, true)) {
|
||||||
|
let ints = [];
|
||||||
|
for (let points of set) {
|
||||||
|
let length = points.length;
|
||||||
|
for (let i=0; i<length; i++) {
|
||||||
|
let p1 = points[i % length];
|
||||||
|
let p2 = points[(i+1) % length];
|
||||||
|
if (
|
||||||
|
(p1.x <= x && p2.x > x) ||
|
||||||
|
(p1.x > x && p2.x <= x)
|
||||||
|
) ints.push([p1,p2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let cntr = [];
|
||||||
|
if (ints.length && ints.length % 2 === 0) {
|
||||||
|
for (let int of ints) {
|
||||||
|
let [p1, p2] = int;
|
||||||
|
if (p2.x < p1.x) {
|
||||||
|
let tp = p1;
|
||||||
|
p1 = p2;
|
||||||
|
p2 = tp;
|
||||||
|
}
|
||||||
|
let minx = Math.min(p1.x, p2.x);
|
||||||
|
let maxx = Math.max(p1.x, p2.x);
|
||||||
|
let miny = Math.min(p1.y, p2.y);
|
||||||
|
let maxy = Math.max(p1.y, p2.y);
|
||||||
|
let dx = maxx - minx;
|
||||||
|
let dy = p2.y - p1.y;
|
||||||
|
let pct = (x - minx) / dx;
|
||||||
|
let ypo = p1.y + pct * dy;
|
||||||
|
cntr.push(ypo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cntr.sort((a, b) => {
|
||||||
|
return b - a;
|
||||||
|
});
|
||||||
|
let lp, eo = 0;
|
||||||
|
for (let y of cntr) {
|
||||||
|
let p = BASE.newPoint(x, y, z);
|
||||||
|
if (eo++ % 2) {
|
||||||
|
let d = lp.distTo2D(p);
|
||||||
|
if (d >= min && d <= max) {
|
||||||
|
if (lines) {
|
||||||
|
cloud.push(lp);
|
||||||
|
cloud.push(p);
|
||||||
|
} else {
|
||||||
|
cloud.push(BASE.newPoint(
|
||||||
|
x, (lp.y + p.y) / 2, z
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lp = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines) {
|
||||||
|
return cloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mindist = opt.mindist || step * 1.5;
|
||||||
|
|
||||||
|
function build(poly) {
|
||||||
|
let lastp = poly.last();
|
||||||
|
let minp;
|
||||||
|
let mind = Infinity;
|
||||||
|
for (let point of cloud) {
|
||||||
|
let dist = point.distTo2D(lastp);
|
||||||
|
if (dist < mindist && dist < mind) {
|
||||||
|
mind = dist;
|
||||||
|
minp = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minp) {
|
||||||
|
cloud = cloud.filter(p => p !== minp);
|
||||||
|
poly.push(minp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// join points into polys
|
||||||
|
let polys = [];
|
||||||
|
let poly = [];
|
||||||
|
while (cloud.length) {
|
||||||
|
if (poly.length === 0) {
|
||||||
|
poly = [ cloud.shift() ];
|
||||||
|
polys.push(poly);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (build(poly)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!poly.flip) {
|
||||||
|
poly.reverse();
|
||||||
|
poly.flip = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (poly.length) {
|
||||||
|
poly = [];
|
||||||
|
} else {
|
||||||
|
throw "whoop there it is";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return polys
|
||||||
|
.filter(poly => poly.length > 1)
|
||||||
|
.map(poly => {
|
||||||
|
let np = BASE.newPolygon().setOpen();
|
||||||
|
for (let p of poly) {
|
||||||
|
np.push(p);
|
||||||
|
}
|
||||||
|
if (np.last().distTo2D(np.first()) <= max) {
|
||||||
|
np.setClosed();
|
||||||
|
}
|
||||||
|
np = np.clean();
|
||||||
|
return np;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
PRO.debur = function(dist) {
|
PRO.debur = function(dist) {
|
||||||
if (this.len < 2) {
|
if (this.len < 2) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -666,6 +858,16 @@
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PRO.addObj = function(obj) {
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
for (let o of obj) {
|
||||||
|
this.addObj(o);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return this.add(obj.x, obj.y, obj.z);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* append array of points to polygon and return polygon
|
* append array of points to polygon and return polygon
|
||||||
*
|
*
|
||||||
|
|
@ -1201,9 +1403,11 @@
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
function fromClipperPath(path,z) {
|
function fromClipperPath(path, z) {
|
||||||
let 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++]));
|
while (i < l) {
|
||||||
|
poly.push(newPoint(null,null,z,null,path[i++]));
|
||||||
|
}
|
||||||
return poly;
|
return poly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1223,6 +1427,31 @@
|
||||||
poly.parent = parent || this.parent;
|
poly.parent = parent || this.parent;
|
||||||
poly.area2 = this.area2;
|
poly.area2 = this.area2;
|
||||||
poly.open = this.open;
|
poly.open = this.open;
|
||||||
|
if (this.open) {
|
||||||
|
// when open, ensure first point on new poly matches old
|
||||||
|
let start = this.points[0];
|
||||||
|
let points = poly.points;
|
||||||
|
let length = points.length;
|
||||||
|
let mi, min = Infinity;
|
||||||
|
for (let i=0; i<length; i++) {
|
||||||
|
let d = points[i].distTo2D(start);
|
||||||
|
if (d < min) {
|
||||||
|
min = d;
|
||||||
|
mi = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// mi > 0 means first point didn't match
|
||||||
|
if (mi) {
|
||||||
|
let nupoints = [];
|
||||||
|
for (let i=mi; i<length; i++) {
|
||||||
|
nupoints.push(points[i]);
|
||||||
|
}
|
||||||
|
for (let i=0; i<mi; i++) {
|
||||||
|
nupoints.push(points[i]);
|
||||||
|
}
|
||||||
|
poly.points = nupoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
return poly;
|
return poly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
expand,
|
expand,
|
||||||
expand_lines,
|
expand_lines,
|
||||||
union,
|
union,
|
||||||
|
inset,
|
||||||
nest,
|
nest,
|
||||||
diff,
|
diff,
|
||||||
setZ,
|
setZ,
|
||||||
|
|
@ -540,6 +541,43 @@
|
||||||
return opts.flat ? opts.outs : polys;
|
return opts.flat ? opts.outs : polys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* progressive insetting that does inset + outset to debur as well
|
||||||
|
* as performing subtractive analysis between initial layer shell (ref)
|
||||||
|
* and last offset (cmp) to produce gap candidates (for thinfill)
|
||||||
|
*/
|
||||||
|
function inset(polys, dist, count, z) {
|
||||||
|
let total = count;
|
||||||
|
let layers = [];
|
||||||
|
let ref = polys;
|
||||||
|
let depth = 0;
|
||||||
|
while (count-- > 0 && ref && ref.length) {
|
||||||
|
let off = offset(ref, -dist, {z});
|
||||||
|
let mid = offset(off, dist / 2, {z});
|
||||||
|
let cmp = offset(off, dist, {z});
|
||||||
|
let gap = [];
|
||||||
|
let aref = ref.map(p => p.areaDeep()).reduce((a,p) => a +p);
|
||||||
|
let cref = cmp.length ? cmp.map(p => p.areaDeep()).reduce((a,p) => a + p) : 0;
|
||||||
|
// threshold subtraction to area deltas > 0.1 % to filter out false
|
||||||
|
// positives where inset/outset are identical floating point error
|
||||||
|
if (Math.abs(aref - cref) > 1 - (Math.abs(aref / cref) / 1000)) {
|
||||||
|
subtract(ref, cmp, gap, null, z);
|
||||||
|
}
|
||||||
|
layers.push({idx: total-count, off, mid, gap});
|
||||||
|
// fixup depth cues
|
||||||
|
for (let m of mid) {
|
||||||
|
m.depth = depth++;
|
||||||
|
if (m.inner) {
|
||||||
|
for (let mi of m.inner) {
|
||||||
|
mi.depth = m.depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ref = off;
|
||||||
|
}
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo use clipper opne poly clipping?
|
* todo use clipper opne poly clipping?
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,10 @@
|
||||||
*/
|
*/
|
||||||
function wireframe(group, points, color) {
|
function wireframe(group, points, color) {
|
||||||
if (points.length % 3 != 0) throw "invalid line : "+points.length;
|
if (points.length % 3 != 0) throw "invalid line : "+points.length;
|
||||||
let lines = new THREE.Geometry(),
|
let lines = new THREE.BufferGeometry(),
|
||||||
hash = {},
|
hash = {},
|
||||||
added = 0;
|
added = 0,
|
||||||
|
vertices = [];
|
||||||
for (let i = 0; i < points.length; i += 3) {
|
for (let i = 0; i < points.length; i += 3) {
|
||||||
let p1 = points[i],
|
let p1 = points[i],
|
||||||
p2 = points[i + 1],
|
p2 = points[i + 1],
|
||||||
|
|
@ -41,22 +42,28 @@
|
||||||
l2 = newOrderedLine(p2, p3),
|
l2 = newOrderedLine(p2, p3),
|
||||||
l3 = newOrderedLine(p3, p1);
|
l3 = newOrderedLine(p3, p1);
|
||||||
if (!hash[l1.key]) {
|
if (!hash[l1.key]) {
|
||||||
lines.vertices.push(new THREE.Vector3(p1.x, p1.y, p1.z));
|
vertices.appendAll([
|
||||||
lines.vertices.push(new THREE.Vector3(p2.x, p2.y, p2.z));
|
p1.x, p1.y, p1.z,
|
||||||
|
p2.x, p2.y, p2.z
|
||||||
|
]);
|
||||||
hash[l1.key] = ++added;
|
hash[l1.key] = ++added;
|
||||||
}
|
}
|
||||||
if (!hash[l2.key]) {
|
if (!hash[l2.key]) {
|
||||||
lines.vertices.push(new THREE.Vector3(p2.x, p2.y, p2.z));
|
vertices.appendAll([
|
||||||
lines.vertices.push(new THREE.Vector3(p3.x, p3.y, p3.z));
|
p2.x, p2.y, p2.z,
|
||||||
|
p3.x, p3.y, p3.z
|
||||||
|
]);
|
||||||
hash[l2.key] = ++added;
|
hash[l2.key] = ++added;
|
||||||
}
|
}
|
||||||
if (!hash[l3.key]) {
|
if (!hash[l3.key]) {
|
||||||
lines.vertices.push(new THREE.Vector3(p3.x, p3.y, p3.z));
|
vertices.appendAll([
|
||||||
lines.vertices.push(new THREE.Vector3(p1.x, p1.y, p1.z));
|
p3.x, p3.y, p3.z,
|
||||||
|
p1.x, p1.y, p1.z
|
||||||
|
]);
|
||||||
hash[l3.key] = ++added;
|
hash[l3.key] = ++added;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lines.verticesNeedUpdate = true;
|
lines.setAttribute('position', new THREE.BufferAttribute( vertices.toFloat32(), 3 ) );
|
||||||
let mesh = new THREE.LineSegments(lines, getMaterial(color));
|
let mesh = new THREE.LineSegments(lines, getMaterial(color));
|
||||||
group.add(mesh);
|
group.add(mesh);
|
||||||
return mesh;
|
return mesh;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
if (!self.kiri) {
|
if (!self.kiri) {
|
||||||
self.kiri = {
|
self.kiri = {
|
||||||
beta: 2608,
|
beta: 2801,
|
||||||
driver: {}, // driver modules
|
driver: {}, // driver modules
|
||||||
loader: [] // module loading: array of functions
|
loader: [] // module loading: array of functions
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,10 @@ let KIRI = self.kiri = self.kiri || {},
|
||||||
seqid = 1,
|
seqid = 1,
|
||||||
syncd = {},
|
syncd = {},
|
||||||
running = {},
|
running = {},
|
||||||
slicing = {},
|
worker = null,
|
||||||
worker = null;
|
restarting = false
|
||||||
|
// occ = new Worker("/kiri/ext/occ-worker.js", {type:"module"}),
|
||||||
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Function} fn name of function in KIRI.worker
|
* @param {Function} fn name of function in KIRI.worker
|
||||||
|
|
@ -26,8 +28,11 @@ let KIRI = self.kiri = self.kiri || {},
|
||||||
function send(fn, data, onreply, zerocopy) {
|
function send(fn, data, onreply, zerocopy) {
|
||||||
let seq = seqid++;
|
let seq = seqid++;
|
||||||
|
|
||||||
running[seq] = { fn:onreply };
|
if (onreply) {
|
||||||
// console.log('send', data);
|
// track it only when we expect and can handle a reply
|
||||||
|
running[seq] = { fn:onreply };
|
||||||
|
}
|
||||||
|
// console.log('send', {fn, data, onreply});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
worker.postMessage({
|
worker.postMessage({
|
||||||
|
|
@ -55,25 +60,35 @@ KIRI.work = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isSlicing: function() {
|
isBusy: function() {
|
||||||
let current = 0;
|
let current = 0;
|
||||||
for (let key in slicing) {
|
|
||||||
current++;
|
for (let rec of Object.values(running)) {
|
||||||
|
if (rec.fn) current++;
|
||||||
}
|
}
|
||||||
return current > 0;
|
return current > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
restart: function() {
|
restart: function() {
|
||||||
|
// prevent re-entry from cancel callback
|
||||||
|
if (restarting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (worker) {
|
if (worker) {
|
||||||
worker.terminate();
|
worker.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let key in slicing) {
|
restarting = true;
|
||||||
slicing[key]({error: "cancelled slicing"});
|
|
||||||
|
for (let key in running) {
|
||||||
|
let rec = running[key];
|
||||||
|
if (rec.fn) {
|
||||||
|
rec.fn({error: "cancelled operation"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncd = {};
|
syncd = {};
|
||||||
slicing = {};
|
|
||||||
running = {};
|
running = {};
|
||||||
worker = KIRI.work.newWorker();
|
worker = KIRI.work.newWorker();
|
||||||
|
|
||||||
|
|
@ -81,7 +96,7 @@ KIRI.work = {
|
||||||
let now = time(),
|
let now = time(),
|
||||||
reply = e.data,
|
reply = e.data,
|
||||||
record = running[reply.seq],
|
record = running[reply.seq],
|
||||||
onreply = record.fn;
|
onreply = record ? record.fn : undefined;
|
||||||
|
|
||||||
// console.log('recv', reply.data)
|
// console.log('recv', reply.data)
|
||||||
if (reply.done) {
|
if (reply.done) {
|
||||||
|
|
@ -91,8 +106,14 @@ KIRI.work = {
|
||||||
// calculate and replace recv time
|
// calculate and replace recv time
|
||||||
reply.time_recv = now - reply.time_recv;
|
reply.time_recv = now - reply.time_recv;
|
||||||
|
|
||||||
onreply(reply.data, reply);
|
if (onreply) {
|
||||||
|
onreply(reply.data, reply);
|
||||||
|
} else {
|
||||||
|
console.log({unexpected_reply: reply});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
restarting = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
decimate: function(vertices, options, callback) {
|
decimate: function(vertices, options, callback) {
|
||||||
|
|
@ -105,35 +126,36 @@ KIRI.work = {
|
||||||
},
|
},
|
||||||
|
|
||||||
config: function(obj) {
|
config: function(obj) {
|
||||||
send("config", obj, function(reply) {
|
send("config", obj, function(reply) { });
|
||||||
// console.log({config:reply});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function(widget) {
|
clear: function() {
|
||||||
send("clear", widget ? {id:widget.id} : {}, function(reply) {
|
syncd = {};
|
||||||
syncd = {};
|
send("clear", {}, function(reply) { });
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
snap: function(data) {
|
snap: function(data) {
|
||||||
send("snap", data, function(reply) {
|
send("snap", data, function(reply) { });
|
||||||
// console.log({snap:reply})
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// widget sync
|
// widget sync
|
||||||
sync: function(widget) {
|
sync: function(widgets) {
|
||||||
let widgets = widget ? [ widget ] : KIRI.api.widgets.all();
|
if (!widgets) {
|
||||||
|
widgets = KIRI.api.widgets.all();
|
||||||
|
}
|
||||||
|
// send list of currently valid widgets
|
||||||
|
send("sync", { valid: widgets.map(w => w.id) }, () => {});
|
||||||
|
// sync any widget that has changed
|
||||||
widgets.forEach(widget => {
|
widgets.forEach(widget => {
|
||||||
if (widget.modified || !syncd[widget.id]) {
|
if (widget.modified || !syncd[widget.id]) {
|
||||||
syncd[widget.id] = true;
|
syncd[widget.id] = true;
|
||||||
let vertices = widget.getGeoVertices().buffer.slice(0);
|
let vertices = widget.getGeoVertices().buffer.slice(0);
|
||||||
send("sync", {
|
send("sync", {
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
|
group: widget.group.id,
|
||||||
|
track: widget.track,
|
||||||
vertices: vertices,
|
vertices: vertices,
|
||||||
position: widget.mesh.position,
|
position: widget.mesh.position,
|
||||||
tracking: widget.track
|
|
||||||
}, done => {
|
}, done => {
|
||||||
widget.modified = false;
|
widget.modified = false;
|
||||||
}, [vertices]);
|
}, [vertices]);
|
||||||
|
|
@ -141,18 +163,42 @@ KIRI.work = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
slice: function(settings, widget, callback) {
|
rotate: function(settings, callback) {
|
||||||
CLIENT.sync(widget);
|
send("rotate", { settings }, reply => {
|
||||||
slicing[widget.id] = callback;
|
if (reply.group) {
|
||||||
|
for (let widget of KIRI.Widget.Groups.forid(reply.group)) {
|
||||||
|
widget.belt = reply.belt;
|
||||||
|
}
|
||||||
|
} else if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unrotate: function(settings, callback) {
|
||||||
|
send("unrotate", { settings }, reply => {
|
||||||
|
if (reply.group) {
|
||||||
|
for (let widget of KIRI.Widget.Groups.forid(reply.group)) {
|
||||||
|
widget.rotinfo = reply.rotinfo;
|
||||||
|
}
|
||||||
|
} else if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
slice: function(settings, widget, callback) {
|
||||||
send("slice", {
|
send("slice", {
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
settings: settings
|
settings: settings
|
||||||
}, function(reply) {
|
}, function(reply) {
|
||||||
if (reply.done || reply.error) {
|
|
||||||
delete slicing[widget.id];
|
|
||||||
}
|
|
||||||
callback(reply);
|
callback(reply);
|
||||||
|
if (reply.done || reply.error) {
|
||||||
|
// in belt mode, slicing modifies a widget and requires re-sync
|
||||||
|
if (settings.device.bedBelt) {
|
||||||
|
widget.modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -164,6 +210,9 @@ KIRI.work = {
|
||||||
if (reply.done) {
|
if (reply.done) {
|
||||||
done(reply.output, reply.maxSpeed);
|
done(reply.output, reply.maxSpeed);
|
||||||
}
|
}
|
||||||
|
if (reply.error) {
|
||||||
|
done(reply);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -175,6 +224,9 @@ KIRI.work = {
|
||||||
if (reply.done) {
|
if (reply.done) {
|
||||||
ondone(reply.output);
|
ondone(reply.output);
|
||||||
}
|
}
|
||||||
|
if (reply.error) {
|
||||||
|
ondone(null, reply.error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -204,7 +256,7 @@ KIRI.work = {
|
||||||
}
|
}
|
||||||
send("parse", args, function(reply) {
|
send("parse", args, function(reply) {
|
||||||
if (reply.progress) {
|
if (reply.progress) {
|
||||||
progress(reply);
|
progress(reply.progress);
|
||||||
}
|
}
|
||||||
if (reply.parsed) {
|
if (reply.parsed) {
|
||||||
done(KIRI.codec.decode(reply.parsed), reply.maxSpeed);
|
done(KIRI.codec.decode(reply.parsed), reply.maxSpeed);
|
||||||
|
|
@ -221,6 +273,16 @@ KIRI.work = {
|
||||||
output(reply.done);
|
output(reply.done);
|
||||||
}
|
}
|
||||||
}, [ data.png ]);
|
}, [ data.png ]);
|
||||||
|
},
|
||||||
|
|
||||||
|
zip: function(files, progress, output) {
|
||||||
|
send("zip", {files}, reply => {
|
||||||
|
if (reply.percent !== undefined) {
|
||||||
|
progress(reply);
|
||||||
|
} else {
|
||||||
|
output(reply);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
const zeroOut = true;
|
const zeroOut = true;
|
||||||
|
|
||||||
const codec = KIRI.codec = {
|
const codec = KIRI.codec = {
|
||||||
|
undef: undefined,
|
||||||
encode: encode,
|
encode: encode,
|
||||||
decode: decode,
|
decode: decode,
|
||||||
registerDecoder: registerDecoder,
|
registerDecoder: registerDecoder,
|
||||||
|
|
@ -154,7 +155,7 @@
|
||||||
polys: encode(layer.polys, state),
|
polys: encode(layer.polys, state),
|
||||||
lines: encodePointArray(layer.lines, state),
|
lines: encodePointArray(layer.lines, state),
|
||||||
faces: codec.allocFloat32Array(layer.faces),
|
faces: codec.allocFloat32Array(layer.faces),
|
||||||
cface: layer.cface,
|
cface: layer.cface || codec.undef,
|
||||||
color: layer.color,
|
color: layer.color,
|
||||||
paths: layer.paths.map(lp => {
|
paths: layer.paths.map(lp => {
|
||||||
const pe = {
|
const pe = {
|
||||||
|
|
@ -167,13 +168,13 @@
|
||||||
}
|
}
|
||||||
return pe;
|
return pe;
|
||||||
}),
|
}),
|
||||||
cpath: layer.cpath,
|
cpath: layer.cpath || codec.undef,
|
||||||
off: layer.off
|
off: layer.off
|
||||||
};
|
};
|
||||||
if (zeroOut && state.zeros && e.faces.length) {
|
if (zeroOut && state.zeros && e.faces.length) {
|
||||||
state.zeros.push(e.faces.buffer);
|
state.zeros.push(e.faces.buffer);
|
||||||
}
|
}
|
||||||
// console.log('-->',e);
|
// console.log('-->',layer,e);
|
||||||
return e;
|
return e;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@
|
||||||
extFilament: device.filamentSize,
|
extFilament: device.filamentSize,
|
||||||
extNozzle: device.nozzleSize,
|
extNozzle: device.nozzleSize,
|
||||||
extSelect: ["T0"],
|
extSelect: ["T0"],
|
||||||
|
extDeselect: [],
|
||||||
extOffsetX: 0,
|
extOffsetX: 0,
|
||||||
extOffsetY: 0
|
extOffsetY: 0
|
||||||
}];
|
}];
|
||||||
|
|
@ -143,6 +144,7 @@
|
||||||
if (rec.offset_x) e.extOffsetX = rec.offset_x;
|
if (rec.offset_x) e.extOffsetX = rec.offset_x;
|
||||||
if (rec.offset_y) e.extOffsetY = rec.offset_y;
|
if (rec.offset_y) e.extOffsetY = rec.offset_y;
|
||||||
if (rec.select) e.extSelect = rec.select;
|
if (rec.select) e.extSelect = rec.select;
|
||||||
|
if (rec.deselect) e.extDeselect = rec.deselect;
|
||||||
device.extruders.push(e);
|
device.extruders.push(e);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -259,6 +261,7 @@
|
||||||
bedHeight: 2.5,
|
bedHeight: 2.5,
|
||||||
bedRound: false,
|
bedRound: false,
|
||||||
bedBelt: false,
|
bedBelt: false,
|
||||||
|
fwRetract: false,
|
||||||
originCenter: false,
|
originCenter: false,
|
||||||
maxHeight: 150,
|
maxHeight: 150,
|
||||||
gcodePre: [],
|
gcodePre: [],
|
||||||
|
|
@ -273,6 +276,7 @@
|
||||||
extFilament: 1.75,
|
extFilament: 1.75,
|
||||||
extNozzle: 0.4,
|
extNozzle: 0.4,
|
||||||
extSelect: ["T0"],
|
extSelect: ["T0"],
|
||||||
|
extDeselect: [],
|
||||||
extOffsetX: 0,
|
extOffsetX: 0,
|
||||||
extOffsetY: 0
|
extOffsetY: 0
|
||||||
}]
|
}]
|
||||||
|
|
@ -285,12 +289,14 @@
|
||||||
sliceShellOrder: "in-out",
|
sliceShellOrder: "in-out",
|
||||||
sliceLayerStart: "last",
|
sliceLayerStart: "last",
|
||||||
sliceFillAngle: 45,
|
sliceFillAngle: 45,
|
||||||
|
sliceFillWidth: 1,
|
||||||
sliceFillOverlap: 0.3,
|
sliceFillOverlap: 0.3,
|
||||||
sliceFillSparse: 0.5,
|
sliceFillSparse: 0.5,
|
||||||
|
sliceFillRate: 0,
|
||||||
sliceFillType: "hex",
|
sliceFillType: "hex",
|
||||||
sliceSupportDensity: 0.25,
|
sliceSupportDensity: 0.25,
|
||||||
sliceSupportOffset: 1.0,
|
sliceSupportOffset: 1.0,
|
||||||
sliceSupportGap: 0.75,
|
sliceSupportGap: 1,
|
||||||
sliceSupportSize: 5,
|
sliceSupportSize: 5,
|
||||||
sliceSupportArea: 0.1,
|
sliceSupportArea: 0.1,
|
||||||
sliceSupportExtra: 0,
|
sliceSupportExtra: 0,
|
||||||
|
|
@ -311,10 +317,11 @@
|
||||||
firstLayerBedTemp: 0,
|
firstLayerBedTemp: 0,
|
||||||
firstLayerBrim: 0,
|
firstLayerBrim: 0,
|
||||||
firstLayerBrimTrig: 0,
|
firstLayerBrimTrig: 0,
|
||||||
|
firstLayerBeltLead: 3,
|
||||||
|
firstLayerFanSpeed: 0,
|
||||||
outputRaft: false,
|
outputRaft: false,
|
||||||
outputRaftSpacing: 0.2,
|
outputRaftSpacing: 0.2,
|
||||||
outputTemp: 200,
|
outputTemp: 200,
|
||||||
outputFanMax: 255,
|
|
||||||
outputBedTemp: 60,
|
outputBedTemp: 60,
|
||||||
outputFeedrate: 50,
|
outputFeedrate: 50,
|
||||||
outputFinishrate: 50,
|
outputFinishrate: 50,
|
||||||
|
|
@ -322,27 +329,30 @@
|
||||||
outputShellMult: 1.25,
|
outputShellMult: 1.25,
|
||||||
outputFillMult: 1.25,
|
outputFillMult: 1.25,
|
||||||
outputSparseMult: 1.25,
|
outputSparseMult: 1.25,
|
||||||
outputFanLayer: 1,
|
outputFanSpeed: 255,
|
||||||
outputRetractDist: 1.5,
|
outputRetractDist: 1.5,
|
||||||
outputRetractSpeed: 40,
|
outputRetractSpeed: 40,
|
||||||
|
outputRetractWipe: 0,
|
||||||
outputRetractDwell: 20,
|
outputRetractDwell: 20,
|
||||||
outputBrimCount: 2,
|
outputBrimCount: 2,
|
||||||
outputBrimOffset: 2,
|
outputBrimOffset: 2,
|
||||||
outputShortPoly: 100.0,
|
outputShortPoly: 100.0,
|
||||||
outputMinSpeed: 10.0,
|
outputMinSpeed: 10.0,
|
||||||
outputCoastDist: 0,
|
outputCoastDist: 0,
|
||||||
outputWipeDistance: 0,
|
|
||||||
outputLayerRetract: false,
|
outputLayerRetract: false,
|
||||||
outputOriginCenter: true,
|
outputOriginCenter: true,
|
||||||
outputLoopLayers: "",
|
outputLoopLayers: "",
|
||||||
|
outputPeelGuard: 0,
|
||||||
outputInvertX: false,
|
outputInvertX: false,
|
||||||
outputInvertY: false,
|
outputInvertY: false,
|
||||||
detectThinWalls: false,
|
detectThinWalls: false,
|
||||||
sliceMinHeight: 0,
|
sliceMinHeight: 0,
|
||||||
sliceAdaptive: false,
|
sliceAdaptive: false,
|
||||||
zHopDistance: 0.2,
|
zHopDistance: 0.2,
|
||||||
|
arcTolerance: 0,
|
||||||
antiBacklash: 1,
|
antiBacklash: 1,
|
||||||
gcodePause: ""
|
gcodePause: "",
|
||||||
|
ranges: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sla:{
|
sla:{
|
||||||
|
|
@ -458,6 +468,7 @@
|
||||||
camTraceDown: 0,
|
camTraceDown: 0,
|
||||||
camTraceSpeed: 250,
|
camTraceSpeed: 250,
|
||||||
camTracePlunge: 200,
|
camTracePlunge: 200,
|
||||||
|
camTraceLines: false,
|
||||||
camDrillTool: 1000,
|
camDrillTool: 1000,
|
||||||
camDrillSpindle: 1000,
|
camDrillSpindle: 1000,
|
||||||
camDrillDownSpeed: 250,
|
camDrillDownSpeed: 250,
|
||||||
|
|
@ -630,6 +641,7 @@
|
||||||
view: null,
|
view: null,
|
||||||
dark: false,
|
dark: false,
|
||||||
decals: true,
|
decals: true,
|
||||||
|
danger: false,
|
||||||
zoomSpeed: 1.0,
|
zoomSpeed: 1.0,
|
||||||
lineType: "path",
|
lineType: "path",
|
||||||
autoSave: true,
|
autoSave: true,
|
||||||
|
|
@ -639,6 +651,7 @@
|
||||||
showSpeeds: true,
|
showSpeeds: true,
|
||||||
freeLayout: true,
|
freeLayout: true,
|
||||||
autoLayout: true,
|
autoLayout: true,
|
||||||
|
spaceLayout: 1,
|
||||||
units: "mm",
|
units: "mm",
|
||||||
exportOcto: false,
|
exportOcto: false,
|
||||||
exportGhost: false,
|
exportGhost: false,
|
||||||
|
|
@ -646,7 +659,16 @@
|
||||||
exportPreview: false,
|
exportPreview: false,
|
||||||
decimate: true,
|
decimate: true,
|
||||||
detail: "good",
|
detail: "good",
|
||||||
animesh: "200"
|
animesh: "200",
|
||||||
|
healMesh: false,
|
||||||
|
ortho: false
|
||||||
|
},
|
||||||
|
// label state preferences
|
||||||
|
labels: {
|
||||||
|
'FDM-3-engage': false,
|
||||||
|
'FDM-3-retract': false,
|
||||||
|
'FDM-3-arrows': false,
|
||||||
|
'FDM-3-move': false
|
||||||
},
|
},
|
||||||
// for passing temporary slice hints (topo currently)
|
// for passing temporary slice hints (topo currently)
|
||||||
synth: {},
|
synth: {},
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@
|
||||||
let KIRI = self.kiri = self.kiri || {};
|
let KIRI = self.kiri = self.kiri || {};
|
||||||
KIRI.newEngine = ()=> { return new Engine ()};
|
KIRI.newEngine = ()=> { return new Engine ()};
|
||||||
|
|
||||||
|
if (!KIRI.api) {
|
||||||
|
KIRI.api = {
|
||||||
|
event: {
|
||||||
|
emit: () => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.widget = KIRI.newWidget();
|
this.widget = KIRI.newWidget();
|
||||||
|
|
@ -27,7 +35,7 @@ class Engine {
|
||||||
try {
|
try {
|
||||||
new moto.STL().load(url, vertices => {
|
new moto.STL().load(url, vertices => {
|
||||||
this.listener({loaded: url, vertices});
|
this.listener({loaded: url, vertices});
|
||||||
this.widget.loadVertices(vertices)
|
this.widget.loadVertices(vertices).center();
|
||||||
accept(this);
|
accept(this);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -39,11 +47,10 @@ class Engine {
|
||||||
parse(data) {
|
parse(data) {
|
||||||
return new Promise((accept, reject) => {
|
return new Promise((accept, reject) => {
|
||||||
try {
|
try {
|
||||||
new moto.STL().parse(data, vertices => {
|
let vertices = new moto.STL().parse(data);
|
||||||
this.listener({parsed: data, vertices});
|
this.listener({parsed: data, vertices});
|
||||||
this.widget.loadVertices(vertices)
|
this.widget.loadVertices(vertices).center();
|
||||||
accept(this);
|
accept(this);
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +104,8 @@ class Engine {
|
||||||
|
|
||||||
slice() {
|
slice() {
|
||||||
return new Promise((accept, reject) => {
|
return new Promise((accept, reject) => {
|
||||||
|
KIRI.client.clear();
|
||||||
|
KIRI.client.sync([ this.widget ]);
|
||||||
KIRI.client.slice(this.settings, this.widget, msg => {
|
KIRI.client.slice(this.settings, this.widget, msg => {
|
||||||
this.listener({slice:msg});
|
this.listener({slice:msg});
|
||||||
if (msg.error) {
|
if (msg.error) {
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function callExport(callback, mode) {
|
function callExport(callback, mode) {
|
||||||
|
let alert = API.feature.work_alerts ? API.show.alert("Exporting") : null;
|
||||||
const gcode = [];
|
const gcode = [];
|
||||||
KIRI.client.export(API.conf.get(), (line) => {
|
KIRI.client.export(API.conf.get(), (line) => {
|
||||||
gcode.push(line);
|
gcode.push(line);
|
||||||
}, (output) => {
|
}, (output, error) => {
|
||||||
if (callback) {
|
API.hide.alert(alert);
|
||||||
|
if (error) {
|
||||||
|
API.show.alert(error, 5);
|
||||||
|
} else if (callback) {
|
||||||
callback(gcode.join('\r\n'), output);
|
callback(gcode.join('\r\n'), output);
|
||||||
} else {
|
} else {
|
||||||
exportGCodeDialog(gcode.join('\r\n'), output);
|
exportGCodeDialog(gcode.join('\r\n'), output);
|
||||||
|
|
@ -46,8 +50,12 @@
|
||||||
function callExportLaser(options) {
|
function callExportLaser(options) {
|
||||||
KIRI.client.export(API.conf.get(), (line) => {
|
KIRI.client.export(API.conf.get(), (line) => {
|
||||||
console.log({unexpected_line: line});
|
console.log({unexpected_line: line});
|
||||||
}, (output) => {
|
}, (output, error) => {
|
||||||
exportLaserDialog(output);
|
if (error) {
|
||||||
|
API.show.alert(error, 5);
|
||||||
|
} else {
|
||||||
|
exportLaserDialog(output);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,9 +66,13 @@
|
||||||
if (line.data) {
|
if (line.data) {
|
||||||
preview.push(line.data);
|
preview.push(line.data);
|
||||||
}
|
}
|
||||||
}, (output) => {
|
}, (output, error) => {
|
||||||
API.show.progress(0);
|
API.show.progress(0);
|
||||||
KIRI.driver.SLA.printDownload(preview, output, API);
|
if (error) {
|
||||||
|
API.show.alert(error, 5);
|
||||||
|
} else {
|
||||||
|
KIRI.driver.SLA.printDownload(preview, output, API);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +124,14 @@
|
||||||
|
|
||||||
let settings = API.conf.get(),
|
let settings = API.conf.get(),
|
||||||
MODE = API.mode.get_id(),
|
MODE = API.mode.get_id(),
|
||||||
pre = (MODE === MODES.CAM ? "cnc-" : "print-") + (printSeq.toString().padStart(3,"0")),
|
names = API.widgets.all()
|
||||||
|
.map(w => w.meta ? w.meta.file : undefined)
|
||||||
|
.filter(v => v)
|
||||||
|
.map(v => v.replace(/ /g,'-'))
|
||||||
|
.map(v => v.substring(0,20))
|
||||||
|
.map(v => v.split('.')[0]),
|
||||||
|
name = names[0] || (MODE === MODES.CAM ? "cnc" : "print"),
|
||||||
|
pre = `${name}-${(printSeq.toString().padStart(3,"0"))}`,
|
||||||
filename = pre,// + (new Date().getTime().toString(36)),
|
filename = pre,// + (new Date().getTime().toString(36)),
|
||||||
fileext = settings.device.gcodeFExt || "gcode",
|
fileext = settings.device.gcodeFExt || "gcode",
|
||||||
codeproc = settings.device.gcodeProc,
|
codeproc = settings.device.gcodeProc,
|
||||||
|
|
@ -489,8 +508,8 @@
|
||||||
$('admin-gridlocal').onclick = admin_gridlocal;
|
$('admin-gridlocal').onclick = admin_gridlocal;
|
||||||
} catch (e) { console.log(e) }
|
} catch (e) { console.log(e) }
|
||||||
|
|
||||||
// preview of the generated GCODE
|
// preview of the generated GCODE (first 64k max)
|
||||||
if (preview && gcode) $('code-preview-textarea').value = gcode;
|
if (preview && gcode) $('code-preview-textarea').value = gcode.substring(0,65535);
|
||||||
|
|
||||||
// show dialog
|
// show dialog
|
||||||
API.modal.show('print');
|
API.modal.show('print');
|
||||||
|
|
|
||||||
471
src/kiri/init.js
471
src/kiri/init.js
|
|
@ -46,7 +46,6 @@
|
||||||
platform = API.platform,
|
platform = API.platform,
|
||||||
selection = API.selection,
|
selection = API.selection,
|
||||||
proto = location.protocol,
|
proto = location.protocol,
|
||||||
root = "grid.space",
|
|
||||||
ver = Date.now().toString(36);
|
ver = Date.now().toString(36);
|
||||||
|
|
||||||
let currentDevice = null,
|
let currentDevice = null,
|
||||||
|
|
@ -58,7 +57,8 @@
|
||||||
editTools = null,
|
editTools = null,
|
||||||
maxTool = 0,
|
maxTool = 0,
|
||||||
fpsTimer = null,
|
fpsTimer = null,
|
||||||
platformColor;
|
platformColor,
|
||||||
|
contextInt;
|
||||||
|
|
||||||
// extend KIRI API with local functions
|
// extend KIRI API with local functions
|
||||||
API.show.devices = showDevices;
|
API.show.devices = showDevices;
|
||||||
|
|
@ -138,7 +138,9 @@
|
||||||
function booleanSave() {
|
function booleanSave() {
|
||||||
let control = settings().controller;
|
let control = settings().controller;
|
||||||
let isDark = control.dark;
|
let isDark = control.dark;
|
||||||
|
let doAlert = UI.ortho.checked !== control.ortho;
|
||||||
control.decals = UI.decals.checked;
|
control.decals = UI.decals.checked;
|
||||||
|
control.danger = UI.danger.checked;
|
||||||
control.showOrigin = UI.showOrigin.checked;
|
control.showOrigin = UI.showOrigin.checked;
|
||||||
control.showRulers = UI.showRulers.checked;
|
control.showRulers = UI.showRulers.checked;
|
||||||
control.autoLayout = UI.autoLayout.checked;
|
control.autoLayout = UI.autoLayout.checked;
|
||||||
|
|
@ -151,8 +153,10 @@
|
||||||
control.exportLocal = UI.exportLocal.checked;
|
control.exportLocal = UI.exportLocal.checked;
|
||||||
control.exportPreview = UI.exportPreview.checked;
|
control.exportPreview = UI.exportPreview.checked;
|
||||||
control.decimate = UI.decimate.checked;
|
control.decimate = UI.decimate.checked;
|
||||||
|
control.healMesh = UI.healMesh.checked;
|
||||||
|
control.ortho = UI.ortho.checked;
|
||||||
SPACE.view.setZoom(control.reverseZoom, control.zoomSpeed);
|
SPACE.view.setZoom(control.reverseZoom, control.zoomSpeed);
|
||||||
platform.layout();
|
// platform.layout();
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
API.platform.update_size();
|
API.platform.update_size();
|
||||||
API.catalog.setOptions({
|
API.catalog.setOptions({
|
||||||
|
|
@ -166,6 +170,9 @@
|
||||||
clearDeviceTexture();
|
clearDeviceTexture();
|
||||||
}
|
}
|
||||||
API.event.emit('boolean.update');
|
API.event.emit('boolean.update');
|
||||||
|
if (doAlert) {
|
||||||
|
API.show.alert("change requires page refresh");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFPS() {
|
function updateFPS() {
|
||||||
|
|
@ -191,7 +198,7 @@
|
||||||
// }
|
// }
|
||||||
API.conf.update();
|
API.conf.update();
|
||||||
DOC.activeElement.blur();
|
DOC.activeElement.blur();
|
||||||
// API.event.emit("boolean.click");
|
API.event.emit("boolean.click");
|
||||||
}
|
}
|
||||||
|
|
||||||
function onButtonClick(ev) {
|
function onButtonClick(ev) {
|
||||||
|
|
@ -240,7 +247,7 @@
|
||||||
// hide all dialogs
|
// hide all dialogs
|
||||||
API.dialog.hide();
|
API.dialog.hide();
|
||||||
// cancel slicing
|
// cancel slicing
|
||||||
if (KIRI.work.isSlicing()) KIRI.work.restart();
|
API.function.cancel();
|
||||||
// kill any poppers in compact mode
|
// kill any poppers in compact mode
|
||||||
UC.hidePoppers();
|
UC.hidePoppers();
|
||||||
// and send an event (used by FDM client)
|
// and send an event (used by FDM client)
|
||||||
|
|
@ -321,16 +328,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyHandler(evt) {
|
function keyHandler(evt) {
|
||||||
let handled = true,
|
let handled = true;
|
||||||
current = settings(),
|
|
||||||
style, sel, i, m, bb,
|
|
||||||
ncc = evt.charCode - 48;
|
|
||||||
if (API.modal.visible() || inputHasFocus()) {
|
if (API.modal.visible() || inputHasFocus()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (API.feature.on_key) {
|
if (API.feature.on_key) {
|
||||||
if (API.feature.on_key({key:evt})) return;
|
if (API.feature.on_key({key:evt})) return;
|
||||||
}
|
}
|
||||||
|
if (evt.ctrlKey) {
|
||||||
|
switch (evt.key) {
|
||||||
|
case 'g': return API.group.merge();
|
||||||
|
case 'u': return API.group.split();
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (evt.charCode) {
|
switch (evt.charCode) {
|
||||||
case cca('`'): API.show.slices(0); break;
|
case cca('`'): API.show.slices(0); break;
|
||||||
case cca('0'): API.show.slices(API.var.layer_max); break;
|
case cca('0'): API.show.slices(API.var.layer_max); break;
|
||||||
|
|
@ -357,14 +367,6 @@
|
||||||
case cca('i'): // file import
|
case cca('i'): // file import
|
||||||
API.event.import();
|
API.event.import();
|
||||||
break;
|
break;
|
||||||
case cca('U'): // full settings url
|
|
||||||
storeSettingsToServer(true);
|
|
||||||
break;
|
|
||||||
case cca('u'): // full settings url
|
|
||||||
UC.prompt("settings id to load", "").then(id => {
|
|
||||||
if (id) loadSettingsFromServer(id);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case cca('S'): // slice
|
case cca('S'): // slice
|
||||||
case cca('s'): // slice
|
case cca('s'): // slice
|
||||||
if (evt.shiftKey) {
|
if (evt.shiftKey) {
|
||||||
|
|
@ -414,6 +416,9 @@
|
||||||
API.show.local();
|
API.show.local();
|
||||||
break;
|
break;
|
||||||
case cca('v'): // toggle single slice view mode
|
case cca('v'): // toggle single slice view mode
|
||||||
|
if (API.view.get() === VIEWS.ARRANGE) {
|
||||||
|
API.space.set_focus(API.selection.widgets());
|
||||||
|
}
|
||||||
if (API.var.layer_hi == API.var.layer_lo) {
|
if (API.var.layer_hi == API.var.layer_lo) {
|
||||||
API.var.layer_lo = 0;
|
API.var.layer_lo = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -422,52 +427,75 @@
|
||||||
API.show.slices();
|
API.show.slices();
|
||||||
break;
|
break;
|
||||||
case cca('d'): // duplicate object
|
case cca('d'): // duplicate object
|
||||||
sel = API.selection.meshes();
|
duplicateSelection();
|
||||||
platform.deselect();
|
|
||||||
for (i=0; i<sel.length; i++) {
|
|
||||||
let mesh = sel[i].clone();
|
|
||||||
mesh.geometry = mesh.geometry.clone();
|
|
||||||
mesh.material = mesh.material.clone();
|
|
||||||
bb = mesh.getBoundingBox();
|
|
||||||
let ow = sel[i].widget;
|
|
||||||
let nw = API.widgets.new().loadGeometry(mesh.geometry);
|
|
||||||
nw.meta.file = ow.meta.file;
|
|
||||||
nw.meta.vertices = ow.meta.vertices;
|
|
||||||
nw.move(bb.max.x - bb.min.x + 1, 0, 0);
|
|
||||||
platform.add(nw,true);
|
|
||||||
let owa = API.widgets.annotate(ow.id);
|
|
||||||
let nwa = API.widgets.annotate(nw.id);
|
|
||||||
if (owa.tab) {
|
|
||||||
nwa.tab = Object.clone(owa.tab);
|
|
||||||
nwa.tab.forEach((tab,i) => {
|
|
||||||
tab.id = Date.now() + i
|
|
||||||
});
|
|
||||||
}
|
|
||||||
KIRI.driver.CAM.restoreTabs([nw]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case cca('m'): // mirror object
|
case cca('m'): // mirror object
|
||||||
API.selection.for_widgets(function(widget) {
|
mirrorSelection();
|
||||||
widget.mirror();
|
|
||||||
});
|
|
||||||
SPACE.update();
|
|
||||||
break;
|
break;
|
||||||
case cca('R'): // toggle slice render mode
|
case cca('R'): // toggle slice render mode
|
||||||
renderMode++;
|
renderMode++;
|
||||||
API.function.slice();
|
API.function.slice();
|
||||||
break;
|
break;
|
||||||
case cca('a'): // auto arrange items on platform
|
case cca('a'):
|
||||||
platform.layout();
|
if (API.view.get() === VIEWS.ARRANGE) {
|
||||||
|
// auto arrange items on platform
|
||||||
|
platform.layout();
|
||||||
|
API.space.set_focus(API.selection.widgets());
|
||||||
|
} else {
|
||||||
|
// go to arrange view
|
||||||
|
API.view.set(VIEWS.ARRANGE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
API.event.emit('keypress', evt);
|
API.event.emit('keypress', evt);
|
||||||
handled = false;
|
handled = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (handled) evt.preventDefault();
|
if (handled) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function layFlat() {
|
||||||
|
let int = contextInt[0];
|
||||||
|
if (int && int.object && int.object.widget) {
|
||||||
|
let q = new THREE.Quaternion();
|
||||||
|
q.setFromUnitVectors(contextInt[0].face.normal, new THREE.Vector3(0,0,-1));
|
||||||
|
API.selection.rotate(q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function duplicateSelection() {
|
||||||
|
API.selection.for_widgets(function(widget) {
|
||||||
|
let mesh = widget.mesh;
|
||||||
|
let bb = mesh.getBoundingBox();
|
||||||
|
let ow = widget;
|
||||||
|
let nw = API.widgets.new().loadGeometry(mesh.geometry.clone());
|
||||||
|
nw.meta.file = ow.meta.file;
|
||||||
|
nw.meta.vertices = ow.meta.vertices;
|
||||||
|
nw.move(bb.max.x - bb.min.x + 1, 0, 0);
|
||||||
|
platform.add(nw,true);
|
||||||
|
let owa = API.widgets.annotate(ow.id);
|
||||||
|
let nwa = API.widgets.annotate(nw.id);
|
||||||
|
if (owa.tab) {
|
||||||
|
nwa.tab = Object.clone(owa.tab);
|
||||||
|
nwa.tab.forEach((tab,i) => {
|
||||||
|
tab.id = Date.now() + i
|
||||||
|
});
|
||||||
|
}
|
||||||
|
KIRI.driver.CAM.restoreTabs([nw]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mirrorSelection() {
|
||||||
|
API.selection.for_widgets(function(widget) {
|
||||||
|
widget.mirror();
|
||||||
|
});
|
||||||
|
SPACE.update();
|
||||||
|
}
|
||||||
|
|
||||||
function keys(o) {
|
function keys(o) {
|
||||||
let key, list = [];
|
let key, list = [];
|
||||||
for (key in o) { if (o.hasOwnProperty(key)) list.push(key) }
|
for (key in o) { if (o.hasOwnProperty(key)) list.push(key) }
|
||||||
|
|
@ -515,43 +543,6 @@
|
||||||
moveSelection(x, y, z, true);
|
moveSelection(x, y, z, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSettingsFromServer(tok) {
|
|
||||||
let hash = (tok || LOC.hash.substring(1)).split("/");
|
|
||||||
if (hash.length === 2) {
|
|
||||||
new moto.Ajax(function(reply) {
|
|
||||||
if (reply) {
|
|
||||||
let res = JSON.parse(reply);
|
|
||||||
if (res && res.ver && res.rec) {
|
|
||||||
let set = JSON.parse(atob(res.rec));
|
|
||||||
set.id = res.space;
|
|
||||||
set.ver = res.ver;
|
|
||||||
API.conf.put(set);
|
|
||||||
API.event.settings();
|
|
||||||
API.ui.sync();
|
|
||||||
LOC.hash = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).request("/data/"+ hash[0] + "/" + hash[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function storeSettingsToServer(display) {
|
|
||||||
let set = btoa(JSON.stringify(settings()));
|
|
||||||
new moto.Ajax(function(reply) {
|
|
||||||
if (reply) {
|
|
||||||
let res = JSON.parse(reply);
|
|
||||||
if (res && res.ver) {
|
|
||||||
LOC.hash = res.space + "/" + res.ver;
|
|
||||||
if (display) {
|
|
||||||
UC.alert(`unique settings id is: <b>${res.space}/${res.ver}</b>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateSpaceState();
|
|
||||||
}
|
|
||||||
}).request("/data/"+ settings().id + "/" + settings().ver, set);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deviceExport(exp, name) {
|
function deviceExport(exp, name) {
|
||||||
name = (name || "device")
|
name = (name || "device")
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
|
@ -559,10 +550,7 @@
|
||||||
.replace(/\./g,'_');
|
.replace(/\./g,'_');
|
||||||
UC.prompt("Export Device Filename", name).then(name => {
|
UC.prompt("Export Device Filename", name).then(name => {
|
||||||
if (name) {
|
if (name) {
|
||||||
let blob = new Blob([exp], {type: "octet/stream"}),
|
API.util.download(exp, `${name}.km`);
|
||||||
url = WIN.URL.createObjectURL(blob);
|
|
||||||
$('mod-any').innerHTML = `<a id="sexport" href="${url}" download="${name}.km">x</a>`;
|
|
||||||
$('sexport').click();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -574,13 +562,7 @@
|
||||||
if (name.toLowerCase().indexOf(".stl") < 0) {
|
if (name.toLowerCase().indexOf(".stl") < 0) {
|
||||||
name = `${name}.stl`;
|
name = `${name}.stl`;
|
||||||
}
|
}
|
||||||
let xprt = API.selection.export(),
|
API.util.download(API.selection.export(), name);
|
||||||
blob = new Blob([xprt], {type: "octet/stream"}),
|
|
||||||
url = WIN.URL.createObjectURL(blob);
|
|
||||||
$('mod-any').innerHTML = [
|
|
||||||
`<a id="sexport" href="${url}" download="${name}">x</a>`
|
|
||||||
].join('');
|
|
||||||
$('sexport').click();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -601,13 +583,8 @@
|
||||||
UC.confirm("Export Filename", {ok:true, cancel: false}, "workspace", opt).then(name => {
|
UC.confirm("Export Filename", {ok:true, cancel: false}, "workspace", opt).then(name => {
|
||||||
if (name) {
|
if (name) {
|
||||||
let work = $('incwork').checked,
|
let work = $('incwork').checked,
|
||||||
json = API.conf.export({work}),
|
json = API.conf.export({work});
|
||||||
blob = new Blob([json], {type: "octet/stream"}),
|
API.util.download(json, `${name}.km`);
|
||||||
url = WIN.URL.createObjectURL(blob);
|
|
||||||
$('mod-any').innerHTML = [
|
|
||||||
`<a id="sexport" href="${url}" download="${name}.km">x</a>`
|
|
||||||
].join('');
|
|
||||||
$('sexport').click();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -630,10 +607,12 @@
|
||||||
if (name) {
|
if (name) {
|
||||||
let np = pl[name] = {};
|
let np = pl[name] = {};
|
||||||
cp.processName = name;
|
cp.processName = name;
|
||||||
|
pl[name] = Object.clone(cp);
|
||||||
for (let k in cp) {
|
for (let k in cp) {
|
||||||
if (!cp.hasOwnProperty(k)) continue;
|
if (!cp.hasOwnProperty(k)) continue;
|
||||||
np[k] = cp[k];
|
np[k] = cp[k];
|
||||||
}
|
}
|
||||||
|
s.cproc[mode] = name;
|
||||||
s.devproc[s.device.deviceName] = name;
|
s.devproc[s.device.deviceName] = name;
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
API.conf.update();
|
API.conf.update();
|
||||||
|
|
@ -694,28 +673,28 @@
|
||||||
let mode = API.mode.get(),
|
let mode = API.mode.get(),
|
||||||
current = settings(),
|
current = settings(),
|
||||||
local = isLocalDevice(devicename),
|
local = isLocalDevice(devicename),
|
||||||
dproc = current.devproc[devicename],
|
|
||||||
dev = current.device = CONF.device_from_code(code,mode),
|
dev = current.device = CONF.device_from_code(code,mode),
|
||||||
proc = current.process,
|
dproc = current.devproc[devicename], // last process name for this device
|
||||||
newdev = dproc === undefined;
|
newdev = dproc === undefined, // first time device is selected
|
||||||
|
predev = current.filter[mode], // previous device selection
|
||||||
|
chgdev = predev !== devicename; // device is changing
|
||||||
|
|
||||||
// first time device use, add any print profiles and set to default if present
|
// first time device use, add any print profiles and set to default if present
|
||||||
// if (newdev) {
|
if (code.profiles) {
|
||||||
// console.log('new device', code);
|
for (let profile of code.profiles) {
|
||||||
if (code.profiles) {
|
let profname = profile.processName;
|
||||||
for (let profile of code.profiles) {
|
// if no saved profile by that name for this mode...
|
||||||
let profname = profile.processName;
|
if (!current.sproc[mode][profname]) {
|
||||||
if (!current.sproc[mode][profname]) {
|
console.log('adding profile', profname, 'to', mode);
|
||||||
console.log('adding profile', profname, 'to', mode);
|
current.sproc[mode][profname] = profile;
|
||||||
current.sproc[mode][profname] = profile;
|
}
|
||||||
}
|
// if it's a new device, seed the new profile name as last profile
|
||||||
if (newdev && !current.devproc[devicename]) {
|
if (newdev && !current.devproc[devicename]) {
|
||||||
console.log('setting default profile for new device', devicename, 'to', profname);
|
console.log('setting default profile for new device', devicename, 'to', profname);
|
||||||
current.devproc[devicename] = dproc = profname;
|
current.devproc[devicename] = dproc = profname;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
dev.new = false;
|
dev.new = false;
|
||||||
dev.deviceName = devicename;
|
dev.deviceName = devicename;
|
||||||
|
|
@ -724,9 +703,16 @@
|
||||||
UI.deviceBelt.checked = dev.bedBelt;
|
UI.deviceBelt.checked = dev.bedBelt;
|
||||||
UI.deviceRound.checked = dev.bedRound;
|
UI.deviceRound.checked = dev.bedRound;
|
||||||
UI.deviceOrigin.checked = dev.outputOriginCenter || dev.originCenter;
|
UI.deviceOrigin.checked = dev.outputOriginCenter || dev.originCenter;
|
||||||
|
UI.fwRetract.checked = dev.fwRetract;
|
||||||
|
|
||||||
// add extruder selection buttons
|
// add extruder selection buttons
|
||||||
if (dev.extruders) {
|
if (dev.extruders) {
|
||||||
|
for (let ext of dev.extruders) {
|
||||||
|
// add missing deselect field from legacy configs
|
||||||
|
if (!ext.extDeselect) {
|
||||||
|
ext.extDeselect = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
let ext = API.lists.extruders = [];
|
let ext = API.lists.extruders = [];
|
||||||
dev.internal = 0;
|
dev.internal = 0;
|
||||||
let selext = $('pop-nozzle');
|
let selext = $('pop-nozzle');
|
||||||
|
|
@ -756,10 +742,10 @@
|
||||||
UI.bedDepth,
|
UI.bedDepth,
|
||||||
UI.bedWidth,
|
UI.bedWidth,
|
||||||
UI.maxHeight,
|
UI.maxHeight,
|
||||||
UI.extrudeAbs,
|
|
||||||
UI.deviceOrigin,
|
UI.deviceOrigin,
|
||||||
UI.deviceRound,
|
UI.deviceRound,
|
||||||
UI.deviceBelt,
|
UI.deviceBelt,
|
||||||
|
UI.fwRetract,
|
||||||
UI.gcodeFan,
|
UI.gcodeFan,
|
||||||
UI.gcodeTrack,
|
UI.gcodeTrack,
|
||||||
UI.gcodeLayer,
|
UI.gcodeLayer,
|
||||||
|
|
@ -780,12 +766,12 @@
|
||||||
UI.extDel,
|
UI.extDel,
|
||||||
UI.extOffsetX,
|
UI.extOffsetX,
|
||||||
UI.extOffsetY,
|
UI.extOffsetY,
|
||||||
UI.extSelect
|
UI.extSelect,
|
||||||
|
UI.extDeselect
|
||||||
].forEach(function(e) {
|
].forEach(function(e) {
|
||||||
e.disabled = !local;
|
e.disabled = !local;
|
||||||
});
|
});
|
||||||
|
|
||||||
UI.extrudeAbs.style.display = mode === 'CAM' ? 'none' : 'flex';
|
|
||||||
UI.deviceSave.disabled = !local;
|
UI.deviceSave.disabled = !local;
|
||||||
UI.deviceDelete.disabled = !local;
|
UI.deviceDelete.disabled = !local;
|
||||||
UI.deviceExport.disabled = !local;
|
UI.deviceExport.disabled = !local;
|
||||||
|
|
@ -802,8 +788,12 @@
|
||||||
|
|
||||||
API.view.update_fields();
|
API.view.update_fields();
|
||||||
platform.update_size();
|
platform.update_size();
|
||||||
|
platform.update_origin();
|
||||||
|
platform.update();
|
||||||
|
|
||||||
|
// store current device name for this mode
|
||||||
current.filter[mode] = devicename;
|
current.filter[mode] = devicename;
|
||||||
|
// cache device record for this mode (restored in setMode)
|
||||||
current.cdev[mode] = currentDevice = dev;
|
current.cdev[mode] = currentDevice = dev;
|
||||||
|
|
||||||
if (dproc) {
|
if (dproc) {
|
||||||
|
|
@ -814,6 +804,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
|
|
||||||
|
API.const.SPACE.view.setHome(dev.bedBelt ? Math.PI/2 : 0);
|
||||||
|
// when changing devices, update focus on widgets
|
||||||
|
if (chgdev) {
|
||||||
|
setTimeout(API.space.set_focus, 0);
|
||||||
|
}
|
||||||
|
|
||||||
UC.refresh();
|
UC.refresh();
|
||||||
|
|
||||||
if (dev.imageURL) {
|
if (dev.imageURL) {
|
||||||
|
|
@ -844,12 +841,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadDeviceImage(dev, url) {
|
function loadDeviceImage(dev, url) {
|
||||||
new THREE.TextureLoader().load(url || dev.imageURL, texture => {
|
let turl = url || dev.imageURL;
|
||||||
|
if (!turl) return;
|
||||||
|
new THREE.TextureLoader().load(turl, texture => {
|
||||||
loadDeviceTexture(dev, texture);
|
loadDeviceTexture(dev, texture);
|
||||||
}, inc => {
|
}, inc => {
|
||||||
console.log({load_inc: inc});
|
console.log({load_inc: inc});
|
||||||
}, error => {
|
}, error => {
|
||||||
console.log({load_error: error});
|
console.log({load_error: error, turl});
|
||||||
clearDeviceTexture();
|
clearDeviceTexture();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -949,12 +948,13 @@
|
||||||
showDevices();
|
showDevices();
|
||||||
};
|
};
|
||||||
UI.deviceExport.onclick = function() {
|
UI.deviceExport.onclick = function() {
|
||||||
let exp = btoa(JSON.stringify({
|
let exp = API.util.b64enc({
|
||||||
version: KIRI.version,
|
version: KIRI.version,
|
||||||
device: selected,
|
device: selected,
|
||||||
|
process: API.process.code(),
|
||||||
code: devs[selected],
|
code: devs[selected],
|
||||||
time: Date.now()
|
time: Date.now()
|
||||||
}));
|
});
|
||||||
deviceExport(exp, selected);
|
deviceExport(exp, selected);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1236,6 +1236,12 @@
|
||||||
function dragOverHandler(evt) {
|
function dragOverHandler(evt) {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
|
// prevent drop actions when a dialog is open
|
||||||
|
if (API.modal.visible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
evt.dataTransfer.dropEffect = 'copy';
|
evt.dataTransfer.dropEffect = 'copy';
|
||||||
let oldcolor = SPACE.platform.setColor(0x00ff00);
|
let oldcolor = SPACE.platform.setColor(0x00ff00);
|
||||||
if (oldcolor !== 0x00ff00) platformColor = oldcolor;
|
if (oldcolor !== 0x00ff00) platformColor = oldcolor;
|
||||||
|
|
@ -1249,6 +1255,11 @@
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
|
// prevent drop actions when a dialog is open
|
||||||
|
if (API.modal.visible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SPACE.platform.setColor(platformColor);
|
SPACE.platform.setColor(platformColor);
|
||||||
|
|
||||||
let files = evt.dataTransfer.files;
|
let files = evt.dataTransfer.files;
|
||||||
|
|
@ -1352,13 +1363,15 @@
|
||||||
return !isBelt();
|
return !isBelt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDanger() {
|
||||||
|
return UI.danger.checked;
|
||||||
|
}
|
||||||
|
|
||||||
// MAIN INITIALIZATION FUNCTION
|
// MAIN INITIALIZATION FUNCTION
|
||||||
|
|
||||||
function init_one() {
|
function init_one() {
|
||||||
API.event.emit('init.one');
|
API.event.emit('init.one');
|
||||||
|
|
||||||
$('gsbox').src = `${proto}//${root}/kiri/gsbox.png?ver=${ver}`;
|
|
||||||
|
|
||||||
// ensure we have settings from last session
|
// ensure we have settings from last session
|
||||||
API.conf.restore();
|
API.conf.restore();
|
||||||
|
|
||||||
|
|
@ -1387,7 +1400,7 @@
|
||||||
SPACE.setSkyColor(controller.dark ? 0 : 0xffffff);
|
SPACE.setSkyColor(controller.dark ? 0 : 0xffffff);
|
||||||
SPACE.init(container, function (delta) {
|
SPACE.init(container, function (delta) {
|
||||||
if (API.var.layer_max === 0 || !delta) return;
|
if (API.var.layer_max === 0 || !delta) return;
|
||||||
if (settings().controller.reverseZoom) delta = -delta;
|
if (controller.reverseZoom) delta = -delta;
|
||||||
let same = API.var.layer_hi === API.var.layer_lo;
|
let same = API.var.layer_hi === API.var.layer_lo;
|
||||||
let track = API.var.layer_lo > 0;
|
let track = API.var.layer_lo > 0;
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
|
|
@ -1406,7 +1419,7 @@
|
||||||
}
|
}
|
||||||
API.view.update_slider();
|
API.view.update_slider();
|
||||||
API.show.slices();
|
API.show.slices();
|
||||||
});
|
}, controller.ortho);
|
||||||
SPACE.platform.onMove(API.conf.save);
|
SPACE.platform.onMove(API.conf.save);
|
||||||
SPACE.platform.setRound(true);
|
SPACE.platform.setRound(true);
|
||||||
SPACE.useDefaultKeys(API.feature.on_key === undefined || API.feature.on_key_defaults);
|
SPACE.useDefaultKeys(API.feature.on_key === undefined || API.feature.on_key_defaults);
|
||||||
|
|
@ -1448,6 +1461,10 @@
|
||||||
|
|
||||||
back: $('lt-back'),
|
back: $('lt-back'),
|
||||||
trash: $('lt-trash'),
|
trash: $('lt-trash'),
|
||||||
|
ltsetup: $('lt-setup'),
|
||||||
|
ltfile: $('lt-file'),
|
||||||
|
ltview: $('lt-view'),
|
||||||
|
ltact: $('act-slice'),
|
||||||
rotate: $('lt-rotate'),
|
rotate: $('lt-rotate'),
|
||||||
scale: $('lt-scale'),
|
scale: $('lt-scale'),
|
||||||
nozzle: $('lt-nozzle'),
|
nozzle: $('lt-nozzle'),
|
||||||
|
|
@ -1534,6 +1551,7 @@
|
||||||
deviceOrigin: UC.newBoolean(LANG.dv_orgc_s, onBooleanClick, {title:LANG.dv_orgc_l, modes:FDM_LASER_SLA}),
|
deviceOrigin: UC.newBoolean(LANG.dv_orgc_s, onBooleanClick, {title:LANG.dv_orgc_l, modes:FDM_LASER_SLA}),
|
||||||
deviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM, trigger:true, show:isNotBelt}),
|
deviceRound: UC.newBoolean(LANG.dv_bedc_s, onBooleanClick, {title:LANG.dv_bedc_l, modes:FDM, trigger:true, show:isNotBelt}),
|
||||||
deviceBelt: UC.newBoolean(LANG.dv_belt_s, onBooleanClick, {title:LANG.dv_belt_l, modes:FDM, trigger:true, show:() => !UI.deviceRound.checked}),
|
deviceBelt: UC.newBoolean(LANG.dv_belt_s, onBooleanClick, {title:LANG.dv_belt_l, modes:FDM, trigger:true, show:() => !UI.deviceRound.checked}),
|
||||||
|
fwRetract: UC.newBoolean(LANG.dv_retr_s, onBooleanClick, {title:LANG.dv_retr_l, modes:FDM}),
|
||||||
|
|
||||||
extruder: UC.newGroup(LANG.dv_gr_ext, $('device2'), {group:"dext", inline:true, modes:FDM}),
|
extruder: UC.newGroup(LANG.dv_gr_ext, $('device2'), {group:"dext", inline:true, modes:FDM}),
|
||||||
extFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
|
extFilament: UC.newInput(LANG.dv_fila_s, {title:LANG.dv_fila_l, convert:UC.toFloat, modes:FDM}),
|
||||||
|
|
@ -1541,7 +1559,7 @@
|
||||||
extOffsetX: UC.newInput(LANG.dv_exox_s, {title:LANG.dv_exox_l, convert:UC.toFloat, modes:FDM}),
|
extOffsetX: UC.newInput(LANG.dv_exox_s, {title:LANG.dv_exox_l, convert:UC.toFloat, modes:FDM}),
|
||||||
extOffsetY: UC.newInput(LANG.dv_exoy_s, {title:LANG.dv_exoy_l, convert:UC.toFloat, modes:FDM}),
|
extOffsetY: UC.newInput(LANG.dv_exoy_s, {title:LANG.dv_exoy_l, convert:UC.toFloat, modes:FDM}),
|
||||||
extSelect: UC.newText(LANG.dv_exts_s, {title:LANG.dv_exts_l, modes:FDM, size:14, height:3, modes:FDM, area:gcode}),
|
extSelect: UC.newText(LANG.dv_exts_s, {title:LANG.dv_exts_l, modes:FDM, size:14, height:3, modes:FDM, area:gcode}),
|
||||||
extrudeAbs: UC.newBoolean(LANG.dv_xtab_s, onBooleanClick, {title:LANG.dv_xtab_l, modes:FDM}),
|
extDeselect: UC.newText(LANG.dv_dext_s, {title:LANG.dv_dext_l, modes:FDM, size:14, height:3, modes:FDM, area:gcode}),
|
||||||
extActions: UC.newRow([
|
extActions: UC.newRow([
|
||||||
UI.extPrev = UC.newButton(undefined, undefined, {icon:'<i class="fas fa-less-than"></i>'}),
|
UI.extPrev = UC.newButton(undefined, undefined, {icon:'<i class="fas fa-less-than"></i>'}),
|
||||||
UI.extAdd = UC.newButton(undefined, undefined, {icon:'<i class="fas fa-plus"></i>'}),
|
UI.extAdd = UC.newButton(undefined, undefined, {icon:'<i class="fas fa-plus"></i>'}),
|
||||||
|
|
@ -1571,8 +1589,10 @@
|
||||||
|
|
||||||
lprefs: UC.newGroup(LANG.op_menu, $('prefs-gen1'), {inline: true}),
|
lprefs: UC.newGroup(LANG.op_menu, $('prefs-gen1'), {inline: true}),
|
||||||
reverseZoom: UC.newBoolean(LANG.op_invr_s, booleanSave, {title:LANG.op_invr_l}),
|
reverseZoom: UC.newBoolean(LANG.op_invr_s, booleanSave, {title:LANG.op_invr_l}),
|
||||||
|
ortho: UC.newBoolean(LANG.op_orth_s, booleanSave, {title:LANG.op_orth_l}),
|
||||||
dark: UC.newBoolean(LANG.op_dark_s, booleanSave, {title:LANG.op_dark_l}),
|
dark: UC.newBoolean(LANG.op_dark_s, booleanSave, {title:LANG.op_dark_l}),
|
||||||
decals: UC.newBoolean(LANG.op_decl_s, booleanSave, {title:LANG.op_decl_s}),
|
decals: UC.newBoolean(LANG.op_decl_s, booleanSave, {title:LANG.op_decl_s}),
|
||||||
|
danger: UC.newBoolean(LANG.op_dang_s, booleanSave, {title:LANG.op_dang_l}),
|
||||||
|
|
||||||
lprefs: UC.newGroup(LANG.op_disp, $('prefs-gen2'), {inline: true}),
|
lprefs: UC.newGroup(LANG.op_disp, $('prefs-gen2'), {inline: true}),
|
||||||
showOrigin: UC.newBoolean(LANG.op_shor_s, booleanSave, {title:LANG.op_shor_l}),
|
showOrigin: UC.newBoolean(LANG.op_shor_s, booleanSave, {title:LANG.op_shor_l}),
|
||||||
|
|
@ -1580,12 +1600,13 @@
|
||||||
showSpeeds: UC.newBoolean(LANG.op_sped_s, speedSave, {title:LANG.op_sped_l}),
|
showSpeeds: UC.newBoolean(LANG.op_sped_s, speedSave, {title:LANG.op_sped_l}),
|
||||||
lineType: UC.newSelect(LANG.op_line_s, {title: LANG.op_line_l, action: lineTypeSave, modes:FDM}, "linetype"),
|
lineType: UC.newSelect(LANG.op_line_s, {title: LANG.op_line_l, action: lineTypeSave, modes:FDM}, "linetype"),
|
||||||
animesh: UC.newSelect(LANG.op_anim_s, {title: LANG.op_anim_l, action: aniMeshSave, modes:CAM}, "animesh"),
|
animesh: UC.newSelect(LANG.op_anim_s, {title: LANG.op_anim_l, action: aniMeshSave, modes:CAM}, "animesh"),
|
||||||
units: UC.newSelect(LANG.op_unit_s, {title: LANG.op_unit_l, action:unitsSave, modes:CAM, trace:true}, "units"),
|
units: UC.newSelect(LANG.op_unit_s, {title: LANG.op_unit_l, action: unitsSave, modes:CAM, trace:true}, "units"),
|
||||||
|
|
||||||
layout: UC.newGroup(LANG.lo_menu, $('prefs-lay'), {inline: true}),
|
layout: UC.newGroup(LANG.lo_menu, $('prefs-lay'), {inline: true}),
|
||||||
|
autoSave: UC.newBoolean(LANG.op_save_s, booleanSave, {title:LANG.op_save_l}),
|
||||||
autoLayout: UC.newBoolean(LANG.op_auto_s, booleanSave, {title:LANG.op_auto_l}),
|
autoLayout: UC.newBoolean(LANG.op_auto_s, booleanSave, {title:LANG.op_auto_l}),
|
||||||
freeLayout: UC.newBoolean(LANG.op_free_s, booleanSave, {title:LANG.op_free_l}),
|
freeLayout: UC.newBoolean(LANG.op_free_s, booleanSave, {title:LANG.op_free_l}),
|
||||||
autoSave: UC.newBoolean(LANG.op_save_s, booleanSave, {title:LANG.op_save_l}),
|
spaceLayout: UC.newInput(LANG.op_spcr_s, {title:LANG.op_spcr_l, convert:UC.toFloat, size:3, units:true}),
|
||||||
|
|
||||||
export: UC.newGroup(LANG.xp_menu, $('prefs-xpo'), {inline: true}),
|
export: UC.newGroup(LANG.xp_menu, $('prefs-xpo'), {inline: true}),
|
||||||
exportOcto: UC.newBoolean(`OctoPrint`, booleanSave),
|
exportOcto: UC.newBoolean(`OctoPrint`, booleanSave),
|
||||||
|
|
@ -1596,6 +1617,7 @@
|
||||||
parts: UC.newGroup(LANG.pt_menu, $('prefs-prt'), {inline: true}),
|
parts: UC.newGroup(LANG.pt_menu, $('prefs-prt'), {inline: true}),
|
||||||
detail: UC.newSelect(LANG.pt_qual_s, {title: LANG.pt_qual_l, action: detailSave}, "detail"),
|
detail: UC.newSelect(LANG.pt_qual_s, {title: LANG.pt_qual_l, action: detailSave}, "detail"),
|
||||||
decimate: UC.newBoolean(LANG.pt_deci_s, booleanSave, {title: LANG.pt_deci_l}),
|
decimate: UC.newBoolean(LANG.pt_deci_s, booleanSave, {title: LANG.pt_deci_l}),
|
||||||
|
healMesh: UC.newBoolean(LANG.pt_heal_s, booleanSave, {title: LANG.pt_heal_l}),
|
||||||
|
|
||||||
prefadd: UC.checkpoint($('prefs-add')),
|
prefadd: UC.checkpoint($('prefs-add')),
|
||||||
|
|
||||||
|
|
@ -1603,7 +1625,7 @@
|
||||||
sliceHeight: UC.newInput(LANG.sl_lahi_s, {title:LANG.sl_lahi_l, convert:UC.toFloat, modes:FDM}),
|
sliceHeight: UC.newInput(LANG.sl_lahi_s, {title:LANG.sl_lahi_l, convert:UC.toFloat, modes:FDM}),
|
||||||
sliceMinHeight: UC.newInput(LANG.ad_minl_s, {title:LANG.ad_minl_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM, show: () => UI.sliceAdaptive.checked}),
|
sliceMinHeight: UC.newInput(LANG.ad_minl_s, {title:LANG.ad_minl_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM, show: () => UI.sliceAdaptive.checked}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
sliceShells: UC.newInput(LANG.sl_shel_s, {title:LANG.sl_shel_l, convert:UC.toInt, modes:FDM}),
|
sliceShells: UC.newInput(LANG.sl_shel_s, {title:LANG.sl_shel_l, convert:UC.toFloat, modes:FDM}),
|
||||||
sliceTopLayers: UC.newInput(LANG.sl_ltop_s, {title:LANG.sl_ltop_l, convert:UC.toInt, modes:FDM}),
|
sliceTopLayers: UC.newInput(LANG.sl_ltop_s, {title:LANG.sl_ltop_l, convert:UC.toInt, modes:FDM}),
|
||||||
sliceSolidLayers: UC.newInput(LANG.sl_lsld_s, {title:LANG.sl_lsld_l, convert:UC.toInt, modes:FDM}),
|
sliceSolidLayers: UC.newInput(LANG.sl_lsld_s, {title:LANG.sl_lsld_l, convert:UC.toInt, modes:FDM}),
|
||||||
sliceBottomLayers: UC.newInput(LANG.sl_lbot_s, {title:LANG.sl_lbot_l, convert:UC.toInt, modes:FDM}),
|
sliceBottomLayers: UC.newInput(LANG.sl_lbot_s, {title:LANG.sl_lbot_l, convert:UC.toInt, modes:FDM}),
|
||||||
|
|
@ -1621,15 +1643,20 @@
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
||||||
firstLayerNozzleTemp:UC.newInput(LANG.fl_nozl_s, {title:LANG.fl_nozl_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
firstLayerNozzleTemp:UC.newInput(LANG.fl_nozl_s, {title:LANG.fl_nozl_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
||||||
firstLayerBedTemp: UC.newInput(LANG.fl_bedd_s, {title:LANG.fl_bedd_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
firstLayerBedTemp: UC.newInput(LANG.fl_bedd_s, {title:LANG.fl_bedd_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
||||||
|
firstLayerFanSpeed: UC.newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:UC.toInt, bound:UC.bound(0,255), modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
||||||
firstLayerYOffset: UC.newInput(LANG.fl_zoff_s, {title:LANG.fl_zoff_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
firstLayerYOffset: UC.newInput(LANG.fl_zoff_s, {title:LANG.fl_zoff_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
||||||
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isBelt}),
|
||||||
firstLayerRate: UC.newInput(LANG.fl_rate_s, {title:LANG.fl_rate_l, convert:UC.toFloat, modes:FDM}),
|
firstLayerRate: UC.newInput(LANG.fl_rate_s, {title:LANG.fl_rate_l, convert:UC.toFloat, modes:FDM}),
|
||||||
firstLayerFillRate: UC.newInput(LANG.fl_frat_s, {title:LANG.fl_frat_l, convert:UC.toFloat, modes:FDM, show:isNotBelt}),
|
firstLayerFillRate: UC.newInput(LANG.fl_frat_s, {title:LANG.fl_frat_l, convert:UC.toFloat, modes:FDM, show:isNotBelt}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
||||||
firstLayerLineMult: UC.newInput(LANG.fl_sfac_s, {title:LANG.fl_sfac_l, convert:UC.toFloat, bound:UC.bound(0.5,2), modes:FDM, show:isNotBelt}),
|
firstLayerLineMult: UC.newInput(LANG.fl_sfac_s, {title:LANG.fl_sfac_l, convert:UC.toFloat, bound:UC.bound(0.5,2), modes:FDM, show:isNotBelt}),
|
||||||
firstLayerPrintMult: UC.newInput(LANG.fl_mult_s, {title:LANG.fl_mult_l, convert:UC.toFloat, modes:FDM}),
|
firstLayerPrintMult: UC.newInput(LANG.fl_mult_s, {title:LANG.fl_mult_l, convert:UC.toFloat, modes:FDM}),
|
||||||
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isBelt}),
|
||||||
firstLayerBrim: UC.newInput(LANG.fl_brim_s, {title:LANG.fl_brim_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
firstLayerBrim: UC.newInput(LANG.fl_brim_s, {title:LANG.fl_brim_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
||||||
firstLayerBrimTrig: UC.newInput(LANG.fl_brmn_s, {title:LANG.fl_brmn_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
firstLayerBrimTrig: UC.newInput(LANG.fl_brmn_s, {title:LANG.fl_brmn_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
||||||
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isBelt}),
|
||||||
|
firstLayerBeltLead: UC.newInput(LANG.fl_bled_s, {title:LANG.fl_bled_l, convert:UC.toFloat, modes:FDM, show:isBelt}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
||||||
outputBrimCount: UC.newInput(LANG.fl_skrt_s, {title:LANG.fl_skrt_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
outputBrimCount: UC.newInput(LANG.fl_skrt_s, {title:LANG.fl_skrt_l, convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
||||||
outputBrimOffset: UC.newInput(LANG.fl_skro_s, {title:LANG.fl_skro_l, convert:UC.toFloat, modes:FDM, show:isNotBelt}),
|
outputBrimOffset: UC.newInput(LANG.fl_skro_s, {title:LANG.fl_skro_l, convert:UC.toFloat, modes:FDM, show:isNotBelt}),
|
||||||
|
|
@ -1639,29 +1666,32 @@
|
||||||
|
|
||||||
fdmInfill: UC.newGroup(LANG.fi_menu, $('settings'), {modes:FDM}),
|
fdmInfill: UC.newGroup(LANG.fi_menu, $('settings'), {modes:FDM}),
|
||||||
sliceFillType: UC.newSelect(LANG.fi_type, {modes:FDM}, "infill"),
|
sliceFillType: UC.newSelect(LANG.fi_type, {modes:FDM}, "infill"),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
|
||||||
sliceFillSparse: UC.newInput(LANG.fi_pcnt_s, {title:LANG.fi_pcnt_l, convert:UC.toFloat, bound:UC.bound(0.0,1.0), modes:FDM}),
|
sliceFillSparse: UC.newInput(LANG.fi_pcnt_s, {title:LANG.fi_pcnt_l, convert:UC.toFloat, bound:UC.bound(0.0,1.0), modes:FDM}),
|
||||||
sliceFillAngle: UC.newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:UC.toFloat, modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
sliceFillOverlap: UC.newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
sliceFillOverlap: UC.newInput(LANG.fi_over_s, {title:LANG.fi_over_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
||||||
|
sliceFillRate: UC.newInput(LANG.ou_feed_s, {title:LANG.fi_rate_l, convert:UC.toInt, bound:UC.bound(0,300), modes:FDM}),
|
||||||
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
|
sliceFillAngle: UC.newInput(LANG.fi_angl_s, {title:LANG.fi_angl_l, convert:UC.toFloat, modes:FDM}),
|
||||||
|
// sliceFillWidth: UC.newInput(LANG.fi_wdth_s, {title:LANG.fi_wdth_l, convert:UC.toFloat, modes:FDM}),
|
||||||
|
|
||||||
fdmSupport: UC.newGroup(LANG.sp_menu, null, {modes:FDM, marker:false}),
|
fdmSupport: UC.newGroup(LANG.sp_menu, null, {modes:FDM, marker:false}),
|
||||||
sliceSupportNozzle: UC.newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, modes:FDM}, "extruders"),
|
sliceSupportNozzle: UC.newSelect(LANG.sp_nozl_s, {title:LANG.sp_nozl_l, modes:FDM}, "extruders"),
|
||||||
sliceSupportDensity: UC.newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:UC.toFloat, bound:UC.bound(0.05,1.0), modes:FDM}),
|
sliceSupportDensity: UC.newInput(LANG.sp_dens_s, {title:LANG.sp_dens_l, convert:UC.toFloat, bound:UC.bound(0.0,1.0), modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
sliceSupportSize: UC.newInput(LANG.sp_size_s, {title:LANG.sp_size_l, bound:UC.bound(1.0,200.0), convert:UC.toFloat, modes:FDM}),
|
sliceSupportSize: UC.newInput(LANG.sp_size_s, {title:LANG.sp_size_l, bound:UC.bound(1.0,200.0), convert:UC.toFloat, modes:FDM}),
|
||||||
sliceSupportOffset: UC.newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
sliceSupportOffset: UC.newInput(LANG.sp_offs_s, {title:LANG.sp_offs_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
||||||
sliceSupportGap: UC.newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, bound:UC.bound(0,5), convert:UC.toInt, modes:FDM}),
|
sliceSupportGap: UC.newInput(LANG.sp_gaps_s, {title:LANG.sp_gaps_l, bound:UC.bound(0,5), convert:UC.toInt, modes:FDM, show:isNotBelt}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
sliceSupportArea: UC.newInput(LANG.sp_area_s, {title:LANG.sp_area_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
sliceSupportArea: UC.newInput(LANG.sp_area_s, {title:LANG.sp_area_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
||||||
sliceSupportExtra: UC.newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
sliceSupportExtra: UC.newInput(LANG.sp_xpnd_s, {title:LANG.sp_xpnd_l, bound:UC.bound(0.0,200.0), convert:UC.toFloat, modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
sliceSupportAngle: UC.newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, bound:UC.bound(0.0,90.0), convert:UC.toFloat, modes:FDM}),
|
sliceSupportAngle: UC.newInput(LANG.sp_angl_s, {title:LANG.sp_angl_l, bound:UC.bound(0.0,90.0), convert:UC.toFloat, modes:FDM, xshow:isNotBelt}),
|
||||||
sliceSupportEnable: UC.newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, modes:FDM, show:isNotBelt}),
|
sliceSupportEnable: UC.newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, modes:FDM, show:isNotBelt}),
|
||||||
|
|
||||||
sliceSupportGen: UC.newRow([
|
sliceSupportGen: UC.newRow([
|
||||||
UI.ssaGen = UC.newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})
|
UI.ssaGen = UC.newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})
|
||||||
], { modes: FDM, class: "ext-buttons f-row grow" }),
|
], { modes: FDM, class: "ext-buttons f-row grow" }),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM, show:isNotBelt}),
|
||||||
sliceSupportManual: UC.newRow([
|
sliceSupportManual: UC.newRow([
|
||||||
(UI.ssmAdd = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
(UI.ssmAdd = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-plus"></i>'})),
|
||||||
(UI.ssmDun = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
(UI.ssmDun = UC.newButton(undefined, onButtonClick, {icon:'<i class="fas fa-check"></i>'})),
|
||||||
|
|
@ -1720,6 +1750,7 @@
|
||||||
|
|
||||||
outputTemp: UC.newInput(LANG.ou_nozl_s, {title:LANG.ou_nozl_l, convert:UC.toInt, modes:FDM}),
|
outputTemp: UC.newInput(LANG.ou_nozl_s, {title:LANG.ou_nozl_l, convert:UC.toInt, modes:FDM}),
|
||||||
outputBedTemp: UC.newInput(LANG.ou_bedd_s, {title:LANG.ou_bedd_l, convert:UC.toInt, modes:FDM}),
|
outputBedTemp: UC.newInput(LANG.ou_bedd_s, {title:LANG.ou_bedd_l, convert:UC.toInt, modes:FDM}),
|
||||||
|
outputFanSpeed: UC.newInput(LANG.ou_fans_s, {title:LANG.ou_fans_l, convert:UC.toInt, bound:UC.bound(0,255), modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
outputFeedrate: UC.newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:UC.toInt, modes:FDM}),
|
outputFeedrate: UC.newInput(LANG.ou_feed_s, {title:LANG.ou_feed_l, convert:UC.toInt, modes:FDM}),
|
||||||
outputFinishrate: UC.newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:UC.toInt, modes:FDM}),
|
outputFinishrate: UC.newInput(LANG.ou_fini_s, {title:LANG.ou_fini_l, convert:UC.toInt, modes:FDM}),
|
||||||
|
|
@ -1729,7 +1760,6 @@
|
||||||
outputFillMult: UC.newInput(LANG.ou_flml_s, {title:LANG.ou_exml_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
outputFillMult: UC.newInput(LANG.ou_flml_s, {title:LANG.ou_exml_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
||||||
outputSparseMult: UC.newInput(LANG.ou_spml_s, {title:LANG.ou_exml_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
outputSparseMult: UC.newInput(LANG.ou_spml_s, {title:LANG.ou_exml_l, convert:UC.toFloat, bound:UC.bound(0.0,2.0), modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
outputFanLayer: UC.newInput(LANG.ou_fanl_s, {title:LANG.ou_fanl_l, convert:UC.toInt, bound:UC.bound(0,100), modes:FDM}),
|
|
||||||
sliceShellOrder: UC.newSelect(LANG.sl_ordr_s, {title:LANG.sl_ordr_l, modes:FDM}, "shell"),
|
sliceShellOrder: UC.newSelect(LANG.sl_ordr_s, {title:LANG.sl_ordr_l, modes:FDM}, "shell"),
|
||||||
sliceLayerStart: UC.newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l, modes:FDM}, "start"),
|
sliceLayerStart: UC.newSelect(LANG.sl_strt_s, {title:LANG.sl_strt_l, modes:FDM}, "start"),
|
||||||
camConventional: UC.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}),
|
camConventional: UC.newBoolean(LANG.ou_conv_s, onBooleanClick, {title:LANG.ou_conv_l, modes:CAM}),
|
||||||
|
|
@ -1745,18 +1775,20 @@
|
||||||
advanced: UC.newGroup(LANG.ad_menu, null, {modes:FDM}),
|
advanced: UC.newGroup(LANG.ad_menu, null, {modes:FDM}),
|
||||||
outputRetractDist: UC.newInput(LANG.ad_rdst_s, {title:LANG.ad_rdst_l, convert:UC.toFloat, modes:FDM}),
|
outputRetractDist: UC.newInput(LANG.ad_rdst_s, {title:LANG.ad_rdst_l, convert:UC.toFloat, modes:FDM}),
|
||||||
outputRetractSpeed: UC.newInput(LANG.ad_rrat_s, {title:LANG.ad_rrat_l, convert:UC.toInt, modes:FDM}),
|
outputRetractSpeed: UC.newInput(LANG.ad_rrat_s, {title:LANG.ad_rrat_l, convert:UC.toInt, modes:FDM}),
|
||||||
|
outputRetractWipe: UC.newInput(LANG.ad_wpln_s, {title:LANG.ad_wpln_l, bound:UC.bound(0.0,10), convert:UC.toFloat, modes:FDM}),
|
||||||
outputRetractDwell: UC.newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:UC.toInt, modes:FDM}),
|
outputRetractDwell: UC.newInput(LANG.ad_rdwl_s, {title:LANG.ad_rdwl_l, convert:UC.toInt, modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
// outputWipeDistance: UC.newInput("wipe", {title:"non-printing move at\close of polygon\nin millimeters", bound:UC.bound(0.0,10), convert:UC.toFloat, modes:FDM}),
|
|
||||||
sliceSolidMinArea: UC.newInput(LANG.ad_msol_s, {title:LANG.ad_msol_l, convert:UC.toFloat, modes:FDM}),
|
sliceSolidMinArea: UC.newInput(LANG.ad_msol_s, {title:LANG.ad_msol_l, convert:UC.toFloat, modes:FDM}),
|
||||||
outputMinSpeed: UC.newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, bound:UC.bound(5,200), convert:UC.toFloat, modes:FDM}),
|
outputMinSpeed: UC.newInput(LANG.ad_mins_s, {title:LANG.ad_mins_l, bound:UC.bound(5,200), convert:UC.toFloat, modes:FDM}),
|
||||||
outputCoastDist: UC.newInput(LANG.ad_scst_s, {title:LANG.ad_scst_l, bound:UC.bound(0.0,10), convert:UC.toFloat, modes:FDM}),
|
|
||||||
outputShortPoly: UC.newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, bound:UC.bound(0,10000), convert:UC.toFloat, modes:FDM}),
|
outputShortPoly: UC.newInput(LANG.ad_spol_s, {title:LANG.ad_spol_l, bound:UC.bound(0,10000), convert:UC.toFloat, modes:FDM}),
|
||||||
|
outputCoastDist: UC.newInput(LANG.ad_scst_s, {title:LANG.ad_scst_l, bound:UC.bound(0.0,10), convert:UC.toFloat, modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
zHopDistance: UC.newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM}),
|
zHopDistance: UC.newInput(LANG.ad_zhop_s, {title:LANG.ad_zhop_l, bound:UC.bound(0,3.0), convert:UC.toFloat, modes:FDM}),
|
||||||
|
arcTolerance: UC.newInput(LANG.ad_arct_s, {title:LANG.ad_arct_l, bound:UC.bound(0,1.0), convert:UC.toFloat, modes:FDM, show:() => { return isDanger() && isNotBelt() }}),
|
||||||
antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM}),
|
antiBacklash: UC.newInput(LANG.ad_abkl_s, {title:LANG.ad_abkl_l, bound:UC.bound(0,3), convert:UC.toInt, modes:FDM}),
|
||||||
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
fdmSep: UC.newBlank({class:"pop-sep", modes:FDM}),
|
||||||
gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, comma:true}),
|
outputPeelGuard: UC.newInput(LANG.ag_peel_s, {title:LANG.ag_peel_l, convert:UC.toInt, modes:FDM, comma:true, show:isBelt}),
|
||||||
|
gcodePauseLayers: UC.newInput(LANG.ag_paws_s, {title:LANG.ag_paws_l, modes:FDM, comma:true, show:isNotBelt}),
|
||||||
outputLoopLayers: UC.newInput(LANG.ag_loop_s, {title:LANG.ag_loop_l, modes:FDM, comma:true, show:isBelt}),
|
outputLoopLayers: UC.newInput(LANG.ag_loop_s, {title:LANG.ag_loop_l, modes:FDM, comma:true, show:isBelt}),
|
||||||
outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM}),
|
outputLayerRetract: UC.newBoolean(LANG.ad_lret_s, onBooleanClick, {title:LANG.ad_lret_l, modes:FDM}),
|
||||||
|
|
||||||
|
|
@ -1798,6 +1830,9 @@
|
||||||
slaFirstOffset: UC.newInput(LANG.sa_opzo_s, {title:LANG.sa_opzo_l, convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}),
|
slaFirstOffset: UC.newInput(LANG.sa_opzo_s, {title:LANG.sa_opzo_l, convert:UC.toFloat, bound:UC.bound(0,1), modes:SLA}),
|
||||||
slaAntiAlias: UC.newSelect(LANG.sa_opaa_s, {title:LANG.sa_opaa_l, modes:SLA}, "antialias"),
|
slaAntiAlias: UC.newSelect(LANG.sa_opaa_s, {title:LANG.sa_opaa_l, modes:SLA}, "antialias"),
|
||||||
|
|
||||||
|
rangeGroup: UC.newGroup("ranges", null, {modes:FDM, group:"ranges"}),
|
||||||
|
rangeList: UC.newRow([], {}),
|
||||||
|
|
||||||
settingsGroup: UC.newGroup(LANG.se_menu, $('settings')),
|
settingsGroup: UC.newGroup(LANG.se_menu, $('settings')),
|
||||||
settingsTable: UC.newRow([ UI.settingsLoad = UC.newButton(LANG.se_load, settingsLoad) ]),
|
settingsTable: UC.newRow([ UI.settingsLoad = UC.newButton(LANG.se_load, settingsLoad) ]),
|
||||||
settingsTable: UC.newRow([ UI.settingsSave = UC.newButton(LANG.se_save, settingsSave) ]),
|
settingsTable: UC.newRow([ UI.settingsSave = UC.newButton(LANG.se_save, settingsSave) ]),
|
||||||
|
|
@ -1955,6 +1990,19 @@
|
||||||
UI.sliderHold.style.marginRight = `${hival}px`;
|
UI.sliderHold.style.marginRight = `${hival}px`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// store layer preferences
|
||||||
|
API.event.on('stack.show', label => {
|
||||||
|
let mode = API.mode.get();
|
||||||
|
let view = API.view.get();
|
||||||
|
API.conf.get().labels[`${mode}-${view}-${label}`] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
API.event.on('stack.hide', label => {
|
||||||
|
let mode = API.mode.get();
|
||||||
|
let view = API.view.get();
|
||||||
|
API.conf.get().labels[`${mode}-${view}-${label}`] = false;
|
||||||
|
});
|
||||||
|
|
||||||
// bind language choices
|
// bind language choices
|
||||||
$('lset-en').onclick = function() {
|
$('lset-en').onclick = function() {
|
||||||
SDB.setItem('kiri-lang', 'en-us');
|
SDB.setItem('kiri-lang', 'en-us');
|
||||||
|
|
@ -1964,6 +2012,18 @@
|
||||||
SDB.setItem('kiri-lang', 'da-dk');
|
SDB.setItem('kiri-lang', 'da-dk');
|
||||||
API.space.reload();
|
API.space.reload();
|
||||||
};
|
};
|
||||||
|
$('lset-de').onclick = function() {
|
||||||
|
SDB.setItem('kiri-lang', 'de-de');
|
||||||
|
API.space.reload();
|
||||||
|
};
|
||||||
|
$('lset-fr').onclick = function() {
|
||||||
|
SDB.setItem('kiri-lang', 'fr-fr');
|
||||||
|
API.space.reload();
|
||||||
|
};
|
||||||
|
$('lset-pl').onclick = function() {
|
||||||
|
SDB.setItem('kiri-lang', 'pl-pl');
|
||||||
|
API.space.reload();
|
||||||
|
};
|
||||||
|
|
||||||
SPACE.addEventHandlers(self, [
|
SPACE.addEventHandlers(self, [
|
||||||
'keyup', keyUpHandler,
|
'keyup', keyUpHandler,
|
||||||
|
|
@ -1981,9 +2041,17 @@
|
||||||
xv = parseFloat(UI.sizeX.was),
|
xv = parseFloat(UI.sizeX.was),
|
||||||
yv = parseFloat(UI.sizeY.was),
|
yv = parseFloat(UI.sizeY.was),
|
||||||
zv = parseFloat(UI.sizeZ.was),
|
zv = parseFloat(UI.sizeZ.was),
|
||||||
xr = (UI.lockX.checked ? ra : 1),
|
ta = e.target,
|
||||||
yr = (UI.lockY.checked ? ra : 1),
|
xc = UI.lockX.checked,
|
||||||
zr = (UI.lockZ.checked ? ra : 1);
|
yc = UI.lockY.checked,
|
||||||
|
zc = UI.lockZ.checked,
|
||||||
|
xt = ta === UI.sizeX,
|
||||||
|
yt = ta === UI.sizeY,
|
||||||
|
zt = ta === UI.sizeZ,
|
||||||
|
tl = (xt && xc) || (yt && yc) || (zt && zc),
|
||||||
|
xr = ((tl && xc) || (!tl && xt) ? ra : 1),
|
||||||
|
yr = ((tl && yc) || (!tl && yt) ? ra : 1),
|
||||||
|
zr = ((tl && zc) || (!tl && zt) ? ra : 1);
|
||||||
API.selection.scale(xr,yr,zr);
|
API.selection.scale(xr,yr,zr);
|
||||||
UI.sizeX.was = UI.sizeX.value = xv * xr;
|
UI.sizeX.was = UI.sizeX.value = xv * xr;
|
||||||
UI.sizeY.was = UI.sizeY.value = yv * yr;
|
UI.sizeY.was = UI.sizeY.value = yv * yr;
|
||||||
|
|
@ -1997,9 +2065,17 @@
|
||||||
xv = parseFloat(UI.scaleX.was),
|
xv = parseFloat(UI.scaleX.was),
|
||||||
yv = parseFloat(UI.scaleY.was),
|
yv = parseFloat(UI.scaleY.was),
|
||||||
zv = parseFloat(UI.scaleZ.was),
|
zv = parseFloat(UI.scaleZ.was),
|
||||||
xr = (UI.lockX.checked ? ra : 1),
|
ta = e.target,
|
||||||
yr = (UI.lockY.checked ? ra : 1),
|
xc = UI.lockX.checked,
|
||||||
zr = (UI.lockZ.checked ? ra : 1);
|
yc = UI.lockY.checked,
|
||||||
|
zc = UI.lockZ.checked,
|
||||||
|
xt = ta === UI.scaleX,
|
||||||
|
yt = ta === UI.scaleY,
|
||||||
|
zt = ta === UI.scaleZ,
|
||||||
|
tl = (xt && xc) || (yt && yc) || (zt && zc),
|
||||||
|
xr = ((tl && xc) || (!tl && xt) ? ra : 1),
|
||||||
|
yr = ((tl && yc) || (!tl && yt) ? ra : 1),
|
||||||
|
zr = ((tl && zc) || (!tl && zt) ? ra : 1);
|
||||||
API.selection.scale(xr,yr,zr);
|
API.selection.scale(xr,yr,zr);
|
||||||
UI.scaleX.was = UI.scaleX.value = xv * xr;
|
UI.scaleX.was = UI.scaleX.value = xv * xr;
|
||||||
UI.scaleY.was = UI.scaleY.value = yv * yr;
|
UI.scaleY.was = UI.scaleY.value = yv * yr;
|
||||||
|
|
@ -2035,6 +2111,35 @@
|
||||||
$('rot_z'), selectionRotate
|
$('rot_z'), selectionRotate
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$('lab-axis').onclick = () => {
|
||||||
|
UI.lockX.checked =
|
||||||
|
UI.lockY.checked =
|
||||||
|
UI.lockZ.checked = !(
|
||||||
|
UI.lockX.checked ||
|
||||||
|
UI.lockY.checked ||
|
||||||
|
UI.lockZ.checked
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$('lab-scale').onclick = () => {
|
||||||
|
API.selection.scale(1 / UI.scaleX.was, 1 / UI.scaleY.was, 1 / UI.scaleZ.was);
|
||||||
|
UI.scaleX.value = UI.scaleY.value = UI.scaleZ.value =
|
||||||
|
UI.scaleX.was = UI.scaleY.was = UI.scaleZ.was = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
let hpops = [];
|
||||||
|
UC.hoverPop(UI.ltsetup, { group: hpops, target: $('set-pop') });
|
||||||
|
UC.hoverPop(UI.ltfile, { group: hpops, target: $('file-pop') });
|
||||||
|
UC.hoverPop(UI.ltview, { group: hpops, target: $('pop-view') });
|
||||||
|
UC.hoverPop(UI.ltact, { group: hpops, target: $('pop-slice') });
|
||||||
|
UC.hoverPop(UI.render, { group: hpops, target: $('pop-render'), sticky: true });
|
||||||
|
UC.hoverPop(UI.rotate, { group: hpops, target: $('pop-rotate'), sticky: true });
|
||||||
|
UC.hoverPop(UI.scale, { group: hpops, target: $('pop-scale'), sticky: true });
|
||||||
|
UC.hoverPop(UI.nozzle, { group: hpops, target: $('pop-nozzle'), sticky: true });
|
||||||
|
UC.hoverPop($('app-acct'), { group: hpops, target: $('acct-pop') } );
|
||||||
|
UC.hoverPop($('app-mode'), { group: hpops, target: $('mode-info') } );
|
||||||
|
UC.hoverPop($('app-name'), { group: hpops, target: $('app-info') } );
|
||||||
|
|
||||||
UC.onBlur([
|
UC.onBlur([
|
||||||
UI.toolName,
|
UI.toolName,
|
||||||
UI.toolNum,
|
UI.toolNum,
|
||||||
|
|
@ -2080,8 +2185,21 @@
|
||||||
if (int) API.event.emit('mouse.hover', {point: int, event, type: 'platform'});
|
if (int) API.event.emit('mouse.hover', {point: int, event, type: 'platform'});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// block standard browser context menu
|
||||||
|
DOC.oncontextmenu = (event) => {
|
||||||
|
if (event.target.tagName === 'CANVAS') {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
SPACE.mouse.up((event, int) => {
|
SPACE.mouse.up((event, int) => {
|
||||||
if (event.button === 2 && API.view.isArrange()) {
|
if (event.button === 2) {
|
||||||
|
let full = API.view.isArrange();
|
||||||
|
for (let key of ["layflat","mirror","duplicate"]) {
|
||||||
|
$(`context-${key}`).disabled = !full;
|
||||||
|
}
|
||||||
let style = UI.context.style;
|
let style = UI.context.style;
|
||||||
style.display = 'flex';
|
style.display = 'flex';
|
||||||
style.left = `${event.clientX-3}px`;
|
style.left = `${event.clientX-3}px`;
|
||||||
|
|
@ -2089,6 +2207,9 @@
|
||||||
UI.context.onmouseleave = () => {
|
UI.context.onmouseleave = () => {
|
||||||
style.display = '';
|
style.display = '';
|
||||||
};
|
};
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
contextInt = int;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2114,6 +2235,10 @@
|
||||||
// return selected meshes for further mouse processing
|
// return selected meshes for further mouse processing
|
||||||
return API.feature.hovers || API.selection.meshes();
|
return API.feature.hovers || API.selection.meshes();
|
||||||
}
|
}
|
||||||
|
if (event.button === 2 && API.view.isArrange()) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
SPACE.mouse.upSelect(function(object, event) {
|
SPACE.mouse.upSelect(function(object, event) {
|
||||||
|
|
@ -2172,6 +2297,8 @@
|
||||||
function init_two() {
|
function init_two() {
|
||||||
API.event.emit('init.two');
|
API.event.emit('init.two');
|
||||||
|
|
||||||
|
// API.space.set_focus();
|
||||||
|
|
||||||
// call driver initializations, if present
|
// call driver initializations, if present
|
||||||
Object.values(KIRI.driver).forEach(driver => {
|
Object.values(KIRI.driver).forEach(driver => {
|
||||||
if (driver.init) try {
|
if (driver.init) try {
|
||||||
|
|
@ -2238,6 +2365,8 @@
|
||||||
UI.reverseZoom.checked = control.reverseZoom;
|
UI.reverseZoom.checked = control.reverseZoom;
|
||||||
UI.autoSave.checked = control.autoSave;
|
UI.autoSave.checked = control.autoSave;
|
||||||
UI.decimate.checked = control.decimate;
|
UI.decimate.checked = control.decimate;
|
||||||
|
UI.healMesh.checked = control.healMesh;
|
||||||
|
UI.ortho.checked = control.ortho;
|
||||||
lineTypeSave();
|
lineTypeSave();
|
||||||
detailSave();
|
detailSave();
|
||||||
updateFPS();
|
updateFPS();
|
||||||
|
|
@ -2272,9 +2401,6 @@
|
||||||
|
|
||||||
UI.sync();
|
UI.sync();
|
||||||
|
|
||||||
// load settings provided in url hash
|
|
||||||
loadSettingsFromServer();
|
|
||||||
|
|
||||||
// clear alerts as they build up
|
// clear alerts as they build up
|
||||||
setInterval(API.event.alerts, 1000);
|
setInterval(API.event.alerts, 1000);
|
||||||
|
|
||||||
|
|
@ -2292,7 +2418,7 @@
|
||||||
API.event.emit('init-done', STATS);
|
API.event.emit('init-done', STATS);
|
||||||
|
|
||||||
// show gdpr if it's never been seen and we're not iframed
|
// show gdpr if it's never been seen and we're not iframed
|
||||||
if (!SDB.gdpr && WIN.self === WIN.top) {
|
if (!SDB.gdpr && WIN.self === WIN.top && !SETUP.debug) {
|
||||||
$('gdpr').style.display = 'flex';
|
$('gdpr').style.display = 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2359,7 +2485,14 @@
|
||||||
// context menu
|
// context menu
|
||||||
$('context-export-stl').onclick = () => { objectsExport() };
|
$('context-export-stl').onclick = () => { objectsExport() };
|
||||||
$('context-export-workspace').onclick = () => { profileExport(true) };
|
$('context-export-workspace').onclick = () => { profileExport(true) };
|
||||||
$('context-clear-workspace').onclick = () => { API.platform.clear(); UI.context.onmouseleave() };
|
$('context-clear-workspace').onclick = () => {
|
||||||
|
API.view.set(VIEWS.ARRANGE);
|
||||||
|
API.platform.clear();
|
||||||
|
UI.context.onmouseleave();
|
||||||
|
};
|
||||||
|
$('context-duplicate').onclick = duplicateSelection;
|
||||||
|
$('context-mirror').onclick = mirrorSelection;
|
||||||
|
$('context-layflat').onclick = layFlat;
|
||||||
|
|
||||||
UI.modal.onclick = API.modal.hide;
|
UI.modal.onclick = API.modal.hide;
|
||||||
UI.modalBox.onclick = (ev) => { ev.stopPropagation() };
|
UI.modalBox.onclick = (ev) => { ev.stopPropagation() };
|
||||||
|
|
@ -2376,21 +2509,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update static html elements with language overrides
|
||||||
|
UI.lang = function() {
|
||||||
|
for (let el of [...DOC.querySelectorAll("[lk]")]) {
|
||||||
|
let key = el.getAttribute('lk');
|
||||||
|
let val = LANG[key];
|
||||||
|
if (val) {
|
||||||
|
el.innerText = val;
|
||||||
|
} else {
|
||||||
|
console.log({missing_ln: key});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// if a language needs to load, the script is injected and loaded
|
// if a language needs to load, the script is injected and loaded
|
||||||
// first. once this loads, or doesn't, the initialization begins
|
// first. once this loads, or doesn't, the initialization begins
|
||||||
|
let lang_load = false;
|
||||||
let lang_set = undefined;
|
let lang_set = undefined;
|
||||||
let lang = SETUP.ln ? SETUP.ln[0] : SDB.getItem('kiri-lang') || KIRI.lang.get();
|
let lang = SETUP.ln ? SETUP.ln[0] : SDB.getItem('kiri-lang') || KIRI.lang.get();
|
||||||
|
|
||||||
// inject language script if not english
|
// inject language script if not english
|
||||||
if (lang && lang !== 'en' && lang !== 'en-us') {
|
if (lang && lang !== 'en' && lang !== 'en-us') {
|
||||||
lang_set = lang;
|
lang_set = lang;
|
||||||
|
let map = KIRI.lang.map(lang);
|
||||||
let scr = DOC.createElement('script');
|
let scr = DOC.createElement('script');
|
||||||
// scr.setAttribute('defer',true);
|
// scr.setAttribute('defer',true);
|
||||||
scr.setAttribute('src',`/kiri/lang/${lang}.js`);
|
scr.setAttribute('src',`/kiri/lang/${map}.js?${KIRI.version}`);
|
||||||
(DOC.body || DOC.head).appendChild(scr);
|
(DOC.body || DOC.head).appendChild(scr);
|
||||||
STATS.set('ll',lang);
|
STATS.set('ll',lang);
|
||||||
scr.onload = function() {
|
scr.onload = function() {
|
||||||
KIRI.lang.set(lang);
|
lang_load = true;
|
||||||
|
KIRI.lang.set(map);
|
||||||
|
UI.lang();
|
||||||
init_one();
|
init_one();
|
||||||
};
|
};
|
||||||
scr.onerror = function(err) {
|
scr.onerror = function(err) {
|
||||||
|
|
@ -2401,7 +2551,10 @@
|
||||||
|
|
||||||
// set to browser default which will be overridden
|
// set to browser default which will be overridden
|
||||||
// by any future script loads (above)
|
// by any future script loads (above)
|
||||||
KIRI.lang.set();
|
if (!lang_load) {
|
||||||
|
KIRI.lang.set();
|
||||||
|
UI.lang();
|
||||||
|
}
|
||||||
|
|
||||||
// schedule init_one to run after all page content is loaded
|
// schedule init_one to run after all page content is loaded
|
||||||
// unless a languge script is loading first, in which case it
|
// unless a languge script is loading first, in which case it
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,25 @@
|
||||||
if (self.kiri.lang) return;
|
if (self.kiri.lang) return;
|
||||||
|
|
||||||
const KIRI = self.kiri, LANG = self.kiri.lang = { current: {} };
|
const KIRI = self.kiri, LANG = self.kiri.lang = { current: {} };
|
||||||
|
const KDFL = 'en-us';
|
||||||
|
|
||||||
let lset = navigator.language.toLocaleLowerCase();
|
let lset = navigator.language.toLocaleLowerCase();
|
||||||
|
|
||||||
|
LANG.map = function(key) {
|
||||||
|
if (!key) {
|
||||||
|
return KDFL;
|
||||||
|
}
|
||||||
|
let tok = key.split('-');
|
||||||
|
switch (tok[0]) {
|
||||||
|
case 'da': return 'da-dk';
|
||||||
|
case 'de': return 'de-de';
|
||||||
|
case 'en': return 'en-us';
|
||||||
|
case 'fr': return 'fr-fr';
|
||||||
|
case 'pl': return 'pl-pl';
|
||||||
|
}
|
||||||
|
return KDFL;
|
||||||
|
};
|
||||||
|
|
||||||
LANG.get = function() {
|
LANG.get = function() {
|
||||||
return lset;
|
return lset;
|
||||||
};
|
};
|
||||||
|
|
@ -39,7 +55,12 @@
|
||||||
// update current map from chosen map
|
// update current map from chosen map
|
||||||
Object.keys(map).forEach(key => {
|
Object.keys(map).forEach(key => {
|
||||||
if (LANG.en[key]) {
|
if (LANG.en[key]) {
|
||||||
LANG.current[key] = map[key];
|
let val = map[key];
|
||||||
|
// turn arrays into newline separated strings
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
val = val.join('\n');
|
||||||
|
}
|
||||||
|
LANG.current[key] = val;
|
||||||
} else {
|
} else {
|
||||||
invalid.push(key);
|
invalid.push(key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
734
src/kiri/main.js
734
src/kiri/main.js
File diff suppressed because it is too large
Load diff
|
|
@ -133,33 +133,102 @@
|
||||||
maxf = 0,
|
maxf = 0,
|
||||||
seq = [],
|
seq = [],
|
||||||
autolayer = true,
|
autolayer = true,
|
||||||
newlayer = false;
|
newlayer = false,
|
||||||
|
arcdivs = Math.PI / 12,
|
||||||
|
hasmoved = false;
|
||||||
|
|
||||||
const output = scope.output = [ seq ];
|
const output = scope.output = [ seq ];
|
||||||
const beltaxis = { X: "X", Y: "Z", Z: "Y", E: "E", F: "F" };
|
const beltaxis = { X: "X", Y: "Z", Z: "Y", E: "E", F: "F" };
|
||||||
const beltfact = Math.cos(Math.PI/4);
|
const beltfact = Math.cos(Math.PI/4);
|
||||||
|
|
||||||
|
function LOG() {
|
||||||
|
console.log(...[...arguments].map(o => Object.clone(o)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function G2G3(g2, line) {
|
||||||
|
const rec = {};
|
||||||
|
|
||||||
|
line.forEach(function(tok) {
|
||||||
|
rec[tok.charAt(0)] = parseFloat(tok.substring(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
let center = { x:0, y:0, r:0 };
|
||||||
|
|
||||||
|
if (rec.I !== undefined && rec.J !== undefined) {
|
||||||
|
center.x = pos.X + rec.I;
|
||||||
|
center.y = pos.Y + rec.J;
|
||||||
|
//center.r = TODO
|
||||||
|
console.log("G[2,3] IJ not supported");
|
||||||
|
} else if (rec.R !== undefined) {
|
||||||
|
let pd = { x: rec.X - pos.X, y: rec.Y - pos.Y };
|
||||||
|
let dst = Math.sqrt(pd.x * pd.x + pd.y * pd.y) / 2;
|
||||||
|
let pr2;
|
||||||
|
if (Math.abs(dst - rec.R) < 0.001) {
|
||||||
|
// center point radius
|
||||||
|
pr2 = { x: (rec.X + pos.X) / 2, y: (rec.Y + pos.Y) / 2};
|
||||||
|
} else {
|
||||||
|
// triangulate
|
||||||
|
pr2 = BASE.util.center2pr({
|
||||||
|
x: pos.X,
|
||||||
|
y: pos.Y
|
||||||
|
}, {
|
||||||
|
x: rec.X,
|
||||||
|
y: rec.Y
|
||||||
|
}, rec.R)[g2 ? 1 : 0];
|
||||||
|
}
|
||||||
|
center.x = pr2.x;
|
||||||
|
center.y = pr2.y;
|
||||||
|
center.r = rec.R;
|
||||||
|
} else {
|
||||||
|
console.log({malfomed_arc: line});
|
||||||
|
}
|
||||||
|
|
||||||
|
// line angles
|
||||||
|
let a1 = Math.atan2(center.y - pos.Y, center.x - pos.X) + Math.PI;
|
||||||
|
let a2 = Math.atan2(center.y - rec.Y, center.x - rec.X) + Math.PI;
|
||||||
|
let ad = BASE.util.thetaDiff(a1, a2, true);
|
||||||
|
let steps = Math.floor(Math.abs(ad) / arcdivs);
|
||||||
|
let step = (Math.abs(ad) > 0.001 ? ad : Math.PI * 2) / steps;
|
||||||
|
let rot = a1 + step;
|
||||||
|
|
||||||
|
// LOG({first: pos, last: rec, center, a1, a2, ad, step, rot, line});
|
||||||
|
// G0G1(false, [`X${center.x}`, `Y${center.y}`, `E1`]);
|
||||||
|
|
||||||
|
let pc = { X: pos.X, Y: pos.Y };
|
||||||
|
for (let i=0; i<=steps-2; i++) {
|
||||||
|
let np = {
|
||||||
|
X: center.x + Math.cos(rot) * center.r,
|
||||||
|
Y: center.y + Math.sin(rot) * center.r
|
||||||
|
};
|
||||||
|
rot += step;
|
||||||
|
G0G1(false, [`X${np.X}`, `Y${np.Y}`, `E1`]);
|
||||||
|
}
|
||||||
|
|
||||||
|
G0G1(false, [`X${rec.X}`, `Y${rec.Y}`, `E1`]);
|
||||||
|
|
||||||
|
pos.X = rec.X;
|
||||||
|
pos.Y = rec.Y;
|
||||||
|
}
|
||||||
|
|
||||||
function G0G1(g0, line) {
|
function G0G1(g0, line) {
|
||||||
const mov = {};
|
const mov = {};
|
||||||
|
const axes = {};
|
||||||
|
|
||||||
line.forEach(function(tok) {
|
line.forEach(function(tok) {
|
||||||
let axis = tok.charAt(0);
|
let axis = tok.charAt(0);
|
||||||
if (morph && belt) {
|
if (morph && belt) {
|
||||||
axis = beltaxis[axis];
|
axis = beltaxis[axis];
|
||||||
}
|
}
|
||||||
|
let val = parseFloat(tok.substring(1));
|
||||||
|
axes[axis] = val;
|
||||||
if (abs) {
|
if (abs) {
|
||||||
pos[axis] = parseFloat(tok.substring(1));
|
pos[axis] = val;
|
||||||
} else {
|
} else {
|
||||||
mov[axis] = parseFloat(tok.substring(1));
|
mov[axis] = val;
|
||||||
|
pos[axis] += val;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!abs) {
|
|
||||||
for (let [k,v] of Object.entries(mov)) {
|
|
||||||
pos[k] += v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const point = newPoint(
|
const point = newPoint(
|
||||||
factor * pos.X + off.X + xoff.X,
|
factor * pos.X + off.X + xoff.X,
|
||||||
factor * pos.Y + off.Y + xoff.Y,
|
factor * pos.Y + off.Y + xoff.Y,
|
||||||
|
|
@ -172,7 +241,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const retract = (fdm && pos.E < 0) || undefined;
|
const retract = (fdm && pos.E < 0) || undefined;
|
||||||
const moving = g0 || (fdm && pos.E <= 0);
|
const moving = g0 || (fdm && (pos.E <= 0 || !(axes.X || axes.Y || axes.Z)));
|
||||||
|
|
||||||
if (!moving && point.x) bounds.min.x = Math.min(bounds.min.x, point.x);
|
if (!moving && point.x) bounds.min.x = Math.min(bounds.min.x, point.x);
|
||||||
if (!moving && point.x) bounds.max.x = Math.max(bounds.max.x, point.x);
|
if (!moving && point.x) bounds.max.x = Math.max(bounds.max.x, point.x);
|
||||||
|
|
@ -210,6 +279,11 @@
|
||||||
output.push(seq);
|
output.push(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasmoved && !moving) {
|
||||||
|
seq.height = seq.Z = pos.Z;
|
||||||
|
hasmoved = true;
|
||||||
|
}
|
||||||
|
|
||||||
// debug extrusion rate
|
// debug extrusion rate
|
||||||
if (false && fdm && lastPos) {
|
if (false && fdm && lastPos) {
|
||||||
let dE = (absE ? pos.E - lastPos.E : pos.E);
|
let dE = (absE ? pos.E - lastPos.E : pos.E);
|
||||||
|
|
@ -278,12 +352,25 @@
|
||||||
pos[tok.charAt(0)] = parseFloat(tok.substring(1));
|
pos[tok.charAt(0)] = parseFloat(tok.substring(1));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'G10':
|
||||||
|
seq.last().retract = true;
|
||||||
|
break;
|
||||||
|
case 'G11':
|
||||||
|
break;
|
||||||
case 'G0':
|
case 'G0':
|
||||||
G0G1(true, line);
|
G0G1(true, line);
|
||||||
break;
|
break;
|
||||||
case 'G1':
|
case 'G1':
|
||||||
G0G1(false, line);
|
G0G1(false, line);
|
||||||
break;
|
break;
|
||||||
|
case 'G2':
|
||||||
|
// turn arc into a series of points
|
||||||
|
G2G3(true, line)
|
||||||
|
break;
|
||||||
|
case 'G3':
|
||||||
|
// turn arc into a series of points
|
||||||
|
G2G3(false, line);
|
||||||
|
break;
|
||||||
case 'M6':
|
case 'M6':
|
||||||
tool = parseInt(line[0].substring(1));
|
tool = parseInt(line[0].substring(1));
|
||||||
break;
|
break;
|
||||||
|
|
@ -371,7 +458,6 @@
|
||||||
first = true,
|
first = true,
|
||||||
close = !options.open,
|
close = !options.open,
|
||||||
last = startPoint,
|
last = startPoint,
|
||||||
wipeDist = options.wipe || 0,
|
|
||||||
coastDist = options.coast || 0,
|
coastDist = options.coast || 0,
|
||||||
tool = options.tool;
|
tool = options.tool;
|
||||||
|
|
||||||
|
|
@ -385,7 +471,7 @@
|
||||||
if (options.onfirst) {
|
if (options.onfirst) {
|
||||||
options.onfirst(point);
|
options.onfirst(point);
|
||||||
}
|
}
|
||||||
// move from startPoint to point
|
// move to first output point on poly
|
||||||
addOutput(output, point, 0, moveSpeed, tool);
|
addOutput(output, point, 0, moveSpeed, tool);
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -418,19 +504,18 @@
|
||||||
*/
|
*/
|
||||||
PRO.slicePrintPath = function(slice, startPoint, offset, output, opt = {}) {
|
PRO.slicePrintPath = function(slice, startPoint, offset, output, opt = {}) {
|
||||||
// console.log({slicePrintPath: slice.index, ext:slice.extruder});
|
// console.log({slicePrintPath: slice.index, ext:slice.extruder});
|
||||||
|
|
||||||
let i,
|
let i,
|
||||||
preout = [],
|
preout = [],
|
||||||
scope = this,
|
scope = this,
|
||||||
settings = this.settings,
|
settings = this.settings,
|
||||||
device = settings.device,
|
device = settings.device,
|
||||||
process = settings.process,
|
process = opt.params || settings.process,
|
||||||
extruder = slice.extruder || 0,
|
extruder = slice.extruder || 0,
|
||||||
nozzleSize = device.extruders[extruder].extNozzle,
|
nozzleSize = device.extruders[extruder].extNozzle,
|
||||||
firstLayer = opt.first || false,
|
firstLayer = opt.first || false,
|
||||||
minSeek = nozzleSize * (opt.minSeek || 1.5),
|
|
||||||
thinWall = nozzleSize * (opt.thinWall || 1.75),
|
thinWall = nozzleSize * (opt.thinWall || 1.75),
|
||||||
retractDist = opt.retractOver || 2,
|
retractDist = opt.retractOver || 2,
|
||||||
|
solidWidth = process.sliceFillWidth || 1,
|
||||||
fillMult = opt.mult || process.outputFillMult,
|
fillMult = opt.mult || process.outputFillMult,
|
||||||
shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0),
|
shellMult = opt.mult || process.outputShellMult || (process.laserSliceHeight >= 0 ? 1 : 0),
|
||||||
shellOrder = {"out-in":-1,"in-out":1}[process.sliceShellOrder] || -1,
|
shellOrder = {"out-in":-1,"in-out":1}[process.sliceShellOrder] || -1,
|
||||||
|
|
@ -442,14 +527,17 @@
|
||||||
firstPrintMult = process.firstLayerPrintMult,
|
firstPrintMult = process.firstLayerPrintMult,
|
||||||
printSpeed = opt.speed || (firstLayer ? firstShellSpeed : process.outputFeedrate),
|
printSpeed = opt.speed || (firstLayer ? firstShellSpeed : process.outputFeedrate),
|
||||||
fillSpeed = opt.speed || opt.fillSpeed || (firstLayer ? firstFillSpeed || firstShellSpeed : process.outputFeedrate),
|
fillSpeed = opt.speed || opt.fillSpeed || (firstLayer ? firstFillSpeed || firstShellSpeed : process.outputFeedrate),
|
||||||
|
infillSpeed = process.sliceFillRate || opt.infillSpeed || fillSpeed || printSpeed,
|
||||||
moveSpeed = process.outputSeekrate,
|
moveSpeed = process.outputSeekrate,
|
||||||
origin = startPoint.add(offset),
|
origin = startPoint.add(offset),
|
||||||
zhop = process.zHopDistance || 0,
|
zhop = process.zHopDistance || 0,
|
||||||
antiBacklash = process.antiBacklash,
|
antiBacklash = process.antiBacklash,
|
||||||
doSupport = opt.support,
|
wipeDist = process.outputRetractWipe || 0,
|
||||||
isBelt = device.bedBelt,
|
isBelt = device.bedBelt,
|
||||||
startClone = startPoint.clone(),
|
startClone = startPoint.clone(),
|
||||||
z = slice.z;
|
seedPoint = opt.seedPoint || startPoint,
|
||||||
|
z = slice.z,
|
||||||
|
lastPoly;
|
||||||
|
|
||||||
// apply first layer extrusion multipliers
|
// apply first layer extrusion multipliers
|
||||||
if (firstLayer) {
|
if (firstLayer) {
|
||||||
|
|
@ -459,28 +547,202 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function retract() {
|
function retract() {
|
||||||
if (preout.length) preout.last().retract = true;
|
let array = preout.length ? preout : output;
|
||||||
|
if (array.length) {
|
||||||
|
let last = array.last();
|
||||||
|
last.retract = true;
|
||||||
|
if (wipeDist && lastPoly && last.point) {
|
||||||
|
let endpoint = last.point.followTo(lastPoly.center(true), wipeDist);
|
||||||
|
if (endpoint.inPolygon(lastPoly)) {
|
||||||
|
addOutput(array, endpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (opt.pretract) {
|
||||||
|
opt.pretract(wipeDist);
|
||||||
|
} else {
|
||||||
|
console.log('unable to retract. no preout or output');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function intersectsTop(p1, p2) {
|
function intersectsTop(p1, p2) {
|
||||||
|
if (opt.danger) {
|
||||||
|
return retractRequired(p1, p2);
|
||||||
|
}
|
||||||
let int = false;
|
let int = false;
|
||||||
POLY.flatten(slice.topPolys().clone(true)).forEach(function(poly) {
|
POLY.flatten(slice.topPolys().clone(true)).forEach(function(poly) {
|
||||||
if (!int) poly.forEachSegment(function(s1, s2) {
|
if (!int) poly.forEachSegment(function(s1, s2) {
|
||||||
if (UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT)) {
|
if (UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT)) {
|
||||||
int = true;
|
return int = true;
|
||||||
return int;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return int;
|
return int;
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputTraces(poly, extrude) {
|
// returns true if no path around and retract required
|
||||||
|
// returns false if routed around or no retract
|
||||||
|
function retractRequired(p1, p2) {
|
||||||
|
const dbug = false;
|
||||||
|
|
||||||
|
let ints = [];
|
||||||
|
let tops = POLY.flatten(slice.topPolys().clone(true));
|
||||||
|
for (let poly of tops) {
|
||||||
|
poly.forEachSegment(function(s1, s2) {
|
||||||
|
let ip = UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT);
|
||||||
|
if (ip) {
|
||||||
|
ints.push({ip, poly});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// no intersections
|
||||||
|
if (ints.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// odd # of intersections ?!? do retraction
|
||||||
|
if (ints.length && ints.length % 2 !== 0) {
|
||||||
|
if (dbug === slice.index) console.log(slice.index, {odd_intersects: ints});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort by distance
|
||||||
|
ints.sort((a, b) => {
|
||||||
|
return a.ip.dist - b.ip.dist;
|
||||||
|
});
|
||||||
|
|
||||||
|
let valid = ints.length;
|
||||||
|
|
||||||
|
// check pairs. eliminate too close points.
|
||||||
|
// pairs must intersect same poly or retract.
|
||||||
|
for (let i=0; i<ints.length; i += 2) {
|
||||||
|
let i1 = ints[0];
|
||||||
|
let i2 = ints[1];
|
||||||
|
// different poly. force retract
|
||||||
|
if (i1.poly !== i2.poly) {
|
||||||
|
if (dbug === slice.index) console.log(slice.index, {int_diff_poly: ints, i});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (i1.ip.distTo2D(i2.ip) < retractDist) {
|
||||||
|
if (dbug === slice.index) console.log(slice.index, {int_dist_too_small: i1.ip.distTo2D(i2.ip), retractDist});
|
||||||
|
valid -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid > 2) {
|
||||||
|
if (dbug === slice.index) console.log(slice.index, {complex_route: valid});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
// can route around intersected top polys
|
||||||
|
for (let i=0; i<ints.length; i += 2) {
|
||||||
|
let i1 = ints[0];
|
||||||
|
let i2 = ints[1];
|
||||||
|
|
||||||
|
// output first point
|
||||||
|
addOutput(preout, i1.ip, 0, moveSpeed, extruder);
|
||||||
|
|
||||||
|
// create two loops around poly
|
||||||
|
// find shortest of two paths and emit poly points
|
||||||
|
let poly = i1.poly;
|
||||||
|
let isCW = poly.isClockwise();
|
||||||
|
let points = poly.points;
|
||||||
|
|
||||||
|
let p1p = isCW ? points : points.slice().reverse(); // CW
|
||||||
|
let p2p = isCW ? points.slice().reverse() : points; // CCW
|
||||||
|
|
||||||
|
let r1s = p1p.indexOf(isCW ? i1.ip.p2 : i1.ip.p1);
|
||||||
|
let r1e = p1p.indexOf(isCW ? i2.ip.p1 : i2.ip.p2);
|
||||||
|
|
||||||
|
let r1 = r1s === r1e ?
|
||||||
|
[ p1p[r1s] ] : r1s < r1e ?
|
||||||
|
[ ...p1p.slice(r1s,r1e+1) ] :
|
||||||
|
[ ...p1p.slice(r1s), ...p1p.slice(0,r1e+1) ];
|
||||||
|
|
||||||
|
let r1d = 0;
|
||||||
|
for (let i=1; i<r1.length; i++) {
|
||||||
|
r1d += r1[i-1].distTo2D(r1[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let r2s = p2p.indexOf(isCW ? i1.ip.p1 : i1.ip.p2);
|
||||||
|
let r2e = p2p.indexOf(isCW ? i2.ip.p2 : i2.ip.p1);
|
||||||
|
|
||||||
|
let r2 = r2s === r2e ?
|
||||||
|
[ p2p[r2s] ] : r2s < r2e ?
|
||||||
|
[ ...p2p.slice(r2s,r2e+1) ] :
|
||||||
|
[ ...p2p.slice(r2s), ...p2p.slice(0,r2e+1) ];
|
||||||
|
|
||||||
|
let r2d = 0;
|
||||||
|
for (let i=1; i<r2.length; i++) {
|
||||||
|
r2d += r2[i-1].distTo2D(r2[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let route = r1d <= r2d ? r1 : r2;
|
||||||
|
|
||||||
|
if (dbug === slice.index) console.log(slice.index, {
|
||||||
|
ints: ints.map(i=>i.ip.dist),
|
||||||
|
i1, i2, same: i1.poly === i2.poly,
|
||||||
|
route,
|
||||||
|
r1, r1d, r1s, r1e,
|
||||||
|
r2, r2d, r2s, r2e,
|
||||||
|
isCW});
|
||||||
|
|
||||||
|
for (let p of route) {
|
||||||
|
addOutput(preout, p, 0, moveSpeed, extruder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// output last point
|
||||||
|
addOutput(preout, i2.ip, 0, moveSpeed, extruder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function outputTraces(poly, opt = {}) {
|
||||||
if (!poly) return;
|
if (!poly) return;
|
||||||
if (Array.isArray(poly)) {
|
if (Array.isArray(poly)) {
|
||||||
outputOrderClosest(poly, function(next) {
|
if (opt.sort) {
|
||||||
outputTraces(next, extrude);
|
let polys = poly.slice().sort(function(a,b) {
|
||||||
}, null);
|
return (a.perimeter() - b.perimeter()) * opt.sort;
|
||||||
|
});
|
||||||
|
let debug = polys.length > 3;
|
||||||
|
let last;
|
||||||
|
while (polys.length) {
|
||||||
|
let next;
|
||||||
|
for (let p of polys) {
|
||||||
|
if (!last) {
|
||||||
|
next = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (opt.sort > 0) {
|
||||||
|
// in-out
|
||||||
|
if (last.isInside(p)) {
|
||||||
|
next = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// out-in
|
||||||
|
if (p.isInside(last)) {
|
||||||
|
next = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next) {
|
||||||
|
last = next;
|
||||||
|
polys.remove(next);
|
||||||
|
outputTraces(next, opt);
|
||||||
|
} else {
|
||||||
|
last = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outputOrderClosest(poly, function(next) {
|
||||||
|
outputTraces(next, opt);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let finishShell = poly.depth === 0 && !firstLayer;
|
let finishShell = poly.depth === 0 && !firstLayer;
|
||||||
startPoint = scope.polyPrintPath(poly, startPoint, preout, {
|
startPoint = scope.polyPrintPath(poly, startPoint, preout, {
|
||||||
|
|
@ -489,13 +751,18 @@
|
||||||
accel: finishShell,
|
accel: finishShell,
|
||||||
wipe: process.outputWipeDistance || 0,
|
wipe: process.outputWipeDistance || 0,
|
||||||
coast: firstLayer ? 0 : coastDist,
|
coast: firstLayer ? 0 : coastDist,
|
||||||
extrude: pref(extrude, shellMult),
|
extrude: pref(opt.extrude, shellMult),
|
||||||
onfirst: function(firstPoint) {
|
onfirst: function(firstPoint) {
|
||||||
if (startPoint.distTo2D(firstPoint) > retractDist) {
|
let from = seedPoint || startPoint;
|
||||||
retract();
|
if (from.distTo2D(firstPoint) > retractDist) {
|
||||||
|
if (intersectsTop(from, firstPoint)) {
|
||||||
|
retract();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
seedPoint = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
lastPoly = slice.lastPoly = poly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,12 +797,12 @@
|
||||||
// let emit = i === 0 ? 0 : extrude;
|
// let emit = i === 0 ? 0 : extrude;
|
||||||
addOutput(preout, p, emit, speed || printSpeed, extruder);
|
addOutput(preout, p, emit, speed || printSpeed, extruder);
|
||||||
lp = p;
|
lp = p;
|
||||||
});
|
}, !poly.open);
|
||||||
return lp;
|
return lp;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputFills(lines, options) {
|
function outputFills(lines, opt = {}) {
|
||||||
if (!lines || lines.length === 0) {
|
if (!lines || lines.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -544,10 +811,10 @@
|
||||||
start = 0,
|
start = 0,
|
||||||
skip = false,
|
skip = false,
|
||||||
lastIndex = -1,
|
lastIndex = -1,
|
||||||
opt = options || {},
|
flow = opt.flow || 1,
|
||||||
near = opt.near || false,
|
near = opt.near || false,
|
||||||
fast = opt.fast || false,
|
fast = opt.fast || false,
|
||||||
fill = opt.fill >= 0 ? opt.fill : fillMult,
|
fill = (opt.fill >= 0 ? opt.fill : fillMult) * flow,
|
||||||
thinDist = near ? thinWall : thinWall;
|
thinDist = near ? thinWall : thinWall;
|
||||||
|
|
||||||
while (lines && marked < lines.length) {
|
while (lines && marked < lines.length) {
|
||||||
|
|
@ -684,11 +951,11 @@
|
||||||
* the special exception that depth is considered into distance
|
* the special exception that depth is considered into distance
|
||||||
* so that inner polygons are emitted first.
|
* so that inner polygons are emitted first.
|
||||||
*
|
*
|
||||||
* @param {Array} array of Polygon or Polygon wrappers
|
* @param {Array} array of Polygons or Polygon wrappers (tops)
|
||||||
* @param {Function} fn
|
* @param {Function} fn call to emit next candidate
|
||||||
* @param {Function} fnp convert 'next' object into a Polygon
|
* @param {Function} fnp convert 'next' object into a Polygon for closeness
|
||||||
*/
|
*/
|
||||||
function outputOrderClosest(array, fn, fnp, newTop) {
|
function outputOrderClosest(array, fn, fnp) {
|
||||||
if (array.length === 1) {
|
if (array.length === 1) {
|
||||||
return fn(array[0]);
|
return fn(array[0]);
|
||||||
}
|
}
|
||||||
|
|
@ -708,7 +975,6 @@
|
||||||
d: find.distance - (poly.depth * thinWall),
|
d: find.distance - (poly.depth * thinWall),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
newTop = false;
|
|
||||||
if (order.length === 0) {
|
if (order.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -753,37 +1019,31 @@
|
||||||
// and enforce optimal shell order (outer first)
|
// and enforce optimal shell order (outer first)
|
||||||
if (isBelt && opt.onBelt) {
|
if (isBelt && opt.onBelt) {
|
||||||
startPoint = startClone;
|
startPoint = startClone;
|
||||||
shellOrder = 1;
|
shellOrder = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// top object
|
// innermost shells
|
||||||
let bounds = POLY.flatten(next.shellsAtDepth(0).clone(true));
|
let inner = next.innerShells() || [];
|
||||||
|
|
||||||
// output inner polygons
|
// output inner polygons
|
||||||
if (shellOrder === 1)
|
if (shellOrder === 1) outputTraces(inner, { sort: shellOrder });
|
||||||
outputTraces([].appendAll(next.innerShells() || []));
|
|
||||||
|
|
||||||
// sort perimeter polygon by length to go out-to-in or in-to-out
|
outputTraces(next.shells, { sort: shellOrder });
|
||||||
(next.shells || []).sort(function(a,b) {
|
|
||||||
return a.perimeter() > b.perimeter() ? shellOrder : -shellOrder;
|
|
||||||
}).forEach(function(poly, index) {
|
|
||||||
outputTraces(poly);
|
|
||||||
});
|
|
||||||
|
|
||||||
// output outer polygons
|
// output outer polygons
|
||||||
if (shellOrder === -1)
|
if (shellOrder === -1) outputTraces(inner, { sort: shellOrder });
|
||||||
outputTraces([].appendAll(next.innerShells() || []));
|
|
||||||
|
|
||||||
// output thin fill
|
// output thin fill
|
||||||
outputFills(next.thin_fill, {near: true});
|
outputFills(next.thin_fill, {near: true});
|
||||||
|
|
||||||
// then output solid and sparse fill
|
// then output solid and sparse fill
|
||||||
outputFills(next.fill_lines);
|
outputFills(next.fill_lines, {flow: solidWidth});
|
||||||
outputSparse(next.fill_sparse, sparseMult);
|
outputSparse(next.fill_sparse, sparseMult, infillSpeed);
|
||||||
|
|
||||||
lastTop = next;
|
lastTop = next;
|
||||||
}
|
}
|
||||||
}, function(obj) {
|
}, function(obj) {
|
||||||
|
// for tops
|
||||||
return obj instanceof Polygon ? obj : obj.poly;
|
return obj instanceof Polygon ? obj : obj.poly;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -971,15 +1231,15 @@
|
||||||
function constOp(tok, consts, opch, op) {
|
function constOp(tok, consts, opch, op) {
|
||||||
let pos, v1, v2;
|
let pos, v1, v2;
|
||||||
if ((pos = tok.indexOf(opch)) > 0) {
|
if ((pos = tok.indexOf(opch)) > 0) {
|
||||||
v1 = consts[tok.substring(0,pos)] || 0;
|
v1 = parseFloat(consts[tok.substring(0,pos)] || 0);
|
||||||
v2 = parseInt(tok.substring(pos+1)) || 0;
|
v2 = parseFloat(tok.substring(pos+1)) || 0;
|
||||||
return op(v1,v2);
|
return op(v1,v2).round(4);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function constReplace(str, consts, start) {
|
function constReplace(str, consts, start, pad, short) {
|
||||||
let cs = str.indexOf("{", start || 0),
|
let cs = str.indexOf("{", start || 0),
|
||||||
ce = str.indexOf("}", cs),
|
ce = str.indexOf("}", cs),
|
||||||
tok, nutok, nustr;
|
tok, nutok, nustr;
|
||||||
|
|
@ -991,9 +1251,24 @@
|
||||||
constOp(tok, consts, "/", function(v1,v2) { return v1/v2 }) ||
|
constOp(tok, consts, "/", function(v1,v2) { return v1/v2 }) ||
|
||||||
constOp(tok, consts, "*", function(v1,v2) { return v1*v2 }) ||
|
constOp(tok, consts, "*", function(v1,v2) { return v1*v2 }) ||
|
||||||
consts[tok] || 0;
|
consts[tok] || 0;
|
||||||
|
if (pad) {
|
||||||
|
nutok = nutok.toString();
|
||||||
|
let oldln = ce-cs+1;
|
||||||
|
let tokln = nutok.length;
|
||||||
|
if (tokln < oldln) {
|
||||||
|
short = (short || 1) + (oldln - tokln);
|
||||||
|
}
|
||||||
|
}
|
||||||
nustr = str.replace("{"+tok+"}",nutok);
|
nustr = str.replace("{"+tok+"}",nutok);
|
||||||
return constReplace(nustr, consts, ce+1+(nustr.length-str.length));
|
return constReplace(nustr, consts, ce+1+(nustr.length-str.length), pad, short);
|
||||||
} else {
|
} else {
|
||||||
|
// insert compensating spaces for accumulated replace string shortages
|
||||||
|
if (short) {
|
||||||
|
let si = str.indexOf(';');
|
||||||
|
if (si > 0) {
|
||||||
|
str = str.replace(';', ';'.padStart(short,' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@
|
||||||
zM = Math.max(p1.z, p2.z, p3.z),
|
zM = Math.max(p1.z, p2.z, p3.z),
|
||||||
bm = Math.floor(zm * zScale),
|
bm = Math.floor(zm * zScale),
|
||||||
bM = Math.ceil(zM * zScale);
|
bM = Math.ceil(zM * zScale);
|
||||||
|
if (bm < 0) bm = 0;
|
||||||
for (j = bm; j < bM; j++) {
|
for (j = bm; j < bM; j++) {
|
||||||
buckets[j].push(p1);
|
buckets[j].push(p1);
|
||||||
buckets[j].push(p2);
|
buckets[j].push(p2);
|
||||||
|
|
@ -529,6 +530,9 @@
|
||||||
// for topo slices, we just need the raw lines
|
// for topo slices, we just need the raw lines
|
||||||
if (!topoMode && !simpleMode) {
|
if (!topoMode && !simpleMode) {
|
||||||
slice.groups = connectLines(slice.lines, slice.z);
|
slice.groups = connectLines(slice.lines, slice.z);
|
||||||
|
if (options.union) {
|
||||||
|
slice.groups = POLY.flatten(POLY.union(POLY.nest(slice.groups), null, true), null, true);
|
||||||
|
}
|
||||||
if ((debug && slice.lines.excessive) || xray) {
|
if ((debug && slice.lines.excessive) || xray) {
|
||||||
const dash = xray || 3;
|
const dash = xray || 3;
|
||||||
slice.lines.forEach((line, i) => {
|
slice.lines.forEach((line, i) => {
|
||||||
|
|
|
||||||
|
|
@ -722,7 +722,11 @@
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no more closest polys (open set)
|
// no more closest polys (open set)
|
||||||
emit(BASE.newPolygon().addPoints(array));
|
if (opt.openok) {
|
||||||
|
emit(BASE.newPolygon().addPoints(array).setOpen());
|
||||||
|
} else {
|
||||||
|
emit(BASE.newPolygon().addPoints(array));
|
||||||
|
}
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,17 @@
|
||||||
this.show();
|
this.show();
|
||||||
for (let i=0, s=this.slices, len=s.length; i<len; i++) {
|
for (let i=0, s=this.slices, len=s.length; i<len; i++) {
|
||||||
s[i].visible = i >= newMin && i <= newMax;
|
s[i].visible = i >= newMin && i <= newMax;
|
||||||
|
if (s[i].visible) this.lastVis = s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLastFraction(frac = 1) {
|
||||||
|
if (this.lastVis)
|
||||||
|
for (let mesh of this.lastVis.children) {
|
||||||
|
let geo = mesh.geometry;
|
||||||
|
let pos = geo.attributes.position;
|
||||||
|
let len = frac === 1 ? Infinity : Math.round(pos.count * frac);
|
||||||
|
geo.setDrawRange(0, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,24 @@
|
||||||
return stacks[name];
|
return stacks[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStacks() {
|
||||||
|
return Object.entries(stacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLabels() {
|
||||||
|
return Object.keys(DYN);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVisible(label, bool) {
|
||||||
|
let ctrl = DYN[label];
|
||||||
|
if (ctrl) {
|
||||||
|
ctrl.toggle.checked = bool;
|
||||||
|
ctrl.group.forEach(mat => {
|
||||||
|
mat.visible = bool;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function create(name, view) {
|
function create(name, view) {
|
||||||
if (stacks[name]) {
|
if (stacks[name]) {
|
||||||
return stacks[name];
|
return stacks[name];
|
||||||
|
|
@ -70,6 +88,11 @@
|
||||||
ctrl.group.forEach(mat => {
|
ctrl.group.forEach(mat => {
|
||||||
mat.visible = ctrl.toggle.checked;
|
mat.visible = ctrl.toggle.checked;
|
||||||
});
|
});
|
||||||
|
if (ctrl.toggle.checked) {
|
||||||
|
KIRI.api.event.emit("stack.show", label);
|
||||||
|
} else {
|
||||||
|
KIRI.api.event.emit("stack.hide", label)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let color = lmap[label].color.check;
|
let color = lmap[label].color.check;
|
||||||
|
|
@ -120,14 +143,24 @@
|
||||||
max = newMax;
|
max = newMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setFraction(frac) {
|
||||||
|
Object.values(stacks).forEach(stack => {
|
||||||
|
stack.obj.setLastFraction(frac);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
KIRI.stacks = {
|
KIRI.stacks = {
|
||||||
clear,
|
clear,
|
||||||
create,
|
create,
|
||||||
rotate,
|
rotate,
|
||||||
remove,
|
remove,
|
||||||
getStack,
|
getStack,
|
||||||
|
getStacks,
|
||||||
getRange,
|
getRange,
|
||||||
setRange,
|
setRange,
|
||||||
|
getLabels,
|
||||||
|
setVisible,
|
||||||
|
setFraction,
|
||||||
setFreeMem
|
setFreeMem
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
prefix = "tab",
|
prefix = "tab",
|
||||||
state = {},
|
state = {},
|
||||||
units = 1,
|
units = 1,
|
||||||
|
lastChange = null,
|
||||||
lastBtn = null,
|
lastBtn = null,
|
||||||
lastTxt = null,
|
lastTxt = null,
|
||||||
lastPop = null,
|
lastPop = null,
|
||||||
|
|
@ -40,6 +41,7 @@
|
||||||
KIRI.ui = {
|
KIRI.ui = {
|
||||||
prefix: function(pre) { prefix = pre; return kiri.ui },
|
prefix: function(pre) { prefix = pre; return kiri.ui },
|
||||||
inputAction: function(fn) { inputAction = fn; return kiri.ui },
|
inputAction: function(fn) { inputAction = fn; return kiri.ui },
|
||||||
|
lastChange: function() { return lastChange },
|
||||||
checkpoint,
|
checkpoint,
|
||||||
restore,
|
restore,
|
||||||
refresh,
|
refresh,
|
||||||
|
|
@ -47,6 +49,7 @@
|
||||||
setExpert,
|
setExpert,
|
||||||
setHoverPop,
|
setHoverPop,
|
||||||
hidePoppers,
|
hidePoppers,
|
||||||
|
hoverPop,
|
||||||
bound,
|
bound,
|
||||||
toInt,
|
toInt,
|
||||||
toFloat,
|
toFloat,
|
||||||
|
|
@ -683,6 +686,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ip.addEventListener('blur', function(event) {
|
ip.addEventListener('blur', function(event) {
|
||||||
|
lastChange = ip;
|
||||||
action(event);
|
action(event);
|
||||||
if (opt.trigger) {
|
if (opt.trigger) {
|
||||||
refresh();
|
refresh();
|
||||||
|
|
@ -761,6 +765,7 @@
|
||||||
}
|
}
|
||||||
ip.setVisible = row.setVisible;
|
ip.setVisible = row.setVisible;
|
||||||
ip.onchange = function(ev) {
|
ip.onchange = function(ev) {
|
||||||
|
lastChange = ip;
|
||||||
action();
|
action();
|
||||||
};
|
};
|
||||||
ip.onclick = (ev) => {
|
ip.onclick = (ev) => {
|
||||||
|
|
@ -882,4 +887,54 @@
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hoverPop(el, opt = {}) {
|
||||||
|
if (Array.isArray(el)) {
|
||||||
|
opt.group = [];
|
||||||
|
return el.forEach(ev => hoverPop(ev, opt));
|
||||||
|
}
|
||||||
|
let group = opt.group || [];
|
||||||
|
let closes = opt.closes || group;
|
||||||
|
let target = opt.target || el;
|
||||||
|
let popped = false;
|
||||||
|
group.push(target);
|
||||||
|
if (closes !== group) {
|
||||||
|
closes.push(target);
|
||||||
|
}
|
||||||
|
let openit = () => {
|
||||||
|
clearTimeout(closes.timer);
|
||||||
|
for (let close of closes) {
|
||||||
|
close.classList.remove("hoverpop");
|
||||||
|
}
|
||||||
|
target.classList.add("hoverpop");
|
||||||
|
popped = true;
|
||||||
|
};
|
||||||
|
let closeit = () => {
|
||||||
|
target.classList.remove("hoverpop");
|
||||||
|
clearTimeout(closes.timer);
|
||||||
|
popped = false;
|
||||||
|
};
|
||||||
|
if (opt.auto !== false) {
|
||||||
|
el.addEventListener("mouseenter", openit);
|
||||||
|
}
|
||||||
|
el.addEventListener("mouseleave", (ev) => {
|
||||||
|
closes.timer = setTimeout(() => {
|
||||||
|
target.classList.remove("hoverpop");
|
||||||
|
}, 750);
|
||||||
|
});
|
||||||
|
if (!opt.sticky) {
|
||||||
|
el.addEventListener("mouseup", (ev) => {
|
||||||
|
if (popped) {
|
||||||
|
closeit();
|
||||||
|
} else {
|
||||||
|
openit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
document.addEventListener("keydown", (ev) => {
|
||||||
|
if (ev.keyCode === 27 || ev.code === 'Escape') {
|
||||||
|
closeit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,39 @@
|
||||||
|
|
||||||
let Group = Widget.Groups = {
|
let Group = Widget.Groups = {
|
||||||
|
|
||||||
|
list: () => {
|
||||||
|
return groups.slice()
|
||||||
|
},
|
||||||
|
|
||||||
|
merge: (widgets) => {
|
||||||
|
let grps = widgets.map(w => w.group).uniq();
|
||||||
|
if (grps.length > 1) {
|
||||||
|
let root = grps.shift();
|
||||||
|
let rpos = root[0].track.pos;
|
||||||
|
for (let grp of grps) {
|
||||||
|
for (let w of grp) {
|
||||||
|
let wpos = w.track.pos;
|
||||||
|
w.group = root;
|
||||||
|
w.moveMesh(rpos.x - wpos.x, rpos.y - wpos.y, rpos.z - wpos.z);
|
||||||
|
w._move(rpos.x, rpos.y, rpos.z, true);
|
||||||
|
root.push(w);
|
||||||
|
}
|
||||||
|
groups.splice(groups.indexOf(grp),1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
split: (widgets) => {
|
||||||
|
for (let group of widgets.map(w => w.group).uniq()) {
|
||||||
|
groups.splice(groups.indexOf(group),1);
|
||||||
|
for (let widget of group) {
|
||||||
|
let nugroup = Group.forid(widget.id);
|
||||||
|
nugroup.push(widget);
|
||||||
|
widget.group = nugroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
forid: function(id) {
|
forid: function(id) {
|
||||||
for (let i=0; i<groups.length; i++) {
|
for (let i=0; i<groups.length; i++) {
|
||||||
if (groups[i].id === id) return groups[i];
|
if (groups[i].id === id) return groups[i];
|
||||||
|
|
@ -101,7 +134,7 @@
|
||||||
* @params {String} [id]
|
* @params {String} [id]
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function Widget(id,group) {
|
function Widget(id, group) {
|
||||||
this.id = id || new Date().getTime().toString(36)+(nextId++);
|
this.id = id || new Date().getTime().toString(36)+(nextId++);
|
||||||
this.group = group || [];
|
this.group = group || [];
|
||||||
this.group.push(this);
|
this.group.push(this);
|
||||||
|
|
@ -254,6 +287,10 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PRO.getVertices = function() {
|
||||||
|
return this.mesh.geometry.attributes.position;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {THREE.Geometry} geometry
|
* @param {THREE.Geometry} geometry
|
||||||
* @returns {Widget}
|
* @returns {Widget}
|
||||||
|
|
@ -461,11 +498,11 @@
|
||||||
this.modified = true;
|
this.modified = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.rotate = function(x, y, z) {
|
PRO.rotate = function(x, y, z, temp) {
|
||||||
this.group.forEach(w => {
|
this.group.forEach(w => {
|
||||||
w._rotate(x, y, z, false);
|
w._rotate(x, y, z, temp);
|
||||||
});
|
});
|
||||||
this.center();
|
this.center(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO._rotate = function(x, y, z, temp) {
|
PRO._rotate = function(x, y, z, temp) {
|
||||||
|
|
@ -509,20 +546,55 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO._mirror = function() {
|
PRO._mirror = function() {
|
||||||
this.setWireframe(false);
|
|
||||||
this.clearSlices();
|
this.clearSlices();
|
||||||
this.mesh.applyMatrix4(new THREE.Matrix4().makeScale(-1, 1, 1));
|
this.setWireframe(false);
|
||||||
let geo = this.mesh.geometry,
|
let geo = this.mesh.geometry, ot = this.track;
|
||||||
o = this.track;
|
let pos = geo.attributes.position;
|
||||||
|
let arr = pos.array;
|
||||||
|
let count = pos.count;
|
||||||
|
// invert x
|
||||||
|
for (let i=0; i<count; i++) {
|
||||||
|
arr[i*3] = -arr[i*3];
|
||||||
|
}
|
||||||
|
// invert face vertices
|
||||||
|
for (let i=0; i<count; i+=3) {
|
||||||
|
let x = arr[i*3+0];
|
||||||
|
let y = arr[i*3+1];
|
||||||
|
let z = arr[i*3+2];
|
||||||
|
arr[i*3+0] = arr[i*3+6];
|
||||||
|
arr[i*3+1] = arr[i*3+7];
|
||||||
|
arr[i*3+2] = arr[i*3+8];
|
||||||
|
arr[i*3+6] = x;
|
||||||
|
arr[i*3+7] = y;
|
||||||
|
arr[i*3+8] = z;
|
||||||
|
}
|
||||||
|
pos.needsUpdate = true;
|
||||||
geo.computeFaceNormals();
|
geo.computeFaceNormals();
|
||||||
geo.computeVertexNormals();
|
geo.computeVertexNormals();
|
||||||
this.mesh.position.x = -this.mesh.position.x;
|
ot.mirror = !ot.mirror;
|
||||||
o.mirror = !o.mirror;
|
|
||||||
this.modified = true;
|
this.modified = true;
|
||||||
|
this.points = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.getGeoVertices = function() {
|
PRO.getGeoVertices = function() {
|
||||||
return this.mesh.geometry.getAttribute('position').array;
|
let geo = this.mesh.geometry;
|
||||||
|
let pos = geo.getAttribute('position').array;
|
||||||
|
if (geo.index) {
|
||||||
|
let idx = geo.index.array;
|
||||||
|
let len = idx.length;
|
||||||
|
let p2 = new Float32Array(len * 3);
|
||||||
|
let inc = 0;
|
||||||
|
for (let i=0; i<len; i++) {
|
||||||
|
let iv = idx[i];
|
||||||
|
let ip = iv * 3;
|
||||||
|
p2[inc++] = pos[ip++];
|
||||||
|
p2[inc++] = pos[ip++];
|
||||||
|
p2[inc++] = pos[ip];
|
||||||
|
}
|
||||||
|
return p2;
|
||||||
|
} else {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PRO.getPoints = function() {
|
PRO.getPoints = function() {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ let BASE = self.base,
|
||||||
print: null,
|
print: null,
|
||||||
snap: null
|
snap: null
|
||||||
},
|
},
|
||||||
cache = {};
|
wgroup = {},
|
||||||
|
wcache = {};
|
||||||
|
|
||||||
// catch clipper alerts and convert to console messages
|
// catch clipper alerts and convert to console messages
|
||||||
self.alert = function(o) {
|
self.alert = function(o) {
|
||||||
|
|
@ -24,7 +25,9 @@ BASE.debug.disable();
|
||||||
const dispatch =
|
const dispatch =
|
||||||
KIRI.server =
|
KIRI.server =
|
||||||
KIRI.worker = {
|
KIRI.worker = {
|
||||||
cache: cache,
|
group: wgroup,
|
||||||
|
|
||||||
|
cache: wcache,
|
||||||
|
|
||||||
decimate: function(data, send) {
|
decimate: function(data, send) {
|
||||||
let { vertices, options } = data;
|
let { vertices, options } = data;
|
||||||
|
|
@ -38,65 +41,128 @@ KIRI.worker = {
|
||||||
send.done();
|
send.done();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clear: function(data, send) {
|
||||||
|
current.snap = null;
|
||||||
|
current.print = null;
|
||||||
|
dispatch.group = wgroup = {};
|
||||||
|
dispatch.cache = wcache = {};
|
||||||
|
send.done({ clear: true });
|
||||||
|
},
|
||||||
|
|
||||||
// widget sync
|
// widget sync
|
||||||
sync: function(data, send) {
|
sync: function(data, send) {
|
||||||
|
if (data.valid) {
|
||||||
|
// remove widgets not present in valid list
|
||||||
|
for (let key in wcache) {
|
||||||
|
if (data.valid.indexOf(key) < 0) {
|
||||||
|
delete wcache[key];
|
||||||
|
for (let [id,group] of Object.entries(wgroup)) {
|
||||||
|
wgroup[id] = group = group.filter(v => v.id !== key);
|
||||||
|
group.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send.done(data.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let group = wgroup[data.group];
|
||||||
|
if (!group) {
|
||||||
|
group = [];
|
||||||
|
group.id = data.group;
|
||||||
|
wgroup[data.group] = group;
|
||||||
|
}
|
||||||
let vertices = new Float32Array(data.vertices),
|
let vertices = new Float32Array(data.vertices),
|
||||||
points = BASE.verticesToPoints(vertices, { maxpass: 0 }),
|
widget = KIRI.newWidget(data.id, group).loadVertices(vertices);
|
||||||
widget = KIRI.newWidget(data.id).setPoints(points);
|
|
||||||
|
|
||||||
// do it here so cancel can work
|
// do it here so cancel can work
|
||||||
cache[data.id] = widget;
|
wcache[data.id] = widget;
|
||||||
// stored for possible future rotations
|
// stored for possible future rotations
|
||||||
widget.vertices = vertices;
|
widget.vertices = vertices;
|
||||||
|
// restore tracking object
|
||||||
// fake mesh object to satisfy printing
|
widget.track = data.track;
|
||||||
widget.track = data.tracking;
|
|
||||||
widget.mesh = {
|
|
||||||
widget: widget,
|
|
||||||
position: data.position
|
|
||||||
};
|
|
||||||
|
|
||||||
send.done(data.id);
|
send.done(data.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
slice: function(data, send) {
|
rotate: function(data, send) {
|
||||||
let { id, settings } = data;
|
let { settings } = data;
|
||||||
|
if (!settings.device.bedBelt) {
|
||||||
|
return send.done({});
|
||||||
|
}
|
||||||
|
|
||||||
send.data({update:0.05, updateStatus:"slicing"});
|
function mins(vert, last = {}) {
|
||||||
|
let miny = last.miny || Infinity,
|
||||||
let widget = cache[data.id],
|
maxy = last.maxy || -Infinity;
|
||||||
last = time(),
|
|
||||||
xpos,
|
|
||||||
ypos,
|
|
||||||
now;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
let rotation = (Math.PI/180) * (settings.device.bedBelt ? 45 : 0);
|
|
||||||
if (rotation) {
|
|
||||||
// need min y for post-rotation offset in prepare
|
|
||||||
let vert = widget.vertices;
|
|
||||||
let miny = Infinity;
|
|
||||||
for (let i=0, l=vert.length; i<l; ) {
|
for (let i=0, l=vert.length; i<l; ) {
|
||||||
let x = vert[i++];
|
let x = vert[i++];
|
||||||
let y = vert[i++];
|
let y = vert[i++];
|
||||||
let z = vert[i++];
|
let z = vert[i++];
|
||||||
if (z < 0.01) miny = Math.min(miny, y);
|
if (z < 0.01) {
|
||||||
|
miny = Math.min(miny, y);
|
||||||
|
maxy = Math.max(maxy, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { miny, maxy };
|
||||||
|
}
|
||||||
|
|
||||||
|
function gmin(group) {
|
||||||
|
let minv = {};
|
||||||
|
for (let w of group) {
|
||||||
|
minv = mins(w.vertices, minv);
|
||||||
|
}
|
||||||
|
return minv;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let group of Object.values(wgroup)) {
|
||||||
|
let { miny, maxy } = gmin(group);
|
||||||
|
|
||||||
|
let widget = group[0];
|
||||||
|
let track = widget.track;
|
||||||
|
let xpos = track.pos.x;
|
||||||
|
let ypos = settings.device.bedDepth / 2 + track.pos.y + miny;
|
||||||
|
let rotation = (Math.PI / 180) * 45;
|
||||||
|
|
||||||
|
widget.rotate(rotation,0,0,true);
|
||||||
|
let minr = gmin(group);
|
||||||
|
widget.belt = { xpos, ypos, yadd: minr.maxy - minr.miny };
|
||||||
|
for (let others of group.slice(1)) {
|
||||||
|
others.belt = widget.belt;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.getBoundingBox(true);
|
send.data({group: group.id, belt: widget.belt});
|
||||||
let track = widget.track;
|
|
||||||
xpos = track.pos.x;
|
|
||||||
ypos = settings.device.bedDepth / 2 + track.pos.y + miny;
|
|
||||||
|
|
||||||
widget.mesh = null;
|
|
||||||
widget.points = null;
|
|
||||||
widget.loadVertices(widget.vertices);
|
|
||||||
widget._rotate(rotation,0,0,true);
|
|
||||||
widget.center(false, true);
|
|
||||||
widget.getBoundingBox(true);
|
|
||||||
widget.belt = { xpos, ypos };
|
|
||||||
}
|
}
|
||||||
|
send.done({});
|
||||||
|
},
|
||||||
|
|
||||||
|
unrotate: function(data, send) {
|
||||||
|
let { settings } = data;
|
||||||
|
if (!settings.device.bedBelt) {
|
||||||
|
return send.done({});
|
||||||
|
}
|
||||||
|
let rotation = (Math.PI / 180) * 45;
|
||||||
|
for (let group of Object.values(wgroup)) {
|
||||||
|
let widget = group[0];
|
||||||
|
widget.groupBounds();
|
||||||
|
widget.rotate(-rotation,0,0,true);
|
||||||
|
let { dy, dz } = widget.track.center;
|
||||||
|
widget.groupBounds();
|
||||||
|
let { xpos, ypos } = widget.belt;
|
||||||
|
widget.rotinfo = { angle: 45, dy, dz, xpos, ypos };
|
||||||
|
for (let others of group.slice(1)) {
|
||||||
|
others.rotinfo = widget.rotinfo;
|
||||||
|
}
|
||||||
|
send.data({group: group.id, rotinfo: widget.rotinfo});
|
||||||
|
}
|
||||||
|
send.done({});
|
||||||
|
},
|
||||||
|
|
||||||
|
slice: function(data, send) {
|
||||||
|
send.data({update:0.001, updateStatus:"slicing"});
|
||||||
|
|
||||||
|
let settings = data.settings,
|
||||||
|
widget = wcache[data.id],
|
||||||
|
last = time(),
|
||||||
|
now;
|
||||||
|
|
||||||
widget.slice(settings, function(error) {
|
widget.slice(settings, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
@ -113,19 +179,7 @@ KIRI.worker = {
|
||||||
send.data({index: index, slice: slice.encode(state)}, state.zeros);
|
send.data({index: index, slice: slice.encode(state)}, state.zeros);
|
||||||
})
|
})
|
||||||
send.data({send_end: time()});
|
send.data({send_end: time()});
|
||||||
// unrotate and send delta coordinates
|
|
||||||
if (rotation) {
|
|
||||||
widget.setPoints(null);
|
|
||||||
widget._rotate(-rotation,0,0,true);
|
|
||||||
let wbb = widget.getBoundingBox(true);
|
|
||||||
widget.center(false, true);
|
|
||||||
let dy = (wbb.max.y + wbb.min.y)/2;
|
|
||||||
let dz = wbb.min.z;
|
|
||||||
widget.rotinfo = { angle: 45, dy, dz, xpos, ypos };
|
|
||||||
send.data({ rotinfo: widget.rotinfo });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send.done({done: true});
|
send.done({done: true});
|
||||||
}, function(update, msg) {
|
}, function(update, msg) {
|
||||||
now = time();
|
now = time();
|
||||||
|
|
@ -134,16 +188,11 @@ KIRI.worker = {
|
||||||
send.data({update: (0.05 + update * 0.95), updateStatus: msg});
|
send.data({update: (0.05 + update * 0.95), updateStatus: msg});
|
||||||
last = now;
|
last = now;
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
send.data({error: error.toString()});
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
prepare: function(data, send) {
|
prepare: function(data, send) {
|
||||||
// create widget array from id:widget cache
|
// create widget array from id:widget cache
|
||||||
const widgets = Object.values(cache);
|
const widgets = Object.values(wcache);
|
||||||
|
|
||||||
// let client know we've started
|
// let client know we've started
|
||||||
send.data({update:0.05, updateStatus:"preview"});
|
send.data({update:0.05, updateStatus:"preview"});
|
||||||
|
|
@ -222,7 +271,7 @@ KIRI.worker = {
|
||||||
z: origin.z
|
z: origin.z
|
||||||
};
|
};
|
||||||
const device = settings.device;
|
const device = settings.device;
|
||||||
const print = current.print = KIRI.newPrint(settings, Object.values(cache));
|
const print = current.print = KIRI.newPrint(settings, Object.values(wcache));
|
||||||
const tools = device.extruders;
|
const tools = device.extruders;
|
||||||
const mode = settings.mode;
|
const mode = settings.mode;
|
||||||
const thin = settings.controller.lineType === 'line' || mode !== 'FDM';
|
const thin = settings.controller.lineType === 'line' || mode !== 'FDM';
|
||||||
|
|
@ -248,30 +297,13 @@ KIRI.worker = {
|
||||||
out.point = BASE.newPoint(x,y,z || 0);
|
out.point = BASE.newPoint(x,y,z || 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const print = current.print = KIRI.newPrint(null, Object.values(cache));
|
const print = current.print = KIRI.newPrint(null, Object.values(wcache));
|
||||||
const layers = KIRI.driver.FDM.prepareRender(parsed, progress => {
|
const layers = KIRI.driver.FDM.prepareRender(parsed, progress => {
|
||||||
send.data({ progress });
|
send.data({ progress });
|
||||||
}, { thin: true });
|
}, { thin: true });
|
||||||
send.done({parsed: KIRI.codec.encode(layers)});
|
send.done({parsed: KIRI.codec.encode(layers)});
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function(data, send) {
|
|
||||||
current.snap = null;
|
|
||||||
current.print = null;
|
|
||||||
if (!data.id) {
|
|
||||||
cache = {};
|
|
||||||
send.done({ clear: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let had = cache[data.id] !== undefined;
|
|
||||||
delete cache[data.id];
|
|
||||||
send.done({
|
|
||||||
id: data.id,
|
|
||||||
had: had,
|
|
||||||
has: cache[data.id] !== undefined
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
config: function(data, send) {
|
config: function(data, send) {
|
||||||
const update = {};
|
const update = {};
|
||||||
if (data.base) {
|
if (data.base) {
|
||||||
|
|
@ -383,11 +415,11 @@ KIRI.worker = {
|
||||||
let p3 = (x - 0) * height + (y - 0);
|
let p3 = (x - 0) * height + (y - 0);
|
||||||
let p4 = (x - 1) * height + (y - 1);
|
let p4 = (x - 1) * height + (y - 1);
|
||||||
faces[ii++] = p1;
|
faces[ii++] = p1;
|
||||||
faces[ii++] = p2;
|
|
||||||
faces[ii++] = p3;
|
faces[ii++] = p3;
|
||||||
faces[ii++] = p1;
|
|
||||||
faces[ii++] = p4;
|
|
||||||
faces[ii++] = p2;
|
faces[ii++] = p2;
|
||||||
|
faces[ii++] = p1;
|
||||||
|
faces[ii++] = p2;
|
||||||
|
faces[ii++] = p4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send.data({progress: x / width});
|
send.data({progress: x / width});
|
||||||
|
|
@ -504,6 +536,24 @@ KIRI.worker = {
|
||||||
// send.done({done: {verts, faces, bigv, vi, ii}}, [ bigv.buffer ]);
|
// send.done({done: {verts, faces, bigv, vi, ii}}, [ bigv.buffer ]);
|
||||||
send.done({done: {bigv}}, [ bigv.buffer ]);
|
send.done({done: {bigv}}, [ bigv.buffer ]);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
zip: function(data, send) {
|
||||||
|
let { files } = data;
|
||||||
|
let zip = new JSZip();
|
||||||
|
for (let file of files) {
|
||||||
|
zip.file(file.name, file.data);
|
||||||
|
}
|
||||||
|
zip.generateAsync({
|
||||||
|
type: "uint8array",
|
||||||
|
compression: "DEFLATE",
|
||||||
|
compressionOptions: { level: 3 },
|
||||||
|
streamFiles: true
|
||||||
|
}, progress => {
|
||||||
|
send.data(progress);
|
||||||
|
}).then(output => {
|
||||||
|
send.done(output);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -543,20 +593,26 @@ self.onmessage = function(e) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (run) {
|
if (run) {
|
||||||
let time_xfer = (time_recv - msg.time),
|
try {
|
||||||
output = run(msg.data, send),
|
let time_xfer = (time_recv - msg.time),
|
||||||
time_send = time(),
|
output = run(msg.data, send),
|
||||||
time_proc = time_send - time_recv;
|
time_send = time(),
|
||||||
|
time_proc = time_send - time_recv;
|
||||||
|
|
||||||
if (output) self.postMessage({
|
if (output) self.postMessage({
|
||||||
seq: msg.seq,
|
seq: msg.seq,
|
||||||
task: msg.task,
|
task: msg.task,
|
||||||
time_send: time_xfer,
|
time_send: time_xfer,
|
||||||
time_proc: time_proc,
|
time_proc: time_proc,
|
||||||
// replaced on reply side
|
// replaced on reply side
|
||||||
time_recv: time(),
|
time_recv: time(),
|
||||||
data: output
|
data: output
|
||||||
});
|
});
|
||||||
|
} catch (wrkerr) {
|
||||||
|
// console.log(wrkerr);
|
||||||
|
console.trace(wrkerr.stack);
|
||||||
|
send.done({error: wrkerr.toString()});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log({kiri_msg:e});
|
console.log({kiri_msg:e});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
let terms = {
|
let terms = {
|
||||||
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
|
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
|
||||||
LICENSE: "See the license.md file included with the source distribution",
|
LICENSE: "See the license.md file included with the source distribution",
|
||||||
VERSION: "2.6.D8"
|
VERSION: "2.8.D1"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof(module) === 'object') {
|
if (typeof(module) === 'object') {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@
|
||||||
API = api;
|
API = api;
|
||||||
|
|
||||||
// wire up animate button in ui
|
// wire up animate button in ui
|
||||||
api.function.animate = () => {
|
api.event.on("function.animate", (mode) => {
|
||||||
|
if (isAnimate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isCamMode && !camStock) {
|
if (isCamMode && !camStock) {
|
||||||
return api.show.alert("animation requires stock to be enabled");
|
return api.show.alert("animation requires stock to be enabled");
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +53,7 @@
|
||||||
animate();
|
animate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
api.event.on("mode.set", (mode) => {
|
api.event.on("mode.set", (mode) => {
|
||||||
isCamMode = mode === 'CAM';
|
isCamMode = mode === 'CAM';
|
||||||
|
|
@ -61,11 +64,11 @@
|
||||||
if (!isCamMode) {
|
if (!isCamMode) {
|
||||||
func.tabClear();
|
func.tabClear();
|
||||||
func.traceDone();
|
func.traceDone();
|
||||||
UI.label.slice.innerText = 'slice';
|
UI.label.slice.innerText = LANG.slice;
|
||||||
UI.label.preview.innerText = 'preview';
|
UI.label.preview.innerText = LANG.preview;
|
||||||
UI.label.export.innerText = 'export';
|
UI.label.export.innerText = LANG.export;
|
||||||
} else {
|
} else {
|
||||||
UI.label.slice.innerText = 'start';
|
UI.label.slice.innerText = LANG.start;
|
||||||
}
|
}
|
||||||
// do not persist traces across page reloads
|
// do not persist traces across page reloads
|
||||||
func.traceClear();
|
func.traceClear();
|
||||||
|
|
@ -534,7 +537,7 @@
|
||||||
KIRI.api.widgets.opacity(0.8);
|
KIRI.api.widgets.opacity(0.8);
|
||||||
KIRI.api.widgets.for(widget => {
|
KIRI.api.widgets.for(widget => {
|
||||||
if (ids.indexOf(widget.id) >= 0) {
|
if (ids.indexOf(widget.id) >= 0) {
|
||||||
unselectTraces(widget);
|
unselectTraces(widget, true);
|
||||||
widget.trace_stack = null;
|
widget.trace_stack = null;
|
||||||
}
|
}
|
||||||
if (widget.trace_stack) {
|
if (widget.trace_stack) {
|
||||||
|
|
@ -578,7 +581,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}, poppedRec.single);
|
||||||
api.feature.hover = true;
|
api.feature.hover = true;
|
||||||
api.feature.hoverAdds = true;
|
api.feature.hoverAdds = true;
|
||||||
func.hover = func.traceHover;
|
func.hover = func.traceHover;
|
||||||
|
|
@ -831,7 +834,7 @@
|
||||||
dogbones: UC.newBoolean(LANG.co_dogb_s, undefined, {title:LANG.co_dogb_l, show:(op) => { return !op.inputs.wide.checked }}),
|
dogbones: UC.newBoolean(LANG.co_dogb_s, undefined, {title:LANG.co_dogb_l, show:(op) => { return !op.inputs.wide.checked }}),
|
||||||
inside: UC.newBoolean(LANG.co_olin_s, undefined, {title:LANG.co_olin_l, show:(op) => { return !op.inputs.outside.checked }}),
|
inside: UC.newBoolean(LANG.co_olin_s, undefined, {title:LANG.co_olin_l, show:(op) => { return !op.inputs.outside.checked }}),
|
||||||
outside: UC.newBoolean(LANG.co_olot_s, undefined, {title:LANG.co_olot_l, show:(op) => { return !op.inputs.inside.checked }}),
|
outside: UC.newBoolean(LANG.co_olot_s, undefined, {title:LANG.co_olot_l, show:(op) => { return !op.inputs.inside.checked }}),
|
||||||
omitthru: UC.newBoolean(LANG.co_omit_s, undefined, {title:LANG.co_omit_l, show:(op) => { return op.inputs.outside.checked }}),
|
omitthru: UC.newBoolean(LANG.co_omit_s, undefined, {title:LANG.co_omit_l, xshow:(op) => { return op.inputs.outside.checked }}),
|
||||||
wide: UC.newBoolean(LANG.co_wide_s, undefined, {title:LANG.co_wide_l, show:(op) => { return !op.inputs.inside.checked }})
|
wide: UC.newBoolean(LANG.co_wide_s, undefined, {title:LANG.co_wide_l, show:(op) => { return !op.inputs.inside.checked }})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -867,7 +870,8 @@
|
||||||
step: 'camTraceOver',
|
step: 'camTraceOver',
|
||||||
down: 'camTraceDown',
|
down: 'camTraceDown',
|
||||||
rate: 'camTraceSpeed',
|
rate: 'camTraceSpeed',
|
||||||
plunge: 'camTracePlunge'
|
plunge: 'camTracePlunge',
|
||||||
|
single: 'camTraceLines',
|
||||||
}).inputs = {
|
}).inputs = {
|
||||||
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
tool: UC.newSelect(LANG.cc_tool, {}, "tools"),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
|
|
@ -879,6 +883,7 @@
|
||||||
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}),
|
rate: UC.newInput(LANG.cc_feed_s, {title:LANG.cc_feed_l, convert:UC.toInt, units:true}),
|
||||||
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}),
|
plunge: UC.newInput(LANG.cc_plng_s, {title:LANG.cc_plng_l, convert:UC.toInt, units:true}),
|
||||||
sep: UC.newBlank({class:"pop-sep"}),
|
sep: UC.newBlank({class:"pop-sep"}),
|
||||||
|
single: UC.newBoolean(LANG.cc_sngl_s, undefined, {title:LANG.cc_sngl_l}),
|
||||||
select: UC.newRow([
|
select: UC.newRow([
|
||||||
UC.newButton(undefined, func.traceAdd, {icon:'<i class="fas fa-plus"></i>'}),
|
UC.newButton(undefined, func.traceAdd, {icon:'<i class="fas fa-plus"></i>'}),
|
||||||
UC.newButton(undefined, func.traceDone, {icon:'<i class="fas fa-check"></i>'}),
|
UC.newButton(undefined, func.traceDone, {icon:'<i class="fas fa-check"></i>'}),
|
||||||
|
|
@ -1044,11 +1049,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function unselectTraces(widget) {
|
function unselectTraces(widget, skip) {
|
||||||
if (widget.trace_stack) {
|
if (widget.trace_stack) {
|
||||||
widget.trace_stack.meshes.forEach(mesh => {
|
widget.trace_stack.meshes.forEach(mesh => {
|
||||||
if (mesh.selected) {
|
if (mesh.selected) {
|
||||||
func.traceToggle(mesh);
|
func.traceToggle(mesh, skip);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
KIRI.loader.push(function(API) {
|
KIRI.loader.push(function(API) {
|
||||||
|
|
||||||
if (KIRI.client)
|
if (KIRI.client)
|
||||||
CAM.traces = function(ondone) {
|
CAM.traces = function(ondone, single) {
|
||||||
KIRI.client.sync();
|
KIRI.client.sync();
|
||||||
let settings = API.conf.get();
|
let settings = API.conf.get();
|
||||||
let widgets = API.widgets.map();
|
let widgets = API.widgets.map();
|
||||||
KIRI.client.send("cam_traces", { settings }, output => {
|
KIRI.client.send("cam_traces", { settings, single }, output => {
|
||||||
let ids = [];
|
let ids = [];
|
||||||
KIRI.codec.decode(output).forEach(rec => {
|
KIRI.codec.decode(output).forEach(rec => {
|
||||||
ids.push(rec.id);
|
ids.push(rec.id);
|
||||||
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
if (KIRI.worker)
|
if (KIRI.worker)
|
||||||
KIRI.worker.cam_traces = function(data, send) {
|
KIRI.worker.cam_traces = function(data, send) {
|
||||||
const { settings } = data;
|
const { settings, single } = data;
|
||||||
const widgets = Object.values(cache);
|
const widgets = Object.values(wcache);
|
||||||
const fresh = widgets.filter(widget => CAM.traces(settings, widget));
|
const fresh = widgets.filter(widget => CAM.traces(settings, widget, single));
|
||||||
send.done(KIRI.codec.encode(fresh.map(widget => { return {
|
send.done(KIRI.codec.encode(fresh.map(widget => { return {
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
traces: widget.traces,
|
traces: widget.traces,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
gcodes = settings.device || {},
|
gcodes = settings.device || {},
|
||||||
tools = settings.tools,
|
tools = settings.tools,
|
||||||
space = gcodes.gcodeSpace ? ' ' : '',
|
space = gcodes.gcodeSpace ? ' ' : '',
|
||||||
|
isRML = device.gcodeFExt.toLowerCase() === 'rml',
|
||||||
stripComments = gcodes.gcodeStrip || false,
|
stripComments = gcodes.gcodeStrip || false,
|
||||||
cmdToolChange = gcodes.gcodeChange || [ "M6 T{tool}" ],
|
cmdToolChange = gcodes.gcodeChange || [ "M6 T{tool}" ],
|
||||||
cmdSpindle = gcodes.gcodeSpindle || [ "M3 S{speed}" ],
|
cmdSpindle = gcodes.gcodeSpindle || [ "M3 S{speed}" ],
|
||||||
|
|
@ -88,7 +89,7 @@
|
||||||
if (!array) return;
|
if (!array) return;
|
||||||
for (i=0; i<array.length; i++) {
|
for (i=0; i<array.length; i++) {
|
||||||
line = print.constReplace(array[i], consts);
|
line = print.constReplace(array[i], consts);
|
||||||
if (stripComments && (cidx = line.indexOf(";")) >= 0) {
|
if (!isRML && stripComments && (cidx = line.indexOf(";")) >= 0) {
|
||||||
line = line.substring(0, cidx).trim();
|
line = line.substring(0, cidx).trim();
|
||||||
if (line.length === 0) continue;
|
if (line.length === 0) continue;
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +180,8 @@
|
||||||
dz = newpos.z - pos.z,
|
dz = newpos.z - pos.z,
|
||||||
maxf = dz ? maxZd : maxXYd,
|
maxf = dz ? maxZd : maxXYd,
|
||||||
feed = Math.min(speed || maxf, maxf),
|
feed = Math.min(speed || maxf, maxf),
|
||||||
dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
dist = Math.sqrt(dx * dx + dy * dy + dz * dz),
|
||||||
|
newFeed = feed && feed !== pos.f;
|
||||||
|
|
||||||
// drop dup points (all deltas are 0)
|
// drop dup points (all deltas are 0)
|
||||||
if (!(dx || dy || dz)) {
|
if (!(dx || dy || dz)) {
|
||||||
|
|
@ -204,11 +206,23 @@
|
||||||
runbox.max.z = Math.max(runbox.max.z, pos.z);
|
runbox.max.z = Math.max(runbox.max.z, pos.z);
|
||||||
nl.append(space).append("Z").append(add0(pos.z * factor));
|
nl.append(space).append("Z").append(add0(pos.z * factor));
|
||||||
}
|
}
|
||||||
if (feed && feed !== pos.f) {
|
if (newFeed) {
|
||||||
pos.f = feed;
|
pos.f = feed;
|
||||||
nl.append(space).append("F").append(add0(feed * factor, true));
|
nl.append(space).append("F").append(add0(feed * factor, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// temp hack to support RML1 dialect from a file extensions trigger
|
||||||
|
if (isRML) {
|
||||||
|
if (speed) {
|
||||||
|
if (newFeed) {
|
||||||
|
append(`VS${feed};`);
|
||||||
|
}
|
||||||
|
nl = [ "Z", add0(pos.x * factor), ",", add0(pos.y * factor), ",", add0(pos.z * factor), ";" ];
|
||||||
|
} else {
|
||||||
|
nl = [ "PU", add0(pos.x * factor), ",", add0(pos.y * factor), ";" ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update time calculation
|
// update time calculation
|
||||||
time += (dist / (pos.f || 1000)) * 60;
|
time += (dist / (pos.f || 1000)) * 60;
|
||||||
|
|
||||||
|
|
@ -279,7 +293,10 @@
|
||||||
if (layerout.spindle && layerout.spindle !== spindle) {
|
if (layerout.spindle && layerout.spindle !== spindle) {
|
||||||
spindle = layerout.spindle;
|
spindle = layerout.spindle;
|
||||||
if (spindle > 0) {
|
if (spindle > 0) {
|
||||||
filterEmit(cmdSpindle, {speed: Math.abs(spindle)});
|
let speed = Math.abs(spindle);
|
||||||
|
filterEmit(cmdSpindle, {
|
||||||
|
speed, spindle: speed, rpm: speed
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
append("M4");
|
append("M4");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,10 @@
|
||||||
let { tshadow, shadowTop, ztOff, zBottom, zMax } = state;
|
let { tshadow, shadowTop, ztOff, zBottom, zMax } = state;
|
||||||
let { process, stock } = settings;
|
let { process, stock } = settings;
|
||||||
|
|
||||||
|
if (op.down <= 0) {
|
||||||
|
throw `invalid step down "${op.down}"`;
|
||||||
|
}
|
||||||
|
|
||||||
let roughIn = op.inside;
|
let roughIn = op.inside;
|
||||||
let roughTop = op.top;
|
let roughTop = op.top;
|
||||||
let roughDown = op.down;
|
let roughDown = op.down;
|
||||||
|
|
@ -219,7 +223,7 @@
|
||||||
});
|
});
|
||||||
shadow = POLY.nest(shadow);
|
shadow = POLY.nest(shadow);
|
||||||
|
|
||||||
// expand shadow by half tool diameter + stock to leave
|
// shell = shadow expanded by half tool diameter + leave stock
|
||||||
const sadd = roughIn ? toolDiam / 2 : toolDiam / 2;
|
const sadd = roughIn ? toolDiam / 2 : toolDiam / 2;
|
||||||
const shell = POLY.offset(shadow, sadd + roughLeave);
|
const shell = POLY.offset(shadow, sadd + roughLeave);
|
||||||
|
|
||||||
|
|
@ -262,7 +266,7 @@
|
||||||
|
|
||||||
if (!offset) return;
|
if (!offset) return;
|
||||||
|
|
||||||
if (process.camStockClipTo) {
|
if (process.camStockClipTo && stock.x && stock.y && stock.center) {
|
||||||
let rect = newPolygon().centerRectangle(stock.center, stock.x, stock.y);
|
let rect = newPolygon().centerRectangle(stock.center, stock.x, stock.y);
|
||||||
offset = cutPolys([rect], offset, slice.z, true);
|
offset = cutPolys([rect], offset, slice.z, true);
|
||||||
}
|
}
|
||||||
|
|
@ -270,10 +274,12 @@
|
||||||
// elimate double inset on inners
|
// elimate double inset on inners
|
||||||
offset.forEach(op => {
|
offset.forEach(op => {
|
||||||
if (op.inner) {
|
if (op.inner) {
|
||||||
let operim = op.perimeter();
|
let pv1 = op.perimeter();
|
||||||
let newinner = [];
|
let newinner = [];
|
||||||
op.inner.forEach(oi => {
|
op.inner.forEach(oi => {
|
||||||
if (Math.abs(oi.perimeter() - operim) > 0.01) {
|
let pv2 = oi.perimeter();
|
||||||
|
let pct = pv1 > pv2 ? pv2/pv1 : pv1/pv2;
|
||||||
|
if (pct < 0.98) {
|
||||||
newinner.push(oi);
|
newinner.push(oi);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -307,8 +313,10 @@
|
||||||
let { polyEmit, poly2polyEmit, depthRoughPath } = ops;
|
let { polyEmit, poly2polyEmit, depthRoughPath } = ops;
|
||||||
let { camOut, newLayer, printPoint } = ops;
|
let { camOut, newLayer, printPoint } = ops;
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
let { process } = settings;
|
let { process, controller } = settings;
|
||||||
|
|
||||||
|
let danger = controller.danger;
|
||||||
|
let easeDown = process.camEaseDown;
|
||||||
let cutdir = process.camConventional;
|
let cutdir = process.camConventional;
|
||||||
let depthFirst = process.camDepthFirst;
|
let depthFirst = process.camDepthFirst;
|
||||||
let depthData = [];
|
let depthData = [];
|
||||||
|
|
@ -368,7 +376,9 @@
|
||||||
// return POLY.nest(level.filter(poly => poly.depth === 0));
|
// return POLY.nest(level.filter(poly => poly.depth === 0));
|
||||||
return POLY.nest(level.filter(poly => poly.depth === 0).clone());
|
return POLY.nest(level.filter(poly => poly.depth === 0).clone());
|
||||||
});
|
});
|
||||||
printPoint = depthRoughPath(printPoint, 0, depthData, tops, polyEmit);
|
// experimental start of ease down
|
||||||
|
let ease = danger && op.down && easeDown ? op.down : 0;
|
||||||
|
printPoint = depthRoughPath(printPoint, 0, depthData, tops, polyEmit, false, ease);
|
||||||
// printPoint = depthRoughPath(printPoint, 0, depthData, tops, (poly, index, count, start) => {
|
// printPoint = depthRoughPath(printPoint, 0, depthData, tops, (poly, index, count, start) => {
|
||||||
// console.log({z: poly.getZ(), i: poly.id, index, poly});
|
// console.log({z: poly.getZ(), i: poly.id, index, poly});
|
||||||
// return polyEmit(poly, index, count, start);
|
// return polyEmit(poly, index, count, start);
|
||||||
|
|
@ -390,6 +400,10 @@
|
||||||
let { updateToolDiams, zThru, zBottom, shadowTop, tabs, cutTabs, cutPolys } = state;
|
let { updateToolDiams, zThru, zBottom, shadowTop, tabs, cutTabs, cutPolys } = state;
|
||||||
let { process, stock } = settings;
|
let { process, stock } = settings;
|
||||||
|
|
||||||
|
if (op.down <= 0) {
|
||||||
|
throw `invalid step down "${op.down}"`;
|
||||||
|
}
|
||||||
|
|
||||||
let toolDiam = this.toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
|
let toolDiam = this.toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
|
||||||
updateToolDiams(toolDiam);
|
updateToolDiams(toolDiam);
|
||||||
|
|
||||||
|
|
@ -405,7 +419,7 @@
|
||||||
indices = indices.appendAll(flats).sort((a,b) => b-a);
|
indices = indices.appendAll(flats).sort((a,b) => b-a);
|
||||||
// console.log('indices', ...indices, {zBottom, slicer});
|
// console.log('indices', ...indices, {zBottom, slicer});
|
||||||
if (op.outside && !op.inside) {
|
if (op.outside && !op.inside) {
|
||||||
console.log({outline_bypass: indices, down: op.down});
|
// console.log({outline_bypass: indices, down: op.down});
|
||||||
indices.forEach((ind,i) => {
|
indices.forEach((ind,i) => {
|
||||||
if (flats.indexOf(ind) >= 0) {
|
if (flats.indexOf(ind) >= 0) {
|
||||||
// exclude flats
|
// exclude flats
|
||||||
|
|
@ -509,7 +523,7 @@
|
||||||
CAM.addDogbones(offset, toolDiam / 5);
|
CAM.addDogbones(offset, toolDiam / 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.camStockClipTo) {
|
if (process.camStockClipTo && stock.x && stock.y && stock.center) {
|
||||||
let rect = newPolygon().centerRectangle(stock.center, stock.x, stock.y);
|
let rect = newPolygon().centerRectangle(stock.center, stock.x, stock.y);
|
||||||
offset = cutPolys([rect], offset, slice.z, true);
|
offset = cutPolys([rect], offset, slice.z, true);
|
||||||
}
|
}
|
||||||
|
|
@ -534,8 +548,10 @@
|
||||||
let { polyEmit, poly2polyEmit, depthOutlinePath } = ops;
|
let { polyEmit, poly2polyEmit, depthOutlinePath } = ops;
|
||||||
let { camOut, newLayer, printPoint } = ops;
|
let { camOut, newLayer, printPoint } = ops;
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
let { process } = settings;
|
let { process, controller } = settings;
|
||||||
|
|
||||||
|
let danger = controller.danger;
|
||||||
|
let easeDown = process.camEaseDown;
|
||||||
let toolDiam = this.toolDiam;
|
let toolDiam = this.toolDiam;
|
||||||
let cutdir = process.camConventional;
|
let cutdir = process.camConventional;
|
||||||
let depthFirst = process.camDepthFirst;
|
let depthFirst = process.camDepthFirst;
|
||||||
|
|
@ -584,8 +600,10 @@
|
||||||
printPoint = flatLevels[0]
|
printPoint = flatLevels[0]
|
||||||
.sort((a,b) => { return a.area() - b.area() })[0]
|
.sort((a,b) => { return a.area() - b.area() })[0]
|
||||||
.average();
|
.average();
|
||||||
printPoint = depthOutlinePath(printPoint, 0, flatLevels, toolDiam, polyEmit, false);
|
// experimental start of ease down
|
||||||
printPoint = depthOutlinePath(printPoint, 0, flatLevels, toolDiam, polyEmit, true);
|
let ease = danger && op.down && easeDown ? op.down : 0;
|
||||||
|
printPoint = depthOutlinePath(printPoint, 0, flatLevels, toolDiam, polyEmit, false, ease);
|
||||||
|
printPoint = depthOutlinePath(printPoint, 0, flatLevels, toolDiam, polyEmit, true, ease);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,7 +647,8 @@
|
||||||
let { settings, widget } = state;
|
let { settings, widget } = state;
|
||||||
let { process } = settings;
|
let { process } = settings;
|
||||||
|
|
||||||
let toolDiam = this.toolDiam;
|
let toolDiam = this.toolDiam = new CAM.Tool(settings, op.tool).fluteDiameter();
|
||||||
|
let stepover = toolDiam * op.step * 2;
|
||||||
let cutdir = process.camConventional;
|
let cutdir = process.camConventional;
|
||||||
let depthFirst = process.camDepthFirst;
|
let depthFirst = process.camDepthFirst;
|
||||||
let depthData = [];
|
let depthData = [];
|
||||||
|
|
@ -656,7 +675,7 @@
|
||||||
poly.reverse();
|
poly.reverse();
|
||||||
}
|
}
|
||||||
poly.forEachPoint(function(point, pidx) {
|
poly.forEachPoint(function(point, pidx) {
|
||||||
camOut(point.clone(), pidx > 0);
|
camOut(point.clone(), pidx > 0, stepover);
|
||||||
}, false);
|
}, false);
|
||||||
});
|
});
|
||||||
newLayer();
|
newLayer();
|
||||||
|
|
@ -670,7 +689,7 @@
|
||||||
poly.reverse();
|
poly.reverse();
|
||||||
}
|
}
|
||||||
poly.forEachPoint(function(point, pidx) {
|
poly.forEachPoint(function(point, pidx) {
|
||||||
camOut(point.clone(), pidx > 0);
|
camOut(point.clone(), pidx > 0, stepover);
|
||||||
}, false);
|
}, false);
|
||||||
newLayer();
|
newLayer();
|
||||||
return lastPoint();
|
return lastPoint();
|
||||||
|
|
@ -700,7 +719,8 @@
|
||||||
let toolOver = toolDiam * op.step;
|
let toolOver = toolDiam * op.step;
|
||||||
let cutdir = process.camConventional;
|
let cutdir = process.camConventional;
|
||||||
let polys = [];
|
let polys = [];
|
||||||
let stockRect = newPolygon().centerRectangle(stock.center, stock.x, stock.y);
|
let stockRect = stock.center && stock.x && stock.y ?
|
||||||
|
newPolygon().centerRectangle(stock.center, stock.x, stock.y) : undefined;
|
||||||
updateToolDiams(toolDiam);
|
updateToolDiams(toolDiam);
|
||||||
if (tabs) {
|
if (tabs) {
|
||||||
tabs.forEach(tab => {
|
tabs.forEach(tab => {
|
||||||
|
|
@ -727,7 +747,7 @@
|
||||||
} else {
|
} else {
|
||||||
slice.camLines = [ poly ];
|
slice.camLines = [ poly ];
|
||||||
}
|
}
|
||||||
if (process.camStockClipTo) {
|
if (process.camStockClipTo && stockRect) {
|
||||||
slice.camLines = cutPolys([stockRect], slice.camLines, z, true);
|
slice.camLines = cutPolys([stockRect], slice.camLines, z, true);
|
||||||
}
|
}
|
||||||
slice.output()
|
slice.output()
|
||||||
|
|
@ -771,19 +791,22 @@
|
||||||
case "inside": offdist = -toolDiam / 2; break;
|
case "inside": offdist = -toolDiam / 2; break;
|
||||||
}
|
}
|
||||||
if (offdist) {
|
if (offdist) {
|
||||||
let pnew = POLY.offset([poly], offdist)[0];
|
let pnew = POLY.offset([poly], offdist);
|
||||||
if (pnew) {
|
if (pnew) {
|
||||||
poly = pnew.setZ(poly.getZ());
|
poly = POLY.setZ(pnew, poly.getZ());
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
poly = [ poly ];
|
||||||
}
|
}
|
||||||
|
for (let pi of poly)
|
||||||
if (down) {
|
if (down) {
|
||||||
for (let z of BASE.util.lerp(zMax, poly.getZ(), down)) {
|
for (let z of BASE.util.lerp(zMax, pi.getZ(), down)) {
|
||||||
followZ(poly.clone().setZ(z));
|
followZ(pi.clone().setZ(z));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
followZ(poly);
|
followZ(pi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -904,6 +927,7 @@
|
||||||
updateToolDiams(tool.fluteDiameter());
|
updateToolDiams(tool.fluteDiameter());
|
||||||
|
|
||||||
let { stock } = settings,
|
let { stock } = settings,
|
||||||
|
tz = widget.track.pos.z,
|
||||||
lx = bounds.min.x,
|
lx = bounds.min.x,
|
||||||
hx = bounds.max.x,
|
hx = bounds.max.x,
|
||||||
ly = bounds.min.y,
|
ly = bounds.min.y,
|
||||||
|
|
@ -915,7 +939,10 @@
|
||||||
dx = (stock.x - (hx - lx)) / 4,
|
dx = (stock.x - (hx - lx)) / 4,
|
||||||
dy = (stock.y - (hy - ly)) / 4,
|
dy = (stock.y - (hy - ly)) / 4,
|
||||||
dz = stock.z,
|
dz = stock.z,
|
||||||
points = [];
|
points = [],
|
||||||
|
wo = stock.z - bounds.max.z,
|
||||||
|
z1 = bounds.max.z + wo + tz,
|
||||||
|
z2 = tz - mz;
|
||||||
|
|
||||||
if (!(stock.x && stock.y && stock.z)) {
|
if (!(stock.x && stock.y && stock.z)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -969,7 +996,7 @@
|
||||||
tv = -tv;
|
tv = -tv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let z of BASE.util.lerp(zMax, -zThru, op.down)) {
|
for (let z of BASE.util.lerp(z1, z2, op.down)) {
|
||||||
let slice = newSlice(z);
|
let slice = newSlice(z);
|
||||||
sliceAll.push(slice);
|
sliceAll.push(slice);
|
||||||
sliceOut.push(slice);
|
sliceOut.push(slice);
|
||||||
|
|
@ -1005,8 +1032,8 @@
|
||||||
let slice = newSlice(0,null), polys = [];
|
let slice = newSlice(0,null), polys = [];
|
||||||
points.forEach(point => {
|
points.forEach(point => {
|
||||||
polys.push(newPolygon()
|
polys.push(newPolygon()
|
||||||
.append(point.clone().setZ(bounds.max.z))
|
.append(point.clone().setZ(z1))
|
||||||
.append(point.clone().setZ(bounds.max.z - stock.z - mz)));
|
.append(point.clone().setZ(z2)));
|
||||||
});
|
});
|
||||||
slice.camLines = polys;
|
slice.camLines = polys;
|
||||||
slice.output()
|
slice.output()
|
||||||
|
|
@ -1096,7 +1123,7 @@
|
||||||
let terrain = slicer.slice(tzindex, { each: (data, index, total) => {
|
let terrain = slicer.slice(tzindex, { each: (data, index, total) => {
|
||||||
tshadow = POLY.union(tshadow.slice().appendAll(data.tops), 0.01, true);
|
tshadow = POLY.union(tshadow.slice().appendAll(data.tops), 0.01, true);
|
||||||
tslices.push(data.slice);
|
tslices.push(data.slice);
|
||||||
if (true) {
|
if (false) {
|
||||||
const slice = data.slice;
|
const slice = data.slice;
|
||||||
sliceAll.push(slice);
|
sliceAll.push(slice);
|
||||||
slice.output()
|
slice.output()
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
boundsz = bounds.max.z + ztOff,
|
boundsz = bounds.max.z + ztOff,
|
||||||
zadd = hasStock ? stock.z - boundsz : alignTop ? outerz - boundsz : 0,
|
zadd = hasStock ? stock.z - boundsz : alignTop ? outerz - boundsz : 0,
|
||||||
zmax = outerz + zclear,
|
zmax = outerz + zclear,
|
||||||
wmpos = widget.mesh.position,
|
wmpos = widget.track.pos,
|
||||||
wmx = wmpos.x,
|
wmx = wmpos.x,
|
||||||
wmy = wmpos.y,
|
wmy = wmpos.y,
|
||||||
originx = startCenter ? 0 : hasStock ? -stock.x / 2 : bounds.min.x,
|
originx = startCenter ? 0 : hasStock ? -stock.x / 2 : bounds.min.x,
|
||||||
|
|
@ -231,7 +231,7 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function camOut(point, cut) {
|
function camOut(point, cut, moveLen = toolDiamMove) {
|
||||||
point = point.clone();
|
point = point.clone();
|
||||||
point.x += wmx;
|
point.x += wmx;
|
||||||
point.y += wmy;
|
point.y += wmy;
|
||||||
|
|
@ -264,7 +264,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert short planar moves to cuts in some cases
|
// convert short planar moves to cuts in some cases
|
||||||
if (isMove && deltaXY <= toolDiamMove) {
|
if (isMove && deltaXY <= moveLen) {
|
||||||
let iscontour = tolerance > 0;
|
let iscontour = tolerance > 0;
|
||||||
let isflat = absDeltaZ < 0.001;
|
let isflat = absDeltaZ < 0.001;
|
||||||
// restrict this to contouring
|
// restrict this to contouring
|
||||||
|
|
@ -279,7 +279,7 @@
|
||||||
}
|
}
|
||||||
} else if (isMove) {
|
} else if (isMove) {
|
||||||
// for longer moves, check the terrain to see if we need to go up and over
|
// for longer moves, check the terrain to see if we need to go up and over
|
||||||
const bigXY = (deltaXY > toolDiamMove);
|
const bigXY = (deltaXY > moveLen);
|
||||||
const bigZ = (deltaZ > toolDiam/2 && deltaXY > tolerance);
|
const bigZ = (deltaZ > toolDiam/2 && deltaXY > tolerance);
|
||||||
const midZ = (absDeltaZ >= tolerance);
|
const midZ = (absDeltaZ >= tolerance);
|
||||||
if ((bigXY || bigZ) && (isMove || midZ)) {
|
if ((bigXY || bigZ) && (isMove || midZ)) {
|
||||||
|
|
@ -296,11 +296,8 @@
|
||||||
) + ztOff,
|
) + ztOff,
|
||||||
mustGoUp = Math.max(maxz - point.z, maxz - lastPoint.z) >= tolerance,
|
mustGoUp = Math.max(maxz - point.z, maxz - lastPoint.z) >= tolerance,
|
||||||
clearz = maxz;
|
clearz = maxz;
|
||||||
// up if any point between higher than start/outline, go up
|
// up if any point between higher than start/outline, go up first
|
||||||
if (mustGoUp) {
|
if (mustGoUp) {
|
||||||
if (bigXY) {
|
|
||||||
clearz += zclear;
|
|
||||||
}
|
|
||||||
layerPush(lastPoint.clone().setZ(clearz), 0, 0, tool.getNumber());
|
layerPush(lastPoint.clone().setZ(clearz), 0, 0, tool.getNumber());
|
||||||
}
|
}
|
||||||
// move to point above target point
|
// move to point above target point
|
||||||
|
|
@ -414,7 +411,7 @@
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
function depthRoughPath(start, depth, levels, tops, emitter, fit) {
|
function depthRoughPath(start, depth, levels, tops, emitter, fit, ease) {
|
||||||
let level = levels[depth];
|
let level = levels[depth];
|
||||||
if (!level) {
|
if (!level) {
|
||||||
return start;
|
return start;
|
||||||
|
|
@ -424,13 +421,19 @@
|
||||||
fitted.filter(top => !top.level_emit).forEach(top => {
|
fitted.filter(top => !top.level_emit).forEach(top => {
|
||||||
top.level_emit = true;
|
top.level_emit = true;
|
||||||
let inside = level.filter(poly => poly.isInside(top));
|
let inside = level.filter(poly => poly.isInside(top));
|
||||||
|
if (ease) {
|
||||||
|
start.z += ease;
|
||||||
|
}
|
||||||
start = poly2polyEmit(inside, start, emitter, { mark: "emark", perm: true });
|
start = poly2polyEmit(inside, start, emitter, { mark: "emark", perm: true });
|
||||||
start = depthRoughPath(start, depth + 1, levels, tops, emitter, top);
|
if (ease) {
|
||||||
|
start.z += ease;
|
||||||
|
}
|
||||||
|
start = depthRoughPath(start, depth + 1, levels, tops, emitter, top, ease);
|
||||||
});
|
});
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
function depthOutlinePath(start, depth, levels, radius, emitter, clr) {
|
function depthOutlinePath(start, depth, levels, radius, emitter, clr, ease) {
|
||||||
let bottm = depth < levels.length - 1 ? levels[levels.length - 1] : null;
|
let bottm = depth < levels.length - 1 ? levels[levels.length - 1] : null;
|
||||||
let above = levels[depth-1];
|
let above = levels[depth-1];
|
||||||
let level = levels[depth];
|
let level = levels[depth];
|
||||||
|
|
@ -458,8 +461,14 @@
|
||||||
// omit polys that match bottom level polys unless level above is cleared
|
// omit polys that match bottom level polys unless level above is cleared
|
||||||
start = poly2polyEmit(level, start, (poly, index, count, fromPoint) => {
|
start = poly2polyEmit(level, start, (poly, index, count, fromPoint) => {
|
||||||
poly.level_emit = true;
|
poly.level_emit = true;
|
||||||
|
if (ease) {
|
||||||
|
fromPoint.z += ease;
|
||||||
|
}
|
||||||
fromPoint = polyEmit(poly, index, count, fromPoint);
|
fromPoint = polyEmit(poly, index, count, fromPoint);
|
||||||
fromPoint = depthOutlinePath(fromPoint, depth + 1, levels, radius, emitter, clr);
|
if (ease) {
|
||||||
|
fromPoint.z += ease;
|
||||||
|
}
|
||||||
|
fromPoint = depthOutlinePath(fromPoint, depth + 1, levels, radius, emitter, clr, ease);
|
||||||
return fromPoint;
|
return fromPoint;
|
||||||
}, {weight: true});
|
}, {weight: true});
|
||||||
return start;
|
return start;
|
||||||
|
|
@ -479,8 +488,9 @@
|
||||||
* return tool Z clearance height for a line segment movement path
|
* return tool Z clearance height for a line segment movement path
|
||||||
*/
|
*/
|
||||||
function getZClearPath(terrain, x1, y1, x2, y2, z, zadd, off, over) {
|
function getZClearPath(terrain, x1, y1, x2, y2, z, zadd, off, over) {
|
||||||
|
// when terrain skipped, top + pass used
|
||||||
if (terrain > 0) {
|
if (terrain > 0) {
|
||||||
return terrain + zadd + over;
|
return terrain;
|
||||||
}
|
}
|
||||||
let maxz = z;
|
let maxz = z;
|
||||||
let check = [];
|
let check = [];
|
||||||
|
|
|
||||||
|
|
@ -221,8 +221,8 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CAM.traces = function(settings, widget) {
|
CAM.traces = function(settings, widget, single) {
|
||||||
if (widget.traces) {
|
if (widget.traces && widget.trace_single === single) {
|
||||||
// do no work if cached
|
// do no work if cached
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -242,6 +242,13 @@
|
||||||
let traces = [];
|
let traces = [];
|
||||||
// find and trim polys (including open) to shadow
|
// find and trim polys (including open) to shadow
|
||||||
let oneach = (data, index, total) => {
|
let oneach = (data, index, total) => {
|
||||||
|
if (single) {
|
||||||
|
for (let line of data.lines) {
|
||||||
|
if (line.p1.distTo2D(line.p2) > 1) {
|
||||||
|
traces.push(newPolygon().append(line.p1).append(line.p2).setOpen());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
BASE.polygons.flatten(data.tops,null,true).forEach(poly => {
|
BASE.polygons.flatten(data.tops,null,true).forEach(poly => {
|
||||||
poly.inner = null;
|
poly.inner = null;
|
||||||
poly.parent = null;
|
poly.parent = null;
|
||||||
|
|
@ -265,6 +272,7 @@
|
||||||
opts.over = true;
|
opts.over = true;
|
||||||
slicer.slice(indices, opts);
|
slicer.slice(indices, opts);
|
||||||
widget.traces = traces;
|
widget.traces = traces;
|
||||||
|
widget.trace_single = single;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,8 @@
|
||||||
if (curvesOnly && lastP) {
|
if (curvesOnly && lastP) {
|
||||||
// maxangle
|
// maxangle
|
||||||
const dz = Math.abs(lastP.z - z);
|
const dz = Math.abs(lastP.z - z);
|
||||||
const dxy = Math.max(Math.abs(lastP.x - x), Math.abs(lastP.y - y));
|
const dv = contourX ? Math.abs(lastP.x - x) : Math.abs(lastP.y - y);
|
||||||
const angle = Math.atan2(dz, dxy) * RAD2DEG;
|
const angle = Math.atan2(dz, dv) * RAD2DEG;
|
||||||
// if (lastP.z < 0.1) console.log('pp', {dz, dxy, angle});
|
// if (lastP.z < 0.1) console.log('pp', {dz, dxy, angle});
|
||||||
if (angle > maxangle) {
|
if (angle > maxangle) {
|
||||||
lastP = newP;
|
lastP = newP;
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,12 @@
|
||||||
BASE = self.base,
|
BASE = self.base,
|
||||||
UTIL = BASE.util,
|
UTIL = BASE.util,
|
||||||
FDM = KIRI.driver.FDM,
|
FDM = KIRI.driver.FDM,
|
||||||
SPACE, API,
|
SPACE, API, VIEWS, LANG, PROC, UI, UC,
|
||||||
|
nextID = Date.now(),
|
||||||
p1, p2, iw,
|
p1, p2, iw,
|
||||||
lastMode, lastView, lastPillar,
|
lastBox,
|
||||||
|
lastMode, lastView,
|
||||||
|
lastPillar, fromPillar,
|
||||||
isFdmMode = false,
|
isFdmMode = false,
|
||||||
addingSupports = false,
|
addingSupports = false,
|
||||||
alert = [],
|
alert = [],
|
||||||
|
|
@ -18,8 +21,133 @@
|
||||||
func = {};
|
func = {};
|
||||||
|
|
||||||
FDM.init = function(kiri, api) {
|
FDM.init = function(kiri, api) {
|
||||||
|
UI = api.ui;
|
||||||
|
UC = api.uc;
|
||||||
API = api;
|
API = api;
|
||||||
SPACE = api.const.SPACE;
|
SPACE = api.const.SPACE;
|
||||||
|
VIEWS = api.const.VIEWS;
|
||||||
|
LANG = KIRI.lang.current;
|
||||||
|
PROC = Object.keys(kiri.conf.defaults.fdm.p);
|
||||||
|
|
||||||
|
let rangeVars = {
|
||||||
|
// slice
|
||||||
|
"sliceShells": LANG.sl_shel_s,
|
||||||
|
"sliceFillType": LANG.fi_type,
|
||||||
|
"sliceFillWidth": LANG.fi_wdth_s,
|
||||||
|
"sliceFillSparse": LANG.fi_pcnt_s,
|
||||||
|
"sliceSolidMinArea": LANG.ad_msol_s,
|
||||||
|
// prepare
|
||||||
|
"sliceShellOrder": LANG.sl_ordr_s,
|
||||||
|
"sliceFillOverlap": LANG.fi_over_s,
|
||||||
|
"outputFeedrate": LANG.ou_feed_s,
|
||||||
|
"outputFinishrate": LANG.ou_fini_s,
|
||||||
|
"outputShellMult": LANG.ou_shml_s,
|
||||||
|
"outputFillMult": LANG.ou_flml_s,
|
||||||
|
"outputSparseMult": LANG.ou_spml_s,
|
||||||
|
"outputRetractWipe": LANG.ad_wpln_s,
|
||||||
|
"outputShortPoly": LANG.ad_spol_s,
|
||||||
|
"outputMinSpeed": LANG.ad_mins_s,
|
||||||
|
"outputCoastDist": LANG.ad_scst_s,
|
||||||
|
"sliceSupportDensity": LANG.sp_dens_s,
|
||||||
|
"sliceSupportOffset": LANG.sp_offs_s,
|
||||||
|
"sliceLayerStart": LANG.sl_strt_s,
|
||||||
|
// export
|
||||||
|
"zHopDistance": LANG.ad_zhop_s,
|
||||||
|
"arcTolerance": LANG.ad_zhop_s,
|
||||||
|
"antiBacklash": LANG.ad_abkl_s,
|
||||||
|
"outputTemp": LANG.ou_nozl_s,
|
||||||
|
"outputBedTemp": LANG.ou_bedd_s,
|
||||||
|
"outputFanSpeed": LANG.ou_fans_s,
|
||||||
|
"outputRetractDist": LANG.ad_rdst_s,
|
||||||
|
"outputRetractSpeed": LANG.outputRetractSpeed,
|
||||||
|
"outputRetractDwell": LANG.ad_rdwl_s,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let key of Object.keys(rangeVars)) {
|
||||||
|
if (UI[key]) {
|
||||||
|
UI[key].range = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterSynth() {
|
||||||
|
api.widgets.filter((widget) => {
|
||||||
|
if (widget.track.synth) {
|
||||||
|
api.const.SPACE.platform.remove(widget.mesh);
|
||||||
|
kiri.Widget.Groups.remove(widget);
|
||||||
|
}
|
||||||
|
return !widget.track.synth
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateRanges(ranges = []) {
|
||||||
|
UI.rangeGroup.style.display = isFdmMode && ranges && ranges.length ? 'flex' : 'none';
|
||||||
|
let html = [];
|
||||||
|
let bind = [];
|
||||||
|
let now = Date.now();
|
||||||
|
let sorted = ranges.sort((a,b) => b.lo - a.lo);
|
||||||
|
for (let range of sorted) {
|
||||||
|
let id = (now++).toString(36);
|
||||||
|
let rows = Object.entries(range.fields).map(a => `<div><label class="pad">${rangeVars[a[0]]}</label><span></span><label class="val">${a[1]}</label></div>`).join('');
|
||||||
|
let hover = `<div id="hov_${id}" class="range-detail">${rows}</div>`;
|
||||||
|
let info = `<button id="sel_${id}" class="j-center grow">${range.lo} - ${range.hi}</button><button id="del_${id}"><i class="far fa-trash-alt"></i></button>`;
|
||||||
|
html.appendAll([
|
||||||
|
`<div id="rng_${id}" class="range-info">${hover}${info}</div>`
|
||||||
|
]);
|
||||||
|
bind.push({id, range});
|
||||||
|
}
|
||||||
|
UI.rangeGroup.firstElementChild.innerHTML = html.join('');
|
||||||
|
for (let rec of bind) {
|
||||||
|
$(`sel_${rec.id}`).onclick = () => {
|
||||||
|
api.show.layer(rec.range.hi, rec.range.lo);
|
||||||
|
};
|
||||||
|
$(`del_${rec.id}`).onclick = () => {
|
||||||
|
let io = ranges.indexOf(rec.range);
|
||||||
|
ranges.splice(io,1);
|
||||||
|
updateRanges(ranges);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
api.event.on("boolean.click", func.updateSupportButtons = () => {
|
||||||
|
if (!isFdmMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let btn of [
|
||||||
|
UI.ssaGen,
|
||||||
|
UI.ssmAdd,
|
||||||
|
UI.ssmDun,
|
||||||
|
UI.ssmClr
|
||||||
|
]) {
|
||||||
|
btn.disabled = UI.sliceSupportEnable.checked;
|
||||||
|
}
|
||||||
|
if (UI.sliceSupportEnable.checked) {
|
||||||
|
func.sclear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
api.event.on("function.animate", (mode) => {
|
||||||
|
if (!isFdmMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!API.conf.get().controller.danger) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pct = 0;
|
||||||
|
let int = setInterval(function() {
|
||||||
|
if (pct <= 1) {
|
||||||
|
api.const.STACKS.setFraction(pct);
|
||||||
|
pct += 0.05;
|
||||||
|
} else {
|
||||||
|
api.const.STACKS.setFraction(1);
|
||||||
|
clearTimeout(int);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
// let slider = $('top-slider');
|
||||||
|
// slider.style.display = 'flex';
|
||||||
|
// slider.oninput = slider.onchange = (ev) => {
|
||||||
|
// api.const.STACKS.setFraction(parseInt(ev.target.value)/100);
|
||||||
|
// };
|
||||||
|
});
|
||||||
api.event.on("mode.set", mode => {
|
api.event.on("mode.set", mode => {
|
||||||
isFdmMode = mode === 'FDM';
|
isFdmMode = mode === 'FDM';
|
||||||
lastMode = mode;
|
lastMode = mode;
|
||||||
|
|
@ -28,14 +156,36 @@
|
||||||
api.event.on("view.set", view => {
|
api.event.on("view.set", view => {
|
||||||
lastView = view;
|
lastView = view;
|
||||||
updateVisiblity();
|
updateVisiblity();
|
||||||
|
filterSynth();
|
||||||
|
func.sdone();
|
||||||
|
// let ranges = API.conf.get().process.ranges;
|
||||||
|
if (isFdmMode) {
|
||||||
|
if (lastView === VIEWS.SLICE) {
|
||||||
|
for (let key of PROC) {
|
||||||
|
if (UI[key] && !UI[key].range) {
|
||||||
|
UI[key].disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let key of PROC) {
|
||||||
|
if (UI[key]) UI[key].disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// UI.rangeGroup.style.display = ranges && ranges.length ? 'flex' : 'none';
|
||||||
});
|
});
|
||||||
|
api.event.on("range.updates", updateRanges);
|
||||||
api.event.on("settings.load", (settings) => {
|
api.event.on("settings.load", (settings) => {
|
||||||
if (settings.mode !== 'FDM') return;
|
if (settings.mode !== 'FDM') return;
|
||||||
settings.process.outputOriginCenter = (settings.device.originCenter || false);
|
settings.process.outputOriginCenter = (settings.device.originCenter || false);
|
||||||
restoreSupports(api.widgets.all());
|
restoreSupports(api.widgets.all());
|
||||||
|
updateRanges(settings.process.ranges);
|
||||||
});
|
});
|
||||||
api.event.on("settings.saved", (settings) => {
|
api.event.on("settings.saved", (settings) => {
|
||||||
api.ui.fdmSupport.style.display = lastMode !== 'FDM' || settings.device.bedBelt ? 'none' : 'flex';
|
updateRanges(settings.process.ranges);
|
||||||
|
func.updateSupportButtons();
|
||||||
|
// let ranges = settings.process.ranges;
|
||||||
|
// UI.rangeGroup.style.display = isFdmMode && ranges && ranges.length ? 'flex' : 'none';
|
||||||
});
|
});
|
||||||
api.event.on("button.click", target => {
|
api.event.on("button.click", target => {
|
||||||
switch (target) {
|
switch (target) {
|
||||||
|
|
@ -43,9 +193,10 @@
|
||||||
case api.ui.ssmAdd: return func.sadd();
|
case api.ui.ssmAdd: return func.sadd();
|
||||||
case api.ui.ssmDun: return func.sdone();
|
case api.ui.ssmDun: return func.sdone();
|
||||||
case api.ui.ssmClr:
|
case api.ui.ssmClr:
|
||||||
return api.uc.confirm("clear supports?").then(ok => {
|
// return api.uc.confirm("clear supports?").then(ok => {
|
||||||
if (ok) func.sclear();
|
// if (ok) func.sclear();
|
||||||
});
|
// });
|
||||||
|
func.sclear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
api.event.on("fdm.supports.detect", func.sgen = () => {
|
api.event.on("fdm.supports.detect", func.sgen = () => {
|
||||||
|
|
@ -86,11 +237,13 @@
|
||||||
delbox('supp');
|
delbox('supp');
|
||||||
api.hide.alert(alert);
|
api.hide.alert(alert);
|
||||||
api.feature.hover = addingSupports = false;
|
api.feature.hover = addingSupports = false;
|
||||||
|
fromPillar = undefined;
|
||||||
});
|
});
|
||||||
api.event.on("fdm.supports.clear", func.sclear = () => {
|
api.event.on("fdm.supports.clear", func.sclear = () => {
|
||||||
func.sdone();
|
func.sdone();
|
||||||
clearAllWidgetSupports();
|
if (clearAllWidgetSupports()) {
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
api.event.on("slice.begin", () => {
|
api.event.on("slice.begin", () => {
|
||||||
if (!isFdmMode) {
|
if (!isFdmMode) {
|
||||||
|
|
@ -98,6 +251,37 @@
|
||||||
}
|
}
|
||||||
func.sdone();
|
func.sdone();
|
||||||
updateVisiblity();
|
updateVisiblity();
|
||||||
|
|
||||||
|
// synth support widget for each widget group
|
||||||
|
let synth = [];
|
||||||
|
for (let group of kiri.Widget.Groups.list()) {
|
||||||
|
let merge = group.filter(w => w.sups).map(w => Object.values(w.sups)).flat();
|
||||||
|
if (!merge.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let boxen = merge.map(m => {
|
||||||
|
let geo = m.box.geometry.clone();
|
||||||
|
if (geo.index) geo = geo.toNonIndexed();
|
||||||
|
return geo.translate(m.x, m.y, m.z);
|
||||||
|
});
|
||||||
|
for (let box of boxen) {
|
||||||
|
// eliminate / normalize uv to allow other widget merge
|
||||||
|
box.setAttribute('uv',new THREE.BufferAttribute(new Float32Array(0), 3));
|
||||||
|
}
|
||||||
|
let bbg = THREE.BufferGeometryUtils.mergeBufferGeometries(boxen);
|
||||||
|
let sw = kiri.newWidget(null, group);
|
||||||
|
let fwp = group[0].track.pos;
|
||||||
|
sw.loadGeometry(bbg);
|
||||||
|
sw._move(fwp.x, fwp.y, fwp.z);
|
||||||
|
api.widgets.add(sw);
|
||||||
|
sw.track.synth = true;
|
||||||
|
api.const.SPACE.platform.add(sw.mesh);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
api.event.on("slice.end", () => {
|
||||||
|
if (!isFdmMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
api.event.on("key.esc", () => {
|
api.event.on("key.esc", () => {
|
||||||
if (!isFdmMode) {
|
if (!isFdmMode) {
|
||||||
|
|
@ -132,8 +316,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
api.event.on("mouse.hover.up", on => {
|
api.event.on("mouse.hover.up", func.hoverup = (on = {}) => {
|
||||||
let { object, event } = on;
|
let { event } = on;
|
||||||
if (!isFdmMode) {
|
if (!isFdmMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -142,34 +326,77 @@
|
||||||
}
|
}
|
||||||
delbox('supp');
|
delbox('supp');
|
||||||
if (lastPillar) {
|
if (lastPillar) {
|
||||||
const {widget, box, id} = lastPillar;
|
removeWidgetSupport(lastPillar.widget, lastPillar);
|
||||||
widget.adds.remove(box);
|
|
||||||
widget.mesh.remove(box);
|
|
||||||
delete widget.sups[id];
|
|
||||||
let sa = API.widgets.annotate(widget.id).support;
|
|
||||||
let ix = 0;
|
|
||||||
sa.forEach((rec,i) => {
|
|
||||||
if (rec.id === id) {
|
|
||||||
ix = i;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sa.splice(ix,1);
|
|
||||||
API.conf.save();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!iw) return;
|
if (!iw) return;
|
||||||
let hy = (p1.y + p2.y) / 2;
|
let { point, dim } = lastBox;
|
||||||
let dh = Math.abs(p1.y - p2.y);
|
p1.y = Math.max(0, p1.y);
|
||||||
|
p2.y = Math.max(0, p2.y);
|
||||||
|
let rz = dim.rz;
|
||||||
|
let dh = dim.z;
|
||||||
let dw = api.conf.get().process.sliceSupportSize / 2;
|
let dw = api.conf.get().process.sliceSupportSize / 2;
|
||||||
let ip = iw.track.pos;
|
let ip = iw.track.pos;
|
||||||
let wa = api.widgets.annotate(iw.id);
|
let wa = api.widgets.annotate(iw.id);
|
||||||
let ws = (wa.support = wa.support || []);
|
let ws = (wa.support = wa.support || []);
|
||||||
let x = p1.x - ip.x, y = -p1.z - ip.y, z = hy, id = Date.now();
|
let id = ++nextID;
|
||||||
let rec = {x, y, z, dw, dh, id};
|
let rec = {x: point.x - ip.x, y: -point.z - ip.y, z: point.y, rz, dw, dh, id};
|
||||||
|
if (fromPillar && event && event.shiftKey) {
|
||||||
|
let targets = api.widgets.meshes().append(SPACE.internals().platform);
|
||||||
|
let from = fromPillar,
|
||||||
|
d = {
|
||||||
|
x: rec.x - from.x,
|
||||||
|
y: rec.y - from.y,
|
||||||
|
z: rec.z - from.z
|
||||||
|
};
|
||||||
|
let dist = Math.sqrt(d.x*d.x + d.y*d.y + d.z*d.z);
|
||||||
|
let lerp = UTIL.lerp(0,dist,dw).map(v => v/dist);
|
||||||
|
let angle = rec.rz = Math.atan2(d.y,d.x);
|
||||||
|
let fromrec = ws.filter(r => r.id === from.id)[0];
|
||||||
|
if (fromrec) {
|
||||||
|
from.rz = fromrec.rz = angle;
|
||||||
|
removeWidgetSupport(iw, fromPillar);
|
||||||
|
ws.push(Object.clone(fromrec));
|
||||||
|
addWidgetSupport(iw, fromrec);
|
||||||
|
}
|
||||||
|
lerp.pop();
|
||||||
|
let seed = Math.random();
|
||||||
|
for (let pct of lerp) {
|
||||||
|
let point = new THREE.Vector3(from.x + d.x * pct, from.z + d.z * pct, from.y + d.y * pct);
|
||||||
|
addSupportAtPoint(targets, point, ip, angle, seed++);
|
||||||
|
}
|
||||||
|
}
|
||||||
ws.push(Object.clone(rec));
|
ws.push(Object.clone(rec));
|
||||||
addWidgetSupport(iw, rec);
|
fromPillar = addWidgetSupport(iw, rec);
|
||||||
API.conf.save();
|
API.conf.save();
|
||||||
});
|
});
|
||||||
|
function addSupportAtPoint(targets, point, ip, angle, id) {
|
||||||
|
let up = new THREE.Vector3(0,1,0)
|
||||||
|
let dn = new THREE.Vector3(0,-1,0)
|
||||||
|
let rp = new THREE.Vector3(point.x + ip.x, point.y, -point.z - ip.y);
|
||||||
|
let iup = new THREE.Raycaster(rp, up)
|
||||||
|
.intersectObjects(targets, false)
|
||||||
|
.filter(t => !t.object.pillar);
|
||||||
|
if (iup.length && iup.length % 2 === 0) {
|
||||||
|
let idn = new THREE.Raycaster(rp, dn)
|
||||||
|
.intersectObjects(targets, false)
|
||||||
|
.filter(t => !t.object.pillar);
|
||||||
|
if (idn.length && idn.length % 2 === 0) {
|
||||||
|
iw = iup[0].object.widget || iw;
|
||||||
|
let wa = api.widgets.annotate(iw.id);
|
||||||
|
let ws = (wa.support = wa.support || []);
|
||||||
|
let phi = iup[0].point;
|
||||||
|
let plo = idn[0].point;
|
||||||
|
let ply = Math.max(0, plo.y);
|
||||||
|
let mp = (phi.y + ply) / 2;
|
||||||
|
let dy = Math.abs(phi.y - ply);
|
||||||
|
let dw = api.conf.get().process.sliceSupportSize / 2;
|
||||||
|
let rec = { rz:angle, x:point.x, y:point.z, z:mp, dw, dh:dy, id };
|
||||||
|
ws.push(Object.clone(rec));
|
||||||
|
fromPillar = addWidgetSupport(iw, rec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
api.event.on("mouse.hover", data => {
|
api.event.on("mouse.hover", data => {
|
||||||
if (!isFdmMode) {
|
if (!isFdmMode) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -177,11 +404,8 @@
|
||||||
if (!addingSupports) {
|
if (!addingSupports) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// delbox('intZ');
|
|
||||||
// delbox('intW');
|
|
||||||
// addbox(point, 0xff0000, 'intZ');
|
|
||||||
delbox('supp');
|
delbox('supp');
|
||||||
const { int, type, point } = data;
|
const { int, type, point, event } = data;
|
||||||
const pillar = int ? int.object.pillar : undefined;
|
const pillar = int ? int.object.pillar : undefined;
|
||||||
if (lastPillar) {
|
if (lastPillar) {
|
||||||
lastPillar.box.material.color.r = 0;
|
lastPillar.box.material.color.r = 0;
|
||||||
|
|
@ -190,6 +414,9 @@
|
||||||
if (pillar) {
|
if (pillar) {
|
||||||
pillar.box.material.color.r = 0.5;
|
pillar.box.material.color.r = 0.5;
|
||||||
lastPillar = pillar;
|
lastPillar = pillar;
|
||||||
|
if (event && (event.metaKey || event.ctrlKey)) {
|
||||||
|
return func.hoverup();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (int && type === 'widget') {
|
if (int && type === 'widget') {
|
||||||
|
|
@ -200,30 +427,29 @@
|
||||||
p1 = point;
|
p1 = point;
|
||||||
let dir = new THREE.Vector3(0,1,0)
|
let dir = new THREE.Vector3(0,1,0)
|
||||||
let ray = new THREE.Raycaster(point, dir);
|
let ray = new THREE.Raycaster(point, dir);
|
||||||
|
let rz = int && int.face ? Math.atan2(int.face.normal.y, int.face.normal.x) : 0;
|
||||||
// when on object, project down on downward faces
|
// when on object, project down on downward faces
|
||||||
if (int && int.face && int.face.normal.z < -0.1) {
|
if (int && int.face && int.face.normal.z < -0.1) {
|
||||||
dir.y = -1;
|
dir.y = -1;
|
||||||
}
|
}
|
||||||
let targets = api.widgets.meshes()
|
let targets = api.widgets.meshes().append(SPACE.internals().platform);
|
||||||
.append(SPACE.internals().platform)
|
let i2 = ray.intersectObjects(targets, false)
|
||||||
.appendAll(activeSupports())
|
.filter(t => !t.object.pillar) // eliminate other pillars
|
||||||
;
|
.filter(i => i.distance > 0.1); // false matches close to origin of ray
|
||||||
let i2 = ray.intersectObjects(targets, false);
|
if (i2.length && i2.length % 2 === 0) {
|
||||||
if (i2 && i2.length > 0) {
|
p2 = i2[0].point;
|
||||||
// prevent false matches close to origin of ray
|
iw = i2[0].object.widget || iw;
|
||||||
i2 = i2.filter(i => i.distance > 0.01);
|
let p1y = Math.max(0, p1.y);
|
||||||
// prevent single point base to top matches
|
let p2y = Math.max(0, p2.y);
|
||||||
if (i2.length > 1) {
|
let hy = (p1y + p2y) / 2;
|
||||||
p2 = i2[0].point;
|
let dy = Math.abs(p1y - p2y);
|
||||||
iw = i2[0].object.widget || iw;
|
let dw = api.conf.get().process.sliceSupportSize / 2;
|
||||||
let hy = (p1.y + p2.y) / 2;
|
addbox({x:p1.x, y:hy, z:p1.z}, 0x0000dd, 'supp', {
|
||||||
let dy = Math.abs(p1.y - p2.y);
|
x:dw, y:dw, z:dy, rz
|
||||||
let dw = api.conf.get().process.sliceSupportSize / 2;
|
});
|
||||||
// addbox(p2, 0x00ff00, 'intW');
|
}
|
||||||
addbox({x:p1.x, y:hy, z:p1.z}, 0x0000dd, 'supp', {
|
if (event && event.altKey) {
|
||||||
x:dw, y:dw, z:dy
|
return func.hoverup();
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +460,6 @@
|
||||||
Object.values(widget.sups || {}).forEach(support => {
|
Object.values(widget.sups || {}).forEach(support => {
|
||||||
active.push(support.box);
|
active.push(support.box);
|
||||||
support.box.support = true;
|
support.box.support = true;
|
||||||
// console.log({support});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return active;
|
return active;
|
||||||
|
|
@ -250,23 +475,41 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWidgetSupport(widget, pos) {
|
function addWidgetSupport(widget, pos) {
|
||||||
const { x, y, z, dw, dh, id } = pos;
|
const { x, y, z, rz, dw, dh, id } = pos;
|
||||||
const sups = widget.sups = (widget.sups || {});
|
const sups = widget.sups = (widget.sups || {});
|
||||||
// prevent duplicate restore from repeated settings load calls
|
// prevent duplicate restore from repeated settings load calls
|
||||||
if (!sups[id]) {
|
if (!sups[id]) {
|
||||||
pos.box = addbox(
|
pos.box = addbox(
|
||||||
{ x, y, z }, 0x0000dd, id,
|
{ x, y, z }, 0x0000dd, id,
|
||||||
{ x:dw, y:dw, z:dh }, { group: widget.mesh }
|
{ x:dw, y:dw, z:dh, rz }, { group: widget.mesh }
|
||||||
);
|
);
|
||||||
pos.box.pillar = Object.assign({widget}, pos);
|
pos.box.pillar = Object.assign({widget}, pos);
|
||||||
sups[id] = pos;
|
sups[id] = pos;
|
||||||
widget.adds.push(pos.box);
|
widget.adds.push(pos.box);
|
||||||
}
|
}
|
||||||
|
return sups[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeWidgetSupport(widget, rec) {
|
||||||
|
const {box, id} = rec;
|
||||||
|
widget.adds.remove(box);
|
||||||
|
widget.mesh.remove(box);
|
||||||
|
delete widget.sups[id];
|
||||||
|
let sa = API.widgets.annotate(widget.id).support;
|
||||||
|
let ix = 0;
|
||||||
|
sa.forEach((rec,i) => {
|
||||||
|
if (rec.id === id) {
|
||||||
|
ix = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sa.splice(ix,1);
|
||||||
|
API.conf.save();
|
||||||
|
fromPillar = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVisiblity() {
|
function updateVisiblity() {
|
||||||
API.widgets.all().forEach(w => {
|
API.widgets.all().forEach(w => {
|
||||||
setSupportVisiblity(w, lastMode === 'FDM' && lastView === API.const.VIEWS.ARRANGE);
|
setSupportVisiblity(w, lastMode === 'FDM' && lastView === VIEWS.ARRANGE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,18 +520,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAllWidgetSupports() {
|
function clearAllWidgetSupports() {
|
||||||
|
let cleared = 0;
|
||||||
API.widgets.all().forEach(widget => {
|
API.widgets.all().forEach(widget => {
|
||||||
clearWidgetSupports(widget);
|
cleared += clearWidgetSupports(widget);
|
||||||
});
|
});
|
||||||
|
return cleared;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearWidgetSupports(widget) {
|
function clearWidgetSupports(widget) {
|
||||||
|
let cleared = 0;
|
||||||
Object.values(widget.sups || {}).forEach(support => {
|
Object.values(widget.sups || {}).forEach(support => {
|
||||||
widget.adds.remove(support.box);
|
widget.adds.remove(support.box);
|
||||||
widget.mesh.remove(support.box);
|
widget.mesh.remove(support.box);
|
||||||
|
cleared++;
|
||||||
});
|
});
|
||||||
widget.sups = {};
|
widget.sups = {};
|
||||||
delete API.widgets.annotate(widget.id).support;
|
delete API.widgets.annotate(widget.id).support;
|
||||||
|
return cleared;
|
||||||
}
|
}
|
||||||
|
|
||||||
function delbox(name) {
|
function delbox(name) {
|
||||||
|
|
@ -298,7 +546,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addbox(point, color, name, dim = {x:1,y:1,z:1}, opt = {}) {
|
function addbox(point, color, name, dim = {x:1,y:1,z:1,rz:0}, opt = {}) {
|
||||||
delbox(name);
|
delbox(name);
|
||||||
const box = boxes[name] = new THREE.Mesh(
|
const box = boxes[name] = new THREE.Mesh(
|
||||||
new THREE.BoxGeometry(dim.x, dim.y, dim.z),
|
new THREE.BoxGeometry(dim.x, dim.y, dim.z),
|
||||||
|
|
@ -312,10 +560,15 @@
|
||||||
box.position.y = point.y;
|
box.position.y = point.y;
|
||||||
box.position.z = point.z;
|
box.position.z = point.z;
|
||||||
|
|
||||||
|
lastBox = {point, dim};
|
||||||
|
|
||||||
const group = opt.group || SPACE.scene
|
const group = opt.group || SPACE.scene
|
||||||
group.add(box);
|
group.add(box);
|
||||||
box.groupTo = group;
|
box.groupTo = group;
|
||||||
|
|
||||||
|
if (dim.rz) {
|
||||||
|
opt.rotate = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1), dim.rz);
|
||||||
|
}
|
||||||
if (opt.rotate) {
|
if (opt.rotate) {
|
||||||
opt.matrix = new THREE.Matrix4().makeRotationFromQuaternion(opt.rotate);
|
opt.matrix = new THREE.Matrix4().makeRotationFromQuaternion(opt.rotate);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
// slice, // src/mode/fdm/slice.js
|
// slice, // src/mode/fdm/slice.js
|
||||||
// prepare, // src/mode/fdm/prepare.js
|
// prepare, // src/mode/fdm/prepare.js
|
||||||
// export, // src/mode/fdm/export.js
|
// export, // src/mode/fdm/export.js
|
||||||
|
getRangeParameters,
|
||||||
fixExtruders
|
fixExtruders
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,10 +29,25 @@
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
// customer gcode post function for XYZ daVinci Mini W
|
function getRangeParameters(settings, index) {
|
||||||
self.kiri_fdm_xyz_mini_w = function(gcode, options) {
|
if (index === undefined || index === null || index < 0) {
|
||||||
return btoa("; filename = kirimoto.gcode\n; machine = dv1MW0A000\n" + gcode);
|
return settings.process;
|
||||||
};
|
}
|
||||||
|
let ranges = settings.process.ranges;
|
||||||
|
if (!(ranges && ranges.length)) {
|
||||||
|
return settings.process;
|
||||||
|
}
|
||||||
|
let params = Object.clone(settings.process);
|
||||||
|
for (let range of ranges) {
|
||||||
|
if (index >= range.lo && index <= range.hi) {
|
||||||
|
for (let [key,value] of Object.entries(range.fields)) {
|
||||||
|
params[key] = value;
|
||||||
|
params._range = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
// defer loading until KIRI.client and KIRI.worker exist
|
// defer loading until KIRI.client and KIRI.worker exist
|
||||||
KIRI.loader.push(function(API) {
|
KIRI.loader.push(function(API) {
|
||||||
|
|
@ -39,6 +55,7 @@
|
||||||
if (KIRI.client)
|
if (KIRI.client)
|
||||||
// FDM.support_generate = KIRI.client.fdm_support_generate = function(ondone) {
|
// FDM.support_generate = KIRI.client.fdm_support_generate = function(ondone) {
|
||||||
FDM.support_generate = function(ondone) {
|
FDM.support_generate = function(ondone) {
|
||||||
|
KIRI.client.clear();
|
||||||
KIRI.client.sync();
|
KIRI.client.sync();
|
||||||
let settings = API.conf.get();
|
let settings = API.conf.get();
|
||||||
let widgets = API.widgets.map();
|
let widgets = API.widgets.map();
|
||||||
|
|
@ -51,7 +68,7 @@
|
||||||
if (KIRI.worker)
|
if (KIRI.worker)
|
||||||
KIRI.worker.fdm_support_generate = function(data, send) {
|
KIRI.worker.fdm_support_generate = function(data, send) {
|
||||||
const { settings } = data;
|
const { settings } = data;
|
||||||
const widgets = Object.values(cache);
|
const widgets = Object.values(wcache);
|
||||||
const fresh = widgets.filter(widget => FDM.supports(settings, widget));
|
const fresh = widgets.filter(widget => FDM.supports(settings, widget));
|
||||||
send.done(KIRI.codec.encode(fresh.map(widget => { return {
|
send.done(KIRI.codec.encode(fresh.map(widget => { return {
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,28 @@
|
||||||
FDM.export = function(print, online) {
|
FDM.export = function(print, online) {
|
||||||
let layers = print.output,
|
let layers = print.output,
|
||||||
settings = FDM.fixExtruders(print.settings),
|
settings = FDM.fixExtruders(print.settings),
|
||||||
|
getRangeParameters = FDM.getRangeParameters,
|
||||||
device = settings.device,
|
device = settings.device,
|
||||||
extruders = device.extruders,
|
extruders = device.extruders,
|
||||||
process = settings.process,
|
|
||||||
gcodeFan = device.gcodeFan,
|
gcodeFan = device.gcodeFan,
|
||||||
gcodeLayer = device.gcodeLayer,
|
gcodeLayer = device.gcodeLayer,
|
||||||
gcodeTrack = device.gcodeTrack,
|
gcodeTrack = device.gcodeTrack,
|
||||||
tool = 0,
|
tool = 0,
|
||||||
|
fwRetract = device.fwRetract,
|
||||||
|
isDanger = settings.controller.danger,
|
||||||
isBelt = device.bedBelt,
|
isBelt = device.bedBelt,
|
||||||
bedType = isBelt ? "belt" : "fixed",
|
bedType = isBelt ? "belt" : "fixed",
|
||||||
extruder = extruders[tool],
|
extruder = extruders[tool],
|
||||||
offset_x = extruder.extOffsetX,
|
offset_x = extruder.extOffsetX,
|
||||||
offset_y = extruder.extOffsetY,
|
offset_y = extruder.extOffsetY,
|
||||||
extrudeAbs = device.extrudeAbs,
|
extrudeAbs = device.extrudeAbs || false,
|
||||||
|
extrudeSet = false,
|
||||||
time = 0,
|
time = 0,
|
||||||
layer = 0,
|
layer = 0,
|
||||||
pause = [],
|
pause = [],
|
||||||
pauseCmd = device.gcodePause,
|
pauseCmd = device.gcodePause,
|
||||||
output = [],
|
output = [],
|
||||||
outputLength = 0,
|
outputLength = 0, // absolute extruder position
|
||||||
lastProgress = 0,
|
lastProgress = 0,
|
||||||
decimals = BASE.config.gcode_decimals || 4,
|
decimals = BASE.config.gcode_decimals || 4,
|
||||||
progress = 0,
|
progress = 0,
|
||||||
|
|
@ -44,26 +47,39 @@
|
||||||
lout = null,
|
lout = null,
|
||||||
last = null,
|
last = null,
|
||||||
zpos = 0,
|
zpos = 0,
|
||||||
zhop = process.zHopDistance || 0,
|
bmax = 0,
|
||||||
|
blast = 0,
|
||||||
|
blastz = 0,
|
||||||
|
process = settings.process,
|
||||||
|
loops = process.outputLoopLayers,
|
||||||
|
zhop = process.zHopDistance || 0, // range
|
||||||
seekMMM = process.outputSeekrate * 60,
|
seekMMM = process.outputSeekrate * 60,
|
||||||
retDist = process.outputRetractDist,
|
retDist = process.outputRetractDist || 0, // range
|
||||||
retSpeed = process.outputRetractSpeed * 60,
|
retSpeed = process.outputRetractSpeed * 60, // range
|
||||||
retDwell = process.outputRetractDwell || 0,
|
retDwell = process.outputRetractDwell || 0, // range
|
||||||
timeDwell = retDwell / 1000,
|
timeDwell = retDwell / 1000,
|
||||||
|
peelGuard = process.outputPeelGuard || 0,
|
||||||
|
arcDist = isBelt || !isDanger ? 0 : (process.arcTolerance || 0),
|
||||||
originCenter = process.outputOriginCenter,
|
originCenter = process.outputOriginCenter,
|
||||||
offset = originCenter ? null : {
|
offset = originCenter ? null : {
|
||||||
x: device.bedWidth/2,
|
x: device.bedWidth/2,
|
||||||
y: isBelt ? 0 : device.bedDepth/2
|
y: isBelt ? 0 : device.bedDepth/2
|
||||||
},
|
},
|
||||||
|
nozzleTemp = process.firstLayerNozzleTemp || process.outputTemp,
|
||||||
|
bedTemp = process.firstLayerBedTemp || process.outputBedTemp,
|
||||||
|
fanSpeed = undefined,
|
||||||
|
lastNozzleTemp = nozzleTemp,
|
||||||
|
lastBedTemp = bedTemp,
|
||||||
|
lastFanSpeed = fanSpeed,
|
||||||
subst = {
|
subst = {
|
||||||
travel_speed: seekMMM,
|
travel_speed: seekMMM,
|
||||||
retract_speed: retSpeed,
|
retract_speed: retSpeed,
|
||||||
retract_distance: retDist,
|
retract_distance: retDist,
|
||||||
temp: process.firstLayerNozzleTemp || process.outputTemp,
|
temp: nozzleTemp,
|
||||||
temp_bed: process.firstLayerBedTemp || process.outputBedTemp,
|
temp_bed: bedTemp,
|
||||||
bed_temp: process.firstLayerBedTemp || process.outputBedTemp,
|
bed_temp: bedTemp,
|
||||||
fan_speed: process.outputFanMax,
|
fan_speed: fanSpeed,
|
||||||
speed: process.outputFanMax, // legacy
|
speed: fanSpeed, // legacy
|
||||||
top: offset ? device.bedDepth : device.bedDepth/2,
|
top: offset ? device.bedDepth : device.bedDepth/2,
|
||||||
left: offset ? 0 : -device.bedWidth/2,
|
left: offset ? 0 : -device.bedWidth/2,
|
||||||
right: offset ? device.bedWidth : device.bedWidth/2,
|
right: offset ? device.bedWidth : device.bedWidth/2,
|
||||||
|
|
@ -79,8 +95,38 @@
|
||||||
bytes = 0,
|
bytes = 0,
|
||||||
bcos = Math.cos(Math.PI/4),
|
bcos = Math.cos(Math.PI/4),
|
||||||
icos = 1 / bcos,
|
icos = 1 / bcos,
|
||||||
loops = process.outputLoopLayers,
|
inLoop,
|
||||||
inLoop;
|
arcQ = [];
|
||||||
|
|
||||||
|
// smallish band-aid. refactor above to remove redundancy
|
||||||
|
function updateParams(layer) {
|
||||||
|
let process = getRangeParameters(settings, layer);
|
||||||
|
zhop = process.zHopDistance || 0; // range
|
||||||
|
retDist = process.outputRetractDist || 0; // range
|
||||||
|
retSpeed = process.outputRetractSpeed * 60; // range
|
||||||
|
retDwell = process.outputRetractDwell || 0; // range
|
||||||
|
timeDwell = retDwell / 1000;
|
||||||
|
nozzleTemp = layer === 0 ?
|
||||||
|
process.firstLayerNozzleTemp || process.outputTemp :
|
||||||
|
process.outputTemp || process.firstLayerNozzleTemp;
|
||||||
|
bedTemp = layer === 0 ?
|
||||||
|
process.firstLayerBedTemp || process.outputBedTemp :
|
||||||
|
process.outputBedTemp || process.firstLayerBedTemp;
|
||||||
|
fanSpeed = layer === 0 ?
|
||||||
|
process.firstLayerFanSpeed || 0 :
|
||||||
|
process.outputFanSpeed || 0;
|
||||||
|
Object.assign(subst, {
|
||||||
|
temp_bed: bedTemp,
|
||||||
|
bed_temp: bedTemp,
|
||||||
|
fan_speed: fanSpeed,
|
||||||
|
speed: fanSpeed, // legacy
|
||||||
|
retract_speed: retSpeed,
|
||||||
|
retract_distance: retDist,
|
||||||
|
temp: process.outputTemp, // range
|
||||||
|
temp_bed: process.outputBedTemp, // range
|
||||||
|
bed_temp: process.outputBedTemp, // range
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (isBelt && loops) {
|
if (isBelt && loops) {
|
||||||
loops = loops.split(',').map(range => {
|
loops = loops.split(',').map(range => {
|
||||||
|
|
@ -116,8 +162,12 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function appendSub(line) {
|
function appendSubPad(line, pad) {
|
||||||
append(print.constReplace(line, subst));
|
appendSub(line, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendSub(line, pad) {
|
||||||
|
append(print.constReplace(line, subst, 0, pad));
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendAll(arr) {
|
function appendAll(arr) {
|
||||||
|
|
@ -126,10 +176,10 @@
|
||||||
arr.forEach(function(line) { append(line) });
|
arr.forEach(function(line) { append(line) });
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendAllSub(arr) {
|
function appendAllSub(arr, pad) {
|
||||||
if (!arr) return;
|
if (!arr || arr.length === 0) return;
|
||||||
if (!Array.isArray(arr)) arr = [ arr ];
|
if (!Array.isArray(arr)) arr = [ arr ];
|
||||||
arr.forEach(function(line) { appendSub(line) });
|
arr.forEach(function(line) { appendSub(line, pad) });
|
||||||
}
|
}
|
||||||
|
|
||||||
append(`; Generated by Kiri:Moto ${KIRI.version}`);
|
append(`; Generated by Kiri:Moto ${KIRI.version}`);
|
||||||
|
|
@ -146,12 +196,18 @@
|
||||||
let t1 = false;
|
let t1 = false;
|
||||||
for (let i=0; i<device.gcodePre.length; i++) {
|
for (let i=0; i<device.gcodePre.length; i++) {
|
||||||
let line = device.gcodePre[i];
|
let line = device.gcodePre[i];
|
||||||
if (line.indexOf('T0') >= 0) t0 = true; else
|
if (line.indexOf('T0') === 0) t0 = true; else
|
||||||
if (line.indexOf('T1') >= 0) t1 = true; else
|
if (line.indexOf('T1') === 0) t1 = true; else
|
||||||
if (line.indexOf('M82') >= 0) extrudeAbs = true; else
|
if (line.indexOf('M82') === 0) {
|
||||||
if (line.indexOf('M83') >= 0) extrudeAbs = false; else
|
extrudeAbs = true;
|
||||||
if (line.indexOf('G90') >= 0) extrudeAbs = true; else
|
extrudeSet = true;
|
||||||
if (line.indexOf('G91') >= 0) extrudeAbs = false; else
|
} else
|
||||||
|
if (line.indexOf('M83') === 0) {
|
||||||
|
extrudeAbs = false;
|
||||||
|
extrudeSet = true;
|
||||||
|
} else
|
||||||
|
if (line.indexOf('G90') === 0 && !extrudeSet) extrudeAbs = true; else
|
||||||
|
if (line.indexOf('G91') === 0 && !extrudeSet) extrudeAbs = false; else
|
||||||
if (line.indexOf('G92') === 0) {
|
if (line.indexOf('G92') === 0) {
|
||||||
line.split(";")[0].split(' ').forEach(function (tok) {
|
line.split(";")[0].split(' ').forEach(function (tok) {
|
||||||
let val = parseFloat(tok.substring(1) || 0) || 0;
|
let val = parseFloat(tok.substring(1) || 0) || 0;
|
||||||
|
|
@ -174,11 +230,11 @@
|
||||||
if (line.indexOf("{tool}") > 0 && extruders.length > 1) {
|
if (line.indexOf("{tool}") > 0 && extruders.length > 1) {
|
||||||
for (let i=0; i<extruders.length; i++) {
|
for (let i=0; i<extruders.length; i++) {
|
||||||
subst.tool = i;
|
subst.tool = i;
|
||||||
appendSub(line);
|
appendSubPad(line);
|
||||||
}
|
}
|
||||||
subst.tool = 0;
|
subst.tool = 0;
|
||||||
} else {
|
} else {
|
||||||
appendSub(line);
|
appendSubPad(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,8 +244,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function retract(zhop) {
|
function retract(zhop) {
|
||||||
|
if (retracted) {
|
||||||
|
// console.log({double_retract: zhop});
|
||||||
|
return;
|
||||||
|
}
|
||||||
retracted = retDist;
|
retracted = retDist;
|
||||||
moveTo({e:-retracted}, retSpeed, `e-retract ${retDist}`);
|
if (fwRetract) {
|
||||||
|
append('G10');
|
||||||
|
} else {
|
||||||
|
moveTo({e:-retracted}, retSpeed, `e-retract ${retDist}`);
|
||||||
|
}
|
||||||
if (zhop) moveTo({z:zpos + zhop}, seekMMM, "z-hop start");
|
if (zhop) moveTo({z:zpos + zhop}, seekMMM, "z-hop start");
|
||||||
time += (retDist / retSpeed) * 60 * 2; // retraction time
|
time += (retDist / retSpeed) * 60 * 2; // retraction time
|
||||||
}
|
}
|
||||||
|
|
@ -199,9 +263,6 @@
|
||||||
let angle = -Math.PI / 4;
|
let angle = -Math.PI / 4;
|
||||||
|
|
||||||
function moveTo(newpos, rate, comment) {
|
function moveTo(newpos, rate, comment) {
|
||||||
if (comment) {
|
|
||||||
append(";; " + comment);
|
|
||||||
}
|
|
||||||
let o = [!rate && !newpos.e ? 'G0' : 'G1'];
|
let o = [!rate && !newpos.e ? 'G0' : 'G1'];
|
||||||
let emit = { x: false, y: false, z: false };
|
let emit = { x: false, y: false, z: false };
|
||||||
if (typeof newpos.x === 'number' && newpos.x !== pos.x) {
|
if (typeof newpos.x === 'number' && newpos.x !== pos.x) {
|
||||||
|
|
@ -221,7 +282,7 @@
|
||||||
let epos = isBelt ? { x: pos.x, y: pos.y, z: pos.z } : pos;
|
let epos = isBelt ? { x: pos.x, y: pos.y, z: pos.z } : pos;
|
||||||
if (isBelt) {
|
if (isBelt) {
|
||||||
epos.x = originCenter ? -pos.x : device.bedWidth - pos.x;
|
epos.x = originCenter ? -pos.x : device.bedWidth - pos.x;
|
||||||
epos.z = pos.z * icos;
|
epos.z = blastz = pos.z * icos;
|
||||||
epos.y = -pos.y + epos.z * bcos;
|
epos.y = -pos.y + epos.z * bcos;
|
||||||
lout = epos;
|
lout = epos;
|
||||||
}
|
}
|
||||||
|
|
@ -241,6 +302,13 @@
|
||||||
o.append(" F").append(Math.round(rate));
|
o.append(" F").append(Math.round(rate));
|
||||||
pos.f = rate
|
pos.f = rate
|
||||||
}
|
}
|
||||||
|
if (comment) {
|
||||||
|
o.append(` ; ${comment}`);
|
||||||
|
}
|
||||||
|
if (o.length === 1) {
|
||||||
|
// console.trace({no_move: o, out, newpos, pos, lastp, emit});
|
||||||
|
return;
|
||||||
|
}
|
||||||
let line = o.join('');
|
let line = o.join('');
|
||||||
if (last == line) {
|
if (last == line) {
|
||||||
// console.log({dup:line});
|
// console.log({dup:line});
|
||||||
|
|
@ -264,20 +332,33 @@
|
||||||
|
|
||||||
while (layer < layers.length) {
|
while (layer < layers.length) {
|
||||||
path = layers[layer];
|
path = layers[layer];
|
||||||
|
|
||||||
|
// range overrides
|
||||||
|
if (path.layer >= 0) {
|
||||||
|
updateParams(path.layer);
|
||||||
|
}
|
||||||
|
|
||||||
emitPerMM = print.extrudePerMM(
|
emitPerMM = print.extrudePerMM(
|
||||||
extruder.extNozzle,
|
extruder.extNozzle,
|
||||||
extruder.extFilament,
|
extruder.extFilament,
|
||||||
path.layer === 0 ?
|
path.layer === 0 ?
|
||||||
(process.firstSliceHeight || process.sliceHeight) : path.height);
|
(process.firstSliceHeight || process.sliceHeight) : path.height);
|
||||||
|
|
||||||
subst.z = zpos = path.z;
|
zpos = path.z || zpos;
|
||||||
subst.Z = subst.z;
|
bmax = Math.max(bmax, pos.z * icos);
|
||||||
|
subst.z = subst.Z = zpos.round(3);
|
||||||
subst.e = subst.E = outputLength;
|
subst.e = subst.E = outputLength;
|
||||||
subst.layer = layer;
|
subst.layer = layer;
|
||||||
subst.height = path.height.toFixed(3);
|
subst.height = path.height.toFixed(3);
|
||||||
|
|
||||||
if (isBelt) {
|
if (isBelt) {
|
||||||
pos.z = zpos;
|
pos.z = zpos;
|
||||||
|
if (peelGuard && bmax > peelGuard && blast < peelGuard) {
|
||||||
|
peelGuard += 50;
|
||||||
|
append(`G0 Z${(blast + 55).round(decimals)} F200 ; peel guard`);
|
||||||
|
append(`G0 Z${blastz.round(decimals)} F200 ; unpeel`);
|
||||||
|
}
|
||||||
|
blast = bmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pauseCmd && pause.indexOf(layer) >= 0) {
|
if (pauseCmd && pause.indexOf(layer) >= 0) {
|
||||||
|
|
@ -309,31 +390,23 @@
|
||||||
if (gcodeLayer && gcodeLayer.length) {
|
if (gcodeLayer && gcodeLayer.length) {
|
||||||
appendAllSub(gcodeLayer);
|
appendAllSub(gcodeLayer);
|
||||||
} else {
|
} else {
|
||||||
append(`;; --- layer ${layer} (${subst.height} @ ${subst.z}) ---`);
|
append(`;; --- layer ${layer} (${subst.height} @ ${subst.z.round(3)}) ---`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer > 0 && process.outputLayerRetract) {
|
// layer temp and fan overrides at layer changes
|
||||||
retract();
|
if (fanSpeed !== lastFanSpeed) {
|
||||||
}
|
|
||||||
|
|
||||||
// enable fan at fan layer
|
|
||||||
if (gcodeFan && layer === process.outputFanLayer) {
|
|
||||||
appendAllSub(gcodeFan);
|
appendAllSub(gcodeFan);
|
||||||
|
lastFanSpeed = fanSpeed;
|
||||||
}
|
}
|
||||||
|
if (bedTemp !== lastBedTemp) {
|
||||||
// second layer transitions
|
append(`M140 S${bedTemp} T0`);
|
||||||
if (layer === 1) {
|
lastBedTemp = bedTemp;
|
||||||
// update temps when first layer overrides are present
|
}
|
||||||
if (process.firstLayerNozzleTemp) {
|
if (nozzleTemp !== lastNozzleTemp) {
|
||||||
subst.temp = process.outputTemp;
|
if (t0) append(`M104 S${nozzleTemp} T0`);
|
||||||
if (t0) appendSub("M104 S{temp} T0");
|
if (t1) append(`M104 S${nozzleTemp} T1`);
|
||||||
if (t1) appendSub("M104 S{temp} T1");
|
if (!(t0 || t1)) append(`M104 S${nozzleTemp} T${tool}`);
|
||||||
if (!(t0 || t1)) appendSub("M104 S{temp} T{tool}");
|
lastNozzleTemp = nozzleTemp;
|
||||||
}
|
|
||||||
if (process.firstLayerBedTemp) {
|
|
||||||
subst.bed_temp = subst.temp_bed = process.outputBedTemp;
|
|
||||||
appendSub("M140 S{temp_bed} T0");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move Z to layer height
|
// move Z to layer height
|
||||||
|
|
@ -344,10 +417,11 @@
|
||||||
// iterate through layer outputs
|
// iterate through layer outputs
|
||||||
for (pidx=0; pidx<path.length; pidx++) {
|
for (pidx=0; pidx<path.length; pidx++) {
|
||||||
out = path[pidx];
|
out = path[pidx];
|
||||||
speedMMM = (out.speed || process.outputFeedrate) * 60;
|
speedMMM = (out.speed || process.outputFeedrate) * 60; // range
|
||||||
|
|
||||||
// look for extruder change and recalc emit factor
|
// look for extruder change, run scripts, recalc emit factor
|
||||||
if (out.tool !== undefined && out.tool !== tool) {
|
if (out.tool !== undefined && out.tool !== tool) {
|
||||||
|
appendAllSub(extruder.extDeselect);
|
||||||
tool = out.tool;
|
tool = out.tool;
|
||||||
subst.nozzle = subst.tool = tool;
|
subst.nozzle = subst.tool = tool;
|
||||||
extruder = extruders[tool];
|
extruder = extruders[tool];
|
||||||
|
|
@ -383,10 +457,16 @@
|
||||||
|
|
||||||
// re-engage post-retraction before new extrusion
|
// re-engage post-retraction before new extrusion
|
||||||
if (out.emit && retracted) {
|
if (out.emit && retracted) {
|
||||||
|
drainQ();
|
||||||
|
// console.log({engage:zhop});
|
||||||
// when enabled, resume previous Z
|
// when enabled, resume previous Z
|
||||||
if (zhop && pos.z != zpos) moveTo({z:zpos}, seekMMM, "z-hop end");
|
if (zhop && pos.z != zpos) moveTo({z:zpos}, seekMMM, "z-hop end");
|
||||||
// re-engage retracted filament
|
// re-engage retracted filament
|
||||||
moveTo({e:retracted}, retSpeed, `e-engage ${retracted}`);
|
if (fwRetract) {
|
||||||
|
append('G11');
|
||||||
|
} else {
|
||||||
|
moveTo({e:retracted}, retSpeed, `e-engage ${retracted}`);
|
||||||
|
}
|
||||||
retracted = 0;
|
retracted = 0;
|
||||||
// optional dwell after re-engaging filament to allow pressure to build
|
// optional dwell after re-engaging filament to allow pressure to build
|
||||||
if (retDwell) dwell(retDwell);
|
if (retDwell) dwell(retDwell);
|
||||||
|
|
@ -394,10 +474,58 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastp && out.emit) {
|
if (lastp && out.emit) {
|
||||||
emitMM = emitPerMM * out.emit * dist;
|
if (arcDist) {
|
||||||
moveTo({x:x, y:y, e:emitMM}, speedMMM);
|
let rec = {e:out.emit, x, y, z, dist, emitPerMM, speedMMM};
|
||||||
emitted += emitMM;
|
arcQ.push(rec);
|
||||||
|
let deem = false;
|
||||||
|
let depm = false;
|
||||||
|
let desp = false;
|
||||||
|
if (arcQ.length > 1) {
|
||||||
|
deem = arcQ[0].e !== rec.e;
|
||||||
|
depm = arcQ[0].emitPerMM !== rec.emitPerMM;
|
||||||
|
desp = arcQ[0].speedMMM !== rec.speedMMM;
|
||||||
|
}
|
||||||
|
if (arcQ.length > 2) {
|
||||||
|
let el = arcQ.length;
|
||||||
|
let e1 = arcQ[el-3];
|
||||||
|
let e2 = arcQ[el-2];
|
||||||
|
let e3 = arcQ[el-1];
|
||||||
|
let cc = BASE.util.center2d(e1, e2, e3, 1);
|
||||||
|
let dc = 0;
|
||||||
|
if (arcQ.length === 3) {
|
||||||
|
arcQ.center = [ cc ];
|
||||||
|
} else {
|
||||||
|
// check center point delta
|
||||||
|
let dx = cc.x - arcQ.center[0].x;
|
||||||
|
let dy = cc.y - arcQ.center[0].y;
|
||||||
|
dc = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
// if new point is off the arc
|
||||||
|
if (deem || depm || desp || dc > arcDist) {
|
||||||
|
// console.log({dc, depm, desp});
|
||||||
|
if (arcQ.length === 4) {
|
||||||
|
// not enough points for an arc, drop first point and recalc center
|
||||||
|
emitQrec(arcQ.shift());
|
||||||
|
arcQ.center = [ BASE.util.center2d(arcQ[0], arcQ[1], arcQ[2], 1) ];
|
||||||
|
} else {
|
||||||
|
// enough to consider an arc, emit and start new arc
|
||||||
|
let defer = arcQ.pop();
|
||||||
|
drainQ();
|
||||||
|
// re-add point that was off the last arc
|
||||||
|
arcQ.push(defer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// new point is on the arc
|
||||||
|
arcQ.center.push(cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emitMM = emitPerMM * out.emit * dist;
|
||||||
|
moveTo({x:x, y:y, e:emitMM}, speedMMM);
|
||||||
|
emitted += emitMM;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
drainQ();
|
||||||
moveTo({x:x, y:y}, seekMMM);
|
moveTo({x:x, y:y}, seekMMM);
|
||||||
// TODO disabling out of plane z moves until a better mechanism
|
// TODO disabling out of plane z moves until a better mechanism
|
||||||
// can be built that doesn't rely on computed zpos from layer heights...
|
// can be built that doesn't rely on computed zpos from layer heights...
|
||||||
|
|
@ -407,7 +535,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// retract filament if point retract flag set
|
// retract filament if point retract flag set
|
||||||
if (!retracted && out.retract) {
|
if (out.retract) {
|
||||||
|
drainQ();
|
||||||
retract(zhop);
|
retract(zhop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,13 +556,72 @@
|
||||||
}
|
}
|
||||||
layer++;
|
layer++;
|
||||||
}
|
}
|
||||||
|
drainQ();
|
||||||
|
|
||||||
|
function emitQrec(rec) {
|
||||||
|
let {e, x, y, dist, emitPerMM, speedMMM} = rec;
|
||||||
|
emitMM = emitPerMM * e * dist;
|
||||||
|
moveTo({x:x, y:y, e:emitMM}, speedMMM);
|
||||||
|
emitted += emitMM;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drainQ() {
|
||||||
|
if (!arcDist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (arcQ.length > 4) {
|
||||||
|
let area = BASE.newPolygon().addObj(arcQ).area();
|
||||||
|
let from = arcQ[0];
|
||||||
|
let to = arcQ.peek();
|
||||||
|
let cc = {x:0, y:0, z:0, r:0};
|
||||||
|
let cl = 0;
|
||||||
|
for (let center of arcQ.center.filter(rec => !isNaN(rec.r))) {
|
||||||
|
cc.x += center.x;
|
||||||
|
cc.y += center.y;
|
||||||
|
cc.z += center.z;
|
||||||
|
cc.r += center.r;
|
||||||
|
cl++;
|
||||||
|
}
|
||||||
|
cc.x /= cl;
|
||||||
|
cc.y /= cl;
|
||||||
|
cc.z /= cl;
|
||||||
|
cc.r /= cl;
|
||||||
|
// first arc point
|
||||||
|
emitQrec(from);
|
||||||
|
// console.log(arcQ.slice(), arcQ.center);
|
||||||
|
// console.log({first: from, last: arcQ.peek(), center: cc});
|
||||||
|
// rest of arc to final point
|
||||||
|
let dist = arcQ.slice(1).map(v => v.dist).reduce((a,v) => a+v);
|
||||||
|
let emit = from.e;//arcQ.slice(1).map(v => v.e).reduce((a,v) => a+v);
|
||||||
|
emit = (from.emitPerMM * emit * dist);
|
||||||
|
outputLength += emit;
|
||||||
|
emitted += emit;
|
||||||
|
if (extrudeAbs) {
|
||||||
|
emit = outputLength;
|
||||||
|
}
|
||||||
|
let gc = area > 0 ? 'G2' : 'G3';
|
||||||
|
let pre = `${gc} X${to.x.toFixed(decimals)} Y${to.y.toFixed(decimals)} R${cc.r.toFixed(decimals)} E${emit.toFixed(decimals)}`;
|
||||||
|
let add = pos.f !== from.speedMMM ? ` E${from.speedMMM}` : '';
|
||||||
|
append(`${pre}${add} ; merged=${cl-1} len=${dist.toFixed(decimals)} cp=${cc.x.round(2)},${cc.y.round(2)}`);
|
||||||
|
pos.x = to.x;
|
||||||
|
pos.y = to.y;
|
||||||
|
pos.z = to.z;
|
||||||
|
} else {
|
||||||
|
for (let rec of arcQ) {
|
||||||
|
emitQrec(rec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arcQ.length = 0;
|
||||||
|
arcQ.center = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (inLoop) {
|
if (inLoop) {
|
||||||
append(`M808`);
|
append(`M808`);
|
||||||
}
|
}
|
||||||
|
|
||||||
subst.time = UTIL.round(time,2);
|
|
||||||
subst.material = UTIL.round(emitted,2);
|
subst.material = UTIL.round(emitted,2);
|
||||||
|
subst.time = UTIL.round(time,2);
|
||||||
|
subst['print-time'] = subst.time;
|
||||||
|
|
||||||
append("; --- shutdown ---");
|
append("; --- shutdown ---");
|
||||||
appendAllSub(device.gcodePost);
|
appendAllSub(device.gcodePost);
|
||||||
|
|
|
||||||
|
|
@ -155,25 +155,28 @@
|
||||||
function fillLinear(target) {
|
function fillLinear(target) {
|
||||||
let bounds = target.bounds();
|
let bounds = target.bounds();
|
||||||
let height = target.zHeight();
|
let height = target.zHeight();
|
||||||
|
|
||||||
|
let density = target.density();
|
||||||
|
let line = target.lineWidth();
|
||||||
|
|
||||||
let span_x = bounds.max.x - bounds.min.x;
|
let span_x = bounds.max.x - bounds.min.x;
|
||||||
let span_y = bounds.max.y - bounds.min.y;
|
let span_y = bounds.max.y - bounds.min.y;
|
||||||
let density = target.density();
|
let steps_x = (span_x / line) * density;
|
||||||
let offset = target.offset() / 2;
|
let steps_y = (span_y / line) * density;
|
||||||
let tile = 1 + (1 - density);
|
let step_x = span_x / steps_x;
|
||||||
let tile_xc = Math.ceil(span_x / tile);
|
let step_y = span_x / steps_x;
|
||||||
let tile_yc = Math.ceil(span_y / tile);
|
|
||||||
|
|
||||||
if (target.zIndex() % 2 === 1) {
|
if (target.zIndex() % 2 === 1) {
|
||||||
for (let tx=0; tx<=tile_xc; tx++) {
|
for (let tx=bounds.min.x; tx<=bounds.max.x; tx += step_x) {
|
||||||
target.newline();
|
target.newline();
|
||||||
target.emit(tx * tile + bounds.min.x, bounds.min.y);
|
target.emit(tx, bounds.min.y);
|
||||||
target.emit(tx * tile + bounds.min.x, bounds.max.y);
|
target.emit(tx, bounds.max.y);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let ty=0; ty<=tile_yc; ty++) {
|
for (let ty=bounds.min.y; ty<=bounds.max.y; ty += step_y) {
|
||||||
target.newline();
|
target.newline();
|
||||||
target.emit(bounds.min.x, ty * tile + bounds.min.y);
|
target.emit(bounds.min.x, ty);
|
||||||
target.emit(bounds.max.x, ty * tile + bounds.min.y);
|
target.emit(bounds.max.x, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
POLY = BASE.polygons,
|
POLY = BASE.polygons,
|
||||||
FDM = KIRI.driver.FDM,
|
FDM = KIRI.driver.FDM,
|
||||||
newPoint = BASE.newPoint,
|
newPoint = BASE.newPoint,
|
||||||
newPolygon = BASE.newPolygon;
|
newPolygon = BASE.newPolygon,
|
||||||
|
getRangeParameters = FDM.getRangeParameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRIVER PRINT CONTRACT
|
* DRIVER PRINT CONTRACT
|
||||||
|
|
@ -19,34 +20,31 @@
|
||||||
* @returns {Object[]} returns array of render objects
|
* @returns {Object[]} returns array of render objects
|
||||||
*/
|
*/
|
||||||
FDM.prepare = function(widgets, settings, update) {
|
FDM.prepare = function(widgets, settings, update) {
|
||||||
settings = FDM.fixExtruders(settings);
|
// filter ignored widgets
|
||||||
|
widgets = widgets.filter(w => !w.track.ignore);
|
||||||
|
|
||||||
|
settings = FDM.fixExtruders(settings);
|
||||||
let render = settings.render !== false,
|
let render = settings.render !== false,
|
||||||
{ device, process, controller, bounds, mode } = settings,
|
{ device, process, controller, bounds, mode } = settings,
|
||||||
|
{ bedWidth, bedDepth } = device,
|
||||||
output = [],
|
output = [],
|
||||||
printPoint = newPoint(0,0,0),
|
printPoint = newPoint(0,0,0),
|
||||||
nozzle = device.extruders[0].extNozzle,
|
nozzle = device.extruders[0].extNozzle,
|
||||||
isBelt = device.bedBelt,
|
isBelt = device.bedBelt,
|
||||||
isThin = controller.lineType === "line",
|
isThin = controller.lineType === "line",
|
||||||
isFlat = controller.lineType === "flat",
|
isFlat = controller.lineType === "flat",
|
||||||
|
isDanger = controller.danger || false,
|
||||||
firstLayerHeight = isBelt ? process.sliceHeight : process.firstSliceHeight || process.sliceHeight,
|
firstLayerHeight = isBelt ? process.sliceHeight : process.firstSliceHeight || process.sliceHeight,
|
||||||
firstLayerSeek = process.outputSeekrate,
|
firstLayerSeek = process.outputSeekrate,
|
||||||
firstLayerRate = process.firstLayerRate,
|
firstLayerRate = process.firstLayerRate,
|
||||||
firstLayerMult = process.firstLayerPrintMult,
|
firstLayerMult = process.firstLayerPrintMult,
|
||||||
firstLayerBrim = process.firstLayerBrim,
|
firstLayerBrim = process.firstLayerBrim,
|
||||||
firstLayerBrimTrig = process.firstLayerBrimTrig,
|
firstLayerBrimTrig = process.firstLayerBrimTrig,
|
||||||
maxLayers = 0,
|
layerRetract = process.outputLayerRetract,
|
||||||
layer = 0,
|
layerno = 0,
|
||||||
zoff = 0,
|
zoff = 0,
|
||||||
meshIndex,
|
|
||||||
lastIndex,
|
|
||||||
closest,
|
|
||||||
mindist,
|
|
||||||
minidx,
|
|
||||||
find,
|
|
||||||
layerout = [],
|
layerout = [],
|
||||||
slices = [],
|
slices = [],
|
||||||
sliceEntry,
|
|
||||||
print = self.worker.print = KIRI.newPrint(settings, widgets),
|
print = self.worker.print = KIRI.newPrint(settings, widgets),
|
||||||
beltYoff = device.bedDepth / 2,
|
beltYoff = device.bedDepth / 2,
|
||||||
beltfact = Math.cos(Math.PI/4),
|
beltfact = Math.cos(Math.PI/4),
|
||||||
|
|
@ -75,7 +73,7 @@
|
||||||
offset = process.outputBrimOffset || (process.outputRaft ? 4 : 0);
|
offset = process.outputBrimOffset || (process.outputRaft ? 4 : 0);
|
||||||
|
|
||||||
// compute first brim
|
// compute first brim
|
||||||
widgets.forEach(function(widget) {
|
widgets.filter(w => w.slices.length).forEach(function(widget) {
|
||||||
let tops = [];
|
let tops = [];
|
||||||
// collect top outer polygons
|
// collect top outer polygons
|
||||||
widget.slices[0].tops.forEach(function(top) {
|
widget.slices[0].tops.forEach(function(top) {
|
||||||
|
|
@ -88,15 +86,16 @@
|
||||||
});
|
});
|
||||||
// nest and offset tops
|
// nest and offset tops
|
||||||
POLY.nest(tops).forEach(function(poly) {
|
POLY.nest(tops).forEach(function(poly) {
|
||||||
poly.offset(-offset + nozzle / 2).forEach(function(brim) {
|
let off = poly.offset(-offset + nozzle / 2);
|
||||||
brim.move(widget.mesh.position);
|
if (off) off.forEach(function(brim) {
|
||||||
|
brim.move(widget.track.pos);
|
||||||
brims.push(brim);
|
brims.push(brim);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// merge brims
|
// merge brims
|
||||||
brims = POLY.union(brims);
|
brims = POLY.union(brims, undefined, true);
|
||||||
|
|
||||||
// if brim is offset, over-expand then shrink to induce brims to merge
|
// if brim is offset, over-expand then shrink to induce brims to merge
|
||||||
if (offset && brims.length) {
|
if (offset && brims.length) {
|
||||||
|
|
@ -132,6 +131,7 @@
|
||||||
speed: speed,
|
speed: speed,
|
||||||
mult: extrude,
|
mult: extrude,
|
||||||
});
|
});
|
||||||
|
layerout.z = zoff + height;
|
||||||
layerout.height = height;
|
layerout.height = height;
|
||||||
output.append(layerout);
|
output.append(layerout);
|
||||||
|
|
||||||
|
|
@ -139,14 +139,15 @@
|
||||||
zoff += height;
|
zoff += height;
|
||||||
};
|
};
|
||||||
|
|
||||||
raft(nozzle/1, process.sliceFillAngle + 0 , nozzle * 6.0, firstLayerRate / 3, 4);
|
raft(nozzle/1, process.sliceFillAngle + 0 , nozzle * 5.0, firstLayerRate / 3, 4);
|
||||||
raft(nozzle/1, process.sliceFillAngle + 0 , nozzle * 6.0, firstLayerRate / 2, 4);
|
raft(nozzle/1, process.sliceFillAngle + 0 , nozzle * 5.0, firstLayerRate / 2, 4);
|
||||||
raft(nozzle/2, process.sliceFillAngle + 90, nozzle * 3.0, process.outputFeedrate, 2.5);
|
raft(nozzle/2, process.sliceFillAngle + 90, nozzle * 3.0, process.outputFeedrate, 2.5);
|
||||||
raft(nozzle/2, process.sliceFillAngle + 0 , nozzle * 1.0, process.outputFeedrate, 1.5);
|
raft(nozzle/2, process.sliceFillAngle + 0 , nozzle * 1.0, process.outputFeedrate, 1.5);
|
||||||
raft(nozzle/2, process.sliceFillAngle + 0 , nozzle * 1.0, process.outputFeedrate, 1.0);
|
raft(nozzle/2, process.sliceFillAngle + 90 , nozzle * 0.7, process.outputFeedrate, 0.75);
|
||||||
|
|
||||||
// raise first layer off raft slightly to lessen adhesion
|
// raise first layer off raft slightly to lessen adhesion
|
||||||
firstLayerHeight += process.outputRaftSpacing || 0;
|
firstLayerHeight += process.outputRaftSpacing || 0;
|
||||||
|
zoff += process.outputRaftSpacing || 0;
|
||||||
|
|
||||||
// retract after last raft layer
|
// retract after last raft layer
|
||||||
output.last().last().retract = true;
|
output.last().last().retract = true;
|
||||||
|
|
@ -169,7 +170,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// output brim points
|
// output brim points
|
||||||
printPoint = print.poly2polyEmit(polys, printPoint, function(poly, index, count, startPoint) {
|
let brimStart = offset < nozzle * 2 ? newPoint(-bedWidth, -bedDepth, 0) : printPoint;
|
||||||
|
printPoint = print.poly2polyEmit(polys, brimStart, (poly, index, count, startPoint) => {
|
||||||
return print.polyPrintPath(poly, startPoint, preout, {
|
return print.polyPrintPath(poly, startPoint, preout, {
|
||||||
rate: firstLayerRate,
|
rate: firstLayerRate,
|
||||||
onfirst: function(point) {
|
onfirst: function(point) {
|
||||||
|
|
@ -203,6 +205,10 @@
|
||||||
// so that they can use a separate extruder
|
// so that they can use a separate extruder
|
||||||
for (let widget of widgets.slice()) {
|
for (let widget of widgets.slice()) {
|
||||||
let sslices = [];
|
let sslices = [];
|
||||||
|
if (!widget.slices) {
|
||||||
|
console.log('invalid widget', widget);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (let slice of widget.slices) {
|
for (let slice of widget.slices) {
|
||||||
if (!slice.supports) {
|
if (!slice.supports) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -210,25 +216,30 @@
|
||||||
let sslice = KIRI.newSlice(slice.z);
|
let sslice = KIRI.newSlice(slice.z);
|
||||||
sslice.extruder = process.sliceSupportNozzle;
|
sslice.extruder = process.sliceSupportNozzle;
|
||||||
sslice.supports = slice.supports.slice();
|
sslice.supports = slice.supports.slice();
|
||||||
|
sslice.height = slice.height;
|
||||||
sslices.push(sslice);
|
sslices.push(sslice);
|
||||||
}
|
}
|
||||||
if (sslices.length) {
|
if (sslices.length) {
|
||||||
let swidget = KIRI.newWidget();
|
let swidget = KIRI.newWidget(null,widget.group);
|
||||||
swidget.slices = sslices;
|
swidget.slices = sslices;
|
||||||
swidget.support = true;
|
swidget.support = true;
|
||||||
swidget.mesh = { widget: swidget, position: widget.mesh.position };
|
swidget.rotinfo = widget.rotinfo;
|
||||||
|
swidget.belt = widget.belt;
|
||||||
|
swidget.track = Object.clone(widget.track);
|
||||||
|
swidget.mesh = { widget: swidget, position: swidget.track.pos };
|
||||||
settings.widget[swidget.id] = { extruder: process.sliceSupportNozzle };
|
settings.widget[swidget.id] = { extruder: process.sliceSupportNozzle };
|
||||||
widgets.push(swidget);
|
widgets.push(swidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastPoly;
|
||||||
|
let lastLayer;
|
||||||
let extruders = [];
|
let extruders = [];
|
||||||
let extcount = 0;
|
let extcount = 0;
|
||||||
|
|
||||||
// find max layers (for updates)
|
// find max layers (for updates)
|
||||||
// generate list of used extruders for purge blocks
|
// generate list of used extruders for purge blocks
|
||||||
for (let widget of widgets) {
|
for (let widget of widgets) {
|
||||||
maxLayers = Math.max(maxLayers, widget.slices.length);
|
|
||||||
let extruder = (settings.widget[widget.id] || {}).extruder || 0;
|
let extruder = (settings.widget[widget.id] || {}).extruder || 0;
|
||||||
if (!extruders[extruder]) {
|
if (!extruders[extruder]) {
|
||||||
extruders[extruder] = {};
|
extruders[extruder] = {};
|
||||||
|
|
@ -265,13 +276,15 @@
|
||||||
|
|
||||||
// generate purge block for given nozzle
|
// generate purge block for given nozzle
|
||||||
function purge(nozzle, track, layer, start, z, using) {
|
function purge(nozzle, track, layer, start, z, using) {
|
||||||
if (extcount < 2) {
|
if (extcount < 2 || isBelt) {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
let rec = track[nozzle];
|
let rec = track[nozzle];
|
||||||
if (rec) {
|
if (rec) {
|
||||||
track[nozzle] = null;
|
track[nozzle] = null;
|
||||||
if (layer.last()) layer.last().retract = true;
|
if (layer.last()) {
|
||||||
|
layer.last().retract = true;
|
||||||
|
}
|
||||||
start = print.polyPrintPath(rec.poly.clone().setZ(z), start, layer, {
|
start = print.polyPrintPath(rec.poly.clone().setZ(z), start, layer, {
|
||||||
tool: using || nozzle,
|
tool: using || nozzle,
|
||||||
open: true,
|
open: true,
|
||||||
|
|
@ -288,13 +301,15 @@
|
||||||
// establish offsets
|
// establish offsets
|
||||||
for (let widget of widgets) {
|
for (let widget of widgets) {
|
||||||
let { rotinfo, belt } = widget;
|
let { rotinfo, belt } = widget;
|
||||||
// console.log({rotinfo, belt});
|
let offset = Object.clone(widget.track.pos);
|
||||||
let offset = widget.mesh ? Object.clone(widget.mesh.position) : {x:0, y:0, z:0};
|
|
||||||
if (isBelt) {
|
if (isBelt) {
|
||||||
offset.x = rotinfo.xpos;
|
let o = rotinfo.ypos * beltfact;
|
||||||
offset.y = -belt.midy;
|
offset = {
|
||||||
offset.y += rotinfo.ypos * beltfact;
|
x: rotinfo.xpos,
|
||||||
offset.z = rotinfo.ypos * beltfact;
|
y: o - belt.midy - belt.yadd/2,
|
||||||
|
z: o,
|
||||||
|
};
|
||||||
|
// offset = { x:0, y:0, z:0 };
|
||||||
// locate the lowest point in slices and widget overall
|
// locate the lowest point in slices and widget overall
|
||||||
let minby = Infinity;
|
let minby = Infinity;
|
||||||
for (let slice of widget.slices) {
|
for (let slice of widget.slices) {
|
||||||
|
|
@ -308,10 +323,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// todo remove b/c this is now calculated at slice time
|
||||||
// flag slices as being on or off the bed / belt
|
// flag slices as being on or off the bed / belt
|
||||||
for (let slice of widget.slices) {
|
// for (let slice of widget.slices) {
|
||||||
slice.onbelt = Math.abs(minby - slice.minby) < 0.01;
|
// slice.onbelt = Math.abs(minby - slice.minby) < 0.01;
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
// when rafts used this is non-zero
|
// when rafts used this is non-zero
|
||||||
offset.z = zoff;
|
offset.z = zoff;
|
||||||
|
|
@ -341,6 +357,8 @@
|
||||||
return a.z - b.z;
|
return a.z - b.z;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let lastWidget;
|
||||||
|
|
||||||
// walk cake layers bottom up
|
// walk cake layers bottom up
|
||||||
for (let layer of cake) {
|
for (let layer of cake) {
|
||||||
// track purge blocks generated for each layer
|
// track purge blocks generated for each layer
|
||||||
|
|
@ -376,41 +394,63 @@
|
||||||
return a.dst - b.dst;
|
return a.dst - b.dst;
|
||||||
});
|
});
|
||||||
let { z, slice, offset } = order[0];
|
let { z, slice, offset } = order[0];
|
||||||
|
let params = getRangeParameters(settings, slice.index);
|
||||||
slice.prep = true;
|
slice.prep = true;
|
||||||
// retract between widgets
|
// retract between widgets or layers (when set)
|
||||||
if (layerout.length && minidx !== lastIndex) {
|
if (layerout.length && slice.widget !== lastWidget) {
|
||||||
layerout.last().retract = true;
|
layerout.last().retract = true;
|
||||||
}
|
}
|
||||||
layerout.z = z;
|
lastWidget = slice.widget;
|
||||||
|
layerout.z = z + slice.height / 2;
|
||||||
layerout.height = layerout.height || slice.height;
|
layerout.height = layerout.height || slice.height;
|
||||||
|
layerout.slice = slice;
|
||||||
|
// mark layer as anchor if slice is belt and flag set
|
||||||
|
layerout.anchor = slice.belt && slice.belt.anchor;
|
||||||
// detect extruder change and print purge block
|
// detect extruder change and print purge block
|
||||||
if (!lastOut || lastOut.extruder !== slice.extruder) {
|
if (!lastOut || lastOut.extruder !== slice.extruder) {
|
||||||
printPoint = purge(slice.extruder, track, layerout, printPoint, slice.z);
|
printPoint = purge(slice.extruder, track, layerout, printPoint, slice.z);
|
||||||
}
|
}
|
||||||
let tmpout = [];
|
|
||||||
let wtb = slice.widget.track.box;
|
let wtb = slice.widget.track.box;
|
||||||
// output seek to start point between mesh slices if previous data
|
// output seek to start point between mesh slices if previous data
|
||||||
printPoint = print.slicePrintPath(
|
printPoint = print.slicePrintPath(
|
||||||
slice,
|
slice,
|
||||||
isBelt ? newPoint(-wtb.w, wtb.d * 2, 0) : printPoint.sub(offset),
|
slice.belt && slice.belt.touch ? newPoint(-wtb.w, wtb.d * 2, 0) : printPoint.sub(offset),
|
||||||
offset,
|
offset,
|
||||||
tmpout, //layerout,
|
layerout,
|
||||||
{
|
{
|
||||||
|
seedPoint: printPoint.sub(offset),
|
||||||
|
danger: isDanger,
|
||||||
|
params, // range parameters
|
||||||
first: slice.index === 0,
|
first: slice.index === 0,
|
||||||
support: slice.widget.support,
|
support: slice.widget.support,
|
||||||
onBelt: slice.onbelt
|
onBelt: slice.belt && slice.belt.touch,
|
||||||
|
pretract: (wipeDist) => {
|
||||||
|
if (lastLayer && lastLayer.length) {
|
||||||
|
let lastOut = lastLayer.last();
|
||||||
|
lastOut.retract = true;
|
||||||
|
if (wipeDist && lastPoly && lastOut.point) {
|
||||||
|
let endpoint = lastOut.point.followTo(lastPoly.center(true).add(offset), wipeDist);
|
||||||
|
if (endpoint.inPolygon(lastPoly)) {
|
||||||
|
print.addOutput(lastLayer, endpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
layerout.appendAll(tmpout);
|
|
||||||
lastOut = slice;
|
lastOut = slice;
|
||||||
lastExt = lastOut.ext
|
lastExt = lastOut.ext
|
||||||
lastIndex = minidx;
|
lastPoly = slice.lastPoly;
|
||||||
|
lastLayer = layerout;
|
||||||
|
if (layerRetract && layerout.length) {
|
||||||
|
layerout.last().retract = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a declared extruder isn't used in a layer, use selected
|
// if a declared extruder isn't used in a layer, use selected
|
||||||
// extruder to fill the relevant purge blocks for later support
|
// extruder to fill the relevant purge blocks for later support
|
||||||
track.forEach(ext => {
|
track.forEach(ext => {
|
||||||
if (ext) {
|
if (ext && lastOut) {
|
||||||
printPoint = purge(ext.extruder, track, layerout, printPoint, lastOut.z, lastExt);
|
printPoint = purge(ext.extruder, track, layerout, printPoint, lastOut.z, lastExt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -421,13 +461,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// retract after last layer
|
// retract after last layer
|
||||||
if (layer === maxLayers && layerout.length) {
|
if (layerno === cake.length - 1 && layerout.length) {
|
||||||
layerout.last().retract = true;
|
layerout.last().retract = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify progress
|
// notify progress
|
||||||
layerout.layer = layer++;
|
layerout.layer = layerno++;
|
||||||
update((layer / maxLayers) * 0.5, "prepare");
|
update((layerno / cake.length) * 0.5, "prepare");
|
||||||
|
|
||||||
slices = [];
|
slices = [];
|
||||||
layerout = [];
|
layerout = [];
|
||||||
|
|
@ -454,6 +494,13 @@
|
||||||
rec.point.y += poff;
|
rec.point.y += poff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add lead in, when specified
|
||||||
|
// if (process.firstLayerBeltLead) {
|
||||||
|
// // add belt lead in
|
||||||
|
// console.log({process, output});
|
||||||
|
// }
|
||||||
|
|
||||||
let thresh = firstLayerHeight * 1.05;
|
let thresh = firstLayerHeight * 1.05;
|
||||||
// iterate over layers, find extrusion on belt and
|
// iterate over layers, find extrusion on belt and
|
||||||
// apply corrections and add brim when specified
|
// apply corrections and add brim when specified
|
||||||
|
|
@ -479,13 +526,17 @@
|
||||||
}
|
}
|
||||||
lastout = rec;
|
lastout = rec;
|
||||||
}
|
}
|
||||||
// skip if brig trigger not met
|
// skip if brim trigger not met
|
||||||
if (firstLayerBrimTrig && mins > firstLayerBrimTrig) {
|
if (firstLayerBrimTrig > 0 && mins > firstLayerBrimTrig) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// do not add brims to anchor layers
|
||||||
|
if (layer.anchor) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// add brim, if specified
|
// add brim, if specified
|
||||||
if (first && firstLayerBrim) {
|
if (first && firstLayerBrim) {
|
||||||
let {emit, tool } = first;
|
let { emit, tool } = first;
|
||||||
let y = maxy;
|
let y = maxy;
|
||||||
let z = minz;
|
let z = minz;
|
||||||
let b = Math.max(firstLayerBrim, 1);
|
let b = Math.max(firstLayerBrim, 1);
|
||||||
|
|
@ -541,8 +592,11 @@
|
||||||
const flat = opts.flat;
|
const flat = opts.flat;
|
||||||
const thin = opts.thin && !flat;
|
const thin = opts.thin && !flat;
|
||||||
const ckspeed = opts.speed !== false;
|
const ckspeed = opts.speed !== false;
|
||||||
|
const headColor = 0x888888;
|
||||||
const moveColor = opts.move >= 0 ? opts.move : 0xaaaaaa;
|
const moveColor = opts.move >= 0 ? opts.move : 0xaaaaaa;
|
||||||
const printColor = opts.print >= 0 ? opts.print : 0x777700;
|
const printColor = opts.print >= 0 ? opts.print : 0x777700;
|
||||||
|
const arrowAll = false;
|
||||||
|
const arrowSize = arrowAll ? 0.2 : 0.4;
|
||||||
const layers = [];
|
const layers = [];
|
||||||
|
|
||||||
const moveOpt = {
|
const moveOpt = {
|
||||||
|
|
@ -569,6 +623,7 @@
|
||||||
let lastOut = null;
|
let lastOut = null;
|
||||||
let current = null;
|
let current = null;
|
||||||
let retracted = false;
|
let retracted = false;
|
||||||
|
let retractz = 0;
|
||||||
|
|
||||||
function color(point) {
|
function color(point) {
|
||||||
return FDM.rateToColor(point.speed, maxspd);
|
return FDM.rateToColor(point.speed, maxspd);
|
||||||
|
|
@ -604,6 +659,7 @@
|
||||||
if (out.retract) {
|
if (out.retract) {
|
||||||
retracts.push(out.point);
|
retracts.push(out.point);
|
||||||
retracted = true;
|
retracted = true;
|
||||||
|
retractz++;
|
||||||
}
|
}
|
||||||
if (!out.point) {
|
if (!out.point) {
|
||||||
// in cam mode, these are drilling or dwell ops
|
// in cam mode, these are drilling or dwell ops
|
||||||
|
|
@ -611,7 +667,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastOut) {
|
if (lastOut) {
|
||||||
if (lastOut.emit !== out.emit) {
|
if (arrowAll || lastOut.emit !== out.emit) {
|
||||||
heads.push({p1: lastOut.point, p2: out.point});
|
heads.push({p1: lastOut.point, p2: out.point});
|
||||||
}
|
}
|
||||||
const op = out.point, lp = lastOut.point;
|
const op = out.point, lp = lastOut.point;
|
||||||
|
|
@ -670,14 +726,14 @@
|
||||||
}
|
}
|
||||||
if (heads.length) {
|
if (heads.length) {
|
||||||
output
|
output
|
||||||
.setLayer('arrows', { face: moveColor, line: 0x555555, opacity: 0.5 }, true)
|
.setLayer('arrows', { face: headColor, line: 0x112233, opacity: 0.5 }, true)
|
||||||
.addAreas(heads.map(points => {
|
.addAreas(heads.map(points => {
|
||||||
const {p1, p2} = points;
|
const {p1, p2} = points;
|
||||||
const slope = p2.slopeTo(p1);
|
const slope = p2.slopeTo(p1);
|
||||||
const s1 = BASE.newSlopeFromAngle(slope.angle + 20);
|
const s1 = BASE.newSlopeFromAngle(slope.angle + 20);
|
||||||
const s2 = BASE.newSlopeFromAngle(slope.angle - 20);
|
const s2 = BASE.newSlopeFromAngle(slope.angle - 20);
|
||||||
const p3 = points.p2.projectOnSlope(s1, 0.4);
|
const p3 = points.p2.projectOnSlope(s1, arrowSize);
|
||||||
const p4 = points.p2.projectOnSlope(s2, 0.4);
|
const p4 = points.p2.projectOnSlope(s2, arrowSize);
|
||||||
return newPolygon().addPoints([p2,p3,p4]).setZ(p2.z + 0.01);
|
return newPolygon().addPoints([p2,p3,p4]).setZ(p2.z + 0.01);
|
||||||
}), { thin: true, outline: true });
|
}), { thin: true, outline: true });
|
||||||
}
|
}
|
||||||
|
|
@ -685,9 +741,7 @@
|
||||||
.setLayer(opts.other || 'move', moveOpt, opts.moves !== true)
|
.setLayer(opts.other || 'move', moveOpt, opts.moves !== true)
|
||||||
.addPolys(moves, { thin: true, z: opts.z });
|
.addPolys(moves, { thin: true, z: opts.z });
|
||||||
// force level when present
|
// force level when present
|
||||||
if (level.z) {
|
let pz = level.z ? level.z - height : opts.z;
|
||||||
opts.z = level.z;
|
|
||||||
}
|
|
||||||
Object.values(prints).forEach(array => {
|
Object.values(prints).forEach(array => {
|
||||||
array.forEach(poly => {
|
array.forEach(poly => {
|
||||||
if (flat && poly.appearsClosed()) {
|
if (flat && poly.appearsClosed()) {
|
||||||
|
|
@ -700,10 +754,10 @@
|
||||||
.addPolys([ poly ],
|
.addPolys([ poly ],
|
||||||
thin ? { thin, z: opts.z, color: poly.color } :
|
thin ? { thin, z: opts.z, color: poly.color } :
|
||||||
flat ? {
|
flat ? {
|
||||||
flat, z: opts.z, color: poly.color,
|
flat, z: pz, color: poly.color,
|
||||||
outline: true, offset: array.width, open: poly.open } :
|
outline: true, offset: array.width, open: poly.open } :
|
||||||
{
|
{
|
||||||
offset: array.width, height, z: opts.z,
|
offset: array.width, height, z: pz,
|
||||||
color: { face: poly.color, line: poly.color }
|
color: { face: poly.color, line: poly.color }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
@ -711,7 +765,7 @@
|
||||||
|
|
||||||
update(index / levels.length, output);
|
update(index / levels.length, output);
|
||||||
});
|
});
|
||||||
|
// console.log({retractz});
|
||||||
return layers;
|
return layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,13 @@
|
||||||
shell: { check: 0x0077bb, face: 0x0077bb, line: 0x0077bb, opacity: 1 },
|
shell: { check: 0x0077bb, face: 0x0077bb, line: 0x0077bb, opacity: 1 },
|
||||||
fill: { check: 0x00bb77, face: 0x00bb77, line: 0x00bb77, opacity: 1 },
|
fill: { check: 0x00bb77, face: 0x00bb77, line: 0x00bb77, opacity: 1 },
|
||||||
infill: { check: 0x3322bb, face: 0x3322bb, line: 0x3322bb, opacity: 1 },
|
infill: { check: 0x3322bb, face: 0x3322bb, line: 0x3322bb, opacity: 1 },
|
||||||
support: { check: 0xaa5533, face: 0xaa5533, line: 0xaa5533, opacity: 1 }
|
support: { check: 0xaa5533, face: 0xaa5533, line: 0xaa5533, opacity: 1 },
|
||||||
|
gaps: { check: 0xaa3366, face: 0xaa3366, line: 0xaa3366, opacity: 1 }
|
||||||
},
|
},
|
||||||
PROTO = Object.clone(COLOR);
|
PROTO = Object.clone(COLOR),
|
||||||
|
bwcomp = (1 / Math.cos(Math.PI/4)),
|
||||||
|
getRangeParameters = FDM.getRangeParameters,
|
||||||
|
debug = false;
|
||||||
|
|
||||||
let isThin = false; // force line rendering
|
let isThin = false; // force line rendering
|
||||||
let isFlat = false; // force flat rendering
|
let isFlat = false; // force flat rendering
|
||||||
|
|
@ -57,14 +61,16 @@
|
||||||
FDM.slice = function(settings, widget, onupdate, ondone) {
|
FDM.slice = function(settings, widget, onupdate, ondone) {
|
||||||
FDM.fixExtruders(settings);
|
FDM.fixExtruders(settings);
|
||||||
let render = settings.render !== false,
|
let render = settings.render !== false,
|
||||||
|
ctrl = settings.controller,
|
||||||
spro = settings.process,
|
spro = settings.process,
|
||||||
sdev = settings.device,
|
sdev = settings.device,
|
||||||
isBelt = sdev.bedBelt,
|
isBelt = sdev.bedBelt,
|
||||||
|
isSynth = widget.track.synth,
|
||||||
update_start = Date.now(),
|
update_start = Date.now(),
|
||||||
minSolid = spro.sliceSolidMinArea,
|
minSolid = spro.sliceSolidMinArea,
|
||||||
solidLayers = spro.sliceSolidLayers,
|
solidLayers = spro.sliceSolidLayers,
|
||||||
vaseMode = spro.sliceFillType === 'vase',
|
vaseMode = spro.sliceFillType === 'vase' && !isSynth,
|
||||||
doSolidLayers = solidLayers && !vaseMode,
|
doSolidLayers = solidLayers && !vaseMode && !isSynth,
|
||||||
metadata = settings.widget[widget.id] || {},
|
metadata = settings.widget[widget.id] || {},
|
||||||
extruder = metadata.extruder || 0,
|
extruder = metadata.extruder || 0,
|
||||||
sliceHeight = spro.sliceHeight,
|
sliceHeight = spro.sliceHeight,
|
||||||
|
|
@ -77,10 +83,13 @@
|
||||||
fillSpacing = lineWidth,
|
fillSpacing = lineWidth,
|
||||||
fillOffset = lineWidth * fillOffsetMult,
|
fillOffset = lineWidth * fillOffsetMult,
|
||||||
sliceFillAngle = spro.sliceFillAngle,
|
sliceFillAngle = spro.sliceFillAngle,
|
||||||
view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null;
|
supportDensity = spro.sliceSupportDensity,
|
||||||
|
view = widget.mesh && widget.mesh.newGroup ? widget.mesh.newGroup() : null,
|
||||||
|
beltfact = Math.cos(Math.PI/4),
|
||||||
|
invbfact = 1 / beltfact;
|
||||||
|
|
||||||
isFlat = settings.controller.lineType === "flat";
|
isFlat = ctrl.lineType === "flat";
|
||||||
isThin = !isFlat && settings.controller.lineType === "line";
|
isThin = !isFlat && ctrl.lineType === "line";
|
||||||
offset = lineWidth / 2;
|
offset = lineWidth / 2;
|
||||||
|
|
||||||
if (isFlat) {
|
if (isFlat) {
|
||||||
|
|
@ -145,6 +154,7 @@
|
||||||
height: sliceHeight,
|
height: sliceHeight,
|
||||||
minHeight: sliceMinHeight,
|
minHeight: sliceMinHeight,
|
||||||
firstHeight: firstSliceHeight,
|
firstHeight: firstSliceHeight,
|
||||||
|
union: ctrl.healMesh,
|
||||||
// debug: true,
|
// debug: true,
|
||||||
// xray: 3,
|
// xray: 3,
|
||||||
// view: view
|
// view: view
|
||||||
|
|
@ -155,9 +165,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSliceDone(slices) {
|
function onSliceDone(slices) {
|
||||||
// slices = slices.filter(slice => slice.tops.length);
|
|
||||||
// remove all empty slices above part but leave below
|
// remove all empty slices above part but leave below
|
||||||
// for multi-part (multi-extruder) setups where the void is ok
|
// for multi-part (multi-extruder) setups where the void is ok
|
||||||
|
// also reverse because slicing occurs bottom-up
|
||||||
let found = false;
|
let found = false;
|
||||||
slices = slices.reverse().filter(slice => {
|
slices = slices.reverse().filter(slice => {
|
||||||
if (slice.tops.length) {
|
if (slice.tops.length) {
|
||||||
|
|
@ -173,6 +183,61 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for synth support widgets, merge tops
|
||||||
|
if (isSynth) {
|
||||||
|
for (let slice of slices) {
|
||||||
|
// union top support polys
|
||||||
|
let tops = slice.topPolys();
|
||||||
|
let union = POLY.union(tops, null, true);
|
||||||
|
if (union.length < tops.length) {
|
||||||
|
slice.tops = [];
|
||||||
|
for (let u of union) {
|
||||||
|
slice.addTop(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let gap = sliceHeight * (isBelt ? 0 : spro.sliceSupportGap);
|
||||||
|
// clip tops to other widgets in group
|
||||||
|
tops = slice.topPolys();
|
||||||
|
for (let peer of widget.group) {
|
||||||
|
// skip self
|
||||||
|
if (peer === widget) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let pslice of peer.slices) {
|
||||||
|
if (Math.abs(Math.abs(pslice.z - slice.z) - gap) > 0.1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// offset pslice tops by spro.sliceSupportOffset
|
||||||
|
if (!pslice.synth_off) {
|
||||||
|
pslice.synth_off = POLY.offset(pslice.topPolys(), spro.sliceSupportOffset);
|
||||||
|
}
|
||||||
|
let ptops = pslice.synth_off;
|
||||||
|
let ntops = [];
|
||||||
|
POLY.subtract(tops, ptops, ntops, null, slice.z, 0);
|
||||||
|
tops = ntops;
|
||||||
|
}
|
||||||
|
// trim to group's shadow if not in belt mode
|
||||||
|
if (!isBelt) {
|
||||||
|
let group = widget.group[0];
|
||||||
|
if (!group.shadow) {
|
||||||
|
let gs = [];
|
||||||
|
for (let w of group) {
|
||||||
|
if (w.shadow) {
|
||||||
|
gs = POLY.union([w.shadow,...gs],null,0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
group.shadow = gs;
|
||||||
|
}
|
||||||
|
tops = POLY.setZ(POLY.trimTo(tops, group.shadow), slice.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slice.tops = [];
|
||||||
|
for (let t of tops) {
|
||||||
|
slice.addTop(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calculate % complete and call onupdate()
|
// calculate % complete and call onupdate()
|
||||||
function doupdate(index, from, to, msg) {
|
function doupdate(index, from, to, msg) {
|
||||||
onupdate(0.5 + (from + ((index/slices.length) * (to-from))) * 0.5, msg);
|
onupdate(0.5 + (from + ((index/slices.length) * (to-from))) * 0.5, msg);
|
||||||
|
|
@ -197,16 +262,15 @@
|
||||||
slice.solids = [];
|
slice.solids = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
// fixed supports (generated ahead of time)
|
// create shadow for clipping supports
|
||||||
const fixed = Object.values(settings.widget[widget.id].support || {});
|
|
||||||
let shadow = null;
|
let shadow = null;
|
||||||
if (fixed.length || spro.sliceSupportEnable) {
|
if (true || spro.sliceSupportEnable) {
|
||||||
// create shadow. TODO test if any supports set
|
|
||||||
let alltops = slices.map(slice => slice.topPolys()).flat();
|
let alltops = slices.map(slice => slice.topPolys()).flat();
|
||||||
shadow = POLY.union(alltops,null,0.1);
|
shadow = POLY.union(alltops,null,0.1);
|
||||||
if (spro.sliceSupportExtra) {
|
if (spro.sliceSupportExtra) {
|
||||||
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
||||||
}
|
}
|
||||||
|
widget.shadow = shadow;
|
||||||
// slices[0].output()
|
// slices[0].output()
|
||||||
// .setLayer('shadow', { line: 0xff0000, check: 0xff0000 })
|
// .setLayer('shadow', { line: 0xff0000, check: 0xff0000 })
|
||||||
// .addPolys(shadow);
|
// .addPolys(shadow);
|
||||||
|
|
@ -214,28 +278,100 @@
|
||||||
|
|
||||||
// create shells and diff inner fillable areas
|
// create shells and diff inner fillable areas
|
||||||
forSlices(0.0, 0.2, slice => {
|
forSlices(0.0, 0.2, slice => {
|
||||||
|
let params = getRangeParameters(settings, slice.index);
|
||||||
|
let shellFrac = (params.sliceShells - (params.sliceShells | 0));
|
||||||
|
let sliceShells = params.sliceShells | 0;
|
||||||
|
if (ctrl.danger && shellFrac) {
|
||||||
|
let v1 = shellFrac > 0.5 ? 1 - shellFrac : shellFrac;
|
||||||
|
let v2 = 1 - v1;
|
||||||
|
let parts = Math.round(v2/v1) + 1;
|
||||||
|
let rem = slice.index % parts;
|
||||||
|
let trg = shellFrac > 0.5 ? 1 : parts - 1;
|
||||||
|
sliceShells += rem >= trg ? 1 : 0;
|
||||||
|
}
|
||||||
let first = slice.index === 0;
|
let first = slice.index === 0;
|
||||||
let solid = (
|
let isBottom = slice.index < spro.sliceBottomLayers;
|
||||||
slice.index < spro.sliceBottomLayers ||
|
let isTop = slice.index > slices.length - spro.sliceTopLayers-1;
|
||||||
slice.index > slices.length - spro.sliceTopLayers-1 ||
|
let isDense = params.sliceFillSparse > 0.98;
|
||||||
spro.sliceFillSparse > 0.95
|
let solid = (isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth;
|
||||||
) && !vaseMode;
|
let solidWidth = params.sliceFillWidth || 1;
|
||||||
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1;
|
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1;
|
||||||
let offset = shellOffset * spaceMult;
|
let offset = shellOffset * spaceMult;
|
||||||
let fillOff = fillOffset * spaceMult;
|
let fillOff = fillOffset * spaceMult;
|
||||||
doShells(slice, spro.sliceShells, offset, fillOff, {
|
let count = isSynth ? 1 : sliceShells;
|
||||||
|
doShells(slice, count, offset, fillOff, {
|
||||||
vase: vaseMode,
|
vase: vaseMode,
|
||||||
thin: spro.detectThinWalls,
|
thin: spro.detectThinWalls && !isSynth,
|
||||||
belt0: isBelt && first,
|
widget: widget,
|
||||||
widget: widget
|
danger: ctrl.danger
|
||||||
});
|
});
|
||||||
if (solid) {
|
if (solid) {
|
||||||
let fillSpace = fillSpacing * spaceMult;
|
let fillSpace = fillSpacing * spaceMult * solidWidth;
|
||||||
doSolidLayerFill(slice, fillSpace, sliceFillAngle);
|
doSolidLayerFill(slice, fillSpace, sliceFillAngle);
|
||||||
}
|
}
|
||||||
sliceFillAngle += 90.0;
|
sliceFillAngle += 90.0;
|
||||||
}, "offsets");
|
}, "offsets");
|
||||||
|
|
||||||
|
// add lead in when specified in belt mode
|
||||||
|
if (!isSynth && isBelt) {
|
||||||
|
let wb = widget.bounds;
|
||||||
|
// find adjusted zero point from slices
|
||||||
|
let smin = Infinity;
|
||||||
|
for (let slice of slices) {
|
||||||
|
let miny = Infinity;
|
||||||
|
for (let poly of slice.topPolys()) {
|
||||||
|
let y = poly.bounds.maxy;
|
||||||
|
let z = slice.z;
|
||||||
|
let by = -y + z;
|
||||||
|
if (by < miny) miny = by;
|
||||||
|
if (by < smin) smin = by;
|
||||||
|
}
|
||||||
|
slice.belt = { miny, touch: false };
|
||||||
|
}
|
||||||
|
// mark slices with tops touching belt
|
||||||
|
// also find max width of first 5 layers
|
||||||
|
let start;
|
||||||
|
let minx = Infinity, maxx = -Infinity;
|
||||||
|
for (let slice of slices) {
|
||||||
|
if (slice.index < 5) {
|
||||||
|
for (let poly of slice.topPolys()) {
|
||||||
|
minx = Math.min(minx, poly.bounds.minx);
|
||||||
|
maxx = Math.max(maxx, poly.bounds.maxx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Math.abs(slice.belt.miny - smin) < 0.001) {
|
||||||
|
slice.belt.touch = true;
|
||||||
|
if (!start) start = slice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log({smin: smin.round(4)});
|
||||||
|
let offset = spro.firstLayerBeltLead * beltfact;
|
||||||
|
// ensure we start against a layer with shells
|
||||||
|
while (start.up && start.topShells().length === 0) {
|
||||||
|
start = start.up;
|
||||||
|
}
|
||||||
|
while (offset && start && offset >= sliceHeight) {
|
||||||
|
let addto = start.down;
|
||||||
|
if (!addto) {
|
||||||
|
addto = newSlice(start.z - sliceHeight);
|
||||||
|
addto.belt = { };
|
||||||
|
addto.height = start.height;
|
||||||
|
addto.up = start;
|
||||||
|
start.down = addto;
|
||||||
|
slices.splice(0,0,addto);
|
||||||
|
}
|
||||||
|
addto.index = -1;
|
||||||
|
addto.belt.anchor = true;
|
||||||
|
let z = addto.z;
|
||||||
|
let y = z - smin - (nozzleSize / 2);
|
||||||
|
// let splat = BASE.newPolygon().add(wb.min.x, y, z).add(wb.max.x, y, z).setOpen();
|
||||||
|
let splat = BASE.newPolygon().add(minx, y, z).add(maxx, y, z).setOpen();
|
||||||
|
addto.addTop(splat).fill_sparse = [ splat ];
|
||||||
|
start = addto;
|
||||||
|
offset -= sliceHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calculations only relevant when solid layers are used
|
// calculations only relevant when solid layers are used
|
||||||
if (doSolidLayers) {
|
if (doSolidLayers) {
|
||||||
forSlices(0.2, 0.34, slice => {
|
forSlices(0.2, 0.34, slice => {
|
||||||
|
|
@ -246,48 +382,68 @@
|
||||||
projectBridges(slice, solidLayers);
|
projectBridges(slice, solidLayers);
|
||||||
}, "solids");
|
}, "solids");
|
||||||
forSlices(0.35, 0.5, slice => {
|
forSlices(0.35, 0.5, slice => {
|
||||||
|
let params = getRangeParameters(settings, slice.index);
|
||||||
let first = slice.index === 0;
|
let first = slice.index === 0;
|
||||||
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1;
|
let solidWidth = params.sliceFillWidth || 1;
|
||||||
let fillSpace = fillSpacing * spaceMult;
|
let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
|
||||||
|
let fillSpace = fillSpacing * spaceMult * solidWidth;
|
||||||
doSolidsFill(slice, fillSpace, sliceFillAngle, minSolid);
|
doSolidsFill(slice, fillSpace, sliceFillAngle, minSolid);
|
||||||
sliceFillAngle += 90.0;
|
sliceFillAngle += 90.0;
|
||||||
}, "solids");
|
}, "solids");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sparse layers only present when non-vase mose and sparse % > 0
|
// sparse layers only present when non-vase mose and sparse % > 0
|
||||||
if (!vaseMode && spro.sliceFillSparse > 0.0) {
|
if (!isSynth) {
|
||||||
|
let lastType;
|
||||||
forSlices(0.5, 0.7, slice => {
|
forSlices(0.5, 0.7, slice => {
|
||||||
|
let params = getRangeParameters(settings, slice.index);
|
||||||
|
if (vaseMode || !params.sliceFillSparse) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newType = params.sliceFillType;
|
||||||
doSparseLayerFill(slice, {
|
doSparseLayerFill(slice, {
|
||||||
settings: settings,
|
settings: settings,
|
||||||
process: spro,
|
process: spro,
|
||||||
device: sdev,
|
device: sdev,
|
||||||
lineWidth: lineWidth,
|
lineWidth: lineWidth,
|
||||||
spacing: fillOffset,
|
spacing: fillOffset,
|
||||||
density: spro.sliceFillSparse,
|
density: params.sliceFillSparse,
|
||||||
bounds: widget.getBoundingBox(),
|
bounds: widget.getBoundingBox(),
|
||||||
height: sliceHeight,
|
height: sliceHeight,
|
||||||
type: spro.sliceFillType
|
type: newType,
|
||||||
|
cache: params._range !== true && lastType === newType
|
||||||
});
|
});
|
||||||
|
lastType = newType;
|
||||||
|
}, "infill");
|
||||||
|
} else if (isSynth) {
|
||||||
|
forSlices(0.5, 0.7, slice => {
|
||||||
|
let params = getRangeParameters(settings, slice.index);
|
||||||
|
let density = params.sliceSupportDensity;
|
||||||
|
if (density)
|
||||||
|
for (let top of slice.tops) {
|
||||||
|
let offset = [];
|
||||||
|
POLY.expand(top.shells, -nozzleSize/4, slice.z, offset);
|
||||||
|
fillSupportPolys(offset, lineWidth, density, slice.z);
|
||||||
|
top.fill_lines = offset.map(o => o.fill).flat().filter(v => v);
|
||||||
|
}
|
||||||
}, "infill");
|
}, "infill");
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculations only relevant when supports are enabled
|
// auto support generation
|
||||||
if (!isBelt) {
|
if (!isBelt && !isSynth && supportDensity && spro.sliceSupportEnable) {
|
||||||
let auto = spro.sliceSupportEnable && spro.sliceSupportDensity > 0.0,
|
|
||||||
minArea = spro.sliceSupportArea;
|
|
||||||
|
|
||||||
forSlices(0.7, 0.8, slice => {
|
forSlices(0.7, 0.8, slice => {
|
||||||
doSupport(slice, spro, auto, fixed, shadow);
|
doSupport(slice, spro, shadow);
|
||||||
}, "support");
|
}, "support");
|
||||||
forSlices(0.8, 0.9, slice => {
|
forSlices(0.8, 0.9, slice => {
|
||||||
doSupportFill(slice, lineWidth, spro.sliceSupportDensity, minArea);
|
doSupportFill(slice, lineWidth, supportDensity, spro.sliceSupportArea);
|
||||||
}, "support");
|
}, "support");
|
||||||
}
|
}
|
||||||
|
|
||||||
// render if not explicitly disabled
|
// render if not explicitly disabled
|
||||||
if (render) {
|
if (render) {
|
||||||
forSlices(0.9, 1.0, slice => {
|
forSlices(0.9, 1.0, slice => {
|
||||||
doRender(slice);
|
let params = getRangeParameters(settings, slice.index);
|
||||||
|
doRender(slice, isSynth, params);
|
||||||
}, "render");
|
}, "render");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,32 +466,35 @@
|
||||||
return Math.max(min,Math.min(max,v));
|
return Math.max(min,Math.min(max,v));
|
||||||
}
|
}
|
||||||
|
|
||||||
function doRender(slice) {
|
function doRender(slice, isSynth, params) {
|
||||||
const output = slice.output();
|
const output = slice.output();
|
||||||
const height = slice.height / 2;
|
const height = slice.height / 2;
|
||||||
|
const solidWidth = params.sliceFillWidth || 1;
|
||||||
|
|
||||||
slice.tops.forEach(top => {
|
slice.tops.forEach(top => {
|
||||||
if (isThin) {
|
if (isThin) output
|
||||||
output
|
.setLayer('slice', { line: 0x000066, check: 0x000066 })
|
||||||
.setLayer('slice', { line: 0x000066, check: 0x000066 })
|
.addPolys(top.poly);
|
||||||
.addPolys(top.poly);
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
if (top.shells) output
|
||||||
.setLayer("shells", COLOR.shell)
|
.setLayer("shells", isSynth ? COLOR.support : COLOR.shell)
|
||||||
.addPolys(top.shells, vopt({ offset, height }));
|
.addPolys(top.shells, vopt({ offset, height }));
|
||||||
|
|
||||||
// if (isThin && debug) {
|
if (top.gaps) output
|
||||||
// slice.output()
|
.setLayer("gaps", COLOR.gaps)
|
||||||
// .setLayer('offset', { face: 0, line: 0x888888 })
|
.addPolys(top.gaps, vopt({ offset, height, thin: true }));
|
||||||
// .addPolys(top.fill_off)
|
|
||||||
// .setLayer('last', { face: 0, line: 0x008888 })
|
|
||||||
// .addPolys(top.last);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (top.fill_lines) output
|
if (isThin && debug) {
|
||||||
.setLayer("fill", COLOR.fill)
|
slice.output()
|
||||||
.addLines(top.fill_lines, vopt({ offset, height }));
|
.setLayer('offset', { face: 0, line: 0x888888 })
|
||||||
|
.addPolys(top.fill_off)
|
||||||
|
.setLayer('last', { face: 0, line: 0x008888 })
|
||||||
|
.addPolys(top.last);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top.fill_lines && top.fill_lines.length) output
|
||||||
|
.setLayer("fill", isSynth ? COLOR.support : COLOR.fill)
|
||||||
|
.addLines(top.fill_lines, vopt({ offset: offset * solidWidth, height }));
|
||||||
|
|
||||||
if (top.fill_sparse) output
|
if (top.fill_sparse) output
|
||||||
.setLayer("infill", COLOR.infill)
|
.setLayer("infill", COLOR.infill)
|
||||||
|
|
@ -344,15 +503,22 @@
|
||||||
if (top.thin_fill) output
|
if (top.thin_fill) output
|
||||||
.setLayer("fill", COLOR.fill)
|
.setLayer("fill", COLOR.fill)
|
||||||
.addLines(top.thin_fill, vopt({ offset, height }));
|
.addLines(top.thin_fill, vopt({ offset, height }));
|
||||||
|
|
||||||
// emit solid areas
|
|
||||||
// if (isThin && debug) {
|
|
||||||
// output
|
|
||||||
// .setLayer("solids", { face: 0x00dd00 })
|
|
||||||
// .addAreas(slice.solids);
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isThin && debug) {
|
||||||
|
if (slice.solids) output
|
||||||
|
.setLayer("solids", { face: 0x00dd00 })
|
||||||
|
.addAreas(slice.solids);
|
||||||
|
|
||||||
|
if (slice.bridges) output
|
||||||
|
.setLayer("bridges", { face: 0x00aaaa, line: 0x00aaaa })
|
||||||
|
.addAreas(slice.bridges);
|
||||||
|
|
||||||
|
if (slice.flats) output
|
||||||
|
.setLayer("flats", { face: 0xaa00aa, line: 0xaa00aa })
|
||||||
|
.addAreas(slice.flats);
|
||||||
|
}
|
||||||
|
|
||||||
if (slice.supports) output
|
if (slice.supports) output
|
||||||
.setLayer("support", COLOR.support)
|
.setLayer("support", COLOR.support)
|
||||||
.addPolys(slice.supports, vopt({ offset, height }));
|
.addPolys(slice.supports, vopt({ offset, height }));
|
||||||
|
|
@ -363,16 +529,6 @@
|
||||||
.addLines(poly.fill, vopt({ offset, height }));
|
.addLines(poly.fill, vopt({ offset, height }));
|
||||||
});
|
});
|
||||||
|
|
||||||
// if (isThin && debug) {
|
|
||||||
// output
|
|
||||||
// .setLayer("bridges", { face: 0x00aaaa, line: 0x00aaaa })
|
|
||||||
// .addAreas(top.bridges);
|
|
||||||
//
|
|
||||||
// output
|
|
||||||
// .setLayer("flats", { face: 0xaa00aa, line: 0xaa00aa })
|
|
||||||
// .addAreas(top.flats);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log(slice.index, slice.render.stats);
|
// console.log(slice.index, slice.render.stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -433,7 +589,22 @@
|
||||||
let dist = p.first().distTo2D(p.last());
|
let dist = p.first().distTo2D(p.last());
|
||||||
if (dist < 1) p.open = false;
|
if (dist < 1) p.open = false;
|
||||||
} });
|
} });
|
||||||
if (opt.thin) {
|
if (opt.danger && opt.thin) {
|
||||||
|
top.thin_fill = [];
|
||||||
|
top.fill_sparse = [];
|
||||||
|
let layers = POLY.inset(top_poly, offsetN, count, z);
|
||||||
|
last = layers.last().mid;
|
||||||
|
top.shells = layers.map(r => r.mid).flat();
|
||||||
|
top.gaps = layers.map(r => r.gap).flat();
|
||||||
|
let off = offsetN;
|
||||||
|
let min = off * 0.75;
|
||||||
|
let max = off * 4;
|
||||||
|
for (let poly of layers.map(r => r.gap).flat()) {
|
||||||
|
let centers = poly.centers(off/2, z, min, max, {lines:false});
|
||||||
|
top.fill_sparse.appendAll(centers);
|
||||||
|
// top.fill_lines.appendAll(centers);
|
||||||
|
}
|
||||||
|
} else if (opt.thin) {
|
||||||
top.thin_fill = [];
|
top.thin_fill = [];
|
||||||
let oso = {z, count, gaps: [], outs: [], minArea: 0.05};
|
let oso = {z, count, gaps: [], outs: [], minArea: 0.05};
|
||||||
POLY.offset(top_poly, [-offset1, -offsetN], oso);
|
POLY.offset(top_poly, [-offset1, -offsetN], oso);
|
||||||
|
|
@ -444,6 +615,11 @@
|
||||||
if (p.fill_off) {
|
if (p.fill_off) {
|
||||||
p.fill_off.forEach(pi => pi.depth = i);
|
p.fill_off.forEach(pi => pi.depth = i);
|
||||||
}
|
}
|
||||||
|
if (p.inner) {
|
||||||
|
for (let pi of p.inner) {
|
||||||
|
pi.depth = p.depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
top.shells.push(p);
|
top.shells.push(p);
|
||||||
});
|
});
|
||||||
last = polys;
|
last = polys;
|
||||||
|
|
@ -453,12 +629,9 @@
|
||||||
oso.gaps.forEach((polys, i) => {
|
oso.gaps.forEach((polys, i) => {
|
||||||
let off = (i == 0 ? offset1 : offsetN);
|
let off = (i == 0 ? offset1 : offsetN);
|
||||||
polys = POLY.offset(polys, -off * 0.8, {z, minArea: 0});
|
polys = POLY.offset(polys, -off * 0.8, {z, minArea: 0});
|
||||||
// polys.forEach(p => { slice.solids.trimmed.push(p); });
|
|
||||||
top.thin_fill.appendAll(cullIntersections(
|
top.thin_fill.appendAll(cullIntersections(
|
||||||
fillArea(polys, 45, off/2, [], 0.01, off*2),
|
fillArea(polys, 45, off/2, [], 0.01, off*2),
|
||||||
fillArea(polys, 135, off/2, [], 0.01, off*2),
|
fillArea(polys, 135, off/2, [], 0.01, off*2),
|
||||||
// fillArea(polys, 90, off, [], 0.05, off*4),
|
|
||||||
// fillArea(polys, 180, off, [], 0.05, off*4),
|
|
||||||
));
|
));
|
||||||
gaps = polys;
|
gaps = polys;
|
||||||
});
|
});
|
||||||
|
|
@ -481,6 +654,11 @@
|
||||||
// use negative offset for inners
|
// use negative offset for inners
|
||||||
pi.depth = -(count - countNow);
|
pi.depth = -(count - countNow);
|
||||||
});
|
});
|
||||||
|
if (p.inner) {
|
||||||
|
for (let pi of p.inner) {
|
||||||
|
pi.depth = p.depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -507,23 +685,6 @@
|
||||||
top.last = last;
|
top.last = last;
|
||||||
|
|
||||||
shellout += top.shells.length;
|
shellout += top.shells.length;
|
||||||
|
|
||||||
// add anchor extrusion if missing on the first belt layer
|
|
||||||
// todo: fix. disabled because throws off layer min y calculations in some cases
|
|
||||||
if (false && opt.belt0 && top.shells.length === 0 && slice.up && slice.up.tops.length) {
|
|
||||||
for (let up of slice.up.tops) {
|
|
||||||
let bounds = up.poly.bounds,
|
|
||||||
midy = (bounds.miny + bounds.maxy) / 2;
|
|
||||||
if (top.poly.isInside(up.poly, 1)) {
|
|
||||||
slice.widget.belt.ymid = midy;
|
|
||||||
slice.widget.belt.zmid = slice.z;
|
|
||||||
top.shells.push(BASE.newPolygon()
|
|
||||||
.setOpen()
|
|
||||||
.add(bounds.minx,midy,slice.z)
|
|
||||||
.add(bounds.maxx,midy,slice.z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -559,6 +720,7 @@
|
||||||
density = options.density, // density of infill 0.0 - 1.0
|
density = options.density, // density of infill 0.0 - 1.0
|
||||||
bounds = options.bounds, // bounding box of widget
|
bounds = options.bounds, // bounding box of widget
|
||||||
height = options.height, // z layer height
|
height = options.height, // z layer height
|
||||||
|
cache = !(options.cache === false),
|
||||||
type = options.type || 'hex';
|
type = options.type || 'hex';
|
||||||
|
|
||||||
if (slice.tops.length === 0 || density === 0.0 || slice.isSolidLayer) {
|
if (slice.tops.length === 0 || density === 0.0 || slice.isSolidLayer) {
|
||||||
|
|
@ -622,7 +784,7 @@
|
||||||
|
|
||||||
// prepare top infill structure
|
// prepare top infill structure
|
||||||
tops.forEach(function(top) {
|
tops.forEach(function(top) {
|
||||||
top.fill_sparse = [];
|
top.fill_sparse = top.fill_sparse || [];
|
||||||
polys.appendAll(top.fill_off);
|
polys.appendAll(top.fill_off);
|
||||||
polys.appendAll(top.solids);
|
polys.appendAll(top.solids);
|
||||||
});
|
});
|
||||||
|
|
@ -630,7 +792,7 @@
|
||||||
// update fill fingerprint for this slice
|
// update fill fingerprint for this slice
|
||||||
slice._fill_finger = POLY.fingerprint(polys);
|
slice._fill_finger = POLY.fingerprint(polys);
|
||||||
|
|
||||||
let skippable = FILLFIXED[type] ? true : false;
|
let skippable = cache && FILLFIXED[type] ? true : false;
|
||||||
let miss = false;
|
let miss = false;
|
||||||
// if the layer below has the same fingerprint,
|
// if the layer below has the same fingerprint,
|
||||||
// we may be able to clone the infill instead of regenerating it
|
// we may be able to clone the infill instead of regenerating it
|
||||||
|
|
@ -779,25 +941,27 @@
|
||||||
|
|
||||||
let minarea = minArea || 1,
|
let minarea = minArea || 1,
|
||||||
tops = slice.tops,
|
tops = slice.tops,
|
||||||
solids = slice.solids,
|
solids = slice.solids;
|
||||||
unioned = POLY.union(solids, undefined, true).flat(), // TODO verify
|
|
||||||
|
if (!(tops && solids)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let unioned = POLY.union(solids, undefined, true).flat(), // TODO verify
|
||||||
isSLA = (spacing === undefined && angle === undefined);
|
isSLA = (spacing === undefined && angle === undefined);
|
||||||
|
|
||||||
if (solids.length === 0) return false;
|
if (solids.length === 0) return false;
|
||||||
if (unioned.length === 0) return false;
|
if (unioned.length === 0) return false;
|
||||||
|
|
||||||
let masks,
|
let trims = [],
|
||||||
trims = [],
|
|
||||||
inner = isSLA ? slice.topPolys() : slice.topFillOff();
|
inner = isSLA ? slice.topPolys() : slice.topFillOff();
|
||||||
|
|
||||||
// trim each solid to the inner bounds
|
// trim each solid to the inner bounds
|
||||||
unioned.forEach(function(p) {
|
unioned.forEach(function(p) {
|
||||||
p.setZ(slice.z);
|
p.setZ(slice.z);
|
||||||
inner.forEach(function(i) {
|
inner.forEach(function(i) {
|
||||||
if (p.del) return;
|
let masks = p.mask(i);
|
||||||
masks = p.mask(i);
|
|
||||||
if (masks && masks.length > 0) {
|
if (masks && masks.length > 0) {
|
||||||
p.del = true;
|
|
||||||
trims.appendAll(masks);
|
trims.appendAll(masks);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -832,6 +996,10 @@
|
||||||
|
|
||||||
// create empty filled line array for each top
|
// create empty filled line array for each top
|
||||||
tops.forEach(function(top) {
|
tops.forEach(function(top) {
|
||||||
|
// synth belt anchor tops don't want fill
|
||||||
|
if (!top.fill_lines) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const tofill = [];
|
const tofill = [];
|
||||||
const angfill = [];
|
const angfill = [];
|
||||||
const newfill = [];
|
const newfill = [];
|
||||||
|
|
@ -857,7 +1025,6 @@
|
||||||
top.fill_lines_ang.poly.push(af.clone());
|
top.fill_lines_ang.poly.push(af.clone());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
top.fill_lines.appendAll(newfill);
|
top.fill_lines.appendAll(newfill);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -865,12 +1032,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculate external overhangs requiring support.
|
* calculate external overhangs requiring support
|
||||||
* this is done bottom-up except for fixed supports (manual)
|
|
||||||
*/
|
*/
|
||||||
function doSupport(slice, proc, auto, fixed, shadow) {
|
function doSupport(slice, proc, shadow) {
|
||||||
let minOffset = proc.sliceSupportOffset,
|
let maxBridge = proc.sliceSupportSpan || 5,
|
||||||
maxBridge = proc.sliceSupportSpan || 5,
|
|
||||||
minArea = proc.supportMinArea,
|
minArea = proc.supportMinArea,
|
||||||
pillarSize = proc.sliceSupportSize,
|
pillarSize = proc.sliceSupportSize,
|
||||||
offset = proc.sliceSupportOffset,
|
offset = proc.sliceSupportOffset,
|
||||||
|
|
@ -900,7 +1065,7 @@
|
||||||
let supported = point.isInPolygonOnly(down_tops);
|
let supported = point.isInPolygonOnly(down_tops);
|
||||||
if (!supported) down_traces.forEach(function(trace) {
|
if (!supported) down_traces.forEach(function(trace) {
|
||||||
trace.forEachSegment(function(p1, p2) {
|
trace.forEachSegment(function(p1, p2) {
|
||||||
if (point.distToLine(p1, p2) <= minOffset) {
|
if (point.distToLine(p1, p2) <= offset) {
|
||||||
return supported = true;
|
return supported = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -927,7 +1092,7 @@
|
||||||
let supports = [];
|
let supports = [];
|
||||||
|
|
||||||
// generate support polys from unsupported points
|
// generate support polys from unsupported points
|
||||||
if (auto && slice.down) (function() {
|
if (slice.down) (function() {
|
||||||
// check trace line support needs
|
// check trace line support needs
|
||||||
traces.forEach(function(trace) {
|
traces.forEach(function(trace) {
|
||||||
trace.forEachSegment(function(p1, p2) { checkLineSupport(p1, p2, true) });
|
trace.forEachSegment(function(p1, p2) { checkLineSupport(p1, p2, true) });
|
||||||
|
|
@ -952,21 +1117,10 @@
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (supports.length === 0 && !(fixed && fixed.length)) {
|
if (supports.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixed && fixed.length) {
|
|
||||||
for (let sup of fixed) {
|
|
||||||
let zmin = sup.z - sup.dh / 2;
|
|
||||||
let zmax = sup.z + sup.dh / 2;
|
|
||||||
if (slice.z >= zmin && slice.z <= zmax) {
|
|
||||||
let center = BASE.newPoint(sup.x, sup.y, slice.z);
|
|
||||||
supports.push(BASE.newPolygon().centerRectangle(center, sup.dw, sup.dw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// then union supports
|
// then union supports
|
||||||
supports = POLY.union(supports, null, true);
|
supports = POLY.union(supports, null, true);
|
||||||
|
|
||||||
|
|
@ -984,7 +1138,7 @@
|
||||||
|
|
||||||
// set depth hint on support polys for infill density
|
// set depth hint on support polys for infill density
|
||||||
trimmed.forEach(function(trim) {
|
trimmed.forEach(function(trim) {
|
||||||
if (trim.area() < 0.1) return;
|
// if (trim.area() < 0.1) return;
|
||||||
culled.push(trim.setZ(down.z));
|
culled.push(trim.setZ(down.z));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1031,23 +1185,29 @@
|
||||||
supports = nsC;
|
supports = nsC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supports) supports.forEach(function (poly) {
|
if (supports) {
|
||||||
|
fillSupportPolys(supports, linewidth, density, slice.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-assign new supports back to slice
|
||||||
|
slice.supports = supports;
|
||||||
|
};
|
||||||
|
|
||||||
|
function fillSupportPolys(polys, linewidth, density, z) {
|
||||||
|
// calculate fill density
|
||||||
|
let spacing = linewidth * (1 / density);
|
||||||
|
polys.forEach(function (poly) {
|
||||||
// angle based on width/height ratio
|
// angle based on width/height ratio
|
||||||
let angle = (poly.bounds.width() / poly.bounds.height() > 1) ? 90 : 0;
|
let angle = (poly.bounds.width() / poly.bounds.height() > 1) ? 90 : 0;
|
||||||
// calculate fill density
|
|
||||||
let spacing = linewidth * (1 / density);
|
|
||||||
// inset support poly for fill lines 33% of nozzle width
|
// inset support poly for fill lines 33% of nozzle width
|
||||||
let inset = POLY.offset([poly], -linewidth/3, {flat: true, z: slice.z});
|
let inset = POLY.offset([poly], -linewidth/3, {flat: true, z});
|
||||||
// do the fill
|
// do the fill
|
||||||
if (inset && inset.length > 0) {
|
if (inset && inset.length > 0) {
|
||||||
fillArea(inset, angle, spacing, poly.fill = []);
|
fillArea(inset, angle, spacing, poly.fill = []);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// re-assign new supports back to slice
|
|
||||||
slice.supports = supports;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -1126,14 +1286,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
FDM.supports = function(settings, widget) {
|
FDM.supports = function(settings, widget) {
|
||||||
|
let isBelt = settings.device.bedBelt;
|
||||||
let process = settings.process;
|
let process = settings.process;
|
||||||
let size = process.sliceSupportSize;
|
let size = process.sliceSupportSize;
|
||||||
let min = process.sliceSupportArea || 0.1;
|
let min = process.sliceSupportArea || 1;
|
||||||
let buf = new THREE.BufferGeometry();
|
let geo = new THREE.BufferGeometry();
|
||||||
buf.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
geo.setAttribute('position', new THREE.BufferAttribute(widget.vertices, 3));
|
||||||
let mat = new THREE.MeshBasicMaterial();
|
let mat = new THREE.MeshBasicMaterial();
|
||||||
let geo = new THREE.Geometry().fromBufferGeometry(buf);
|
let rad = (Math.PI / 180);
|
||||||
let angle = (Math.PI / 180) * settings.process.sliceSupportAngle;
|
let deg = (180 / Math.PI);
|
||||||
|
let angle = rad * settings.process.sliceSupportAngle;
|
||||||
let thresh = -Math.sin(angle);
|
let thresh = -Math.sin(angle);
|
||||||
let dir = new THREE.Vector3(0,0,-1)
|
let dir = new THREE.Vector3(0,0,-1)
|
||||||
let add = [];
|
let add = [];
|
||||||
|
|
@ -1167,6 +1329,13 @@
|
||||||
if (point.added) {
|
if (point.added) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (let added of add) {
|
||||||
|
let p2 = new THREE.Vector2(point.x, point.y);
|
||||||
|
let pm = new THREE.Vector2(added.mid.x, added.mid.y);
|
||||||
|
if (p2.distanceTo(pm) < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
let ray = new THREE.Raycaster(point, dir);
|
let ray = new THREE.Raycaster(point, dir);
|
||||||
let int = ray.intersectObjects([ mesh, platform ], false);
|
let int = ray.intersectObjects([ mesh, platform ], false);
|
||||||
if (int && int.length && int[0].distance > 0.01) {
|
if (int && int.length && int[0].distance > 0.01) {
|
||||||
|
|
@ -1175,20 +1344,33 @@
|
||||||
point.added = true;
|
point.added = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
geo.faces.filter(f => f.normal.z < thresh).forEach(face => {
|
let filter = isBelt ? (norm) => {
|
||||||
let a = geo.vertices[face.a];
|
return norm.z < thresh && norm.y < -0.001;
|
||||||
let b = geo.vertices[face.b];
|
} : (norm) => {
|
||||||
let c = geo.vertices[face.c];
|
return norm.z < thresh;
|
||||||
|
};
|
||||||
|
let { position } = geo.attributes;
|
||||||
|
let { itemSize, count, array } = position;
|
||||||
|
for (let i = 0; i<count; i += 3) {
|
||||||
|
let ip = i * itemSize;
|
||||||
|
let a = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
|
let b = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
|
let c = new THREE.Vector3(array[ip++], array[ip++], array[ip++]);
|
||||||
|
let norm = THREE.computeFaceNormal(a,b,c);
|
||||||
|
// limit to downward faces
|
||||||
|
if (!filter(norm)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// skip tiny faces
|
// skip tiny faces
|
||||||
|
let area = BASE.newPolygon().addPoints([a,b,c]).area();
|
||||||
if (BASE.newPolygon().addPoints([a,b,c]).area() < min) {
|
if (BASE.newPolygon().addPoints([a,b,c]).area() < min) {
|
||||||
skip++;
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
tp(new THREE.Vector3().add(a).add(b).add(c).divideScalar(3));
|
tp(new THREE.Vector3().add(a).add(b).add(c).divideScalar(3));
|
||||||
tl(a,b);
|
tl(a,b);
|
||||||
tl(b,c);
|
tl(b,c);
|
||||||
tl(a,c);
|
tl(a,c);
|
||||||
});
|
}
|
||||||
widget.supports = add;
|
widget.supports = add;
|
||||||
return add.length > 0;
|
return add.length > 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@
|
||||||
e = o.point;
|
e = o.point;
|
||||||
e.x += p.max.w / 2 - m.fit.x;
|
e.x += p.max.w / 2 - m.fit.x;
|
||||||
e.y += p.max.h / 2 - m.fit.y;
|
e.y += p.max.h / 2 - m.fit.y;
|
||||||
// e.z = 0;
|
e.z = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -476,6 +476,8 @@
|
||||||
// };
|
// };
|
||||||
// } else
|
// } else
|
||||||
// load renderer code in worker context only
|
// load renderer code in worker context only
|
||||||
|
let wasm;
|
||||||
|
|
||||||
fetch('/wasm/kiri-sla.wasm')
|
fetch('/wasm/kiri-sla.wasm')
|
||||||
.then(response => response.arrayBuffer())
|
.then(response => response.arrayBuffer())
|
||||||
.then(bytes => WebAssembly.instantiate(bytes, {
|
.then(bytes => WebAssembly.instantiate(bytes, {
|
||||||
|
|
@ -488,7 +490,7 @@
|
||||||
let {module, instance} = results;
|
let {module, instance} = results;
|
||||||
let {exports} = instance;
|
let {exports} = instance;
|
||||||
let heap = new Uint8Array(exports.memory.buffer);
|
let heap = new Uint8Array(exports.memory.buffer);
|
||||||
self.wasm = {
|
wasm = {
|
||||||
heap,
|
heap,
|
||||||
memory: exports.memory,
|
memory: exports.memory,
|
||||||
render: exports.render,
|
render: exports.render,
|
||||||
|
|
@ -502,7 +504,6 @@
|
||||||
let width2 = width / 2, height2 = height / 2;
|
let width2 = width / 2, height2 = height / 2;
|
||||||
let array = [];
|
let array = [];
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let wasm = self.wasm;
|
|
||||||
|
|
||||||
function scaleMovePoly(poly) {
|
function scaleMovePoly(poly) {
|
||||||
let points = poly.points;
|
let points = poly.points;
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,15 @@ MOTO.CTRL = function (object, domElement, notify, slider) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getTarget = function() {
|
||||||
|
return this.target;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setTarget = function(t) {
|
||||||
|
this.target = t;
|
||||||
|
this.target0 = t.clone();
|
||||||
|
}
|
||||||
|
|
||||||
function isValue(v) {
|
function isValue(v) {
|
||||||
return v !== null && v !== undefined;
|
return v !== null && v !== undefined;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,13 @@
|
||||||
PI2 = PI / 2,
|
PI2 = PI / 2,
|
||||||
PI4 = PI / 4,
|
PI4 = PI / 4,
|
||||||
ROUND = Math.round,
|
ROUND = Math.round,
|
||||||
|
panX = 0,
|
||||||
panY = 0,
|
panY = 0,
|
||||||
|
panZ = 0,
|
||||||
|
home = 0,
|
||||||
gridZOff = 0,
|
gridZOff = 0,
|
||||||
|
tweenTime = 500,
|
||||||
|
tweenDelay = 20,
|
||||||
platformZOff = 0,
|
platformZOff = 0,
|
||||||
perspective = 35,
|
perspective = 35,
|
||||||
refreshTimeout = null,
|
refreshTimeout = null,
|
||||||
|
|
@ -92,6 +97,7 @@
|
||||||
camera,
|
camera,
|
||||||
renderer,
|
renderer,
|
||||||
container,
|
container,
|
||||||
|
raycaster,
|
||||||
freezeTo,
|
freezeTo,
|
||||||
freeze,
|
freeze,
|
||||||
isRound = false,
|
isRound = false,
|
||||||
|
|
@ -139,7 +145,7 @@
|
||||||
|
|
||||||
function tweenit() {
|
function tweenit() {
|
||||||
TWEEN.update();
|
TWEEN.update();
|
||||||
setTimeout(tweenit, 20);
|
setTimeout(tweenit, tweenDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
tweenit();
|
tweenit();
|
||||||
|
|
@ -170,12 +176,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new TWEEN.Tween(from).
|
new TWEEN.Tween(from).
|
||||||
to(to, 500).
|
to(to, tweenTime).
|
||||||
onUpdate(tf).
|
onUpdate(tf).
|
||||||
onComplete(() => {
|
onComplete(() => {
|
||||||
viewControl.setPosition(pos);
|
viewControl.setPosition(pos);
|
||||||
updateLastAction();
|
updateLastAction();
|
||||||
refresh();
|
refresh();
|
||||||
|
if (pos.then) pos.then();
|
||||||
}).
|
}).
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +202,7 @@
|
||||||
setGrid();
|
setGrid();
|
||||||
};
|
};
|
||||||
new TWEEN.Tween(from).
|
new TWEEN.Tween(from).
|
||||||
to(to, 500).
|
to(to, tweenTime).
|
||||||
onStart(start).
|
onStart(start).
|
||||||
onUpdate(update).
|
onUpdate(update).
|
||||||
onComplete(complete).
|
onComplete(complete).
|
||||||
|
|
@ -676,14 +683,15 @@
|
||||||
if (points.length % 2 != 0) {
|
if (points.length % 2 != 0) {
|
||||||
throw "invalid line : "+points.length;
|
throw "invalid line : "+points.length;
|
||||||
}
|
}
|
||||||
const geo = new THREE.Geometry();
|
const geo = new THREE.BufferGeometry();
|
||||||
for (let i=0; i < points.length; ) {
|
const vrt = new Float32Array(points.length * 3);
|
||||||
const p1 = points[i++];
|
let vi = 0;
|
||||||
const p2 = points[i++];
|
for (let p of points) {
|
||||||
geo.vertices.push(new THREE.Vector3(p1.x, p1.y, p1.z));
|
vrt[vi++] = p.x;
|
||||||
geo.vertices.push(new THREE.Vector3(p2.x, p2.y, p2.z));
|
vrt[vi++] = p.y;
|
||||||
|
vrt[vi++] = p.z;
|
||||||
}
|
}
|
||||||
geo.verticesNeedUpdate = true;
|
geo.setAttribute('position', new THREE.BufferAttribute(vrt, 3));
|
||||||
return new THREE.LineSegments(geo, new THREE.LineBasicMaterial({
|
return new THREE.LineSegments(geo, new THREE.LineBasicMaterial({
|
||||||
color: color,
|
color: color,
|
||||||
opacity: opacity || 1,
|
opacity: opacity || 1,
|
||||||
|
|
@ -692,9 +700,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function intersect(objects, recurse) {
|
function intersect(objects, recurse) {
|
||||||
let lookAt = new THREE.Vector3(mouse.x, mouse.y, 0.0).unproject(camera);
|
return raycaster.intersectObjects(objects, recurse);
|
||||||
let ray = new THREE.Raycaster(camera.position, lookAt.sub(camera.position).normalize());
|
|
||||||
return ray.intersectObjects(objects, recurse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ******************************************************************
|
/** ******************************************************************
|
||||||
|
|
@ -802,6 +808,11 @@
|
||||||
updateLastAction();
|
updateLastAction();
|
||||||
let int, vis;
|
let int, vis;
|
||||||
|
|
||||||
|
const mv = new THREE.Vector2();
|
||||||
|
mv.x = ( event.clientX / window.innerWidth ) * 2 - 1;
|
||||||
|
mv.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
|
||||||
|
raycaster.setFromCamera( mv, camera );
|
||||||
|
|
||||||
if (viewControl.enabled) {
|
if (viewControl.enabled) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let selection = mouseHover ? mouseHover() : null;
|
let selection = mouseHover ? mouseHover() : null;
|
||||||
|
|
@ -847,6 +858,7 @@
|
||||||
onEnterKey: onEnterKey,
|
onEnterKey: onEnterKey,
|
||||||
onResize: onResize,
|
onResize: onResize,
|
||||||
update: requestRefresh,
|
update: requestRefresh,
|
||||||
|
raycast: intersect,
|
||||||
refresh: refresh,
|
refresh: refresh,
|
||||||
|
|
||||||
showSkyGrid: function(b) {
|
showSkyGrid: function(b) {
|
||||||
|
|
@ -884,6 +896,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
platform: {
|
platform: {
|
||||||
|
update: updateDraws,
|
||||||
tweenTo: tweenPlatform,
|
tweenTo: tweenPlatform,
|
||||||
setSize: setPlatformSizeUpdateGrid,
|
setSize: setPlatformSizeUpdateGrid,
|
||||||
setColor: setPlatformColor,
|
setColor: setPlatformColor,
|
||||||
|
|
@ -896,6 +909,7 @@
|
||||||
add: function(o) { WORLD.add(o) },
|
add: function(o) { WORLD.add(o) },
|
||||||
remove: function(o) { WORLD.remove(o) },
|
remove: function(o) { WORLD.remove(o) },
|
||||||
setMaxZ: function(z) { panY = z / 2 },
|
setMaxZ: function(z) { panY = z / 2 },
|
||||||
|
setCenter: function(x,y,z) { panX = x; panY = z, panZ = y },
|
||||||
isHidden: function() { return !showPlatform },
|
isHidden: function() { return !showPlatform },
|
||||||
setHidden: function(b) { showPlatform = !b; platform.visible = !b },
|
setHidden: function(b) { showPlatform = !b; platform.visible = !b },
|
||||||
setHiding: function(b) { hidePlatformBelow = b },
|
setHiding: function(b) { hidePlatformBelow = b },
|
||||||
|
|
@ -935,12 +949,12 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
view: {
|
view: {
|
||||||
top: function() { tweenCam({left: 0, up: 0, panX: 0, panY: panY, panZ: 0}) },
|
top: function(then) { tweenCam({left: home, up: 0, panX, panY, panZ, then}) },
|
||||||
back: function() { tweenCam({left: PI, up: PI2, panX: 0, panY: panY, panZ: 0}) },
|
back: function(then) { tweenCam({left: PI, up: PI2, panX, panY, panZ, then}) },
|
||||||
home: function() { tweenCam({left: 0, up: PI4, panX: 0, panY: panY, panZ: 0}) },
|
home: function(then) { tweenCam({left: home, up: PI4, panX, panY, panZ, then}) },
|
||||||
front: function() { tweenCam({left: 0, up: PI2, panX: 0, panY: panY, panZ: 0}) },
|
front: function(then) { tweenCam({left: 0, up: PI2, panX, panY, panZ, then}) },
|
||||||
right: function() { tweenCam({left: PI2, up: PI2, panX: 0, panY: panY, panZ: 0}) },
|
right: function(then) { tweenCam({left: PI2, up: PI2, panX, panY, panZ, then}) },
|
||||||
left: function() { tweenCam({left: -PI2, up: PI2, panX: 0, panY: panY, panZ: 0}) },
|
left: function(then) { tweenCam({left: -PI2, up: PI2, panX, panY, panZ, then}) },
|
||||||
reset: function() { viewControl.reset(); requestRefresh() },
|
reset: function() { viewControl.reset(); requestRefresh() },
|
||||||
load: function(cam) { viewControl.setPosition(cam) },
|
load: function(cam) { viewControl.setPosition(cam) },
|
||||||
save: function() { return viewControl.getPosition(true) },
|
save: function() { return viewControl.getPosition(true) },
|
||||||
|
|
@ -953,7 +967,30 @@
|
||||||
viewControl.setMouse(viewControl.mouseDefault);
|
viewControl.setMouse(viewControl.mouseDefault);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getFPS: function() { return fps }
|
getFPS: function() { return fps },
|
||||||
|
getFocus: function() { return viewControl.getTarget() },
|
||||||
|
setFocus: function(v) {
|
||||||
|
viewControl.setTarget(v);
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
|
setHome: function(r) {
|
||||||
|
home = r || 0;
|
||||||
|
},
|
||||||
|
spin: function(then, count) {
|
||||||
|
Space.view.front(() => {
|
||||||
|
Space.view.right(() => {
|
||||||
|
Space.view.back(() => {
|
||||||
|
Space.view.left(() => {
|
||||||
|
if (--count > 0) {
|
||||||
|
Space.view.spin(then, count);
|
||||||
|
} else {
|
||||||
|
Space.view.front(then);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mouse: {
|
mouse: {
|
||||||
|
|
@ -973,6 +1010,14 @@
|
||||||
selectRecurse = b;
|
selectRecurse = b;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setTweenTime: function(t) {
|
||||||
|
tweenTime = t || 500;
|
||||||
|
},
|
||||||
|
|
||||||
|
setTweenDelay: function(d) {
|
||||||
|
tweenDelay = d || 20;
|
||||||
|
},
|
||||||
|
|
||||||
objects: function() {
|
objects: function() {
|
||||||
return WC;
|
return WC;
|
||||||
},
|
},
|
||||||
|
|
@ -985,7 +1030,7 @@
|
||||||
return { renderer, camera, platform };
|
return { renderer, camera, platform };
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function(domelement, slider) {
|
init: function(domelement, slider, ortho) {
|
||||||
container = domelement;
|
container = domelement;
|
||||||
|
|
||||||
WORLD.rotation.x = -PI2;
|
WORLD.rotation.x = -PI2;
|
||||||
|
|
@ -998,14 +1043,16 @@
|
||||||
antialias: true,
|
antialias: true,
|
||||||
preserveDrawingBuffer: true
|
preserveDrawingBuffer: true
|
||||||
});
|
});
|
||||||
camera = perspective ?
|
camera = ortho ?
|
||||||
new THREE.PerspectiveCamera(perspective, aspect(), 5, 100000) :
|
new THREE.OrthographicCamera(-100 * aspect(), 100 * aspect(), 100, -100, 0.1, 100000) :
|
||||||
new THREE.OrthographicCamera(-100 * aspect(), 100 * aspect(), 100, -100, 0.1, 100000);
|
new THREE.PerspectiveCamera(perspective, aspect(), 5, 100000);
|
||||||
|
|
||||||
camera.position.set(0, 200, 340);
|
camera.position.set(0, 200, 340);
|
||||||
renderer.setSize(width(), height());
|
renderer.setSize(width(), height());
|
||||||
domelement.appendChild(renderer.domElement);
|
domelement.appendChild(renderer.domElement);
|
||||||
|
|
||||||
|
raycaster = new THREE.Raycaster();
|
||||||
|
|
||||||
viewControl = new MOTO.CTRL(camera, domelement, function (position, moved) {
|
viewControl = new MOTO.CTRL(camera, domelement, function (position, moved) {
|
||||||
if (platform) {
|
if (platform) {
|
||||||
platform.visible = hidePlatformBelow ?
|
platform.visible = hidePlatformBelow ?
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,12 @@
|
||||||
#jbody, #gbody {
|
#jbody, #gbody {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
#jfoot {
|
#jfoot, #dfoot {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
#jfoot button {
|
#jfoot button, #dfoot button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
#gbody {
|
#gbody {
|
||||||
|
|
@ -58,6 +58,7 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
#gfoot {
|
#gfoot {
|
||||||
|
display: none;
|
||||||
background-color: rgba(61,133,198,0.25);
|
background-color: rgba(61,133,198,0.25);
|
||||||
border-top: 1px solid #aaa;
|
border-top: 1px solid #aaa;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
|
@ -66,6 +67,9 @@
|
||||||
#api {
|
#api {
|
||||||
width: 812px;
|
width: 812px;
|
||||||
}
|
}
|
||||||
|
#download {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
li {
|
li {
|
||||||
list-style: circle;
|
list-style: circle;
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +81,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
|
||||||
<script src="/code/engine.js"></script>
|
<script src="/code/engine.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let edit;
|
let edit, saveit = "";
|
||||||
function $(id) { return document.getElementById(id) }
|
function $(id) { return document.getElementById(id) }
|
||||||
function onload() {
|
function onload() {
|
||||||
let fnstr = demo.toString().split("\n");
|
let fnstr = demo.toString().split("\n");
|
||||||
|
|
@ -97,10 +101,14 @@
|
||||||
$('gfoot').innerText = msg ? Object.keys(msg).join(' - ') : '';
|
$('gfoot').innerText = msg ? Object.keys(msg).join(' - ') : '';
|
||||||
}
|
}
|
||||||
function display_gcode(gcode) {
|
function display_gcode(gcode) {
|
||||||
$('gbody').innerText = gcode;
|
$('gbody').innerText = saveit = gcode;
|
||||||
display_message();
|
display_message();
|
||||||
|
$('dfoot').style.display = 'block';
|
||||||
|
$('gfoot').style.display = '';
|
||||||
}
|
}
|
||||||
function run_code() {
|
function run_code() {
|
||||||
|
$('dfoot').style.display = 'none';
|
||||||
|
$('gfoot').style.display = 'block';
|
||||||
let code = edit.session.getValue();
|
let code = edit.session.getValue();
|
||||||
eval(`(function(){${code}})()`);
|
eval(`(function(){${code}})()`);
|
||||||
}
|
}
|
||||||
|
|
@ -108,11 +116,28 @@
|
||||||
kiri.newEngine()
|
kiri.newEngine()
|
||||||
.setListener(display_message)
|
.setListener(display_message)
|
||||||
.load("/obj/cube.stl")
|
.load("/obj/cube.stl")
|
||||||
|
.then(eng => eng.setProcess({
|
||||||
|
sliceShells: 1,
|
||||||
|
sliceFillSparse: 0.25,
|
||||||
|
sliceTopLayers: 2,
|
||||||
|
sliceSolidLayers: 2,
|
||||||
|
sliceBottomLayers: 2
|
||||||
|
}))
|
||||||
|
.then(eng => eng.setDevice({
|
||||||
|
gcodePre: [ "M82", "M104 S220" ],
|
||||||
|
gcodePost: [ "M107" ]
|
||||||
|
}))
|
||||||
.then(eng => eng.slice())
|
.then(eng => eng.slice())
|
||||||
.then(eng => eng.prepare())
|
.then(eng => eng.prepare())
|
||||||
.then(eng => eng.export())
|
.then(eng => eng.export())
|
||||||
.then(display_gcode);
|
.then(display_gcode);
|
||||||
}
|
}
|
||||||
|
function download() {
|
||||||
|
let blob = new Blob([saveit], {type: "octet/stream"});
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
$('download').innerHTML = `<a id="xo" href="${url}" download="sample.gcode"></a>`;
|
||||||
|
$('xo').click();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body onload="onload()">
|
<body onload="onload()">
|
||||||
|
|
@ -127,6 +152,7 @@
|
||||||
<div id="ghead">gcode output</div>
|
<div id="ghead">gcode output</div>
|
||||||
<div id="gbody"></div>
|
<div id="gbody"></div>
|
||||||
<div id="gfoot"></div>
|
<div id="gfoot"></div>
|
||||||
|
<div id="dfoot"><button onclick="download()">download</button></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="api">
|
<div id="api">
|
||||||
|
|
@ -145,5 +171,6 @@
|
||||||
<li><label>prepare()</label> - async path routing of slice data</li>
|
<li><label>prepare()</label> - async path routing of slice data</li>
|
||||||
<li><label>export()</label> - async gcode generation from path routing</li>
|
<li><label>export()</label> - async gcode generation from path routing</li>
|
||||||
</div>
|
</div>
|
||||||
|
<a id="download"></a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ th, tr, td, label {
|
||||||
#app-mode, #app-acct {
|
#app-mode, #app-acct {
|
||||||
width: 125px;
|
width: 125px;
|
||||||
}
|
}
|
||||||
#app-mode:hover #mode-info {
|
#mode-info.hoverpop {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
#mode-info {
|
#mode-info {
|
||||||
|
|
@ -295,7 +295,7 @@ th, tr, td, label {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app-name:hover #app-info {
|
#app-info.hoverpop {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
#app-info {
|
#app-info {
|
||||||
|
|
@ -317,8 +317,8 @@ th, tr, td, label {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
#app-acct:hover #acct-pop {
|
#acct-pop.hoverpop {
|
||||||
display: flex;
|
display: flex !important;
|
||||||
}
|
}
|
||||||
#acct-pop {
|
#acct-pop {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -441,7 +441,7 @@ th, tr, td, label {
|
||||||
background-color: rgba(255,255,255,0.85);
|
background-color: rgba(255,255,255,0.85);
|
||||||
border: 1px solid rgba(0,0,0,0.1);
|
border: 1px solid rgba(0,0,0,0.1);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
width: 60px;
|
min-width: 60px;
|
||||||
color: var(--fg-gray);
|
color: var(--fg-gray);
|
||||||
}
|
}
|
||||||
.pop-lcol > div:hover {
|
.pop-lcol > div:hover {
|
||||||
|
|
@ -471,10 +471,10 @@ th, tr, td, label {
|
||||||
.lt-menu label {
|
.lt-menu label {
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
}
|
}
|
||||||
.lt-enabled {
|
.lt-enabled, .lt-active {
|
||||||
color: var(--fg-gray);
|
color: var(--fg-gray);
|
||||||
}
|
}
|
||||||
.lt-enabled:hover {
|
.lt-enabled:hover, .lt-active:hover {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|
@ -482,6 +482,9 @@ th, tr, td, label {
|
||||||
.lt-enabled:hover .pop-lcol {
|
.lt-enabled:hover .pop-lcol {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
.lt-active .hoverpop {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
@media only screen and (max-height : 800px) {
|
@media only screen and (max-height : 800px) {
|
||||||
.lt-menu, .pop-lcol {
|
.lt-menu, .pop-lcol {
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
|
|
@ -524,7 +527,7 @@ th, tr, td, label {
|
||||||
.txt-sel button, .btn-sel {
|
.txt-sel button, .btn-sel {
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
}
|
}
|
||||||
#pop-rotate .value, #pop-scale .value {
|
#pop-rotate input.value, #pop-scale input.value {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
#pop-rotate label {
|
#pop-rotate label {
|
||||||
|
|
@ -870,8 +873,8 @@ th, tr, td, label {
|
||||||
min-height: 4em !important;
|
min-height: 4em !important;
|
||||||
}
|
}
|
||||||
#code-preview-textarea {
|
#code-preview-textarea {
|
||||||
width: 100%;
|
width: 40em;
|
||||||
height: 250px;
|
height: 12em;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
.mod-end {
|
.mod-end {
|
||||||
|
|
@ -962,6 +965,8 @@ th, tr, td, label {
|
||||||
}
|
}
|
||||||
#help .content li {
|
#help .content li {
|
||||||
line-height: 1.75em;
|
line-height: 1.75em;
|
||||||
|
padding-left: 22px ;
|
||||||
|
text-indent: -22px ;
|
||||||
}
|
}
|
||||||
#help .footer {
|
#help .footer {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
|
@ -1239,6 +1244,17 @@ th, tr, td, label {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#top-slider {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
top: 60px;
|
||||||
|
left: 50px;
|
||||||
|
right: 50px;
|
||||||
|
}
|
||||||
|
#anim-slider {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#alert-area {
|
#alert-area {
|
||||||
display: none;
|
display: none;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -1500,3 +1516,43 @@ th, tr, td, label {
|
||||||
border-top: 1px solid #ddd;
|
border-top: 1px solid #ddd;
|
||||||
margin: 5px 0 5px 0;
|
margin: 5px 0 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#lab-axis, #lab-scale {
|
||||||
|
padding: 0 6px 0 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
#lab-axis:hover, #lab-scale:hover {
|
||||||
|
background-color: rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.range-info {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.range-info:hover .range-detail {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.range-detail {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
bottom: 50%;
|
||||||
|
right: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0 10px 0 10px;
|
||||||
|
font-size: smaller;
|
||||||
|
font-family: monospace;
|
||||||
|
transform: translateY(50%);
|
||||||
|
background-color: rgba(255,255,255,0.8);
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.range-detail label.pad {
|
||||||
|
padding-right: 8px;
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.range-detail label.val {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.range-detail span {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="author" content="Stewart Allen">
|
<meta name="author" content="Stewart Allen">
|
||||||
<meta name="keywords" content="3d slicer,slicer,3d slicing,cnc,cam,toolpaths,toolpath generation,kiri,kirimoto,kiri:moto,gcode,cura,simplify 3d,prusaslicer,fdm,sla" />
|
<meta name="keywords" content="3d slicer,chromebook,slicer,3d slicing,cnc,cam,toolpaths,toolpath generation,kiri,kirimoto,kiri:moto,gcode,cura,simplify 3d,prusaslicer,fdm,sla" />
|
||||||
<meta name="copyright" content="stewart allen [sa@grid.space]">
|
<meta name="copyright" content="stewart allen [sa@grid.space]">
|
||||||
<meta name="description" content="Browser-based 3D slicer, gcode and CNC toolpath generator">
|
<meta name="description" content="Browser-based 3D slicer, gcode and CNC toolpath generator">
|
||||||
<meta property="og:description" content="Kiri:Moto is a unique 3D slicer that runs entirely in browser and creates output for your favorite maker tools: 3D Printers, CNC Mills and Laser Cutters.">
|
<meta property="og:description" content="Kiri:Moto is a unique 3D slicer that runs entirely in browser and creates output for your favorite maker tools: 3D Printers, CNC Mills and Laser Cutters.">
|
||||||
|
|
@ -45,17 +45,20 @@
|
||||||
<div id="acct-pop" class="f-col">
|
<div id="acct-pop" class="f-col">
|
||||||
<div id="acct-menu" class="f-col">
|
<div id="acct-menu" class="f-col">
|
||||||
<div id="acct-lang">
|
<div id="acct-lang">
|
||||||
<label><i class="fas fa-caret-left"></i> language</label>
|
<label><i class="fas fa-caret-left"></i> <span lk="language">language</span></label>
|
||||||
<div id="lang-pop" class="f-col">
|
<div id="lang-pop" class="f-col">
|
||||||
<div id="lset-en">english</div>
|
|
||||||
<div id="lset-da">danish</div>
|
<div id="lset-da">danish</div>
|
||||||
|
<div id="lset-en">english</div>
|
||||||
|
<div id="lset-fr">french</div>
|
||||||
|
<div id="lset-de">german</div>
|
||||||
|
<div id="lset-pl">polish</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="acct-export" class="f-col a-end">
|
<div id="acct-export" class="f-col a-end">
|
||||||
<label>export</label>
|
<label lk="export">export</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="acct-help" class="f-col a-end">
|
<div id="acct-help" class="f-col a-end">
|
||||||
<label>help</label>
|
<label lk="help">help</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -72,104 +75,104 @@
|
||||||
<i class="fas fa-times-circle"></i>
|
<i class="fas fa-times-circle"></i>
|
||||||
</div>
|
</div>
|
||||||
<div id="lt-top"></div>
|
<div id="lt-top"></div>
|
||||||
<div id="lt-setup" class="lt-menu lt-enabled">
|
<div id="lt-setup" class="lt-menu lt-active">
|
||||||
<i class="fas fa-cogs"></i>
|
<i class="fas fa-cogs"></i>
|
||||||
<label>setup</label>
|
<label lk="setup">setup</label>
|
||||||
<div id="set-pop" class="pop-lcol f-row">
|
<div id="set-pop" class="pop-lcol f-row">
|
||||||
<div id="set-device">
|
<div id="set-device">
|
||||||
<i class="fas fa-cube"></i>
|
<i class="fas fa-cube"></i>
|
||||||
<label>machine</label>
|
<label lk="machine">machine</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="set-tools">
|
<div id="set-tools">
|
||||||
<i class="fas fa-tools"></i>
|
<i class="fas fa-tools"></i>
|
||||||
<label>tools<label>
|
<label lk="tools">tools<label>
|
||||||
</div>
|
</div>
|
||||||
<div id="set-prefs">
|
<div id="set-prefs">
|
||||||
<i class="fas fa-sliders-h"></i>
|
<i class="fas fa-sliders-h"></i>
|
||||||
<label>prefs<label>
|
<label lk="prefs">prefs<label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="lt-file" class="lt-menu lt-enabled">
|
<div id="lt-file" class="lt-menu lt-active">
|
||||||
<i class="fas fa-folder"></i>
|
<i class="fas fa-folder"></i>
|
||||||
<label>files</label>
|
<label lk="files">files</label>
|
||||||
<div id="file-pop" class="pop-lcol f-row">
|
<div id="file-pop" class="pop-lcol f-row">
|
||||||
<div id="file-recent">
|
<div id="file-recent">
|
||||||
<i class="fas fa-list"></i>
|
<i class="fas fa-list"></i>
|
||||||
<label>recent</label>
|
<label lk="recent">recent</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="file-import">
|
<div id="file-import">
|
||||||
<i class="fas fa-file-upload"></i>
|
<i class="fas fa-file-upload"></i>
|
||||||
<label>import<label>
|
<label lk="import">import<label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="act-sep"></div>
|
<div id="act-sep"></div>
|
||||||
<div id="lt-view" class="lt-menu lt-enabled">
|
<div id="lt-view" class="lt-menu lt-active">
|
||||||
<i class="fas fa-eye"></i>
|
<i class="fas fa-eye"></i>
|
||||||
<label>view</label>
|
<label lk="view">view</label>
|
||||||
<div id="pop-view" class="pop-lcol f-row">
|
<div id="pop-view" class="pop-lcol f-row">
|
||||||
<div id="view-arrange">
|
<div id="view-arrange">
|
||||||
<i class="fas fa-th"></i>
|
<i class="fas fa-th"></i>
|
||||||
<label>arrange</label>
|
<label lk="arrange">arrange</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="view-top">
|
<div id="view-top">
|
||||||
<i class="fas fa-square"></i>
|
<i class="fas fa-square"></i>
|
||||||
<label>top</label>
|
<label lk="top">top</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="view-home">
|
<div id="view-home">
|
||||||
<i class="fas fa-home"></i>
|
<i class="fas fa-home"></i>
|
||||||
<label>home</label>
|
<label lk="home">home</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="view-clear">
|
<div id="view-clear">
|
||||||
<i class="far fa-square"></i>
|
<i class="far fa-square"></i>
|
||||||
<label>clear</label>
|
<label lk="clear">clear</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="act-slice" class="lt-menu lt-enabled">
|
<div id="act-slice" class="lt-menu lt-active">
|
||||||
<i class="fas fa-bars"></i>
|
<i class="fas fa-bars"></i>
|
||||||
<label id="label-slice" title="analyze parts">slice</label>
|
<label id="label-slice" title="analyze parts" lk="slice">slice</label>
|
||||||
<div id="pop-slice" class="pop-lcol f-row">
|
<div id="pop-slice" class="pop-lcol f-row">
|
||||||
<div id="act-preview">
|
<div id="act-preview">
|
||||||
<i class="fas fa-cubes"></i>
|
<i class="fas fa-cubes"></i>
|
||||||
<label id="label-preview" title="show routing and paths">preview</label>
|
<label id="label-preview" title="show routing and paths" lk="preview">preview</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="act-animate">
|
<div id="act-animate">
|
||||||
<i class="fas fa-running"></i>
|
<i class="fas fa-running"></i>
|
||||||
<label id="label-animate" title="render routing on a mesh">animate</label>
|
<label id="label-animate" title="render routing on a mesh" lk="animate">animate</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="act-export">
|
<div id="act-export">
|
||||||
<i class="fas fa-file-download"></i>
|
<i class="fas fa-file-download"></i>
|
||||||
<label id="label-export" title="generate downloadable files">export</label>
|
<label id="label-export" title="generate downloadable files" lk="export">export</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="lt-sep"></div>
|
<div id="lt-sep"></div>
|
||||||
<div id="lt-render" class="lt-menu lt-enabled">
|
<div id="lt-render" class="lt-menu lt-active">
|
||||||
<i class="fas fa-border-style"></i>
|
<i class="fas fa-border-style"></i>
|
||||||
<label>render</label>
|
<label lk="render">render</label>
|
||||||
<div id="pop-render" class="pop-lcol f-row">
|
<div id="pop-render" class="pop-lcol f-row">
|
||||||
<div id="render-solid" class="grow a-center">
|
<div id="render-solid" class="grow a-center">
|
||||||
<i class="fas fa-th-large"></i>
|
<i class="fas fa-th-large"></i>
|
||||||
<label>solid</label>
|
<label lk="solid">solid</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="render-wire" class="grow a-center">
|
<div id="render-wire" class="grow a-center">
|
||||||
<i class="fas fa-border-all"></i>
|
<i class="fas fa-border-all"></i>
|
||||||
<label>wire</label>
|
<label lk="wire">wire</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="render-ghost" class="grow a-center">
|
<div id="render-ghost" class="grow a-center">
|
||||||
<i class="fas fa-border-none"></i>
|
<i class="fas fa-border-none"></i>
|
||||||
<label>ghost</label>
|
<label lk="ghost">ghost</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="render-hide" class="grow a-center">
|
<div id="render-hide" class="grow a-center">
|
||||||
<label>hide</label>
|
<label lk="hide">hide</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="lt-rotate" class="lt-menu">
|
<div id="lt-rotate" class="lt-menu">
|
||||||
<i class="fas fa-sync-alt"></i>
|
<i class="fas fa-sync-alt"></i>
|
||||||
<label>rotate</label>
|
<label lk="rotate">rotate</label>
|
||||||
<div id="pop-rotate" class="pop-lcol f-row russo">
|
<div id="pop-rotate" class="pop-lcol f-row russo">
|
||||||
<div>
|
<div>
|
||||||
<div class="grow a-center">
|
<div class="grow a-center">
|
||||||
|
|
@ -196,12 +199,12 @@
|
||||||
<input id="rot_z" class="value center" size="5"/ value="0">
|
<input id="rot_z" class="value center" size="5"/ value="0">
|
||||||
</div>
|
</div>
|
||||||
<!-- <div id="lay-flat" class="f-col j-center center">lay flat</div> -->
|
<!-- <div id="lay-flat" class="f-col j-center center">lay flat</div> -->
|
||||||
<div id="unrotate" class="f-col j-center">reset</div>
|
<div id="unrotate" class="f-col j-center" lk="reset">reset</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="lt-scale" class="lt-menu">
|
<div id="lt-scale" class="lt-menu">
|
||||||
<i class="fas fa-expand"></i>
|
<i class="fas fa-expand"></i>
|
||||||
<label>scale</label>
|
<label lk="scale">scale</label>
|
||||||
<div id="pop-scale" class="pop-lcol f-row russo">
|
<div id="pop-scale" class="pop-lcol f-row russo">
|
||||||
<div>
|
<div>
|
||||||
<input id="lock_x" type="checkbox" checked/>
|
<input id="lock_x" type="checkbox" checked/>
|
||||||
|
|
@ -222,9 +225,9 @@
|
||||||
<div><input id="scale_z" xsize="8" class="value" value="1"/></div>
|
<div><input id="scale_z" xsize="8" class="value" value="1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="f-col j-center">
|
<div class="f-col j-center">
|
||||||
<div><label>axis</label></div>
|
<div><label id="lab-axis" lk="axis">axis</label></div>
|
||||||
<div><label>size</label></div>
|
<div><label id="lab-size" lk="size">size</label></div>
|
||||||
<div><label>scale</label></div>
|
<div><label id="lab-scale" lk="scale">scale</label></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -249,7 +252,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="mod-setup" class="mdialog f-row">
|
<div id="mod-setup" class="mdialog f-row">
|
||||||
<div class="f-col left a-stretch">
|
<div class="f-col left a-stretch">
|
||||||
<label class="header">select a device type</label>
|
<label class="header" lk="dm_sldt">select a device type</label>
|
||||||
<div class="f-col">
|
<div class="f-col">
|
||||||
<table><tr>
|
<table><tr>
|
||||||
<th><button id="mode-fdm" class="dev-type"><label>FDM</label></button></th>
|
<th><button id="mode-fdm" class="dev-type"><label>FDM</label></button></th>
|
||||||
|
|
@ -260,7 +263,7 @@
|
||||||
</tr></table>
|
</tr></table>
|
||||||
</div>
|
</div>
|
||||||
<div class="header sub f-col j-center">
|
<div class="header sub f-col j-center">
|
||||||
<label>standard devices</label>
|
<label lk="dm_stdd">standard devices</label>
|
||||||
<div id="dev-search">
|
<div id="dev-search">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
<input id="dev-filter" />
|
<input id="dev-filter" />
|
||||||
|
|
@ -269,20 +272,20 @@
|
||||||
<div class="f-col mh0 mh35 j-center a-stretch">
|
<div class="f-col mh0 mh35 j-center a-stretch">
|
||||||
<div id="device-list" class="devlist f-col overy"></div>
|
<div id="device-list" class="devlist f-col overy"></div>
|
||||||
</div>
|
</div>
|
||||||
<label class="header sub">my devices</label>
|
<label class="header sub" lk="dm_mydd">my devices</label>
|
||||||
<div class="f-col grow">
|
<div class="f-col grow">
|
||||||
<div id="device-my" class="devlist f-col grow overy"></div>
|
<div id="device-my" class="devlist f-col grow overy"></div>
|
||||||
<div class="f-row footer">
|
<div class="f-row footer">
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
<button id="device-add">copy</button>
|
<button id="device-add" lk="copy">copy</button>
|
||||||
<button id="device-del">delete</button>
|
<button id="device-del" lk="delete">delete</button>
|
||||||
<button id="device-exp">export</button>
|
<button id="device-exp" lk="export">export</button>
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="f-col grow a-stretch">
|
<div class="f-col grow a-stretch">
|
||||||
<label class="header">selected device</label>
|
<label class="header" lk="dm_seld">selected device</label>
|
||||||
<div class="f-row">
|
<div class="f-row">
|
||||||
<div id="device1" class="f-col t-body t-inset overy grow"></div>
|
<div id="device1" class="f-col t-body t-inset overy grow"></div>
|
||||||
<div class="t-pad"></div>
|
<div class="t-pad"></div>
|
||||||
|
|
@ -296,27 +299,27 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="device-action" class="f-row footer">
|
<div id="device-action" class="f-row footer">
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
<button id="device-save">save</button>
|
<button id="device-save" lk="save">save</button>
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mod-files" class="mdialog f-col">
|
<div id="mod-files" class="mdialog f-col">
|
||||||
<label class="set-header">recent files</label>
|
<label class="set-header" lk="dm_rcnt">recent files</label>
|
||||||
<div id="catalogList" class="f-col"></div>
|
<div id="catalogList" class="f-col"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mod-saves" class="mdialog f-col">
|
<div id="mod-saves" class="mdialog f-col">
|
||||||
<label class="set-header">saved settings</label>
|
<label class="set-header" lk="dm_savs">saved settings</label>
|
||||||
<div id="settingsList" class="f-col"></div>
|
<div id="settingsList" class="f-col"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mod-tools" class="mdialog">
|
<div id="mod-tools" class="mdialog">
|
||||||
<div class="f-col">
|
<div class="f-col">
|
||||||
<div class="f-row t-head">
|
<div class="f-row t-head">
|
||||||
<label class="t-33">tool</label>
|
<label class="t-33" lk="tool">tool</label>
|
||||||
<div class="t-pad"></div>
|
<div class="t-pad"></div>
|
||||||
<label class="t-33">detail</label>
|
<label class="t-33" lk="detail">detail</label>
|
||||||
<div class="t-pad"></div>
|
<div class="t-pad"></div>
|
||||||
<label class="t-33">view</label>
|
<label class="t-33" lk="view">view</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="f-row">
|
<div class="f-row">
|
||||||
<div class="f-col t-33">
|
<div class="f-col t-33">
|
||||||
|
|
@ -324,23 +327,23 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="t-pad"></div>
|
<div class="t-pad"></div>
|
||||||
<div class="f-col t-33 t-body t-inset">
|
<div class="f-col t-33 t-body t-inset">
|
||||||
<div class="f-row var-row"><label>name</label><input id="tool-name" size="15"></input></div>
|
<div class="f-row var-row"><label lk="name">name</label><input id="tool-name" size="15"></input></div>
|
||||||
<div class="f-row var-row"><label>type</label>
|
<div class="f-row var-row"><label lk="type">type</label>
|
||||||
<select id="tool-type">
|
<select id="tool-type">
|
||||||
<option value="endmill" selected>end</option>
|
<option value="endmill" lk="td_tyem" selected>end</option>
|
||||||
<option value="ballmill">ball</option>
|
<option value="ballmill" lk="td_tybm">ball</option>
|
||||||
<option value="tapermill">taper</option>
|
<option value="tapermill" lk="td_tytm">taper</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="f-row var-row" title="tool number to use
in gcode commands"><label>tool #</label><input id="tool-num" size="7"></input></div>
|
<div class="f-row var-row" title="tool number to use
in gcode commands"><label lk="td_tonm">tool #</label><input id="tool-num" size="7"></input></div>
|
||||||
<div class="f-row var-row"><label>metric</label><input id="tool-metric" type="checkbox"></input></div>
|
<div class="f-row var-row"><label lk="metric">metric</label><input id="tool-metric" type="checkbox"></input></div>
|
||||||
<div class="set-header f-col">shaft</div>
|
<div class="set-header f-col" lk="td_shft">shaft</div>
|
||||||
<div class="f-row var-row" title="shaft diameter in inches
unless metric is checked
then in millimeters"><label>diameter</label><input id="tool-sdiam" size="7"></input></div>
|
<div class="f-row var-row" title="shaft diameter in inches
unless metric is checked
then in millimeters"><label>diameter</label><input id="tool-sdiam" size="7"></input></div>
|
||||||
<div class="f-row var-row" title="shaft length in inches
unless metric is checked
then in millimeters"><label>length</label><input id="tool-slen" size="7"></input></div>
|
<div class="f-row var-row" title="shaft length in inches
unless metric is checked
then in millimeters"><label>length</label><input id="tool-slen" size="7"></input></div>
|
||||||
<div class="set-header f-col">flute</div>
|
<div class="set-header f-col" lk="td_flut">flute</div>
|
||||||
<div class="f-row var-row" title="flute diameter in inches
unless metric is checked
then in millimeters"><label>diameter</label><input id="tool-fdiam" size="7"></input></div>
|
<div class="f-row var-row" title="flute diameter in inches
unless metric is checked
then in millimeters"><label>diameter</label><input id="tool-fdiam" size="7"></input></div>
|
||||||
<div class="f-row var-row" title="flute length in inches
unless metric is checked
then in millimeters"><label>length</label><input id="tool-flen" size="7"></input></div>
|
<div class="f-row var-row" title="flute length in inches
unless metric is checked
then in millimeters"><label>length</label><input id="tool-flen" size="7"></input></div>
|
||||||
<div class="set-header f-col">taper</div>
|
<div class="set-header f-col" ln="td_tapr">taper</div>
|
||||||
<!-- <div class="flow-row" title="taper angle"><label>angle</label><input id="tool-tangle" size=5></input></div> -->
|
<!-- <div class="flow-row" title="taper angle"><label>angle</label><input id="tool-tangle" size=5></input></div> -->
|
||||||
<div class="f-row var-row" title="tip width in inches
unless metric is checked
then in millimeters"><label>tip</label><input id="tool-ttip" size="7"></input></div>
|
<div class="f-row var-row" title="tip width in inches
unless metric is checked
then in millimeters"><label>tip</label><input id="tool-ttip" size="7"></input></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -351,13 +354,13 @@
|
||||||
<button id="tool-add"><i class="fas fa-plus"></i></button>
|
<button id="tool-add"><i class="fas fa-plus"></i></button>
|
||||||
<button id="tool-del"><i class="fas fa-minus"></i></button>
|
<button id="tool-del"><i class="fas fa-minus"></i></button>
|
||||||
<div class="t-pad2"></div>
|
<div class="t-pad2"></div>
|
||||||
<button id="tools-save">save</button>
|
<button id="tools-save" lk="save">save</button>
|
||||||
<button id="tools-close">done</button>
|
<button id="tools-close" lk="done">done</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mod-prefs" class="mdialog f-col a-center">
|
<div id="mod-prefs" class="mdialog f-col a-center">
|
||||||
<b>Application Preferences</b>
|
<b lk="dm_appp">Application Preferences</b>
|
||||||
<hr width="80%">
|
<hr width="80%">
|
||||||
<div class="f-row">
|
<div class="f-row">
|
||||||
<div id="prefs-gen1" class="f-col"></div>
|
<div id="prefs-gen1" class="f-col"></div>
|
||||||
|
|
@ -378,7 +381,7 @@
|
||||||
<div id="mod-print" class="mdialog f-col"></div>
|
<div id="mod-print" class="mdialog f-col"></div>
|
||||||
<div id="mod-any" class="mdialog f-col"></div>
|
<div id="mod-any" class="mdialog f-col"></div>
|
||||||
<!-- hidden file input loader -->
|
<!-- hidden file input loader -->
|
||||||
<input id="load-file" type="file" name="loadme" style="display:none" accept=".stl,.gcode,.nc,.km,.b64,.png"/>
|
<input id="load-file" type="file" name="loadme" style="display:none"/>
|
||||||
<div class="mod-end"></div></div>
|
<div class="mod-end"></div></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="layer-slider" class="f-col a-stretch">
|
<div id="layer-slider" class="f-col a-stretch">
|
||||||
|
|
@ -440,13 +443,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="tool-info" class="noshow"></div>
|
<div id="tool-info" class="noshow"></div>
|
||||||
<div id="context-menu">
|
<div id="context-menu">
|
||||||
<button id="context-clear-workspace">clear workspace</button>
|
<button id="context-clear-workspace" lk="rc_clws">clear workspace</button>
|
||||||
<button id="context-export-workspace">export workspace</button>
|
<button id="context-export-workspace" lk="rc_xpws">export workspace</button>
|
||||||
<div class="sep"></div>
|
<div class="sep"></div>
|
||||||
<button id="context-mirror">mirror</button>
|
<button id="context-layflat" lk="rc_lafl">lay flat</button>
|
||||||
<button id="context-duplicate">duplicate</button>
|
<button id="context-mirror" lk="rc_mirr">mirror</button>
|
||||||
|
<button id="context-duplicate" lk="rc_dupl">duplicate</button>
|
||||||
<div class="sep"></div>
|
<div class="sep"></div>
|
||||||
<button id="context-export-stl">export as STL</button>
|
<button id="context-export-stl" lk="rc_xstl">export as STL</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="fps" class="noshow"></div>
|
<div id="fps" class="noshow"></div>
|
||||||
<div id="layer-animate" class="f-col a-center"></div>
|
<div id="layer-animate" class="f-col a-center"></div>
|
||||||
|
|
@ -457,6 +461,9 @@
|
||||||
<div id="alert-text">alerts<br>alerts<br>alerts</div>
|
<div id="alert-text">alerts<br>alerts<br>alerts</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="top-slider" class="f-col grow">
|
||||||
|
<input id="anim-slider" type="range" min="0" max="1000" value="0"></input>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,7 @@
|
||||||
<tr><td>mouse-wheel</td><td>Zoom</td></tr>
|
<tr><td>mouse-wheel</td><td>Zoom</td></tr>
|
||||||
<tr><td>middle-drag</td><td>Zoom</td></tr>
|
<tr><td>middle-drag</td><td>Zoom</td></tr>
|
||||||
<tr><td>2-touch-pinch</td><td>Zoom</td></tr>
|
<tr><td>2-touch-pinch</td><td>Zoom</td></tr>
|
||||||
</table>
|
<tr><td><br><br></td></tr>
|
||||||
<table>
|
|
||||||
<tr><th colspan=2 class="header">Konfiguration</th></tr>
|
<tr><th colspan=2 class="header">Konfiguration</th></tr>
|
||||||
<tr><td><label>?</label></td><td>Dette Hjælpe Vindue</td></tr>
|
<tr><td><label>?</label></td><td>Dette Hjælpe Vindue</td></tr>
|
||||||
<tr><td><label>e</label></td><td>Enhed Udvælger</td></tr>
|
<tr><td><label>e</label></td><td>Enhed Udvælger</td></tr>
|
||||||
|
|
|
||||||
1109
web/kiri/lang/da.js
1109
web/kiri/lang/da.js
File diff suppressed because it is too large
Load diff
1
web/kiri/lang/de-de-help.html
Symbolic link
1
web/kiri/lang/de-de-help.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
de-help.html
|
||||||
640
web/kiri/lang/de-de.js
Normal file
640
web/kiri/lang/de-de.js
Normal file
|
|
@ -0,0 +1,640 @@
|
||||||
|
// english. other language maps will defer to english
|
||||||
|
// map for any missing key/value pairs
|
||||||
|
kiri.lang['de'] =
|
||||||
|
kiri.lang['de-de'] = {
|
||||||
|
// common keys and menus
|
||||||
|
animate: "Animieren", // CAM animate button
|
||||||
|
arrange: "Anordnen", // layout workspace objects
|
||||||
|
axis: "Achse", // left object scale pop menu
|
||||||
|
clear: "alles entfernen", // clear workspace (remove all objects)
|
||||||
|
copy: "Kopieren",
|
||||||
|
delete: "Löschen",
|
||||||
|
detail: "Details",
|
||||||
|
done: "Fertig",
|
||||||
|
enable: "Aktivieren",
|
||||||
|
export: "Export",
|
||||||
|
files: "Dateien",
|
||||||
|
help: "Hilfe",
|
||||||
|
ghost: "Geist", // left render pop menu (wireframe)
|
||||||
|
hide: "Verbergen", // left render pop menu (invisible)
|
||||||
|
home: "home",
|
||||||
|
import: "Import",
|
||||||
|
language: "Sprache",
|
||||||
|
machine: "Maschine", // device or machine
|
||||||
|
metric: "Metrisch",
|
||||||
|
name: "Name",
|
||||||
|
prefs: "Einstellungen", // left menu "preferences"
|
||||||
|
preview: "Vorschau",
|
||||||
|
recent: "Letzte Objekte",
|
||||||
|
render: "Rendern", // left render pop menu
|
||||||
|
reset: "Zurücksetzen",
|
||||||
|
rotate: "Rotieren", // left rotate pop menu
|
||||||
|
save: "Speichern",
|
||||||
|
scale: "Skalieren", // left object scale pop menu
|
||||||
|
setup: "Einrichtung",
|
||||||
|
settings: "Einstellungen",
|
||||||
|
size: "Größe",
|
||||||
|
solid: "Undurchsichtig", // view type pop menu
|
||||||
|
tool: "Werkzeug",
|
||||||
|
tools: "Werkzeuge", // CAM tool menu button
|
||||||
|
top: "Oben",
|
||||||
|
type: "Typ", // CAM tool type
|
||||||
|
version: "Version",
|
||||||
|
view: "Ansicht", // left view pop menu
|
||||||
|
wire: "Drahtansicht", // left render pop menu
|
||||||
|
|
||||||
|
acct_xpo: ["Lege ein Backup Deiner Geräte","und Geräte-Profile an, mit der","Option, den Arbeitsbereich und","mit Objekten und Anordnung zu speichern"],
|
||||||
|
|
||||||
|
// RIGHT-CLICK CONTEXT MENU
|
||||||
|
rc_clws: "Arbeitsbereich freiräumen",
|
||||||
|
rc_xpws: "Arbeitsbereich exportieren",
|
||||||
|
rc_lafl: "Auf das Bett",
|
||||||
|
rc_mirr: "Spiegeln",
|
||||||
|
rc_dupl: "Duplizieren",
|
||||||
|
rc_xstl: "Als STL exportieren",
|
||||||
|
|
||||||
|
// DEVICE MENU and related dialogs
|
||||||
|
dm_sldt: "Wähle einen Geräte-Typ aus",
|
||||||
|
dm_stdd: "Vordefinierte Geräte",
|
||||||
|
dm_mydd: "Meine Geräte",
|
||||||
|
dm_seld: "Ausgweähltes Gerät",
|
||||||
|
dm_rcnt: "Letzte Dateien",
|
||||||
|
dm_savs: "Gespeicherte Voreinstellungen",
|
||||||
|
dm_appp: "Anwendungseinsetllungen",
|
||||||
|
|
||||||
|
// CAM Tool Dialog
|
||||||
|
td_tyem: "end", // end mill
|
||||||
|
td_tybm: "ball", // ball mill
|
||||||
|
td_tytm: "taper", // taper mill
|
||||||
|
td_tonm: "tool #",
|
||||||
|
td_shft: "shaft", // endmill shaft specs
|
||||||
|
td_flut: "flute", // endmill flute specs
|
||||||
|
td_tapr: "taper", // endmill taper specs
|
||||||
|
|
||||||
|
// DEVICE dialog groups
|
||||||
|
dv_gr_dev: "Gerät",
|
||||||
|
dv_gr_ext: "Extruder",
|
||||||
|
dv_gr_out: "Output",
|
||||||
|
dv_gr_gco: "GCode Macros",
|
||||||
|
|
||||||
|
// DEVICE dialog (_s = label, _l = hover help)
|
||||||
|
dv_name_s: "Name",
|
||||||
|
dv_name_l: "Geräte-Name",
|
||||||
|
dv_fila_s: "Filament",
|
||||||
|
dv_fila_l: "Durchmesser in mm",
|
||||||
|
dv_nozl_s: "Düse",
|
||||||
|
dv_nozl_l: "Durchmesser in mm",
|
||||||
|
dv_bedw_s: "Breite",
|
||||||
|
dv_bedw_l: "Maßeinheiten des Arbeitsbereichs",
|
||||||
|
dv_bedd_s: "Tiefe",
|
||||||
|
dv_bedd_l: "Maßeinheiten der Arbeitsfläche",
|
||||||
|
dv_bedh_s: "Höhe",
|
||||||
|
dv_bedh_l: ["Maximale Objekthöhe","in Maßeinheiten der Arbeitsfläche"],
|
||||||
|
dv_spmx_s: "Spindel-Maximum",
|
||||||
|
dv_spmx_l: ["Maximale Umdrehungen pro Minute der Spindel","0 zum deaktivieren"],
|
||||||
|
dv_xtab_s: "Absolute Positionierung",
|
||||||
|
dv_xtab_l: "Filament wird mit absoluter Positionierung extrudiert",
|
||||||
|
dv_orgc_s: "Nullpunkt in der Mitte",
|
||||||
|
dv_orgc_l: "Nullpunkt des Druckbetts in der Mitte",
|
||||||
|
// dv_orgt_s: "origin top",
|
||||||
|
// dv_orgt_l: "part z origin top",
|
||||||
|
dv_bedc_s: "Rundes Druckbett",
|
||||||
|
dv_bedc_l: "Der Druckbereich des Gerätes ist rund",
|
||||||
|
dv_belt_s: "Riemen-Druckbett",
|
||||||
|
dv_belt_l: "Für bewegliche Druckbetten",
|
||||||
|
dv_fanp_s: "Lüfter-Einstellung",
|
||||||
|
dv_fanp_l: "Wie stark der Lüfter eingestellt sein soll",
|
||||||
|
dv_prog_s: "Fortschrittsanzeige",
|
||||||
|
dv_prog_l: "Wenn für jedes % der Fertigstellung eine Nachicht angezeigt werden soll",
|
||||||
|
dv_layr_s: "Ebene",
|
||||||
|
dv_layr_l: ["Ausgabe bei jeder","neuen Ebene"],
|
||||||
|
dv_tksp_s: "Befehls-Trenner",
|
||||||
|
dv_tksp_l: ["Füge ein Leerzeichen ein bei","GCode-Achsen-Befehlen","G0X0Y0X0","oder","G0 X0 Y0 Z0"],
|
||||||
|
dv_strc_s: "Kommentare entfernen",
|
||||||
|
dv_strc_l: ["Kommentare aus GCode entfernen","Kommentare beginnen mit ;"],
|
||||||
|
dv_fext_s: "Datei-Erweiterung",
|
||||||
|
dv_fext_l: "Datei-Erweiterung",
|
||||||
|
dv_dwll_s: "dwell",
|
||||||
|
dv_dwll_l: "gcode dwell script",
|
||||||
|
dv_tool_s: "Werkzeg-Wechel",
|
||||||
|
dv_tool_l: "Skript zum Werkzegwechsel",
|
||||||
|
dv_sspd_s: "Spindelgeschwindigkeit",
|
||||||
|
dv_sspd_l: "Einstellung der Spindelgeschwindigkeit",
|
||||||
|
dv_paus_s: "Pause",
|
||||||
|
dv_paus_l: "Skript zum Ausführen bei einer Pause",
|
||||||
|
dv_head_s: "Anfang",
|
||||||
|
dv_head_l: "Skript für den Anfang einer GCode-Datei",
|
||||||
|
dv_foot_s: "Ende",
|
||||||
|
dv_foot_l: "Skript für das Ende einer GCode-Datei",
|
||||||
|
dv_lzon_s: "Laser an",
|
||||||
|
dv_lzon_l: "Skript, um den Laser einzuschalten",
|
||||||
|
dv_lzof_s: "Laser aus",
|
||||||
|
dv_lzof_l: "Skript, um den Laser auszuschalten",
|
||||||
|
dv_exts_s: "Auswhälen",
|
||||||
|
dv_exts_l: "GCode, um diesen Extruder auszuwählen",
|
||||||
|
dv_dext_s: "Abwählen",
|
||||||
|
dv_dext_l: "GCode, bevor ein anderer Extruder ausgewählt wird",
|
||||||
|
dv_extd_s: "Deaktivieren",
|
||||||
|
dv_extd_l: "GCode, um diesen Extruder zu deaktivieren",
|
||||||
|
dv_exox_s: "X-Offset",
|
||||||
|
dv_exox_l: "X-Offset der Düse",
|
||||||
|
dv_exoy_s: "Y-Offset",
|
||||||
|
dv_exoy_l: "Y-Offset der Düse",
|
||||||
|
|
||||||
|
// MODE
|
||||||
|
mo_menu: "Arbeits-Modus",
|
||||||
|
mo_fdmp: "FDM-Druck",
|
||||||
|
mo_slap: "SLA-Druck",
|
||||||
|
mo_lazr: "Laser-Cutting",
|
||||||
|
mo_cncm: "CNC-Fräsen",
|
||||||
|
|
||||||
|
// SETUP
|
||||||
|
su_menu: "setup",
|
||||||
|
su_devi: "Geräte",
|
||||||
|
su_tool: "Werkzeuge",
|
||||||
|
su_locl: "Lokal",
|
||||||
|
su_xprt: "Export",
|
||||||
|
su_help: "Hilfe",
|
||||||
|
|
||||||
|
// LOAD
|
||||||
|
fe_menu: "Datei",
|
||||||
|
fn_recn: "Letzte",
|
||||||
|
fn_impo: "Import",
|
||||||
|
|
||||||
|
// FUNCTION
|
||||||
|
fn_menu: "Modus",
|
||||||
|
fn_arra: "Anordnen",
|
||||||
|
fn_slic: "Slice",
|
||||||
|
fn_prev: "Vorschau",
|
||||||
|
fn_expo: "Export",
|
||||||
|
|
||||||
|
// VIEW
|
||||||
|
vu_menu: "Ansicht",
|
||||||
|
vu_home: "Standard",
|
||||||
|
vu_rset: "Zurücksetzen",
|
||||||
|
vu_sptp: "Oben",
|
||||||
|
vu_spfr: "Vorn",
|
||||||
|
vu_splt: "Links",
|
||||||
|
vu_sprt: "Ansicht",
|
||||||
|
|
||||||
|
// WORKSPACE
|
||||||
|
ws_menu: "Ansicht",
|
||||||
|
ws_save: "Speichern",
|
||||||
|
ws_cler: "Leeren",
|
||||||
|
|
||||||
|
// OPTIONS
|
||||||
|
op_menu: "interface",
|
||||||
|
op_disp: "Anzeige",
|
||||||
|
op_xprt_s: "Fortgeschritten",
|
||||||
|
op_xprt_l: "weitere Einstellungen",
|
||||||
|
op_decl_s: "decals",
|
||||||
|
op_decl_l: "show device decals and logos",
|
||||||
|
op_dang_s: "Experimentell",
|
||||||
|
op_dang_l: "Zeige experimentelle Parameter",
|
||||||
|
op_hopo_s: "hover pop",
|
||||||
|
op_hopo_l: ["enable menu hover","to activate"],
|
||||||
|
op_dark_s: "Dunkler Modus",
|
||||||
|
op_dark_l: "Dunkles Interface",
|
||||||
|
op_comp_s: "Kompakt",
|
||||||
|
op_comp_l: ["Kompakte Ansicht","Besser für kleine Bildschirme","und Tablets"],
|
||||||
|
op_shor_s: "Nullpunkt anzeigen",
|
||||||
|
op_shor_l: "Zeige den Nullpunkt des Gerätes oder des Prozesses",
|
||||||
|
op_shru_s: "Lineal einblenden",
|
||||||
|
op_shru_l: ["Zeige Lineale mit Maßen","auf den Hauptachsen"],
|
||||||
|
op_sped_s: "Geschwindigkeiten einblenden",
|
||||||
|
op_sped_l: ["Zeige Legende für Farben und Geschwindigkeiten","in der Vorschau"],
|
||||||
|
op_auto_s: "Automatische Anordnung",
|
||||||
|
op_auto_l: ["Ordne automatisch an","wenn neue Objekte hinzugefügt werden"],
|
||||||
|
op_free_s: "Freie Anordnung",
|
||||||
|
op_free_l: ["Erlaube Freie Anordnung von Objekten","Keine Auswirkung im Laser-Cutting Arbeitsmodus"],
|
||||||
|
op_spcr_s: "Abstand",
|
||||||
|
op_spcr_l: ["Abstand zwischen Objekten","bei automatischer Anordnung","in Maßeinheiten der Arbeitsfläche"],
|
||||||
|
op_invr_s: "Zoom Umkehren",
|
||||||
|
op_invr_l: ["Kehre die Richtung beim Mausrad-","Zoomen um"],
|
||||||
|
op_save_s: "Automatisch speichern",
|
||||||
|
op_save_l: ["Behalte Objekte im Arbeitsbereich","wenn die Anwendung neu geladen wird"],
|
||||||
|
op_line_s: "Darstellungs-Typ",
|
||||||
|
op_line_l: ["Wie Linien bei der Darstellung der Pfade gezeichnet werden","Beeinflußt 3D-Performance","Pfad: 3D (beste)","Flach: 2d (gut)","Linie = 1d (schnell)"],
|
||||||
|
op_unit_s: "Maßeinheiten",
|
||||||
|
op_unit_l: ["die Maßeinheit des Arbeitsbereich wirkt sich auf die Darstellung von ","Geschwindigkeiten und Entfernungen aus"],
|
||||||
|
op_anim_s: "Animieren",
|
||||||
|
op_anim_l: ["Dichte des Netzgitters beim Animieren","Je höher, desto dichter","benötigt mehr Speicher","und ist langsamer"],
|
||||||
|
|
||||||
|
lo_menu: "Anordnung",
|
||||||
|
|
||||||
|
pt_menu: "Objekte",
|
||||||
|
pt_deci_s: "Deizimierung",
|
||||||
|
pt_deci_l: ["Punktdezimierung","während des Imports. Für schnelleres Slicen","und weniger Speicherverbrauch"],
|
||||||
|
pt_qual_s: "Qualität",
|
||||||
|
pt_qual_l: ["Detailstufe beim","Slicen","geringer ist schneller"],
|
||||||
|
pt_heal_s: "Mesh reparieren",
|
||||||
|
pt_heal_l: ["Versuche","defekte Meshes zu reparieren","wirkt sich auf die Verarbeitungszeit us"],
|
||||||
|
|
||||||
|
xp_menu: "Export",
|
||||||
|
|
||||||
|
// SETTINGS
|
||||||
|
se_menu: "Profil",
|
||||||
|
se_load: "Laden",
|
||||||
|
se_save: "Speichern",
|
||||||
|
|
||||||
|
// FDM SLICING
|
||||||
|
sl_menu: "Schichten",
|
||||||
|
sl_lahi_s: "Höhe",
|
||||||
|
sl_lahi_l: ["Höhe jeder Schicht","Schichthöhe in mm"],
|
||||||
|
ad_minl_s: "Mindesthöhe",
|
||||||
|
ad_minl_l: ["Mindesthöhe für adaptive Schichthöhe","in mm","Darf nicht null sein"],
|
||||||
|
sl_ltop_s: "top layers",
|
||||||
|
sl_ltop_l: ["number of solid layers","to enforce at the","top of the print"],
|
||||||
|
sl_lsld_s: "solid layers",
|
||||||
|
sl_lsld_l: ["solid fill areas computed","from layer deltas. see","layer pop menu"],
|
||||||
|
sl_lbot_s: "base layers",
|
||||||
|
sl_lbot_l: ["Anzahl der soliden Schichten","um die Unterseite des","Drucks zu verstärken"],
|
||||||
|
ad_adap_s: "Adaptive Höhe",
|
||||||
|
ad_adap_l: ["Verwende adaptive Schichthöhe","mit 'Maximale Höhe' als Maximum","und 'Mindesthöhe' als Minimum"],
|
||||||
|
|
||||||
|
// FDM SHELLS
|
||||||
|
sl_shel_s: "Anzahl Außenwände",
|
||||||
|
sl_shel_l: ["Anzahl der äußeren","Wände, die erzeugt werden sollen"],
|
||||||
|
sl_ordr_s: "Druckreihenfolge der Wände",
|
||||||
|
sl_ordr_l: ["In welcher Reihenfolge die Wände gedruckt werden","innen nach aussen","oder aussen nach innen","wirkt sich auf die Oberflächenqualität aus"],
|
||||||
|
sl_strt_s: "Start der Ebene",
|
||||||
|
sl_strt_l: ["Startpunkt der Ebene","Letzte = Ende der letzten Ebene ","Mitte = Zur Mitte des Objekts","Nullpunkt = Zum Nullpunkt des Gerätes"],
|
||||||
|
ad_thin_s: "Dünne Wände",
|
||||||
|
ad_thin_l: ["Finde und fülle schmale Lücken","zwischen Außenwänden"],
|
||||||
|
|
||||||
|
// FDM FILL
|
||||||
|
fi_menu: "Füllmaterial",
|
||||||
|
fi_type: "Typ",
|
||||||
|
fi_pcnt_s: "Füll-Dichte",
|
||||||
|
fi_pcnt_l: ["Füll-Dichte ","0.0 - 1.0"],
|
||||||
|
fi_angl_s: "Startwinkel für volle Füllung",
|
||||||
|
fi_angl_l: ["Startwinkel in Grad","90 Grad werden ","bei jeder folgender Schicht dazugerechnet","Wirkt sich nur auf vollgefüllte Schichten aus."],
|
||||||
|
fi_over_s: "Schicht-Überlappung",
|
||||||
|
fi_over_l: ["Überlappung von Schichten und Füllung","als Anteil des Düsen-Durchmessers","0.0 - 1.0"],
|
||||||
|
// fi_rate_s: "print speed",
|
||||||
|
fi_rate_l: ["Druckgeschwindigkeit für Füllmaterial","Auf 0 setzen, um die Standard-","Druckgeschwindigkeit zu verwenden"],
|
||||||
|
|
||||||
|
// FDM FIRST LAYER
|
||||||
|
fl_menu: "Erste Schicht",
|
||||||
|
fl_lahi_s: "Schichthöhe",
|
||||||
|
fl_lahi_l: ["Höhe der ersten Schicht","in in mm","sollte >= der Standard-Schichthöhe sein"],
|
||||||
|
fl_rate_s: "Wand-Geschwindigkeit",
|
||||||
|
fl_rate_l: ["Maximalgeschwindigkeit beim Drucken von Wänden","in mm / min"],
|
||||||
|
fl_frat_s: "Füll-Geschwindikeit",
|
||||||
|
fl_frat_l: ["Maximalgeschwindikeit beim Drucken von Füllung","in mm / min"],
|
||||||
|
fl_mult_s: "Extrusions-Faktor",
|
||||||
|
fl_mult_l: ["Exktrusions-Faktor","0.0 - 2.0"],
|
||||||
|
fl_sfac_s: "Breiten-Faktor",
|
||||||
|
fl_sfac_l: ["Multipliziert mit dem Düsenfaktor","beeinflußt die Breite der Drucklinien"],
|
||||||
|
fl_skrt_s: "Anzahl der Skirt-Linien",
|
||||||
|
fl_skrt_l: ["Wieviele Linien um die erste Schicht","herum generiert werden sollen"],
|
||||||
|
fl_skro_s: "Skirt-Abstand",
|
||||||
|
fl_skro_l: ["Abstand des Skirts vom Objekt","in mm"],
|
||||||
|
fl_nozl_s: "Drucktemperatur",
|
||||||
|
fl_nozl_l: ["in Grad Celsius","Standard-Einstellung wird verwendet","wenn auf 0 gestellt"],
|
||||||
|
fl_bedd_s: "Betttemperatur",
|
||||||
|
fl_bedd_l: ["in Grad Celsius","Standard-Einstellung wird verwendet","when auf 0 gestellt"],
|
||||||
|
fr_spac_s: "Raft Abstand",
|
||||||
|
fr_spac_l: ["Zusätzlicher Abstand","zwischen erster Schicht und Raft","in mm"],
|
||||||
|
fr_nabl_s: "Raft verwenden",
|
||||||
|
fr_nabl_l: ["Erzeuge ein Raft unter dem","Objekt für bessere Betthaftung","verwendet Skirt-Abstand und","Deaktiviert die Erzeugung eines Skirt"],
|
||||||
|
|
||||||
|
// FDM BELT ONLY
|
||||||
|
fl_zoff_s: "belt offset",
|
||||||
|
fl_zoff_l: ["height offset from belt","of lowest extrusion","in millimeters"],
|
||||||
|
fl_brim_s: "Größe des Brim",
|
||||||
|
fl_brim_l: ["Brim am Fuß des Objekts erzeugen","Größe in mm","0 um zu deaktivieren"],
|
||||||
|
fl_brmn_s: "Brim-Auslöser",
|
||||||
|
fl_brmn_l: ["Erzeuge nur Brim, wenn die Fläche","auf dem Gurt kürzer ist als dieser Wert","Angegeben in mm","0 = Immer"],
|
||||||
|
fl_bled_s: "Objekt verankern",
|
||||||
|
fl_bled_l: ["Objekt mit dem Gurt verankern","zu Beginn des Drucks","in mm"],
|
||||||
|
|
||||||
|
// FDM SUPPORT
|
||||||
|
sp_menu: "Stützstrukturen",
|
||||||
|
sp_detect: "Analysieren",
|
||||||
|
sp_dens_s: "Dichte",
|
||||||
|
sp_dens_l: ["Anteil 0.0 - 1.0","empfohlen 0.15","0 zum deaktivieren"],
|
||||||
|
sp_size_s: "Breite der Säule",
|
||||||
|
sp_size_l: ["Breite der Säule","in mm"],
|
||||||
|
sp_offs_s: "Abstand",
|
||||||
|
sp_offs_l: ["Abstand vom Objekt","in mm"],
|
||||||
|
sp_gaps_s: "Schicht-Abstand",
|
||||||
|
sp_gaps_l: ["Anzahl der Schichten","zwischen Stützstruktur und Objekt"],
|
||||||
|
sp_span_s: "Maximale Spannbreite",
|
||||||
|
sp_span_l: ["Für Spannen über dieser Breite","werden Stützstrukturen erzeugt","in mm"],
|
||||||
|
sp_angl_s: "Maximaler Winkel",
|
||||||
|
sp_angl_l: ["Für Überhänge über diesem Winkel","werden Stützstrukturen erzeugt"],
|
||||||
|
sp_area_s: "Mindestfläche",
|
||||||
|
sp_area_l: ["Mindestfläche für","Eine Stützsäule","in mm"],
|
||||||
|
sp_xpnd_s: "Ausdehung",
|
||||||
|
sp_xpnd_l: ["Dehne die Stützstruktur","über die Objekt-Grenzen aus","in mm"],
|
||||||
|
sp_nozl_s: "Extruder",
|
||||||
|
sp_nozl_l: ["In Geräten mit mehreren Extrudern","welcher Extruder wird für","Stützmaterial verwendet"],
|
||||||
|
sp_auto_s: "Automatisch",
|
||||||
|
sp_auto_l: ["Erzeuge Stützstrukturen automatisch","beim Slicen","Stützstruktuen werden erst","Nach dem Slicen angezeigt"],
|
||||||
|
|
||||||
|
// LASER SLICING
|
||||||
|
ls_offs_s: "Abstand",
|
||||||
|
ls_offs_l: ["Anpassung for Strahlbreite","in millimeters"],
|
||||||
|
ls_lahi_s: "Höhe",
|
||||||
|
ls_lahi_l: ["Schichthöhe","in mm","0 = auto/erkennen"],
|
||||||
|
ls_lahm_s: "min",
|
||||||
|
ls_lahm_l: ["Minimale Schichthöhe","Autoslices unter dieser Höhe","werden zusammengeführt","in millimeters"],
|
||||||
|
ls_sngl_s: "Einfach",
|
||||||
|
ls_sngl_l: ["Nur einen Slice bei","angegebener Schichthöhe ausführen"],
|
||||||
|
|
||||||
|
// CNC COMMON terms
|
||||||
|
cc_tool: "Werkzeug",
|
||||||
|
cc_offs_s: "offset",
|
||||||
|
cc_offs_l: ["offset tool center","from chosen path"],
|
||||||
|
cc_spnd_s: "spindle rpm",
|
||||||
|
cc_spnd_l: ["spindle speed in","revolutions / minute"],
|
||||||
|
cc_sovr_s: "step over",
|
||||||
|
cc_sovr_l: ["as a fraction of","tool diameter"],
|
||||||
|
cc_sdwn_s: "step down",
|
||||||
|
cc_sdwn_l: ["step down depth","for each pass","in workspace units","0 to disable"],
|
||||||
|
cc_feed_s: "feed rate",
|
||||||
|
cc_feed_l: ["max cutting speed in","workspace units / minute"],
|
||||||
|
cc_plng_s: "plunge rate",
|
||||||
|
cc_plng_l: ["max z axis speed in","workspace units / minute"],
|
||||||
|
cc_sngl_s: "select lines only",
|
||||||
|
cc_sngl_l: ["select only single edges","instead of connected polylines"],
|
||||||
|
|
||||||
|
// CNC COMMON
|
||||||
|
cc_menu: "limits",
|
||||||
|
cc_flip: "flip",
|
||||||
|
cc_rapd_s: "xy feed",
|
||||||
|
cc_rapd_l: ["max xy moves feedrate","in workspace units / minute"],
|
||||||
|
cc_rzpd_s: "z feed",
|
||||||
|
cc_rzpd_l: ["max z moves feedrate","in workspace units / minute"],
|
||||||
|
|
||||||
|
cc_loff_s: "offset",
|
||||||
|
cc_loff_l: ["distance from stock face","for leveling pass","in workspace units"],
|
||||||
|
|
||||||
|
// CNC ROUGHING
|
||||||
|
cr_menu: "rough",
|
||||||
|
cr_lsto_s: "leave stock",
|
||||||
|
cr_lsto_l: ["horizontal offset from vertical faces","stock to leave for finishing pass","in workspace units"],
|
||||||
|
cr_ease_s: "ease down",
|
||||||
|
cr_ease_l: ["plunge cuts will","spiral down or ease","along a linear path"],
|
||||||
|
cr_clrt_s: "clear top",
|
||||||
|
cr_clrt_l: ["run a clearing pass over","the bounding area of the part","at z = 0"],
|
||||||
|
cr_clrp_s: "clear voids",
|
||||||
|
cr_clrp_l: ["mill out through pockets","instead of just the outline"],
|
||||||
|
cr_clrf_s: "clear faces",
|
||||||
|
cr_clrf_l: ["interpolate step down to","clear any detected flat areas"],
|
||||||
|
cr_olin_s: "inside only",
|
||||||
|
cr_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
|
||||||
|
// CNC OUTLINE
|
||||||
|
co_menu: "outline",
|
||||||
|
co_dogb_s: "dogbones",
|
||||||
|
co_dogb_l: ["insert dogbone cuts","into inside corners"],
|
||||||
|
co_wide_s: "wide cutout",
|
||||||
|
co_wide_l: ["widen outside cutout paths","for deep cuts in hard material"],
|
||||||
|
co_olin_s: "inside only",
|
||||||
|
co_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
co_olot_s: "outside only",
|
||||||
|
co_olot_l: ["limit cutting to","exterior part boundaries","which can be thought of","as the shadow outline"],
|
||||||
|
co_omit_s: "omit through",
|
||||||
|
co_omit_l: "eliminate thru holes",
|
||||||
|
co_olen_s: "enable",
|
||||||
|
co_olen_l: "enabled outline cutting",
|
||||||
|
|
||||||
|
// CNC CONTOUR
|
||||||
|
cn_menu: "contour",
|
||||||
|
cf_angl_s: "max angle",
|
||||||
|
cf_angl_l: ["angles greater than this","are considered vertical"],
|
||||||
|
cf_curv_s: "curves only",
|
||||||
|
cf_curv_l: ["limit linear cleanup","to curved surfaces"],
|
||||||
|
cf_olin_s: "inside only",
|
||||||
|
cf_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
cf_linx_s: "enable y pass",
|
||||||
|
cf_linx_l: "linear y-axis finishing",
|
||||||
|
cf_liny_s: "enable x pass",
|
||||||
|
cf_liny_l: "linear x-axis finishing",
|
||||||
|
|
||||||
|
// CNC TRACE
|
||||||
|
cu_menu: "trace",
|
||||||
|
cu_type_s: "type",
|
||||||
|
cu_type_l: ["follow = tool tip follows line","right or left = tool tip","follows line offset by tool radius"],
|
||||||
|
|
||||||
|
// CNC DRILLING
|
||||||
|
cd_menu: "drill",
|
||||||
|
cd_axis: "axis",
|
||||||
|
cd_points: "points",
|
||||||
|
cd_plpr_s: "plunge per",
|
||||||
|
cd_plpr_l: ["max plunge between","dwell periods","in workspace units","0 to disable"],
|
||||||
|
cd_dwll_s: "dwell time",
|
||||||
|
cd_dwll_l: ["dwell time","between plunges in","in milliseconds"],
|
||||||
|
cd_lift_s: "drill lift",
|
||||||
|
cd_lift_l: ["lift between plunges","after dwell period","in workspace units","0 to disable"],
|
||||||
|
cd_regi_s: "register",
|
||||||
|
cd_regi_l: ["drill registration holes","for double-sided parts","independent of enable","drilling but uses same","tool and settings"],
|
||||||
|
|
||||||
|
// CNC CUTOUT TABS
|
||||||
|
ct_menu: "tabs",
|
||||||
|
ct_angl_s: "angle",
|
||||||
|
ct_angl_l: ["starting angle for tab spacing","in degrees (0-360)"],
|
||||||
|
ct_numb_s: "count",
|
||||||
|
ct_numb_l: ["number of tabs to use","will be spaced evenly","around the part"],
|
||||||
|
ct_wdth_s: "width",
|
||||||
|
ct_wdth_l: "width in workspace units",
|
||||||
|
ct_hght_s: "height",
|
||||||
|
ct_hght_l: "height in workspace units",
|
||||||
|
ct_dpth_s: "depth",
|
||||||
|
ct_dpth_l: ["distance in workspace units","that the tab projects from","the part surface"],
|
||||||
|
ct_midl_s: "midline",
|
||||||
|
ct_midl_l: ["use midline of tab","instead of z bottom","for double-sided work"],
|
||||||
|
ct_nabl_s: "auto",
|
||||||
|
ct_nabl_l: ["auto generate radial tabs","projected from part center","using count and angle offset"],
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
ou_menu: "output",
|
||||||
|
|
||||||
|
// LASER KNIFE
|
||||||
|
dk_menu: "knife",
|
||||||
|
dk_dpth_s: "cut depth",
|
||||||
|
dk_dpth_l: ["final cut depth","in millimeters"],
|
||||||
|
dk_pass_s: "cut passes",
|
||||||
|
dk_pass_l: ["number of passes","down to cut depth"],
|
||||||
|
dk_offs_s: "tip offset",
|
||||||
|
dk_offs_l: ["distance from blade tip","to center of tool","in millimeters"],
|
||||||
|
|
||||||
|
// OUTPUT LASER
|
||||||
|
ou_spac_s: "spacing",
|
||||||
|
ou_spac_l: ["distance between layer output","in millimeters"],
|
||||||
|
ou_scal_s: "scaling",
|
||||||
|
ou_scal_l: "multiplier (0.1 to 100)",
|
||||||
|
ou_powr_s: "power",
|
||||||
|
ou_powr_l: ["0 - 100","represents %"],
|
||||||
|
ou_sped_s: "speed",
|
||||||
|
ou_sped_l: "millimeters / minute",
|
||||||
|
ou_mrgd_s: "merged",
|
||||||
|
ou_mrgd_l: ["merge all layers using","color coding to denote","stacking depth"],
|
||||||
|
ou_grpd_s: "grouped",
|
||||||
|
ou_grpd_l: ["retain each layer as","a unified grouping","instead of separated","polygons"],
|
||||||
|
ou_layr_s: "layer order",
|
||||||
|
ou_layr_l: ["output layer order","from top right to","bottom left"],
|
||||||
|
ou_layo_s: "layer color",
|
||||||
|
ou_layo_l: ["output layer colors","for each z index","overridden by merged"],
|
||||||
|
ou_drkn_s: "drag knife",
|
||||||
|
ou_drkn_l: ["enable drag knife","output in gcode","cut radii are added","to corners with","cut down passes"],
|
||||||
|
|
||||||
|
// OUTPUT FDM
|
||||||
|
ou_nozl_s: "Drucktemperatur",
|
||||||
|
ou_nozl_l: "In Grad Celsius",
|
||||||
|
ou_bedd_s: "Betttemperatur",
|
||||||
|
ou_bedd_l: "In Grad Celsius",
|
||||||
|
ou_feed_s: "Druckgewschwindigkeit",
|
||||||
|
ou_feed_l: ["Maximale Druckgeschwindigkeit","mm / min"],
|
||||||
|
ou_fini_s: "Außengeschwindigkeit",
|
||||||
|
ou_fini_l: ["Geschwindigkeit für Außenwände","mm / min"],
|
||||||
|
ou_move_s: "Bewegungsgeschwnidgkeit",
|
||||||
|
ou_move_l: ["Geschwndigkeit, wenn nicht gedruckt wird ","mm / min","0 = aktiviere G0 Befehle"],
|
||||||
|
ou_shml_s: "Wand-Faktor",
|
||||||
|
ou_flml_s: "Voll-Füll-Faktor",
|
||||||
|
ou_spml_s: "Füll-Material-Faktor",
|
||||||
|
ou_exml_l: ["Extrusions-Multiplikator","0.0 - 2.0"],
|
||||||
|
ou_fans_s: "Geschwindigkeit der Bauteilkühlung",
|
||||||
|
ou_fans_l: "0 - 255",
|
||||||
|
|
||||||
|
// OUTPUT CAM
|
||||||
|
ou_toll_s: "tolerance",
|
||||||
|
ou_toll_l: ["surface precision","in workspace units","lower is slower and","uses more memory","0 = automatic based","on animate preference"],
|
||||||
|
ou_zanc_s: "z anchor",
|
||||||
|
ou_zanc_l: ["controls the position of the part","when stock Z exceeds part Z"],
|
||||||
|
ou_ztof_s: "z offset",
|
||||||
|
ou_ztof_l: ["offset z anchor","in workspace units","has no effect when","anchor is middle"],
|
||||||
|
ou_zbot_s: "z bottom",
|
||||||
|
ou_zbot_l: ["offset from part bottom","to limit cutting depth","in workspace units"],
|
||||||
|
ou_zclr_s: "z clearance",
|
||||||
|
ou_zclr_l: ["safe travel offset","from top of part","in workspace units"],
|
||||||
|
ou_ztru_s: "z thru",
|
||||||
|
ou_ztru_l: ["extend cutout pass down","in workspace units"],
|
||||||
|
ou_conv_s: "conventional",
|
||||||
|
ou_conv_l: ["milling direction","uncheck for 'climb'"],
|
||||||
|
ou_depf_s: "depth first",
|
||||||
|
ou_depf_l: ["optimize pocket cuts","with depth priority"],
|
||||||
|
|
||||||
|
// CAM STOCK
|
||||||
|
cs_menu: "stock",
|
||||||
|
cs_wdth_s: "width",
|
||||||
|
cs_wdth_l: ["width (x) in workspace units","0 defaults to part size"],
|
||||||
|
cs_dpth_s: "depth",
|
||||||
|
cs_dpth_l: ["depth (y) in workspace units","0 defaults to part size"],
|
||||||
|
cs_hght_s: "height",
|
||||||
|
cs_hght_l: ["height (z) in workspace units","0 defaults to part size"],
|
||||||
|
cs_offs_s: "offset",
|
||||||
|
cs_offs_l: ["use width, depth, height","as offsets from max","part size on platform"],
|
||||||
|
cs_clip_s: "clip to",
|
||||||
|
cs_clip_l: ["rough and outline","clip cutting paths","to defined stock"],
|
||||||
|
cs_offe_s: "enable",
|
||||||
|
cs_offe_l: "enable milling stock",
|
||||||
|
|
||||||
|
// ORIGIN (CAM & LASER)
|
||||||
|
or_bnds_s: "origin bounds",
|
||||||
|
or_bnds_l: ["origin is relative to","boundary of all objects"],
|
||||||
|
or_cntr_s: "origin center",
|
||||||
|
or_cntr_l: "origin is referenced from the center",
|
||||||
|
or_topp_s: "origin top",
|
||||||
|
or_topp_l: "origin is references from the top of objects",
|
||||||
|
|
||||||
|
// FDM ADVANCED
|
||||||
|
ad_menu: "Fortgeschritten",
|
||||||
|
ad_rdst_s: "Einzugslänge",
|
||||||
|
ad_rdst_l: ["Wie weit das Filament eingezogen werden soll","bei langen Bewegungen (in mm)"],
|
||||||
|
ad_rrat_s: "Einzugsgeschwindigkeit",
|
||||||
|
ad_rrat_l: ["Geschwindigkeit des Filamenteinzugs","in mm/s"],
|
||||||
|
ad_rdwl_s: "Vorschub-Pause",
|
||||||
|
ad_wpln_s: "Einzugs-Bewegung",
|
||||||
|
ad_wpln_l: ["Bewegung ohne Druck","nach Einzug","in millimeters"],
|
||||||
|
ad_rdwl_l: ["Zeitabstand zwischen","Bewegung und Vorschub nach Einzug ","in msec"],
|
||||||
|
ad_scst_s: "Außenwand-Coasting",
|
||||||
|
ad_scst_l: ["Welche Strecke am Ende einer","Außenwand nicht extrudiert wird","in mm"],
|
||||||
|
ad_msol_s: "Mindestfläche für vollständige Füllung",
|
||||||
|
ad_msol_l: ["Mindestfläche in mm^2 ","für vollständige Füllung","muß > 0.1 sein"],
|
||||||
|
ad_mins_s: "Mindestgeschwindigkeit",
|
||||||
|
ad_mins_l: ["Mindestgeschwindigkeit","für kurze Segmente"],
|
||||||
|
ad_spol_s: "Kurze Segmente",
|
||||||
|
ad_spol_l: ["Segmente die kürzer sind","werden mit","Mindestgeschwindigkeit gedruckt","in mm"],
|
||||||
|
ad_arct_s: "arc tolerance",
|
||||||
|
ad_arct_l: ["convert faceted lines to arcs","center point drift tolerance","when matching arc points","consider values around 0.15","in millimeters","0 to disable"],
|
||||||
|
ad_zhop_s: "Z Hop",
|
||||||
|
ad_zhop_l: ["Hebe Düse bei Einzug an","in mm","0 zum deaaktivieren"],
|
||||||
|
ad_abkl_s: "anti-backlash",
|
||||||
|
ad_abkl_l: ["Für schöneres Aussehen Flacher Oberflächen","verwende Micro-Bewegungen","um Backlash auszugleichen","in mm","0 zum deaktivieren","Wenn Deine Firmware M425 unterstützt","verwende das im Start-GCode und setze hier auf 0"],
|
||||||
|
ad_lret_s: "Einzug bei Ebenenwechsel",
|
||||||
|
ad_lret_l: ["Erzwinge Einzug","bei Ebenen wechseln"],
|
||||||
|
ad_play_s: "Ebenen glätten",
|
||||||
|
ad_play_l: ["glätte bis zu","dieser Anzahl Ebenen"],
|
||||||
|
ad_pspd_s: "Glätt-Geschwindigkeit",
|
||||||
|
ad_pspd_l: ["Glätt-Geschwindigkeit","in mm / min"],
|
||||||
|
|
||||||
|
// CAM EXPERT
|
||||||
|
cx_fast_s: "skip shadow",
|
||||||
|
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
||||||
|
|
||||||
|
// FDM GCODE
|
||||||
|
ag_menu: "GCode",
|
||||||
|
ag_nozl_s: "Düse",
|
||||||
|
ag_nozl_l: "Wählt Düse oder Druckkopf aus",
|
||||||
|
ag_paws_s: "Pause bei Ebenen",
|
||||||
|
ag_paws_l: ["Liste von Ebenen (kommasepariert","vor denen pausiert werden soll"],
|
||||||
|
ag_loop_s: "Schichten wiederholen",
|
||||||
|
ag_loop_l: ["Schichten die wiederholt werden sollen, im Format ","erste-letzte-anzahl,erste-letzte-anzahl,...","omitted count = 1"],
|
||||||
|
|
||||||
|
// SLA MENU
|
||||||
|
sa_menu: "Slicen",
|
||||||
|
sa_lahe_s: "Schichthöhe",
|
||||||
|
sa_lahe_l: ["Schichthöhe","in mm"],
|
||||||
|
sa_shel_s: "Aushöhlen",
|
||||||
|
sa_shel_l: ["Wanddick mm","verwene Mehrfaches der Schichthöhe","setze 0 zum deaktivieren"],
|
||||||
|
sa_otop_s: "oben offen",
|
||||||
|
sa_otop_l: ["Wenn Aushöhlen aktiviert ist","bleibt das Objekt oben offen"],
|
||||||
|
sa_obas_s: "unten offen",
|
||||||
|
sa_obas_l: ["Wenn Aushöhlen aktiviert ist","bleibt das Objekt unten offen","deaktiviert, wenn Stützstrukturen verwendet werden"],
|
||||||
|
|
||||||
|
sa_layr_m: "layers",
|
||||||
|
sa_lton_s: "light on time",
|
||||||
|
sa_lton_l: ["layer light on","time in seconds"],
|
||||||
|
sa_ltof_s: "light off time",
|
||||||
|
sa_ltof_l: ["layer light off","time in seconds"],
|
||||||
|
sa_pldi_s: "peel distance",
|
||||||
|
sa_pldi_l: ["peel distance","in millimeters"],
|
||||||
|
sa_pllr_s: "peel lift rate",
|
||||||
|
sa_pllr_l: ["peel lift speed","in mm/sec"],
|
||||||
|
sa_pldr_s: "peel drop rate",
|
||||||
|
sa_pldr_l: ["peel drop speed","in mm/sec"],
|
||||||
|
|
||||||
|
sa_base_m: "base",
|
||||||
|
sa_balc_s: "layer count",
|
||||||
|
sa_balc_l: ["number of","base layers"],
|
||||||
|
sa_bltn_l: ["base layer light on","time in seconds"],
|
||||||
|
sa_bltf_l: ["base layer light off","time in seconds"],
|
||||||
|
|
||||||
|
sa_infl_m: "Füllstrukturen",
|
||||||
|
sa_ifdn_s: "Dichte",
|
||||||
|
sa_ifdn_l: ["percent infill","requires shell","0 = disabled","valid 0.0 - 1.0"],
|
||||||
|
sa_iflw_s: "line width",
|
||||||
|
sa_iflw_l: ["hatch line width","in millimeters"],
|
||||||
|
|
||||||
|
sa_supp_m: "support",
|
||||||
|
sa_slyr_s: "base layers",
|
||||||
|
sa_slyr_l: ["base support layers","value range 0-10"],
|
||||||
|
sa_slgp_s: "gap layers",
|
||||||
|
sa_slgp_l: ["number of layers between","raft and bottom of object"],
|
||||||
|
sa_sldn_s: "density",
|
||||||
|
sa_sldn_l: ["used to compute the","number of support pillars","0.0-1.0 (0 = disable)"],
|
||||||
|
sa_slsz_s: "size",
|
||||||
|
sa_slsz_l: ["max size of a","support pillar","in millimeters"],
|
||||||
|
sa_slpt_s: "points",
|
||||||
|
sa_slpt_l: ["number of points in","each support pillar","in millimeters"],
|
||||||
|
sl_slen_l: "enable supports",
|
||||||
|
|
||||||
|
sa_outp_m: "output",
|
||||||
|
sa_opzo_s: "z offset",
|
||||||
|
sa_opzo_l: ["z layer offset","almost always 0.0","0.0-1.0 in millimeters"],
|
||||||
|
sa_opaa_s: "anti alias",
|
||||||
|
sa_opaa_l: ["enable anti-aliasing","produces larger files","can blur details"]
|
||||||
|
};
|
||||||
177
web/kiri/lang/de-help.html
Normal file
177
web/kiri/lang/de-help.html
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
<div id="help" class="f-col a-stretch">
|
||||||
|
|
||||||
|
<div class="title f-row j-center">
|
||||||
|
<label>Kiri:Moto Slicer Help</label>
|
||||||
|
<label id="kiri-version"></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="f-row">
|
||||||
|
|
||||||
|
<div id="help-sel" class="f-col">
|
||||||
|
<div class="help-label" tab="about">Über</div>
|
||||||
|
<div class="help-label" tab="start">starting</div>
|
||||||
|
<div class="help-label" tab="controls">Steuerung</div>
|
||||||
|
<div class="help-label" tab="support">Unterstützung</div>
|
||||||
|
<div class="help-label" tab="project">Das Projekt</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tabs" class="f-grow">
|
||||||
|
<div id="help-tab-about" class="help-tab f-col a-center">
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<b>Kiri:Moto</b> ist ein einzigartiger browser-basierter, komplett quelloffener slicer,
|
||||||
|
mit dem Du 3D-Modelle in Steuerbefehle für <u>3D-Drucker</u>, <u>CNC-Fräsen</u>,
|
||||||
|
uns <u>Laser Cutter</u> umwandeln kannst.
|
||||||
|
</p><br><p>
|
||||||
|
Browser-basiert bedeutet, dass <i>alle</i> Verarbeitung in Deinem Browser stattfindet,
|
||||||
|
und nicht in der Cloud. Deine Modelle und Daten bleiben <i>privat</i> auf Deinem Rechner.
|
||||||
|
</p><br><p>
|
||||||
|
Das heisst, das Kiri wie eine lokale Anwendung auf Deinem Computer läuft, aber zusätzlich
|
||||||
|
so sicher ist, wie Dein Browser.
|
||||||
|
</p><br><p>
|
||||||
|
Ein weiterer Vorteil von Kiri als Web-Anwendung ist, dass Du immer die aktuelle Version
|
||||||
|
verwendest. Neue Funktionen, Fehlerbehebungen, und andere Updates kommen regelmäßig und automatisch
|
||||||
|
bei Dir an. Wenn Du eine ältere, oder eine Entwicklungsversion von Kiri verwenden willst, kannst
|
||||||
|
Du diese im Nutzer-Menü oben rechts auswählen.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grow"></div>
|
||||||
|
<i>Kiri leitet sich von Kiri-e ab, der Japanischen Scherenschnitt-Kunst.</i>
|
||||||
|
<i>Moto ist ein Kürzel für "Modeling Tool" (Modellierungs-Werkzeug)</i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tab-start" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Schnell-Anleitung</b>
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<li id="help-start">Schau Dir <a href="https://youtu.be/08795Sj22QE" target="youtube">The Definitive Video Guide to Kiri:Moto 2.5</a> an (auf Englisch)</li>
|
||||||
|
<li><button><i class="fas fa-cogs"></i></button> Im Einrichtungs-Menü wählst Du <button><i class="fas fa-cube"></i></button> Geräte und Arbeitsmodus</li>
|
||||||
|
<li><button><i class="fas fa-sliders-h"></i></button> preferences allow interface and mode-specific settings</li>
|
||||||
|
<li><button><i class="fas fa-plus"></i></button> Du kannst Geräte-Konfigurationen anpassen, wenn Du die Standard-Einstellungen verändern willst</li>
|
||||||
|
<li><button><i class="fas fa-folder"></i></button> Öffne Dateien <button><i class="fas fa-file-upload"></i></button> importiere Teile in den Arbeitsbereich</li>
|
||||||
|
<li>use the right-side profile menus to customize slicing parameters</li>
|
||||||
|
<li><button><i class="fas fa-bars"></i></button> Mit Slice siehst du, wie die Parameter sich auf Objekte auswirken</li>
|
||||||
|
<li><button><i class="fas fa-cubes"></i></button> Vorschau berechnet Pfade (Maschinen-Anweisungen) aus den gesliceten Objekten</li>
|
||||||
|
<li><button><i class="fas fa-file-download"></i></button> Export speichert diese Pfade in GCode- oder SVG-Dateien</li>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<b class="header">Arbeits-Modi</b>
|
||||||
|
<p>Jeder Modus (FDM, CAM, Laser, SLA) hat unterschiedliche Funktionen und Einstellungsmöglichkeiten.
|
||||||
|
Schau Dir die Youtube-Videos an, um mehr zu erfahren.</p>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-print" class="help-tab f-col">Über 3d-Druck</div>
|
||||||
|
<div id="help-tab-mill" class="help-tab f-col">Über CNC-Fräsen</div>
|
||||||
|
<div id="help-tab-laser" class="help-tab f-col">Über Laser-Cutting</div>
|
||||||
|
|
||||||
|
<div id="help-tab-controls" class="help-tab f-col a-center"><div class="content">
|
||||||
|
<div class="f-row">
|
||||||
|
<table>
|
||||||
|
<tr><td colspan="2" class="header">Tastatur-Befehle</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Taste</th><th>Befehl</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Konfiguration</td></tr>
|
||||||
|
<tr><td><label>e</label></td><td>Geräte Auswahl</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>Auswahl des Fräswerkzeugs</td></tr>
|
||||||
|
<tr><td><label>c</label></td><td>Grid-Geräte im Netzwerk</td></tr>
|
||||||
|
<tr><td><label>q</label></td><td>Voreinstellungen</td></tr>
|
||||||
|
<tr><td><label>l</label></td><td>Arbeits-Profile</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Modus</td></tr>
|
||||||
|
<tr><td><label>a</label></td><td>Platzieren</td></tr>
|
||||||
|
<tr><td><label>s</label></td><td>Slice</td></tr>
|
||||||
|
<tr><td><label>p</label></td><td>Vorschau</td></tr>
|
||||||
|
<tr><td><label>g</label></td><td>Animieren</td></tr>
|
||||||
|
<tr><td><label>x</label></td><td>Export</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Datei</td></tr>
|
||||||
|
<tr><td><label>i</label></td><td>Importieren</td></tr>
|
||||||
|
<tr><td><label>r</label></td><td>Letzte Dateien</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Ansicht</td></tr>
|
||||||
|
<tr><td><label>h</label></td><td>Standard</td></tr>
|
||||||
|
<tr><td><label>t</label></td><td>Oben</td></tr>
|
||||||
|
<tr><td><label>f</label></td><td>Vorn</td></tr>
|
||||||
|
<tr><td><label>b</label></td><td>Hinten</td></tr>
|
||||||
|
<tr><td><label>z</label></td><td>Ansicht zurüksetzen</td></tr>
|
||||||
|
<tr><td><label>< ></label></td><td>Durch die Seitenansichten wechseln</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Fokus (Platzieren)</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Ebene (Slice/Vorschau)</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Objekte</td></tr>
|
||||||
|
<tr><td><label>d</label></td><td>Duplizieren</td></tr>
|
||||||
|
<tr><td><label>m</label></td><td>Spiegeln</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>Rotieren (Dialog)</td></tr>
|
||||||
|
<tr><td><label>delete</label></td><td>Löschen</td></tr>
|
||||||
|
<tr><td><label>arrow</label></td><td>Um 90° rotieren</td></tr>
|
||||||
|
<tr><td><label>shift-arrow</label></td><td>Um 5° rotieren</td></tr>
|
||||||
|
<tr><td><label>option-arrow</label></td><td>5mm bewegen</td></tr>
|
||||||
|
<tr><td><label>ctrl-a</label></td><td>Alle Objekte auswählen</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Hilfe</td></tr>
|
||||||
|
<tr><td><label>?</label></td><td>Dieses Fenster</td></tr>
|
||||||
|
<tr><td><br><br></td></tr>
|
||||||
|
<tr><td colspan="2" class="header">Maus-Kontrollen</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Tastenkombination</th><th>Befehl</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Ansicht</td></tr>
|
||||||
|
<tr><td><label>shift</label> wheel</td><td>Schicht wechseln</td></tr>
|
||||||
|
<tr><td><label>meta</label> verschieben</td><td>Ansicht schwenken</td></tr>
|
||||||
|
<tr><td><label>right-drag</label></td><td>Ansicht schwenken</td></tr>
|
||||||
|
<tr><td><label>left-drag</label></td><td>Ansicht rotieren</td></tr>
|
||||||
|
<tr><td><label>mouse-wheel</label></td><td>Ausschnitt verändern</td></tr>
|
||||||
|
<tr><td><label>middle-drag</label></td><td>Ausschnitt verändern</td></tr>
|
||||||
|
<tr><td><label>meta</label> drag</td><td>Ansicht schwenkden</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Objekte</td></tr>
|
||||||
|
<tr><td><label>ctrl-click</label></td><td>Seite aufs Bett ausrichten</td></tr>
|
||||||
|
<tr><td><label>meta-click</label></td><td>Seite aufs Bett ausrichten</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-support" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Weitere Informationen</b>
|
||||||
|
<div class="content nounderline">
|
||||||
|
<a target="_rsc" href="https://docs.grid.space/projects/kiri-moto"><i class="fas fa-question-circle"></i>Weitereführende Dokumentation</a>
|
||||||
|
<a target="_rsc" href="https://forum.grid.space"><i class="fab fa-discourse"></i> Grid.Space forums</a>
|
||||||
|
<a target="_rsc" href="https://discord.gg/suyCCgr"><i class="fab fa-discord"></i> Discord live chat server</a>
|
||||||
|
<a target="_rsc" href="https://www.youtube.com/playlist?list=PLRoVgyRoWZpumQIKWm7oldx3bjDivqP24"><i class="fab fa-youtube"></i> Youtube videos und Tutorials</a>
|
||||||
|
<a target="_rsc" href="https://twitter.com/grid_space_3d"><i class="fab fa-twitter"></i>Grid.Space auf Twitter</a>
|
||||||
|
<a target="_rsc" href="https://facebook.com/groups/kirimoto"><i class="fab fa-facebook"></i> Kiri:Moto Gruppe aufn Facebook</a>
|
||||||
|
</div>
|
||||||
|
<b class="header">Weitere Optionen</b>
|
||||||
|
<p>
|
||||||
|
Im button><i class="fas fa-user-cog"></i></button> NutzerMenü open rechts, kannst Du die Funktion
|
||||||
|
<span class="mono">Export</span> verwenden, um eine Kopie Deiner Geräte Profile und (optional) Deines Arbeitsbereichs
|
||||||
|
herunterzuladen. Mit dieser Datei kannst Du jederzeit Deine komplette Arbeitsumgebung bei Kiri:Moto wieder herstellen.
|
||||||
|
Du kannst sie auch mit anderen Teilen, zum Beispiel um die Entwickler oder andere Nutzer bei der Fehlersuche zu unterstützen.
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-project" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Open Source</b>
|
||||||
|
<p>
|
||||||
|
Kiri:Moto ist komplett <a href="https://github.com/GridSpace/grid-apps" target="_github">quelloffen</a>.
|
||||||
|
Mehr kannst Du auf der Github-Seite zum Projekt erfahten. Es gibt verwandte Projekte, sowohl Software als auch
|
||||||
|
Hardware. Neue Entwickler und Code-Erweiterungen werden gerne entgegen genommen. Der Quellcode ist unter der
|
||||||
|
MIT-Lizenz veröffentlicht.
|
||||||
|
</p><br><p>
|
||||||
|
<a target="_paypal" href="https://paypal.me/gridspace3d?locale.x=en_US">Spenden</a> sind natürlich auch willkommen.
|
||||||
|
</p>
|
||||||
|
<br><b class="header">Integrationen</b>
|
||||||
|
<p>Kiri:Moto ist auch in anderen Applikationen integriert.</p>
|
||||||
|
<li><a target="app" href="https://appstore.onshape.com/apps/CAM/EAAEWYIOMQKBENEMYW2N7MF253CT4WYL6SUJGEY=/description"><b>Onshape</b></a> im App store</li>
|
||||||
|
<li><a target="app" href="http://www.thingiverse.com/apps/kirimoto/"><b>Thingiverse</b></a> als Thing Apps</li>
|
||||||
|
<li><a target="app" href="https://simplyprint.io">SimplyPrint.io</a> verwendet Kiri:Moto als primären Slicer</li>
|
||||||
|
<li><a target="app" href="https://sienci.com/camlab-help/">CAMLab</a> ist eine Variante einer früheren Version von Kiri:Moto</li>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
1
web/kiri/lang/de.js
Symbolic link
1
web/kiri/lang/de.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
de-de.js
|
||||||
|
|
@ -11,13 +11,6 @@
|
||||||
<div class="help-label" tab="about">about</div>
|
<div class="help-label" tab="about">about</div>
|
||||||
<div class="help-label" tab="start">starting</div>
|
<div class="help-label" tab="start">starting</div>
|
||||||
<div class="help-label" tab="controls">controls</div>
|
<div class="help-label" tab="controls">controls</div>
|
||||||
<!--
|
|
||||||
<hr width=75%>
|
|
||||||
<div class="help-label" tab="print">3d print</div>
|
|
||||||
<div class="help-label" tab="mill">cnc mill</div>
|
|
||||||
<div class="help-label" tab="laser">laser cut</div>
|
|
||||||
<hr width=75%>
|
|
||||||
-->
|
|
||||||
<div class="help-label" tab="support">support</div>
|
<div class="help-label" tab="support">support</div>
|
||||||
<div class="help-label" tab="project">project</div>
|
<div class="help-label" tab="project">project</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -83,6 +76,7 @@
|
||||||
<tr><td><label>o</label></td><td>CAM Tool Selection</td></tr>
|
<tr><td><label>o</label></td><td>CAM Tool Selection</td></tr>
|
||||||
<tr><td><label>c</label></td><td>Grid Local Devices</td></tr>
|
<tr><td><label>c</label></td><td>Grid Local Devices</td></tr>
|
||||||
<tr><td><label>q</label></td><td>Preference panel</td></tr>
|
<tr><td><label>q</label></td><td>Preference panel</td></tr>
|
||||||
|
<tr><td><label>l</label></td><td>Work Profiles</td></tr>
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><td colspan=2 class="header2">Mode</td></tr>
|
<tr><td colspan=2 class="header2">Mode</td></tr>
|
||||||
<tr><td><label>a</label></td><td>Arrange</td></tr>
|
<tr><td><label>a</label></td><td>Arrange</td></tr>
|
||||||
|
|
@ -96,11 +90,14 @@
|
||||||
<tr><td><label>r</label></td><td>Recent</td></tr>
|
<tr><td><label>r</label></td><td>Recent</td></tr>
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><td colspan=2 class="header2">View</td></tr>
|
<tr><td colspan=2 class="header2">View</td></tr>
|
||||||
<tr><td><label>t</label></td><td>Top</td></tr>
|
|
||||||
<tr><td><label>h</label></td><td>Home</td></tr>
|
<tr><td><label>h</label></td><td>Home</td></tr>
|
||||||
<tr><td><label>v</label></td><td>Layer</td></tr>
|
<tr><td><label>t</label></td><td>Top</td></tr>
|
||||||
|
<tr><td><label>f</label></td><td>Front</td></tr>
|
||||||
|
<tr><td><label>b</label></td><td>Back</td></tr>
|
||||||
<tr><td><label>z</label></td><td>Reset View</td></tr>
|
<tr><td><label>z</label></td><td>Reset View</td></tr>
|
||||||
<tr><td><label>meta</label> drag</td><td>Pan</td></tr>
|
<tr><td><label>< ></label></td><td>Cycle Side Views</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Focus (arrange)</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Layer (slice/preview)</td></tr>
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><td colspan=2 class="header2">Objects</td></tr>
|
<tr><td colspan=2 class="header2">Objects</td></tr>
|
||||||
<tr><td><label>d</label></td><td>Duplicate</td></tr>
|
<tr><td><label>d</label></td><td>Duplicate</td></tr>
|
||||||
|
|
@ -114,10 +111,7 @@
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><td colspan=2 class="header2">Help</td></tr>
|
<tr><td colspan=2 class="header2">Help</td></tr>
|
||||||
<tr><td><label>?</label></td><td>This Window</td></tr>
|
<tr><td><label>?</label></td><td>This Window</td></tr>
|
||||||
<tr><td></td></tr>
|
<tr><td><br><br></td></tr>
|
||||||
</table>
|
|
||||||
<div class="t-pad"></div>
|
|
||||||
<table>
|
|
||||||
<tr><td colspan="2" class="header">Mouse Controls</td><tr>
|
<tr><td colspan="2" class="header">Mouse Controls</td><tr>
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><th>Combo</th><th>Action</th></tr>
|
<tr><th>Combo</th><th>Action</th></tr>
|
||||||
|
|
@ -128,6 +122,7 @@
|
||||||
<tr><td><label>left-drag</label></td><td>Rotate</td></tr>
|
<tr><td><label>left-drag</label></td><td>Rotate</td></tr>
|
||||||
<tr><td><label>mouse-wheel</label></td><td>Zoom</td></tr>
|
<tr><td><label>mouse-wheel</label></td><td>Zoom</td></tr>
|
||||||
<tr><td><label>middle-drag</label></td><td>Zoom</td></tr>
|
<tr><td><label>middle-drag</label></td><td>Zoom</td></tr>
|
||||||
|
<tr><td><label>meta</label> drag</td><td>Pan</td></tr>
|
||||||
<tr><td></td></tr>
|
<tr><td></td></tr>
|
||||||
<tr><td colspan=2 class="header2">Objects</td></tr>
|
<tr><td colspan=2 class="header2">Objects</td></tr>
|
||||||
<tr><td><label>ctrl-click</label></td><td>Align face to bed</td></tr>
|
<tr><td><label>ctrl-click</label></td><td>Align face to bed</td></tr>
|
||||||
|
|
@ -140,12 +135,12 @@
|
||||||
<div id="help-tab-support" class="help-tab f-col"><div class="content">
|
<div id="help-tab-support" class="help-tab f-col"><div class="content">
|
||||||
<b class="header">Resources</b>
|
<b class="header">Resources</b>
|
||||||
<div class="content nounderline">
|
<div class="content nounderline">
|
||||||
|
<a target="_rsc" href="https://docs.grid.space/projects/kiri-moto"><i class="fas fa-question-circle"></i> Extended Documentation</a>
|
||||||
<a target="_rsc" href="https://forum.grid.space"><i class="fab fa-discourse"></i> Grid.Space forums</a>
|
<a target="_rsc" href="https://forum.grid.space"><i class="fab fa-discourse"></i> Grid.Space forums</a>
|
||||||
<a target="_rsc" href="https://discord.gg/suyCCgr"><i class="fab fa-discord"></i> Discord live chat server</a>
|
<a target="_rsc" href="https://discord.gg/suyCCgr"><i class="fab fa-discord"></i> Discord live chat server</a>
|
||||||
<a target="_rsc" href="https://www.youtube.com/playlist?list=PLRoVgyRoWZpumQIKWm7oldx3bjDivqP24"><i class="fab fa-youtube"></i> Youtube videos and tutorials</a>
|
<a target="_rsc" href="https://www.youtube.com/playlist?list=PLRoVgyRoWZpumQIKWm7oldx3bjDivqP24"><i class="fab fa-youtube"></i> Youtube videos and tutorials</a>
|
||||||
<a target="_rsc" href="https://twitter.com/grid_space_3d"><i class="fab fa-twitter"></i> Follow Grid.Space on Twitter</a>
|
<a target="_rsc" href="https://twitter.com/grid_space_3d"><i class="fab fa-twitter"></i> Follow Grid.Space on Twitter</a>
|
||||||
<a target="_rsc" href="https://facebook.com/groups/kirimoto"><i class="fab fa-facebook"></i> Kiri:Moto Users group on Facebook</a>
|
<a target="_rsc" href="https://facebook.com/groups/kirimoto"><i class="fab fa-facebook"></i> Kiri:Moto Users group on Facebook</a>
|
||||||
<a target="_rsc" href="https://wiki.grid.space/"><i class="fab fa-github"></i> Grid.Space Wiki</a>
|
|
||||||
</div>
|
</div>
|
||||||
<b class="header">In-App Options</b>
|
<b class="header">In-App Options</b>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,76 @@
|
||||||
// map for any missing key/value pairs
|
// map for any missing key/value pairs
|
||||||
kiri.lang['en'] =
|
kiri.lang['en'] =
|
||||||
kiri.lang['en-us'] = {
|
kiri.lang['en-us'] = {
|
||||||
version: "version",
|
// common keys and menus
|
||||||
|
animate: "animate", // CAM animate button
|
||||||
|
arrange: "arrange", // layout workspace objects
|
||||||
|
axis: "axis", // left object scale pop menu
|
||||||
|
clear: "clear", // clear workspace (remove all objects)
|
||||||
|
copy: "copy",
|
||||||
|
delete: "delete",
|
||||||
|
detail: "detail",
|
||||||
|
done: "done",
|
||||||
enable: "enable",
|
enable: "enable",
|
||||||
|
export: "export",
|
||||||
|
files: "files",
|
||||||
|
help: "help",
|
||||||
|
ghost: "ghost", // left render pop menu (wireframe)
|
||||||
|
hide: "hide", // left render pop menu (invisible)
|
||||||
|
home: "home",
|
||||||
|
import: "import",
|
||||||
|
language: "language",
|
||||||
|
machine: "machine", // device or machine
|
||||||
|
metric: "metric",
|
||||||
|
name: "name",
|
||||||
|
prefs: "prefs", // left menu "preferences"
|
||||||
|
preview: "preview",
|
||||||
|
recent: "recent",
|
||||||
|
render: "render", // left render pop menu
|
||||||
|
reset: "reset",
|
||||||
|
rotate: "rotate", // left rotate pop menu
|
||||||
|
save: "save",
|
||||||
|
scale: "scale", // left object scale pop menu
|
||||||
|
setup: "setup",
|
||||||
settings: "settings",
|
settings: "settings",
|
||||||
|
size: "size",
|
||||||
|
slice: "slice",
|
||||||
|
solid: "solid", // view type pop menu
|
||||||
|
start: "start",
|
||||||
|
tool: "tool",
|
||||||
|
tools: "tools", // CAM tool menu button
|
||||||
|
top: "top",
|
||||||
|
type: "type", // CAM tool type
|
||||||
|
version: "version",
|
||||||
|
view: "view", // left view pop menu
|
||||||
|
wire: "wire", // left render pop menu
|
||||||
|
|
||||||
acct_xpo: "make a backup of your device\nand device profiles with the\noption to include workspace\nobjects and positions",
|
acct_xpo: ["make a backup of your device","and device profiles with the","option to include workspace","objects and positions"],
|
||||||
|
|
||||||
|
// RIGHT-CLICK CONTEXT MENU
|
||||||
|
rc_clws: "clear workspace",
|
||||||
|
rc_xpws: "export workspace",
|
||||||
|
rc_lafl: "lay flat",
|
||||||
|
rc_mirr: "mirror",
|
||||||
|
rc_dupl: "duplicate",
|
||||||
|
rc_xstl: "export as STL",
|
||||||
|
|
||||||
|
// DEVICE MENU and related dialogs
|
||||||
|
dm_sldt: "select a device type",
|
||||||
|
dm_stdd: "standard devices",
|
||||||
|
dm_mydd: "my devices",
|
||||||
|
dm_seld: "selected device",
|
||||||
|
dm_rcnt: "recent files",
|
||||||
|
dm_savs: "saved settings",
|
||||||
|
dm_appp: "Application Preferences",
|
||||||
|
|
||||||
|
// CAM Tool Dialog
|
||||||
|
td_tyem: "end", // end mill
|
||||||
|
td_tybm: "ball", // ball mill
|
||||||
|
td_tytm: "taper", // taper mill
|
||||||
|
td_tonm: "tool #",
|
||||||
|
td_shft: "shaft", // endmill shaft specs
|
||||||
|
td_flut: "flute", // endmill flute specs
|
||||||
|
td_tapr: "taper", // endmill taper specs
|
||||||
|
|
||||||
// DEVICE dialog groups
|
// DEVICE dialog groups
|
||||||
dv_gr_dev: "device",
|
dv_gr_dev: "device",
|
||||||
|
|
@ -26,9 +91,9 @@ kiri.lang['en-us'] = {
|
||||||
dv_bedd_s: "depth",
|
dv_bedd_s: "depth",
|
||||||
dv_bedd_l: "workspace units",
|
dv_bedd_l: "workspace units",
|
||||||
dv_bedh_s: "height",
|
dv_bedh_s: "height",
|
||||||
dv_bedh_l: "max build height\nin workspace units",
|
dv_bedh_l: ["max build height","in workspace units"],
|
||||||
dv_spmx_s: "max spindle",
|
dv_spmx_s: "max spindle",
|
||||||
dv_spmx_l: "max spindle rpm speed\n0 to disable",
|
dv_spmx_l: ["max spindle rpm speed","0 to disable"],
|
||||||
dv_xtab_s: "absolute positioning",
|
dv_xtab_s: "absolute positioning",
|
||||||
dv_xtab_l: "extrusion moves absolute",
|
dv_xtab_l: "extrusion moves absolute",
|
||||||
dv_orgc_s: "origin center",
|
dv_orgc_s: "origin center",
|
||||||
|
|
@ -39,16 +104,18 @@ kiri.lang['en-us'] = {
|
||||||
dv_bedc_l: "device bed is circular",
|
dv_bedc_l: "device bed is circular",
|
||||||
dv_belt_s: "belt bed",
|
dv_belt_s: "belt bed",
|
||||||
dv_belt_l: "continuous printing bed",
|
dv_belt_l: "continuous printing bed",
|
||||||
|
dv_retr_s: "firmware retract",
|
||||||
|
dv_retr_l: ["device fimware supports G10/G11"],
|
||||||
dv_fanp_s: "fan power",
|
dv_fanp_s: "fan power",
|
||||||
dv_fanp_l: "set cooling fan power",
|
dv_fanp_l: "set cooling fan power",
|
||||||
dv_prog_s: "progress",
|
dv_prog_s: "progress",
|
||||||
dv_prog_l: "output on each % progress",
|
dv_prog_l: "output on each % progress",
|
||||||
dv_layr_s: "layer",
|
dv_layr_s: "layer",
|
||||||
dv_layr_l: "output at each\nlayer change",
|
dv_layr_l: ["output at each","layer change"],
|
||||||
dv_tksp_s: "token spacer",
|
dv_tksp_s: "token spacer",
|
||||||
dv_tksp_l: "add a space between\ngcode axis parameters\nG0X0Y0X0\nvs\nG0 X0 Y0 Z0",
|
dv_tksp_l: ["add a space between","gcode axis parameters","G0X0Y0X0","vs","G0 X0 Y0 Z0"],
|
||||||
dv_strc_s: "strip comments",
|
dv_strc_s: "strip comments",
|
||||||
dv_strc_l: "strip gcode comments\ncomments begin with ;",
|
dv_strc_l: ["strip gcode comments","comments begin with ;"],
|
||||||
dv_fext_s: "file extension",
|
dv_fext_s: "file extension",
|
||||||
dv_fext_l: "file name extension",
|
dv_fext_l: "file name extension",
|
||||||
dv_dwll_s: "dwell",
|
dv_dwll_s: "dwell",
|
||||||
|
|
@ -68,7 +135,9 @@ kiri.lang['en-us'] = {
|
||||||
dv_lzof_s: "laser off",
|
dv_lzof_s: "laser off",
|
||||||
dv_lzof_l: "gcode laser off script",
|
dv_lzof_l: "gcode laser off script",
|
||||||
dv_exts_s: "select",
|
dv_exts_s: "select",
|
||||||
dv_exts_l: "gcode to select this extruder",
|
dv_exts_l: "gcode run to enable this extruder",
|
||||||
|
dv_dext_s: "deselect",
|
||||||
|
dv_dext_l: "gcode run before enabling another extruder",
|
||||||
dv_extd_s: "deselect",
|
dv_extd_s: "deselect",
|
||||||
dv_extd_l: "gcode to deselect this extruder",
|
dv_extd_l: "gcode to deselect this extruder",
|
||||||
dv_exox_s: "offset x",
|
dv_exox_s: "offset x",
|
||||||
|
|
@ -124,40 +193,48 @@ kiri.lang['en-us'] = {
|
||||||
op_xprt_l: "show more settings options",
|
op_xprt_l: "show more settings options",
|
||||||
op_decl_s: "decals",
|
op_decl_s: "decals",
|
||||||
op_decl_l: "show device decals and logos",
|
op_decl_l: "show device decals and logos",
|
||||||
|
op_dang_s: "experimental",
|
||||||
|
op_dang_l: "show experimental parameters",
|
||||||
op_hopo_s: "hover pop",
|
op_hopo_s: "hover pop",
|
||||||
op_hopo_l: "enable menu hover\nto activate",
|
op_hopo_l: ["enable menu hover","to activate"],
|
||||||
op_dark_s: "dark mode",
|
op_dark_s: "dark mode",
|
||||||
op_dark_l: "dark mode interface",
|
op_dark_l: "dark mode interface",
|
||||||
op_comp_s: "compact ui",
|
op_comp_s: "compact ui",
|
||||||
op_comp_l: "compact user interface\nbetter for small screens\nand tablets",
|
op_comp_l: ["compact user interface","better for small screens","and tablets"],
|
||||||
op_shor_s: "show origin",
|
op_shor_s: "show origin",
|
||||||
op_shor_l: "show device or process origin",
|
op_shor_l: "show device or process origin",
|
||||||
op_shru_s: "show rulers",
|
op_shru_s: "show rulers",
|
||||||
op_shru_l: "show axes rulers\non major gridlines",
|
op_shru_l: ["show axes rulers","on major gridlines"],
|
||||||
op_sped_s: "show speeds",
|
op_sped_s: "show speeds",
|
||||||
op_sped_l: "show speed to color bar\nin preview mode",
|
op_sped_l: ["show speed to color bar","in preview mode"],
|
||||||
op_auto_s: "auto layout",
|
op_auto_s: "auto layout",
|
||||||
op_auto_l: "automatically layout platform\nwhen new items added",
|
op_auto_l: ["automatically layout platform","when new items added"],
|
||||||
op_free_s: "free layout",
|
op_free_s: "free layout",
|
||||||
op_free_l: "permit dragable layout\nno effect in laser mode",
|
op_free_l: ["permit dragable layout","no effect in laser mode"],
|
||||||
|
op_spcr_s: "spacing",
|
||||||
|
op_spcr_l: ["spacing between objects","during auto layout","in workspace units"],
|
||||||
|
op_orth_s: "orthographic",
|
||||||
|
op_orth_l: ["orthographic display","requires page refresh"],
|
||||||
op_invr_s: "invert zoom",
|
op_invr_s: "invert zoom",
|
||||||
op_invr_l: "invert mouse wheel\nscroll zoom",
|
op_invr_l: ["invert mouse wheel","scroll zoom"],
|
||||||
op_save_s: "auto save",
|
op_save_s: "auto save",
|
||||||
op_save_l: "preserve objects in workspace\nbetween application reloads",
|
op_save_l: ["preserve objects in workspace","between application reloads"],
|
||||||
op_line_s: "line type",
|
op_line_s: "line type",
|
||||||
op_line_l: "line style for path rendering\nimpacts 3d performance\npath: 3d best\nflat: 2d good\nline = 1d fast",
|
op_line_l: ["line style for path rendering","impacts 3d performance","path: 3d best","flat: 2d good","line = 1d fast"],
|
||||||
op_unit_s: "units",
|
op_unit_s: "units",
|
||||||
op_unit_l: "workspace units affects\nspeeds and distances",
|
op_unit_l: ["workspace units affects","speeds and distances"],
|
||||||
op_anim_s: "animate",
|
op_anim_s: "animate",
|
||||||
op_anim_l: "animation mesh density\nhigher is more dense\ntakes more memory\nand is slower",
|
op_anim_l: ["animation mesh density","higher is more dense","takes more memory","and is slower"],
|
||||||
|
|
||||||
lo_menu: "layout",
|
lo_menu: "layout",
|
||||||
|
|
||||||
pt_menu: "parts",
|
pt_menu: "parts",
|
||||||
pt_deci_s: "decimate",
|
pt_deci_s: "decimate",
|
||||||
pt_deci_l: "enable or disable point decimation\nduring port import. for faster slicing\nand lower memory usage",
|
pt_deci_l: ["enable or disable point decimation","during port import. for faster slicing","and lower memory usage"],
|
||||||
pt_qual_s: "quality",
|
pt_qual_s: "quality",
|
||||||
pt_qual_l: "level of detail to retain\nduring slicing operations\nlower is faster",
|
pt_qual_l: ["level of detail to retain","during slicing operations","lower is faster"],
|
||||||
|
pt_heal_s: "heal mesh",
|
||||||
|
pt_heal_l: ["attempt to heal","non-manifold meshes","adds to slicing time"],
|
||||||
|
|
||||||
xp_menu: "exports",
|
xp_menu: "exports",
|
||||||
|
|
||||||
|
|
@ -169,156 +246,164 @@ kiri.lang['en-us'] = {
|
||||||
// FDM SLICING
|
// FDM SLICING
|
||||||
sl_menu: "layers",
|
sl_menu: "layers",
|
||||||
sl_lahi_s: "height",
|
sl_lahi_s: "height",
|
||||||
sl_lahi_l: "height of each slice\nlayer in millimeters",
|
sl_lahi_l: ["height of each slice","layer in millimeters"],
|
||||||
ad_minl_s: "height min",
|
ad_minl_s: "height min",
|
||||||
ad_minl_l: "adaptive min layer height\nin millimeters\nmust be non-zero",
|
ad_minl_l: ["adaptive min layer height","in millimeters","must be non-zero"],
|
||||||
sl_ltop_s: "top layers",
|
sl_ltop_s: "top layers",
|
||||||
sl_ltop_l: "number of solid layers\nto enforce at the\ntop of the print",
|
sl_ltop_l: ["number of solid layers","to enforce at the","top of the print"],
|
||||||
sl_lsld_s: "solid layers",
|
sl_lsld_s: "solid layers",
|
||||||
sl_lsld_l: "solid fill areas computed\nfrom layer deltas. see\nlayer pop menu",
|
sl_lsld_l: ["solid fill areas computed","from layer deltas. see","layer pop menu"],
|
||||||
sl_lbot_s: "base layers",
|
sl_lbot_s: "base layers",
|
||||||
sl_lbot_l: "number of solid layers\nto enforce at the\nbottom of the print",
|
sl_lbot_l: ["number of solid layers","to enforce at the","bottom of the print"],
|
||||||
ad_adap_s: "adaptive",
|
ad_adap_s: "adaptive",
|
||||||
ad_adap_l: "use adaptive layer heights\nwith 'layer height' as max\nand 'layer min' as the min",
|
ad_adap_l: ["use adaptive layer heights","with 'layer height' as max","and 'layer min' as the min"],
|
||||||
|
|
||||||
// FDM SHELLS
|
// FDM SHELLS
|
||||||
sl_shel_s: "shell count",
|
sl_shel_s: "shell count",
|
||||||
sl_shel_l: "number of perimeter\nwalls to generate",
|
sl_shel_l: ["number of perimeter","walls to generate"],
|
||||||
sl_ordr_s: "shell order",
|
sl_ordr_s: "shell order",
|
||||||
sl_ordr_l: "output shell order\ninside to outside\nor outside to inside\naffects surface quality",
|
sl_ordr_l: ["output shell order","inside to outside","or outside to inside","affects surface quality"],
|
||||||
sl_strt_s: "layer start",
|
sl_strt_s: "layer start",
|
||||||
sl_strt_l: "layer starting point\nlast = last layer end\ncenter = part center\norigin = device origin",
|
sl_strt_l: ["layer starting point","last = last layer end","center = part center","origin = device origin"],
|
||||||
ad_thin_s: "thin walls",
|
ad_thin_s: "thin walls",
|
||||||
ad_thin_l: "detect and fill gaps\nbetween shell walls",
|
ad_thin_l: ["detect and fill gaps","between shell walls"],
|
||||||
|
|
||||||
// FDM FILL
|
// FDM FILL
|
||||||
fi_menu: "infill",
|
fi_menu: "infill",
|
||||||
fi_type: "type",
|
fi_type: "fill type",
|
||||||
fi_pcnt_s: "fraction",
|
fi_pcnt_s: "fill fraction",
|
||||||
fi_pcnt_l: "fill density values\n0.0 - 1.0",
|
fi_pcnt_l: ["fill density values","0.0 - 1.0"],
|
||||||
fi_angl_s: "start angle",
|
fi_angl_s: "solid start",
|
||||||
fi_angl_l: "base angle in degrees",
|
fi_angl_l: ["starting angle in degrees","90 degrees added to ","each following layer","applies only to solid layers"],
|
||||||
fi_over_s: "overlap",
|
fi_wdth_s: "solid width",
|
||||||
fi_over_l: "overlap with shell and fill\nas % of nozzle width\nhigher bonds better\n0.0 - 1.0",
|
fi_wdth_l: ["line width for solid fill","as a fraction of nozzle width","values < 1 are more dense","good for surface finishes","0.0 - 1.0"],
|
||||||
|
fi_over_s: "shell overlap",
|
||||||
|
fi_over_l: ["overlap with shell and other fill","as fraction of nozzle diameter","0.0 - 2.0"],
|
||||||
|
// fi_rate_s: "print speed",
|
||||||
|
fi_rate_l: ["extrusion speed for infill","set to 0 to use default","output print speeds"],
|
||||||
|
|
||||||
// FDM FIRST LAYER
|
// FDM FIRST LAYER
|
||||||
fl_menu: "base",
|
fl_menu: "base",
|
||||||
fl_lahi_s: "layer height",
|
fl_lahi_s: "layer height",
|
||||||
fl_lahi_l: "height of each slice\nin millimeters\nshould be >= slice height",
|
fl_lahi_l: ["height of each slice","in millimeters","should be >= slice height"],
|
||||||
fl_rate_s: "shell speed",
|
fl_rate_s: "shell speed",
|
||||||
fl_rate_l: "shell printing max speed\nin millimeters / minute",
|
fl_rate_l: ["shell printing max speed","in millimeters / minute"],
|
||||||
fl_frat_s: "fill speed",
|
fl_frat_s: "fill speed",
|
||||||
fl_frat_l: "fill printing max speed\nin millimeters / minute",
|
fl_frat_l: ["fill printing max speed","in millimeters / minute"],
|
||||||
fl_mult_s: "flow factor",
|
fl_mult_s: "flow factor",
|
||||||
fl_mult_l: "extrusion multiplier\n0.0 - 2.0",
|
fl_mult_l: ["extrusion multiplier","0.0 - 2.0"],
|
||||||
fl_sfac_s: "width factor",
|
fl_sfac_s: "width factor",
|
||||||
fl_sfac_l: "multiplier on nozzle size\nchanges line spacing",
|
fl_sfac_l: ["multiplier on nozzle size","changes line spacing"],
|
||||||
fl_skrt_s: "skirt count",
|
fl_skrt_s: "skirt count",
|
||||||
fl_skrt_l: "number of first-layer offset\nbrims to generate",
|
fl_skrt_l: ["number of first-layer offset","brims to generate"],
|
||||||
fl_skro_s: "skirt offset",
|
fl_skro_s: "skirt offset",
|
||||||
fl_skro_l: "skirt offset from part\nin millimeters",
|
fl_skro_l: ["skirt offset from part","in millimeters"],
|
||||||
fl_nozl_s: "nozzle temp",
|
fl_nozl_s: "nozzle temp",
|
||||||
fl_nozl_l: "degrees in celsius\noutput setting used\nwhen this is zero",
|
fl_nozl_l: ["degrees in celsius","output setting used","when this is zero"],
|
||||||
fl_bedd_s: "bed temp",
|
fl_bedd_s: "bed temp",
|
||||||
fl_bedd_l: "degrees in celsius\noutput setting used\nwhen this is zero",
|
fl_bedd_l: ["degrees in celsius","output setting used","when this is zero"],
|
||||||
fr_spac_s: "raft gap",
|
fr_spac_s: "raft gap",
|
||||||
fr_spac_l: "additional layer spacing\nbetween 1st layer and raft\nin millimeters",
|
fr_spac_l: ["additional layer spacing","between 1st layer and raft","in millimeters"],
|
||||||
fr_nabl_s: "raft enable",
|
fr_nabl_s: "raft enable",
|
||||||
fr_nabl_l: "create a raft under the\nmodel for better adhesion\nuses skirt offset and\ndisables skirt output",
|
fr_nabl_l: ["create a raft under the","model for better adhesion","uses skirt offset and","disables skirt output"],
|
||||||
|
|
||||||
// FDM BELT ONLY
|
// FDM BELT ONLY
|
||||||
fl_zoff_s: "layer offset",
|
fl_zoff_s: "belt offset",
|
||||||
fl_zoff_l: "height offset from belt\nof lowest extrusion\nin millimeters",
|
fl_zoff_l: ["height offset from belt","of lowest extrusion","in millimeters"],
|
||||||
fl_brim_s: "brim size",
|
fl_brim_s: "brim size",
|
||||||
fl_brim_l: "add brim to part bottom\nsize is width in millimeters\n0 to disable",
|
fl_brim_l: ["add brim to part bottom","size is width in millimeters","0 to disable"],
|
||||||
fl_brmn_s: "brim trigger",
|
fl_brmn_s: "brim trigger",
|
||||||
fl_brmn_l: "add brims only when segment\nfacing belt is shorter than this\nvalue in millimeters\n0 = Infinity",
|
fl_brmn_l: ["add brims only when segment","facing belt is shorter than this","value in millimeters","0 = Infinity"],
|
||||||
|
fl_bled_s: "part anchor",
|
||||||
|
fl_bled_l: ["belt part anchor","at start of print","in millimeters"],
|
||||||
|
|
||||||
// FDM SUPPORT
|
// FDM SUPPORT
|
||||||
sp_menu: "support",
|
sp_menu: "support",
|
||||||
sp_detect: "detect",
|
sp_detect: "detect",
|
||||||
sp_dens_s: "density",
|
sp_dens_s: "density",
|
||||||
sp_dens_l: "fraction 0.0 - 1.0\nrecommended 0.15\n0 to disable",
|
sp_dens_l: ["fraction 0.0 - 1.0","recommended 0.15","0 to disable"],
|
||||||
sp_size_s: "pillar size",
|
sp_size_s: "pillar size",
|
||||||
sp_size_l: "pillar width\nin millimeters",
|
sp_size_l: ["pillar width","in millimeters"],
|
||||||
sp_offs_s: "part offset",
|
sp_offs_s: "part offset",
|
||||||
sp_offs_l: "offset from part\nin millimeters",
|
sp_offs_l: ["offset from part","in millimeters"],
|
||||||
sp_gaps_s: "gap layers",
|
sp_gaps_s: "gap layers",
|
||||||
sp_gaps_l: "number of layers\noffset from part",
|
sp_gaps_l: ["number of layers","offset from part"],
|
||||||
sp_span_s: "max span",
|
sp_span_s: "max span",
|
||||||
sp_span_l: "unsupported span that causes\na new support to be generated\nin millimeters",
|
sp_span_l: ["unsupported span that causes","a new support to be generated","in millimeters"],
|
||||||
sp_angl_s: "max angle",
|
sp_angl_s: "max angle",
|
||||||
sp_angl_l: "max overhang angle before\nsupporting pillar is generated",
|
sp_angl_l: ["max overhang angle before","supporting pillar is generated"],
|
||||||
sp_area_s: "min area",
|
sp_area_s: "min area",
|
||||||
sp_area_l: "minimum area for\na support column\nin millimeters",
|
sp_area_l: ["minimum area for","a support column","in millimeters"],
|
||||||
sp_xpnd_s: "expand",
|
sp_xpnd_s: "expand",
|
||||||
sp_xpnd_l: "expand support area\nbeyond part boundary\nin millimeters",
|
sp_xpnd_l: ["expand support area","beyond part boundary","in millimeters"],
|
||||||
sp_nozl_s: "extruder",
|
sp_nozl_s: "extruder",
|
||||||
sp_nozl_l: "in multi-extruder systems\nthe extruder to use for\nsupport material",
|
sp_nozl_l: ["in multi-extruder systems","the extruder to use for","support material"],
|
||||||
sp_auto_s: "automatic",
|
sp_auto_s: "automatic",
|
||||||
sp_auto_l: "enable generated supports\nusing at-slice-time geometry\nsupports will only appear\nafter slicing completes",
|
sp_auto_l: ["enable generated supports","using at-slice-time geometry","supports will only appear","after slicing completes"],
|
||||||
|
|
||||||
// LASER SLICING
|
// LASER SLICING
|
||||||
ls_offs_s: "offset",
|
ls_offs_s: "offset",
|
||||||
ls_offs_l: "adjust for beam width\nin millimeters",
|
ls_offs_l: ["adjust for beam width","in millimeters"],
|
||||||
ls_lahi_s: "height",
|
ls_lahi_s: "height",
|
||||||
ls_lahi_l: "layer height\nin millimeters\n0 = auto/detect",
|
ls_lahi_l: ["layer height","in millimeters","0 = auto/detect"],
|
||||||
ls_lahm_s: "min",
|
ls_lahm_s: "min",
|
||||||
ls_lahm_l: "layer height minimum\nwill merge auto slices\nunder this thickness\nin millimeters",
|
ls_lahm_l: ["layer height minimum","will merge auto slices","under this thickness","in millimeters"],
|
||||||
ls_sngl_s: "single",
|
ls_sngl_s: "single",
|
||||||
ls_sngl_l: "perform only one slice\nat specified layer height",
|
ls_sngl_l: ["perform only one slice","at specified layer height"],
|
||||||
|
|
||||||
// CNC COMMON terms
|
// CNC COMMON terms
|
||||||
cc_tool: "tool",
|
cc_tool: "tool",
|
||||||
cc_offs_s: "offset",
|
cc_offs_s: "offset",
|
||||||
cc_offs_l: "offset tool center\nfrom chosen path",
|
cc_offs_l: ["offset tool center","from chosen path"],
|
||||||
cc_spnd_s: "spindle rpm",
|
cc_spnd_s: "spindle rpm",
|
||||||
cc_spnd_l: "spindle speed in\nrevolutions / minute",
|
cc_spnd_l: ["spindle speed in","revolutions / minute"],
|
||||||
cc_sovr_s: "step over",
|
cc_sovr_s: "step over",
|
||||||
cc_sovr_l: "as a fraction of\ntool diameter",
|
cc_sovr_l: ["as a fraction of","tool diameter"],
|
||||||
cc_sdwn_s: "step down",
|
cc_sdwn_s: "step down",
|
||||||
cc_sdwn_l: "step down depth\nfor each pass\nin workspace units\n0 to disable",
|
cc_sdwn_l: ["step down depth","for each pass","in workspace units","0 to disable"],
|
||||||
cc_feed_s: "feed rate",
|
cc_feed_s: "feed rate",
|
||||||
cc_feed_l: "max cutting speed in\nworkspace units / minute",
|
cc_feed_l: ["max cutting speed in","workspace units / minute"],
|
||||||
cc_plng_s: "plunge rate",
|
cc_plng_s: "plunge rate",
|
||||||
cc_plng_l: "max z axis speed in\nworkspace units / minute",
|
cc_plng_l: ["max z axis speed in","workspace units / minute"],
|
||||||
|
cc_sngl_s: "select lines only",
|
||||||
|
cc_sngl_l: ["select only single edges","instead of connected polylines"],
|
||||||
|
|
||||||
// CNC COMMON
|
// CNC COMMON
|
||||||
cc_menu: "limits",
|
cc_menu: "limits",
|
||||||
cc_flip: "flip",
|
cc_flip: "flip",
|
||||||
cc_rapd_s: "xy feed",
|
cc_rapd_s: "xy feed",
|
||||||
cc_rapd_l: "max xy moves feedrate\nin workspace units / minute",
|
cc_rapd_l: ["max xy moves feedrate","in workspace units / minute"],
|
||||||
cc_rzpd_s: "z feed",
|
cc_rzpd_s: "z feed",
|
||||||
cc_rzpd_l: "max z moves feedrate\nin workspace units / minute",
|
cc_rzpd_l: ["max z moves feedrate","in workspace units / minute"],
|
||||||
|
|
||||||
cc_loff_s: "offset",
|
cc_loff_s: "offset",
|
||||||
cc_loff_l: "distance from stock face\nfor leveling pass\nin workspace units",
|
cc_loff_l: ["distance from stock face","for leveling pass","in workspace units"],
|
||||||
|
|
||||||
// CNC ROUGHING
|
// CNC ROUGHING
|
||||||
cr_menu: "rough",
|
cr_menu: "rough",
|
||||||
cr_lsto_s: "leave stock",
|
cr_lsto_s: "leave stock",
|
||||||
cr_lsto_l: "horizontal offset from vertical faces\nstock to leave for finishing pass\nin workspace units",
|
cr_lsto_l: ["horizontal offset from vertical faces","stock to leave for finishing pass","in workspace units"],
|
||||||
cr_ease_s: "ease down",
|
cr_ease_s: "ease down",
|
||||||
cr_ease_l: "plunge cuts will\nspiral down or ease\nalong a linear path",
|
cr_ease_l: ["plunge cuts will","spiral down or ease","along a linear path"],
|
||||||
cr_clrt_s: "clear top",
|
cr_clrt_s: "clear top",
|
||||||
cr_clrt_l: "run a clearing pass over\nthe bounding area of the part\nat z = 0",
|
cr_clrt_l: ["run a clearing pass over","the bounding area of the part","at z = 0"],
|
||||||
cr_clrp_s: "clear voids",
|
cr_clrp_s: "clear voids",
|
||||||
cr_clrp_l: "mill out through pockets\ninstead of just the outline",
|
cr_clrp_l: ["mill out through pockets","instead of just the outline"],
|
||||||
cr_clrf_s: "clear faces",
|
cr_clrf_s: "clear faces",
|
||||||
cr_clrf_l: "interpolate step down to\nclear any detected flat areas",
|
cr_clrf_l: ["interpolate step down to","clear any detected flat areas"],
|
||||||
cr_olin_s: "inside only",
|
cr_olin_s: "inside only",
|
||||||
cr_olin_l: "limit cutting to\ninside part boundaries",
|
cr_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
|
||||||
// CNC OUTLINE
|
// CNC OUTLINE
|
||||||
co_menu: "outline",
|
co_menu: "outline",
|
||||||
co_dogb_s: "dogbones",
|
co_dogb_s: "dogbones",
|
||||||
co_dogb_l: "insert dogbone cuts\ninto inside corners",
|
co_dogb_l: ["insert dogbone cuts","into inside corners"],
|
||||||
co_wide_s: "wide cutout",
|
co_wide_s: "wide cutout",
|
||||||
co_wide_l: "widen outside cutout paths\nfor deep cuts in hard material",
|
co_wide_l: ["widen outside cutout paths","for deep cuts in hard material"],
|
||||||
co_olin_s: "inside only",
|
co_olin_s: "inside only",
|
||||||
co_olin_l: "limit cutting to\ninside part boundaries",
|
co_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
co_olot_s: "outside only",
|
co_olot_s: "outside only",
|
||||||
co_olot_l: "limit cutting to\nexterior part boundaries\nwhich can be thought of\nas the shadow outline",
|
co_olot_l: ["limit cutting to","exterior part boundaries","which can be thought of","as the shadow outline"],
|
||||||
co_omit_s: "omit through",
|
co_omit_s: "omit through",
|
||||||
co_omit_l: "eliminate thru holes",
|
co_omit_l: "eliminate thru holes",
|
||||||
co_olen_s: "enable",
|
co_olen_s: "enable",
|
||||||
|
|
@ -327,11 +412,11 @@ kiri.lang['en-us'] = {
|
||||||
// CNC CONTOUR
|
// CNC CONTOUR
|
||||||
cn_menu: "contour",
|
cn_menu: "contour",
|
||||||
cf_angl_s: "max angle",
|
cf_angl_s: "max angle",
|
||||||
cf_angl_l: "angles greater than this\nare considered vertical",
|
cf_angl_l: ["angles greater than this","are considered vertical"],
|
||||||
cf_curv_s: "curves only",
|
cf_curv_s: "curves only",
|
||||||
cf_curv_l: "limit linear cleanup\nto curved surfaces",
|
cf_curv_l: ["limit linear cleanup","to curved surfaces"],
|
||||||
cf_olin_s: "inside only",
|
cf_olin_s: "inside only",
|
||||||
cf_olin_l: "limit cutting to\ninside part boundaries",
|
cf_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
cf_linx_s: "enable y pass",
|
cf_linx_s: "enable y pass",
|
||||||
cf_linx_l: "linear y-axis finishing",
|
cf_linx_l: "linear y-axis finishing",
|
||||||
cf_liny_s: "enable x pass",
|
cf_liny_s: "enable x pass",
|
||||||
|
|
@ -340,37 +425,37 @@ kiri.lang['en-us'] = {
|
||||||
// CNC TRACE
|
// CNC TRACE
|
||||||
cu_menu: "trace",
|
cu_menu: "trace",
|
||||||
cu_type_s: "type",
|
cu_type_s: "type",
|
||||||
cu_type_l: "follow = tool tip follows line\nright or left = tool tip\nfollows line offset by tool radius",
|
cu_type_l: ["follow = tool tip follows line","right or left = tool tip","follows line offset by tool radius"],
|
||||||
|
|
||||||
// CNC DRILLING
|
// CNC DRILLING
|
||||||
cd_menu: "drill",
|
cd_menu: "drill",
|
||||||
cd_axis: "axis",
|
cd_axis: "axis",
|
||||||
cd_points: "points",
|
cd_points: "points",
|
||||||
cd_plpr_s: "plunge per",
|
cd_plpr_s: "plunge per",
|
||||||
cd_plpr_l: "max plunge between\ndwell periods\nin workspace units\n0 to disable",
|
cd_plpr_l: ["max plunge between","dwell periods","in workspace units","0 to disable"],
|
||||||
cd_dwll_s: "dwell time",
|
cd_dwll_s: "dwell time",
|
||||||
cd_dwll_l: "dwell time\nbetween plunges in\nin milliseconds",
|
cd_dwll_l: ["dwell time","between plunges in","in milliseconds"],
|
||||||
cd_lift_s: "drill lift",
|
cd_lift_s: "drill lift",
|
||||||
cd_lift_l: "lift between plunges\nafter dwell period\nin workspace units\n0 to disable",
|
cd_lift_l: ["lift between plunges","after dwell period","in workspace units","0 to disable"],
|
||||||
cd_regi_s: "register",
|
cd_regi_s: "register",
|
||||||
cd_regi_l: "drill registration holes\nfor double-sided parts\nindependent of enable\ndrilling but uses same\ntool and settings",
|
cd_regi_l: ["drill registration holes","for double-sided parts","independent of enable","drilling but uses same","tool and settings"],
|
||||||
|
|
||||||
// CNC CUTOUT TABS
|
// CNC CUTOUT TABS
|
||||||
ct_menu: "tabs",
|
ct_menu: "tabs",
|
||||||
ct_angl_s: "angle",
|
ct_angl_s: "angle",
|
||||||
ct_angl_l: "starting angle for tab spacing\nin degrees (0-360)",
|
ct_angl_l: ["starting angle for tab spacing","in degrees (0-360)"],
|
||||||
ct_numb_s: "count",
|
ct_numb_s: "count",
|
||||||
ct_numb_l: "number of tabs to use\nwill be spaced evenly\naround the part",
|
ct_numb_l: ["number of tabs to use","will be spaced evenly","around the part"],
|
||||||
ct_wdth_s: "width",
|
ct_wdth_s: "width",
|
||||||
ct_wdth_l: "width in workspace units",
|
ct_wdth_l: "width in workspace units",
|
||||||
ct_hght_s: "height",
|
ct_hght_s: "height",
|
||||||
ct_hght_l: "height in workspace units",
|
ct_hght_l: "height in workspace units",
|
||||||
ct_dpth_s: "depth",
|
ct_dpth_s: "depth",
|
||||||
ct_dpth_l: "distance in workspace units\nthat the tab projects from\nthe part surface",
|
ct_dpth_l: ["distance in workspace units","that the tab projects from","the part surface"],
|
||||||
ct_midl_s: "midline",
|
ct_midl_s: "midline",
|
||||||
ct_midl_l: "use midline of tab\ninstead of z bottom\nfor double-sided work",
|
ct_midl_l: ["use midline of tab","instead of z bottom","for double-sided work"],
|
||||||
ct_nabl_s: "auto",
|
ct_nabl_s: "auto",
|
||||||
ct_nabl_l: "auto generate radial tabs\nprojected from part center\nusing count and angle offset",
|
ct_nabl_l: ["auto generate radial tabs","projected from part center","using count and angle offset"],
|
||||||
|
|
||||||
// OUTPUT
|
// OUTPUT
|
||||||
ou_menu: "output",
|
ou_menu: "output",
|
||||||
|
|
@ -378,31 +463,31 @@ kiri.lang['en-us'] = {
|
||||||
// LASER KNIFE
|
// LASER KNIFE
|
||||||
dk_menu: "knife",
|
dk_menu: "knife",
|
||||||
dk_dpth_s: "cut depth",
|
dk_dpth_s: "cut depth",
|
||||||
dk_dpth_l: "final cut depth\nin millimeters",
|
dk_dpth_l: ["final cut depth","in millimeters"],
|
||||||
dk_pass_s: "cut passes",
|
dk_pass_s: "cut passes",
|
||||||
dk_pass_l: "number of passes\ndown to cut depth",
|
dk_pass_l: ["number of passes","down to cut depth"],
|
||||||
dk_offs_s: "tip offset",
|
dk_offs_s: "tip offset",
|
||||||
dk_offs_l: "distance from blade tip\nto center of tool\nin millimeters",
|
dk_offs_l: ["distance from blade tip","to center of tool","in millimeters"],
|
||||||
|
|
||||||
// OUTPUT LASER
|
// OUTPUT LASER
|
||||||
ou_spac_s: "spacing",
|
ou_spac_s: "spacing",
|
||||||
ou_spac_l: "distance between layer output\nin millimeters",
|
ou_spac_l: ["distance between layer output","in millimeters"],
|
||||||
ou_scal_s: "scaling",
|
ou_scal_s: "scaling",
|
||||||
ou_scal_l: "multiplier (0.1 to 100)",
|
ou_scal_l: "multiplier (0.1 to 100)",
|
||||||
ou_powr_s: "power",
|
ou_powr_s: "power",
|
||||||
ou_powr_l: "0 - 100\nrepresents %",
|
ou_powr_l: ["0 - 100","represents %"],
|
||||||
ou_sped_s: "speed",
|
ou_sped_s: "speed",
|
||||||
ou_sped_l: "millimeters / minute",
|
ou_sped_l: "millimeters / minute",
|
||||||
ou_mrgd_s: "merged",
|
ou_mrgd_s: "merged",
|
||||||
ou_mrgd_l: "merge all layers using\ncolor coding to denote\nstacking depth",
|
ou_mrgd_l: ["merge all layers using","color coding to denote","stacking depth"],
|
||||||
ou_grpd_s: "grouped",
|
ou_grpd_s: "grouped",
|
||||||
ou_grpd_l: "retain each layer as\na unified grouping\ninstead of separated\npolygons",
|
ou_grpd_l: ["retain each layer as","a unified grouping","instead of separated","polygons"],
|
||||||
ou_layr_s: "layer order",
|
ou_layr_s: "layer order",
|
||||||
ou_layr_l: "output layer order\nfrom top right to\nbottom left",
|
ou_layr_l: ["output layer order","from top right to","bottom left"],
|
||||||
ou_layo_s: "layer color",
|
ou_layo_s: "layer color",
|
||||||
ou_layo_l: "output layer colors\nfor each z index\noverridden by merged",
|
ou_layo_l: ["output layer colors","for each z index","overridden by merged"],
|
||||||
ou_drkn_s: "drag knife",
|
ou_drkn_s: "drag knife",
|
||||||
ou_drkn_l: "enable drag knife\noutput in gcode\ncut radii are added\nto corners with\ncut down passes",
|
ou_drkn_l: ["enable drag knife","output in gcode","cut radii are added","to corners with","cut down passes"],
|
||||||
|
|
||||||
// OUTPUT FDM
|
// OUTPUT FDM
|
||||||
ou_nozl_s: "nozzle temp",
|
ou_nozl_s: "nozzle temp",
|
||||||
|
|
@ -410,54 +495,54 @@ kiri.lang['en-us'] = {
|
||||||
ou_bedd_s: "bed temp",
|
ou_bedd_s: "bed temp",
|
||||||
ou_bedd_l: "degrees in celsius",
|
ou_bedd_l: "degrees in celsius",
|
||||||
ou_feed_s: "print speed",
|
ou_feed_s: "print speed",
|
||||||
ou_feed_l: "max print speed\nmillimeters / minute",
|
ou_feed_l: ["max print speed","millimeters / minute"],
|
||||||
ou_fini_s: "finish speed",
|
ou_fini_s: "finish speed",
|
||||||
ou_fini_l: "outermost shell speed\nmillimeters / minute",
|
ou_fini_l: ["outermost shell speed","millimeters / minute"],
|
||||||
ou_move_s: "move speed",
|
ou_move_s: "move speed",
|
||||||
ou_move_l: "non-print move speed\nmillimeters / minute\n0 = enable G0 moves",
|
ou_move_l: ["non-print move speed","millimeters / minute","0 = enable G0 moves"],
|
||||||
ou_shml_s: "shell factor",
|
ou_shml_s: "shell factor",
|
||||||
ou_flml_s: "solid factor",
|
ou_flml_s: "solid factor",
|
||||||
ou_spml_s: "infill factor",
|
ou_spml_s: "infill factor",
|
||||||
ou_exml_l: "extrusion multiplier\n0.0 - 2.0",
|
ou_exml_l: ["extrusion multiplier","0.0 - 2.0"],
|
||||||
ou_fanl_s: "fan layer",
|
ou_fans_s: "fan speed",
|
||||||
ou_fanl_l: "layer to enable fan",
|
ou_fans_l: "0 - 255",
|
||||||
|
|
||||||
// OUTPUT CAM
|
// OUTPUT CAM
|
||||||
ou_toll_s: "tolerance",
|
ou_toll_s: "tolerance",
|
||||||
ou_toll_l: "surface precision\nin workspace units\nlower is slower and\nuses more memory\n0 = automatic based\non animate preference",
|
ou_toll_l: ["surface precision","in workspace units","lower is slower and","uses more memory","0 = automatic based","on animate preference"],
|
||||||
ou_zanc_s: "z anchor",
|
ou_zanc_s: "z anchor",
|
||||||
ou_zanc_l: "controls the position of the part\nwhen stock Z exceeds part Z",
|
ou_zanc_l: ["controls the position of the part","when stock Z exceeds part Z"],
|
||||||
ou_ztof_s: "z offset",
|
ou_ztof_s: "z offset",
|
||||||
ou_ztof_l: "offset z anchor\nin workspace units\nhas no effect when\nanchor is middle",
|
ou_ztof_l: ["offset z anchor","in workspace units","has no effect when","anchor is middle"],
|
||||||
ou_zbot_s: "z bottom",
|
ou_zbot_s: "z bottom",
|
||||||
ou_zbot_l: "offset from part bottom\nto limit cutting depth\nin workspace units",
|
ou_zbot_l: ["offset from part bottom","to limit cutting depth","in workspace units"],
|
||||||
ou_zclr_s: "z clearance",
|
ou_zclr_s: "z clearance",
|
||||||
ou_zclr_l: "safe travel offset\nfrom top of part\nin workspace units",
|
ou_zclr_l: ["safe travel offset","from top of part","in workspace units"],
|
||||||
ou_ztru_s: "z thru",
|
ou_ztru_s: "z thru",
|
||||||
ou_ztru_l: "extend cutout pass down\nin workspace units",
|
ou_ztru_l: ["extend cutout pass down","in workspace units"],
|
||||||
ou_conv_s: "conventional",
|
ou_conv_s: "conventional",
|
||||||
ou_conv_l: "milling direction\nuncheck for 'climb'",
|
ou_conv_l: ["milling direction","uncheck for 'climb'"],
|
||||||
ou_depf_s: "depth first",
|
ou_depf_s: "depth first",
|
||||||
ou_depf_l: "optimize pocket cuts\nwith depth priority",
|
ou_depf_l: ["optimize pocket cuts","with depth priority"],
|
||||||
|
|
||||||
// CAM STOCK
|
// CAM STOCK
|
||||||
cs_menu: "stock",
|
cs_menu: "stock",
|
||||||
cs_wdth_s: "width",
|
cs_wdth_s: "width",
|
||||||
cs_wdth_l: "width (x) in workspace units\n0 defaults to part size",
|
cs_wdth_l: ["width (x) in workspace units","0 defaults to part size"],
|
||||||
cs_dpth_s: "depth",
|
cs_dpth_s: "depth",
|
||||||
cs_dpth_l: "depth (y) in workspace units\n0 defaults to part size",
|
cs_dpth_l: ["depth (y) in workspace units","0 defaults to part size"],
|
||||||
cs_hght_s: "height",
|
cs_hght_s: "height",
|
||||||
cs_hght_l: "height (z) in workspace units\n0 defaults to part size",
|
cs_hght_l: ["height (z) in workspace units","0 defaults to part size"],
|
||||||
cs_offs_s: "offset",
|
cs_offs_s: "offset",
|
||||||
cs_offs_l: "use width, depth, height\nas offsets from max\npart size on platform",
|
cs_offs_l: ["use width, depth, height","as offsets from max","part size on platform"],
|
||||||
cs_clip_s: "clip to",
|
cs_clip_s: "clip to",
|
||||||
cs_clip_l: "rough and outline\nclip cutting paths\nto defined stock",
|
cs_clip_l: ["rough and outline","clip cutting paths","to defined stock"],
|
||||||
cs_offe_s: "enable",
|
cs_offe_s: "enable",
|
||||||
cs_offe_l: "enable milling stock",
|
cs_offe_l: "enable milling stock",
|
||||||
|
|
||||||
// ORIGIN (CAM & LASER)
|
// ORIGIN (CAM & LASER)
|
||||||
or_bnds_s: "origin bounds",
|
or_bnds_s: "origin bounds",
|
||||||
or_bnds_l: "origin is relative to\nboundary of all objects",
|
or_bnds_l: ["origin is relative to","boundary of all objects"],
|
||||||
or_cntr_s: "origin center",
|
or_cntr_s: "origin center",
|
||||||
or_cntr_l: "origin is referenced from the center",
|
or_cntr_l: "origin is referenced from the center",
|
||||||
or_topp_s: "origin top",
|
or_topp_s: "origin top",
|
||||||
|
|
@ -466,94 +551,100 @@ kiri.lang['en-us'] = {
|
||||||
// FDM ADVANCED
|
// FDM ADVANCED
|
||||||
ad_menu: "expert",
|
ad_menu: "expert",
|
||||||
ad_rdst_s: "retract dist",
|
ad_rdst_s: "retract dist",
|
||||||
ad_rdst_l: "amount to retract filament\nfor long moves. in millimeters",
|
ad_rdst_l: ["amount to retract filament","for long moves. in millimeters"],
|
||||||
ad_rrat_s: "retract rate",
|
ad_rrat_s: "retract rate",
|
||||||
ad_rrat_l: "speed of filament\nretraction in mm/s",
|
ad_rrat_l: ["speed of filament","retraction in mm/s"],
|
||||||
ad_rdwl_s: "engage dwell",
|
ad_rdwl_s: "engage dwell",
|
||||||
ad_rdwl_l: "time between re-engaging\nfilament and movement\nin milliseconds",
|
ad_wpln_s: "retract wipe",
|
||||||
|
ad_wpln_l: ["non-printing move","after retraction","in millimeters"],
|
||||||
|
ad_rdwl_l: ["time between re-engaging","filament and movement","in milliseconds"],
|
||||||
ad_scst_s: "shell coast",
|
ad_scst_s: "shell coast",
|
||||||
ad_scst_l: "non-printing end\nof perimeter shells\nin millimeters",
|
ad_scst_l: ["non-printing end","of perimeter shells","in millimeters"],
|
||||||
ad_msol_s: "min solid",
|
ad_msol_s: "min solid",
|
||||||
ad_msol_l: "minimum area (mm^2)\nrequired to keep solid\nmust be > 0.1",
|
ad_msol_l: ["minimum area (mm^2)","required to keep solid","must be > 0.1"],
|
||||||
ad_mins_s: "min speed",
|
ad_mins_s: "min speed",
|
||||||
ad_mins_l: "minimum speed\nfor short segments",
|
ad_mins_l: ["minimum speed","for short segments"],
|
||||||
ad_spol_s: "slow poly",
|
ad_spol_s: "short path",
|
||||||
ad_spol_l: "polygons shorter than this\nwill have their print speed\nscaled down to min speed\nin millimeters",
|
ad_spol_l: ["polygons shorter than this","will have their print speed","scaled down to min speed","in millimeters"],
|
||||||
|
ad_arct_s: "arc tolerance",
|
||||||
|
ad_arct_l: ["convert faceted lines to arcs","center point drift tolerance","when matching arc points","consider values around 0.15","in millimeters","0 to disable"],
|
||||||
ad_zhop_s: "z hop dist",
|
ad_zhop_s: "z hop dist",
|
||||||
ad_zhop_l: "amount to raise z\non retraction moves\nin millimeters\n0 to disable",
|
ad_zhop_l: ["amount to raise z","on retraction moves","in millimeters","0 to disable"],
|
||||||
ad_abkl_s: "anti-backlash",
|
ad_abkl_s: "anti-backlash",
|
||||||
ad_abkl_l: "use micro-movements to cancel\nbacklash during fills\nin millimeters",
|
ad_abkl_l: ["for better flat surface finish","use micro-movements to cancel","backlash in solid layer output","in millimeters","0 to disable","if your firmware has M425","put that in the gcode header","and leave this as 0"],
|
||||||
ad_lret_s: "layer retract",
|
ad_lret_s: "layer retract",
|
||||||
ad_lret_l: "force filament retraction\nbetween layers",
|
ad_lret_l: ["force filament retraction","between layers"],
|
||||||
ad_play_s: "polish layers",
|
ad_play_s: "polish layers",
|
||||||
ad_play_l: "polish up to specified\n# of layers at a time",
|
ad_play_l: ["polish up to specified","# of layers at a time"],
|
||||||
ad_pspd_s: "polish speed",
|
ad_pspd_s: "polish speed",
|
||||||
ad_pspd_l: "polishing speed\nin millimeters / minute",
|
ad_pspd_l: ["polishing speed","in millimeters / minute"],
|
||||||
|
|
||||||
// CAM EXPERT
|
// CAM EXPERT
|
||||||
cx_fast_s: "skip shadow",
|
cx_fast_s: "skip shadow",
|
||||||
cx_fast_l: "disable overhang detection\ncan be faster and use less\nmemory with complex models\nbut fails with overhangs\ntry enabling if slicing\nhangs during shadowing",
|
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
||||||
|
|
||||||
// FDM GCODE
|
// FDM GCODE
|
||||||
ag_menu: "gcode",
|
ag_menu: "gcode",
|
||||||
ag_nozl_s: "nozzle",
|
ag_nozl_s: "nozzle",
|
||||||
ag_nozl_l: "select output nozzle or head",
|
ag_nozl_l: "select output nozzle or head",
|
||||||
|
ag_peel_s: "peel guard",
|
||||||
|
ag_peel_l: ["starting at this belt z positoin","periodically roll the print off and","back on to the belt to unstick it","and prevent rolling deflection"],
|
||||||
ag_paws_s: "pause layers",
|
ag_paws_s: "pause layers",
|
||||||
ag_paws_l: "comma-separated list of layers\nto inject pause commands before",
|
ag_paws_l: ["comma-separated list of layers","to inject pause commands before"],
|
||||||
ag_loop_s: "loop layers",
|
ag_loop_s: "loop layers",
|
||||||
ag_loop_l: "layer ranges to repeat in the format\nfirst-last-count,first-last-count,...\nomitted count = 1",
|
ag_loop_l: ["layer ranges to repeat in the format","first-last-count,first-last-count,...","omitted count = 1"],
|
||||||
|
|
||||||
// SLA MENU
|
// SLA MENU
|
||||||
sa_menu: "slicing",
|
sa_menu: "slicing",
|
||||||
sa_lahe_s: "layer height",
|
sa_lahe_s: "layer height",
|
||||||
sa_lahe_l: "layer height\nin millimeters",
|
sa_lahe_l: ["layer height","in millimeters"],
|
||||||
sa_shel_s: "hollow shell",
|
sa_shel_s: "hollow shell",
|
||||||
sa_shel_l: "shell thickness in mm\nuse multiple of layer height\nuse 0 for solid (disabled)",
|
sa_shel_l: ["shell thickness in mm","use multiple of layer height","use 0 for solid (disabled)"],
|
||||||
sa_otop_s: "open top",
|
sa_otop_s: "open top",
|
||||||
sa_otop_l: "if shell is enabled\nresults in an open top",
|
sa_otop_l: ["if shell is enabled","results in an open top"],
|
||||||
sa_obas_s: "open base",
|
sa_obas_s: "open base",
|
||||||
sa_obas_l: "if shell is enabled\nresults in an open base\ndisabled with supports",
|
sa_obas_l: ["if shell is enabled","results in an open base","disabled with supports"],
|
||||||
|
|
||||||
sa_layr_m: "layers",
|
sa_layr_m: "layers",
|
||||||
sa_lton_s: "light on time",
|
sa_lton_s: "light on time",
|
||||||
sa_lton_l: "layer light on\ntime in seconds",
|
sa_lton_l: ["layer light on","time in seconds"],
|
||||||
sa_ltof_s: "light off time",
|
sa_ltof_s: "light off time",
|
||||||
sa_ltof_l: "layer light off\ntime in seconds",
|
sa_ltof_l: ["layer light off","time in seconds"],
|
||||||
sa_pldi_s: "peel distance",
|
sa_pldi_s: "peel distance",
|
||||||
sa_pldi_l: "peel distance\nin millimeters",
|
sa_pldi_l: ["peel distance","in millimeters"],
|
||||||
sa_pllr_s: "peel lift rate",
|
sa_pllr_s: "peel lift rate",
|
||||||
sa_pllr_l: "peel lift speed\nin mm/sec",
|
sa_pllr_l: ["peel lift speed","in mm/sec"],
|
||||||
sa_pldr_s: "peel drop rate",
|
sa_pldr_s: "peel drop rate",
|
||||||
sa_pldr_l: "peel drop speed\nin mm/sec",
|
sa_pldr_l: ["peel drop speed","in mm/sec"],
|
||||||
|
|
||||||
sa_base_m: "base",
|
sa_base_m: "base",
|
||||||
sa_balc_s: "layer count",
|
sa_balc_s: "layer count",
|
||||||
sa_balc_l: "number of\nbase layers",
|
sa_balc_l: ["number of","base layers"],
|
||||||
sa_bltn_l: "base layer light on\ntime in seconds",
|
sa_bltn_l: ["base layer light on","time in seconds"],
|
||||||
sa_bltf_l: "base layer light off\ntime in seconds",
|
sa_bltf_l: ["base layer light off","time in seconds"],
|
||||||
|
|
||||||
sa_infl_m: "infill",
|
sa_infl_m: "infill",
|
||||||
sa_ifdn_s: "density",
|
sa_ifdn_s: "density",
|
||||||
sa_ifdn_l: "percent infill\nrequires shell\n0 = disabled\nvalid 0.0 - 1.0",
|
sa_ifdn_l: ["percent infill","requires shell","0 = disabled","valid 0.0 - 1.0"],
|
||||||
sa_iflw_s: "line width",
|
sa_iflw_s: "line width",
|
||||||
sa_iflw_l: "hatch line width\nin millimeters",
|
sa_iflw_l: ["hatch line width","in millimeters"],
|
||||||
|
|
||||||
sa_supp_m: "support",
|
sa_supp_m: "support",
|
||||||
sa_slyr_s: "base layers",
|
sa_slyr_s: "base layers",
|
||||||
sa_slyr_l: "base support layers\nvalue range 0-10",
|
sa_slyr_l: ["base support layers","value range 0-10"],
|
||||||
sa_slgp_s: "gap layers",
|
sa_slgp_s: "gap layers",
|
||||||
sa_slgp_l: "number of layers between\nraft and bottom of object",
|
sa_slgp_l: ["number of layers between","raft and bottom of object"],
|
||||||
sa_sldn_s: "density",
|
sa_sldn_s: "density",
|
||||||
sa_sldn_l: "used to compute the\nnumber of support pillars\n0.0-1.0 (0 = disable)",
|
sa_sldn_l: ["used to compute the","number of support pillars","0.0-1.0 (0 = disable)"],
|
||||||
sa_slsz_s: "size",
|
sa_slsz_s: "size",
|
||||||
sa_slsz_l: "max size of a\nsupport pillar\nin millimeters",
|
sa_slsz_l: ["max size of a","support pillar","in millimeters"],
|
||||||
sa_slpt_s: "points",
|
sa_slpt_s: "points",
|
||||||
sa_slpt_l: "number of points in\neach support pillar\nin millimeters",
|
sa_slpt_l: ["number of points in","each support pillar","in millimeters"],
|
||||||
sl_slen_l: "enable supports",
|
sl_slen_l: "enable supports",
|
||||||
|
|
||||||
sa_outp_m: "output",
|
sa_outp_m: "output",
|
||||||
sa_opzo_s: "z offset",
|
sa_opzo_s: "z offset",
|
||||||
sa_opzo_l: "z layer offset\nalmost always 0.0\n0.0-1.0 in millimeters",
|
sa_opzo_l: ["z layer offset","almost always 0.0","0.0-1.0 in millimeters"],
|
||||||
sa_opaa_s: "anti alias",
|
sa_opaa_s: "anti alias",
|
||||||
sa_opaa_l: "enable anti-aliasing\nproduces larger files\ncan blur details"
|
sa_opaa_l: ["enable anti-aliasing","produces larger files","can blur details"]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
web/kiri/lang/fr-fr-help.html
Symbolic link
1
web/kiri/lang/fr-fr-help.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
fr-help.html
|
||||||
1
web/kiri/lang/fr-fr.js
Symbolic link
1
web/kiri/lang/fr-fr.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
fr.js
|
||||||
176
web/kiri/lang/fr-help.html
Normal file
176
web/kiri/lang/fr-help.html
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
<div id="help" class="f-col a-stretch">
|
||||||
|
|
||||||
|
<div class="title f-row j-center">
|
||||||
|
<label>Kiri:Moto Aide</label>
|
||||||
|
<label id="kiri-version"></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="f-row">
|
||||||
|
|
||||||
|
<div id="help-sel" class="f-col">
|
||||||
|
<div class="help-label" tab="about">A propos</div>
|
||||||
|
<div class="help-label" tab="start">débuter</div>
|
||||||
|
<div class="help-label" tab="controls">contrôles</div>
|
||||||
|
<div class="help-label" tab="support">support</div>
|
||||||
|
<div class="help-label" tab="project">projet</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tabs" class="f-grow">
|
||||||
|
<div id="help-tab-about" class="help-tab f-col a-center">
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<b>Kiri:Moto</b> est un logiciel de découpe unique, fonctionnant dans un navigateur, entièrement open source, qui
|
||||||
|
transforme les modèles 3d en instructions de machine pour <u>des imprimantes 3D</u>, <u>des CNC</u>,
|
||||||
|
et <u>des graveurs laser</u>.
|
||||||
|
</p><br><p>
|
||||||
|
Le fait d'être basé sur un navigateur signifie que <i>tout</i> le processus de découpe a lieu dans le navigateur local,
|
||||||
|
et non dans le nuage. Vos données et modèles restent <i>totalement privés</i>.
|
||||||
|
</p><br><p>
|
||||||
|
Cela signifie que Kiri se comporte comme une application native de votre ordinateur avec en plus
|
||||||
|
la sécurité de l'exécution dans le bac à sable de sécurité du navigateur.
|
||||||
|
</p><br><p>
|
||||||
|
L'autre avantage de fonctionner à partir du web est que Kiri est toujours à jour. Les nouvelles
|
||||||
|
fonctionnalités, les corrections de bogues et les mises à jour sont fréquemment mises en place. Si vous souhaitez exécuter une ancienne
|
||||||
|
ou une version de développement de Kiri, sélectionnez cette version dans le menu utilisateur en haut à droite.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grow"></div>
|
||||||
|
<i>Kiri vient de Kiri-e qui est l'art Japonais du découpage de papiers</i>
|
||||||
|
<i>Moto est un raccourci pour "Modeling Tool" (Outil de modélisation)</i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tab-start" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Guide de démarrage rapide</b>
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<li id="help-start">visionner <a href="https://youtu.be/08795Sj22QE" target="youtube">The Definitive Video Guide to Kiri:Moto 2.5</a></li>
|
||||||
|
<li><button><i class="fas fa-cogs"></i></button> le menu setup sélectionne le <button><i class="fas fa-cube"></i></button> type de matériel et un appareil</li>
|
||||||
|
<li><button><i class="fas fa-sliders-h"></i></button> les préférences permettent de régler l'interface et les caractéristiques de l'appareil</li>
|
||||||
|
<li><button><i class="fas fa-plus"></i></button> personnaliser un appareil si vous souhaitez modifier les paramètres par défaut</li>
|
||||||
|
<li><button><i class="fas fa-folder"></i></button> ouvre un fichier ou <button><i class="fas fa-file-upload"></i></button> importe des pièces dans l'espace de travail</li>
|
||||||
|
<li>utiliser les menus de droite pour personnaliser les paramètres de découpage</li>
|
||||||
|
<li><button><i class="fas fa-bars"></i></button> découper les objets pour voir l'effet des paramètres</li>
|
||||||
|
<li><button><i class="fas fa-cubes"></i></button> la prévisualisation calcule les données de cheminement des objets tranchés</li>
|
||||||
|
<li><button><i class="fas fa-file-download"></i></button> l'exportation convertit les chemins d'accès aux fichiers GCode et SVG</li>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<b class="header">Modes de fonctionnement</b>
|
||||||
|
<p>Chaque mode (FDM, CAM, Laser, SLA) a des caractéristiques et des paramètres différents.
|
||||||
|
Explorez les vidéos Youtube pour en savoir plus.</p>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-print" class="help-tab f-col">about 3d printing</div>
|
||||||
|
<div id="help-tab-mill" class="help-tab f-col">about cnc milling</div>
|
||||||
|
<div id="help-tab-laser" class="help-tab f-col">about laser cutting</div>
|
||||||
|
|
||||||
|
<div id="help-tab-controls" class="help-tab f-col a-center"><div class="content">
|
||||||
|
<div class="f-row">
|
||||||
|
<table>
|
||||||
|
<tr><td colspan="2" class="header">Contrôles via le clavier</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Touche</th><th>Action</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Configuration</td></tr>
|
||||||
|
<tr><td><label>e</label></td><td>Sélection de l'appareil</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>CAM Sélection des outils</td></tr>
|
||||||
|
<tr><td><label>c</label></td><td>Grid Local Devices</td></tr>
|
||||||
|
<tr><td><label>q</label></td><td>Panneau des préférence</td></tr>
|
||||||
|
<tr><td><label>l</label></td><td>Profils de travail</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Mode</td></tr>
|
||||||
|
<tr><td><label>a</label></td><td>Organiser</td></tr>
|
||||||
|
<tr><td><label>s</label></td><td>Découper</td></tr>
|
||||||
|
<tr><td><label>p</label></td><td>Prévisualiser</td></tr>
|
||||||
|
<tr><td><label>g</label></td><td>Animer</td></tr>
|
||||||
|
<tr><td><label>x</label></td><td>Exporter</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Fichier</td></tr>
|
||||||
|
<tr><td><label>i</label></td><td>Importer</td></tr>
|
||||||
|
<tr><td><label>r</label></td><td>Récent</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Voir</td></tr>
|
||||||
|
<tr><td><label>h</label></td><td>Home</td></tr>
|
||||||
|
<tr><td><label>t</label></td><td>Top</td></tr>
|
||||||
|
<tr><td><label>f</label></td><td>Avant</td></tr>
|
||||||
|
<tr><td><label>b</label></td><td>Arrière</td></tr>
|
||||||
|
<tr><td><label>z</label></td><td>Réinitialiser la vue</td></tr>
|
||||||
|
<tr><td><label>< ></label></td><td>Alterner les vues de côtés</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Focus (organiser)</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Couche (découper/prévisualiser)</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Objets</td></tr>
|
||||||
|
<tr><td><label>d</label></td><td>Dupliquer</td></tr>
|
||||||
|
<tr><td><label>m</label></td><td>Miroir</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>Pivoter/tourner</td></tr>
|
||||||
|
<tr><td><label>delete</label></td><td>Supprimer</td></tr>
|
||||||
|
<tr><td><label>arrow</label></td><td>Tounrer de 90°</td></tr>
|
||||||
|
<tr><td><label>shift-arrow</label></td><td>Tourner de 5°</td></tr>
|
||||||
|
<tr><td><label>option-arrow</label></td><td>Déplacer de 5mm</td></tr>
|
||||||
|
<tr><td><label>ctrl-a</label></td><td>Tout sélectionner</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Aide</td></tr>
|
||||||
|
<tr><td><label>?</label></td><td>Cette fenêtre</td></tr>
|
||||||
|
<tr><td><br><br></td></tr>
|
||||||
|
<tr><td colspan="2" class="header">Contrôles via la souris</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Combo</th><th>Action</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">View</td></tr>
|
||||||
|
<tr><td><label>shift</label> molette</td><td>Changer de couche</td></tr>
|
||||||
|
<tr><td><label>meta</label> déplacer</td><td>Pan</td></tr>
|
||||||
|
<tr><td><label>déplacer-droit</label></td><td>Pan</td></tr>
|
||||||
|
<tr><td><label>déplacer-gauche</label></td><td>Tourner</td></tr>
|
||||||
|
<tr><td><label>molette-souris</label></td><td>Zoom</td></tr>
|
||||||
|
<tr><td><label>déplacer-milieu</label></td><td>Zoom</td></tr>
|
||||||
|
<tr><td><label>meta</label> déplacer</td><td>Pan</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Objets</td></tr>
|
||||||
|
<tr><td><label>ctrl-clic</label></td><td>Aligner la face sur le plateau</td></tr>
|
||||||
|
<tr><td><label>meta-clic</label></td><td>Aligner la face sur le plateau</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-support" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Ressources</b>
|
||||||
|
<div class="content nounderline">
|
||||||
|
<a target="_rsc" href="https://docs.grid.space/projects/kiri-moto"><i class="fas fa-question-circle"></i> Documentation étendue</a>
|
||||||
|
<a target="_rsc" href="https://forum.grid.space"><i class="fab fa-discourse"></i> fora Grid.Space</a>
|
||||||
|
<a target="_rsc" href="https://discord.gg/suyCCgr"><i class="fab fa-discord"></i> Discord serveur de chat en direct</a>
|
||||||
|
<a target="_rsc" href="https://www.youtube.com/playlist?list=PLRoVgyRoWZpumQIKWm7oldx3bjDivqP24"><i class="fab fa-youtube"></i> Youtube vidéos et tutoriels</a>
|
||||||
|
<a target="_rsc" href="https://twitter.com/grid_space_3d"><i class="fab fa-twitter"></i> Suivre Grid.Space sur Twitter</a>
|
||||||
|
<a target="_rsc" href="https://facebook.com/groups/kirimoto"><i class="fab fa-facebook"></i> Kiri:Moto Groupe d'usagers sur Facebook</a>
|
||||||
|
</div>
|
||||||
|
<b class="header">Options complémentaires</b>
|
||||||
|
<p>
|
||||||
|
Dans <button><i class="fas fa-user-cog"></i></button> le menu utilsateur en haut à droite,
|
||||||
|
utiliser l'option <span class="mono">export</span> pour créer unecopie téléchargeable des
|
||||||
|
profils du matériel et (optionellement) de l'espace de travail. Ce fichier pourra ensuite
|
||||||
|
être utilisé pour contrôler et rétablir un instantané de votre installation à tout moment.
|
||||||
|
Il peut également être partagé afin que les développeurs et autres utilisateurs puissent
|
||||||
|
reproduire votre environnement pour aider au débogage.
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-project" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Open Source</b>
|
||||||
|
<p>
|
||||||
|
Kiri:Moto est totalement <a href="https://github.com/GridSpace/grid-apps" target="_github">open-source</a>.
|
||||||
|
Consultez la page du projet Github. Il existe des projets complémentaires, tant sur le plan matériel que logiciel.
|
||||||
|
Les nouveaux développeurs et les contributions au code sont les bienvenus à tout moment. La licence du code est celle du MIT.
|
||||||
|
</p><br><p>
|
||||||
|
<a target="_paypal" href="https://paypal.me/gridspace3d?locale.x=en_US">Toute donation</a> est également bienvenue.
|
||||||
|
</p>
|
||||||
|
<br><b class="header">Intégrations</b>
|
||||||
|
<p>Kiri:Moto est également intégré dans plusieurs autres applications web</p>
|
||||||
|
<li><a target="app" href="https://appstore.onshape.com/apps/CAM/EAAEWYIOMQKBENEMYW2N7MF253CT4WYL6SUJGEY=/description"><b>Onshape</b></a> via son magasin d'Applications</li>
|
||||||
|
<li><a target="app" href="http://www.thingiverse.com/apps/kirimoto/"><b>Thingiverse</b></a> en tant que native Thing Apps</li>
|
||||||
|
<li><a target="app" href="https://simplyprint.io">SimplyPrint.io</a> as the primary slicer under the covers</li>
|
||||||
|
<li><a target="app" href="https://sienci.com/camlab-help/">CAMLab</a> est une branche d'une version antérieure de Kiri:Moto</li>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
642
web/kiri/lang/fr.js
Normal file
642
web/kiri/lang/fr.js
Normal file
|
|
@ -0,0 +1,642 @@
|
||||||
|
// French localization for Kiri:Moto
|
||||||
|
// Will defer to English map for any missing key/value pairs
|
||||||
|
kiri.lang['fr'] =
|
||||||
|
kiri.lang['fr-fr'] = {
|
||||||
|
// common keys and menus
|
||||||
|
animate: "animer", // CAM animate button
|
||||||
|
arrange: "organiser", // layout workspace objects
|
||||||
|
axis: "axe", // left object scale pop menu
|
||||||
|
clear: "effacer", // clear workspace (remove all objects)
|
||||||
|
copy: "copier",
|
||||||
|
delete: "supprimer",
|
||||||
|
detail: "détail",
|
||||||
|
done: "terminé",
|
||||||
|
enable: "permettre",
|
||||||
|
export: "exporter",
|
||||||
|
files: "fichiers",
|
||||||
|
help: "aide",
|
||||||
|
ghost: "translucide", // left render pop menu (wireframe)
|
||||||
|
hide: "cacher", // left render pop menu (invisible)
|
||||||
|
home: "position d'origine",
|
||||||
|
import: "importer",
|
||||||
|
language: "langue",
|
||||||
|
machine: "machine", // device or machine
|
||||||
|
metric: "métrique",
|
||||||
|
name: "nom",
|
||||||
|
prefs: "préfs", // left menu "preferences"
|
||||||
|
preview: "prévisualiser",
|
||||||
|
recent: "récent",
|
||||||
|
render: "rendu", // left render pop menu
|
||||||
|
reset: "remettre",
|
||||||
|
rotate: "tourner", // left rotate pop menu
|
||||||
|
save: "sauvegarder",
|
||||||
|
scale: "échelle", // left object scale pop menu
|
||||||
|
setup: "setup",
|
||||||
|
settings: "paramètres",
|
||||||
|
size: "taille",
|
||||||
|
solid: "solide", // view type pop menu
|
||||||
|
tool: "outil",
|
||||||
|
tools: "outils", // CAM tool menu button
|
||||||
|
top: "haut",
|
||||||
|
type: "genre", // CAM tool type
|
||||||
|
version: "version",
|
||||||
|
view: "vue", // left view pop menu
|
||||||
|
wire: "filaire", // left render pop menu
|
||||||
|
|
||||||
|
acct_xpo: ["faites une sauvegarde de votre machine","et des profils des machines avec","l'option d'inclure les","objets et positions d'environnement"],
|
||||||
|
|
||||||
|
// RIGHT-CLICK CONTEXT MENU
|
||||||
|
rc_clws: "effacer l'environnement",
|
||||||
|
rc_xpws: "exporter l'environnement",
|
||||||
|
rc_lafl: "poser à plat",
|
||||||
|
rc_mirr: "refléter",
|
||||||
|
rc_dupl: "dupliquer",
|
||||||
|
rc_xstl: "exporter en STL",
|
||||||
|
|
||||||
|
// DEVICE MENU and related dialogs
|
||||||
|
dm_sldt: "sélectionner un genre de machine",
|
||||||
|
dm_stdd: "machines standards",
|
||||||
|
dm_mydd: "mes machines",
|
||||||
|
dm_seld: "machine sélectionnée",
|
||||||
|
dm_rcnt: "fichiers récents",
|
||||||
|
dm_savs: "paramètres sauvegardés",
|
||||||
|
dm_appp: "Préférences d'Application",
|
||||||
|
|
||||||
|
// CAM Tool Dialog
|
||||||
|
td_tyem: "plat", // end mill
|
||||||
|
td_tybm: "boule", // ball mill
|
||||||
|
td_tytm: "v forme", // taper mill
|
||||||
|
td_tonm: "outil #",
|
||||||
|
td_shft: "tige", // endmill shaft specs
|
||||||
|
td_flut: "flûte", // endmill flute specs
|
||||||
|
td_tapr: "cône", // endmill taper specs
|
||||||
|
|
||||||
|
// DEVICE dialog groups
|
||||||
|
dv_gr_dev: "périphérique",
|
||||||
|
dv_gr_ext: "extrudeur",
|
||||||
|
dv_gr_out: "sortie",
|
||||||
|
dv_gr_gco: "macros gcode",
|
||||||
|
|
||||||
|
// DEVICE dialog (_s = label, _l = hover help)
|
||||||
|
dv_name_s: "nom",
|
||||||
|
dv_name_l: "nom du matériel",
|
||||||
|
dv_fila_s: "filament",
|
||||||
|
dv_fila_l: "diamètre en millimètres",
|
||||||
|
dv_nozl_s: "buse",
|
||||||
|
dv_nozl_l: "diamètre en millimètres",
|
||||||
|
dv_bedw_s: "largeur",
|
||||||
|
dv_bedw_l: "unités de l'espace de travail",
|
||||||
|
dv_bedd_s: "profondeur",
|
||||||
|
dv_bedd_l: "unités de l'espace de travail",
|
||||||
|
dv_bedh_s: "hauteur",
|
||||||
|
dv_bedh_l: ["hauteur de construction maximale","en unités de l'espace de travail"],
|
||||||
|
dv_spmx_s: "max spindle",
|
||||||
|
dv_spmx_l: ["max spindle rpm speed","0 to disable"],
|
||||||
|
dv_xtab_s: "positionnement absolu",
|
||||||
|
dv_xtab_l: "déplacements extrusion absolu",
|
||||||
|
dv_orgc_s: "origine au centre",
|
||||||
|
dv_orgc_l: "origin du plateau au centre",
|
||||||
|
// dv_orgt_s: "origin top",
|
||||||
|
// dv_orgt_l: "part z origin top",
|
||||||
|
dv_bedc_s: "plateau circulaire",
|
||||||
|
dv_bedc_l: "le plateau du matériel est circulaire",
|
||||||
|
dv_belt_s: "plateau tapis-roulant",
|
||||||
|
dv_belt_l: "plateau à impression continue",
|
||||||
|
dv_retr_s: "rétraction firmware",
|
||||||
|
dv_retr_l: ["le firmware supporte G10/G11"],
|
||||||
|
dv_fanp_s: "refroidissement",
|
||||||
|
dv_fanp_l: "régler la puissance du ventilateur de refroidissement",
|
||||||
|
dv_prog_s: "progression",
|
||||||
|
dv_prog_l: "résultats de chaque % de progression",
|
||||||
|
dv_layr_s: "couche",
|
||||||
|
dv_layr_l: ["résultats de chaque","changement de couche"],
|
||||||
|
dv_tksp_s: "délimiteur d'instruction",
|
||||||
|
dv_tksp_l: ["ajouter un espace","entre les paramètres des axes","G0X0Y0X0","vs","G0 X0 Y0 Z0"],
|
||||||
|
dv_strc_s: "éliminer les commentaires",
|
||||||
|
dv_strc_l: ["éliminer les commentaires du gcode","les commentaires débutent par ;"],
|
||||||
|
dv_fext_s: "extension du fichier",
|
||||||
|
dv_fext_l: "extension du nom de fichier",
|
||||||
|
dv_dwll_s: "dwell",
|
||||||
|
dv_dwll_l: "script gcode dwell",
|
||||||
|
dv_tool_s: "changement d'outil",
|
||||||
|
dv_tool_l: "script de changement d'outil",
|
||||||
|
dv_sspd_s: "spindle speed",
|
||||||
|
dv_sspd_l: "set spindle speed",
|
||||||
|
dv_paus_s: "pause",
|
||||||
|
dv_paus_l: "script gcode de pause",
|
||||||
|
dv_head_s: "header",
|
||||||
|
dv_head_l: "script gcode de démarrage",
|
||||||
|
dv_foot_s: "footer",
|
||||||
|
dv_foot_l: "script gcode de fin",
|
||||||
|
dv_lzon_s: "laser on",
|
||||||
|
dv_lzon_l: "gcode laser on script",
|
||||||
|
dv_lzof_s: "laser off",
|
||||||
|
dv_lzof_l: "gcode laser off script",
|
||||||
|
dv_exts_s: "sélectionner",
|
||||||
|
dv_exts_l: "gcode pour activer cet extrudeur",
|
||||||
|
dv_dext_s: "désélectionner",
|
||||||
|
dv_dext_l: "gcode à lancer avant d'activer un autre extrudeur",
|
||||||
|
dv_extd_s: "désélectionner",
|
||||||
|
dv_extd_l: "gcode pour désactiver cet extrudeur",
|
||||||
|
dv_exox_s: "décalage x",
|
||||||
|
dv_exox_l: "décalage de buse en x",
|
||||||
|
dv_exoy_s: "décalage y",
|
||||||
|
dv_exoy_l: "décalage de buse en y",
|
||||||
|
|
||||||
|
// MODE
|
||||||
|
mo_menu: "mode",
|
||||||
|
mo_fdmp: "Impression FDM",
|
||||||
|
mo_slap: "Impression SLA",
|
||||||
|
mo_lazr: "Découpe / gravure Laser",
|
||||||
|
mo_cncm: "Routeur CNC",
|
||||||
|
|
||||||
|
// SETUP
|
||||||
|
su_menu: "installation",
|
||||||
|
su_devi: "Matériels",
|
||||||
|
su_tool: "Outils",
|
||||||
|
su_locl: "Local",
|
||||||
|
su_xprt: "Exporter",
|
||||||
|
su_help: "Aide",
|
||||||
|
|
||||||
|
// LOAD
|
||||||
|
fe_menu: "fichier",
|
||||||
|
fn_recn: "Récents",
|
||||||
|
fn_impo: "Importer",
|
||||||
|
|
||||||
|
// FUNCTION
|
||||||
|
fn_menu: "action",
|
||||||
|
fn_arra: "Organiser",
|
||||||
|
fn_slic: "Découper",
|
||||||
|
fn_prev: "Prévisualiser",
|
||||||
|
fn_expo: "Exporter",
|
||||||
|
|
||||||
|
// VIEW
|
||||||
|
vu_menu: "vue",
|
||||||
|
vu_home: "Origine",
|
||||||
|
vu_rset: "RAZ",
|
||||||
|
vu_sptp: "Haut",
|
||||||
|
vu_spfr: "Avant",
|
||||||
|
vu_splt: "Gauche",
|
||||||
|
vu_sprt: "Droite",
|
||||||
|
|
||||||
|
// WORKSPACE
|
||||||
|
ws_menu: "vue",
|
||||||
|
ws_save: "Sauvegarder",
|
||||||
|
ws_cler: "Effacer",
|
||||||
|
|
||||||
|
// OPTIONS
|
||||||
|
op_menu: "interface",
|
||||||
|
op_disp: "affichage",
|
||||||
|
op_xprt_s: "expert",
|
||||||
|
op_xprt_l: "afficher plus d'options de paramétrage",
|
||||||
|
op_decl_s: "logos",
|
||||||
|
op_decl_l: "montrer les logos des appareils",
|
||||||
|
op_dang_s: "expérimental",
|
||||||
|
op_dang_l: "montrer les paramètres expérimentaux",
|
||||||
|
op_hopo_s: "survol du menu",
|
||||||
|
op_hopo_l: ["activer le survol du menu", "pour activer"],
|
||||||
|
op_dark_s: "mode sombre",
|
||||||
|
op_dark_l: "interface en mode sombre",
|
||||||
|
op_comp_s: "ui compacte",
|
||||||
|
op_comp_l: ["interface utilisateur compacte", "plus adapté aux petits écrans", "et tablettes"],
|
||||||
|
op_shor_s: "montrer l'origine",
|
||||||
|
op_shor_l: "indiquer l'origine du dispositif ou du processus",
|
||||||
|
op_shru_s: "afficher les règles",
|
||||||
|
op_shru_l: ["montrer les règles des axes", "sur le quadrillage"],
|
||||||
|
op_sped_s: "afficher les vitesses",
|
||||||
|
op_sped_l: ["afficher la vitesse en barre de couleur","en mode prévisualisation"],
|
||||||
|
op_auto_s: "disposition automatique",
|
||||||
|
op_auto_l: ["disposition automatique sur le plateau", "lorsque de nouveaux éléments sont ajoutés"],
|
||||||
|
op_free_s: "disposition libre",
|
||||||
|
op_free_l: ["autoriser la disposition déplaçable","sans effet en mode laser"],
|
||||||
|
op_spcr_s: "espacement",
|
||||||
|
op_spcr_l: ["espacement entre les objets", "avec la disposition automatique", "en unités d'espace de travail"],
|
||||||
|
op_invr_s: "inverser zoom",
|
||||||
|
op_invr_l: ["inverser la molette de la souris", "faire défiler le zoom"],
|
||||||
|
op_save_s: "auto enregt",
|
||||||
|
op_save_l: ["préserve les objets dans l'espace de travail","entre rechargement de l'application"],
|
||||||
|
op_line_s: "type de ligne",
|
||||||
|
op_line_l: ["style de ligne pour le rendu","impacte les performances 3d","chemin: 3d meilleur","plat: 2d bon","ligne = 1d rapide"],
|
||||||
|
op_unit_s: "unités",
|
||||||
|
op_unit_l: ["les unités d'espace de travail affectent","vitesses et distances"],
|
||||||
|
op_anim_s: "animer",
|
||||||
|
op_anim_l: ["densité du maillage de l'animation","plus haut = plus dense","nécessite plus de mémoire","et est plus lent"],
|
||||||
|
|
||||||
|
lo_menu: "disposition",
|
||||||
|
|
||||||
|
pt_menu: "pièces",
|
||||||
|
pt_deci_s: "compression",
|
||||||
|
pt_deci_l: ["activer / désactiver la compression","durant l'importation. Tranchage plus rapide","et usage réduit de la mémoire"],
|
||||||
|
pt_qual_s: "qualité",
|
||||||
|
pt_qual_l: ["niveau de détail à garder", "lors des opérations de tranchage", "plus bas = plus rapide"],
|
||||||
|
pt_heal_s: "correction de maillage",
|
||||||
|
pt_heal_l: ["tentative de correction", "des mailles non-fermées", "accroit le temps de tranchage"],
|
||||||
|
|
||||||
|
xp_menu: "exports",
|
||||||
|
|
||||||
|
// SETTINGS
|
||||||
|
se_menu: "profil",
|
||||||
|
se_load: "charger",
|
||||||
|
se_save: "sauvegarder",
|
||||||
|
|
||||||
|
// FDM SLICING
|
||||||
|
sl_menu: "couches",
|
||||||
|
sl_lahi_s: "hauteur",
|
||||||
|
sl_lahi_l: ["hauteur de chaque couche", "couche en millimètres"],
|
||||||
|
ad_minl_s: "hauteur min",
|
||||||
|
ad_minl_l: ["hauteur de couche minimale adaptative", "en millimètres", "doit être non nulle"],
|
||||||
|
sl_ltop_s: "couches du haut",
|
||||||
|
sl_ltop_l: ["nombre de couches solides", "à appliquer en", "haut de l'impression"],
|
||||||
|
sl_lsld_s: "couches solides",
|
||||||
|
sl_lsld_l: ["zones de remplissage solide calculées", "à partir des deltas de couches. voir", "menu surgissant des couches"],
|
||||||
|
sl_lbot_s: "couches de base",
|
||||||
|
sl_lbot_l: ["nombre de couches solides", "à appliquer en", "bas de l'impression"],
|
||||||
|
ad_adap_s: "adaptive",
|
||||||
|
ad_adap_l: ["utiliser des hauteurs de couche adaptatives", "avec 'hauteur de couche' en maximum", "et 'hauteur min' en minimum"],
|
||||||
|
|
||||||
|
// FDM SHELLS
|
||||||
|
sl_shel_s: "parois",
|
||||||
|
sl_shel_l: ["nombre de périmètre", "murs à générer"],
|
||||||
|
sl_ordr_s: "ordre des parois",
|
||||||
|
sl_ordr_l: ["ordre d'impression des parois","de l'intérieur vers l'extérieur", "ou de l'extérieur vers l'intérieur","affecte la qualité de surface"],
|
||||||
|
sl_strt_s: "début de couche",
|
||||||
|
sl_strt_l: ["point de départ de la couche", "dernier = fin de la couche", "centre = centre de la pièce", "origine = origine du dispositif"],
|
||||||
|
ad_thin_s: "parois fines",
|
||||||
|
ad_thin_l: ["détecte et comble les vides", "entre les parois de la coque"],
|
||||||
|
|
||||||
|
// FDM FILL
|
||||||
|
fi_menu: "remplissage",
|
||||||
|
fi_type: "type",
|
||||||
|
fi_pcnt_s: "fraction de remplissage",
|
||||||
|
fi_pcnt_l: ["valeurs de densité de remplissage","0.0 - 1.0"],
|
||||||
|
fi_angl_s: "départ solide",
|
||||||
|
fi_angl_l: ["angle de départ en degrés", "90 degrés ajoutés à ", "chaque couche suivante", "s'applique uniquement aux couches solides"],
|
||||||
|
fi_over_s: "chevauchement",
|
||||||
|
fi_over_l: ["chevauchement de l'enveloppe et du remplissage", "en tant que fraction du diamètre de la buse", "0,0 - 1,0"],
|
||||||
|
// fi_rate_s: "vitesse d'impression",
|
||||||
|
fi_rate_l: ["vitesse d'extrusion du remplissage", "régler à 0 pour utiliser par défaut", "la vitesse d'impression"],
|
||||||
|
|
||||||
|
// FDM FIRST LAYER
|
||||||
|
fl_menu: "base",
|
||||||
|
fl_lahi_s: "hauteur de couche",
|
||||||
|
fl_lahi_l: ["hauteur de chaque couche", "en millimètres", "devrait être >= hauteur de la couche"],
|
||||||
|
fl_rate_s: "vitesse périmètres",
|
||||||
|
fl_rate_l: ["vitesse maximale d'impression des coques", "en millimètres / minute"],
|
||||||
|
fl_frat_s: "vitesse remplissage",
|
||||||
|
fl_frat_l: ["vitesse maximale d'impression du remplissage", "en millimètres / minute"],
|
||||||
|
fl_mult_s: "débit",
|
||||||
|
fl_mult_l: ["multiplicateur d'extrusion","0.0 - 2.0"],
|
||||||
|
fl_sfac_s: "largeur",
|
||||||
|
fl_sfac_l: ["multiplicateur de la taille de la buse", "modifie l'espacement des lignes"],
|
||||||
|
fl_skrt_s: "jupe nb",
|
||||||
|
fl_skrt_l: ["nombre de lignes de la jupe", "à générer pour la première couche"],
|
||||||
|
fl_skro_s: "décalage bordure",
|
||||||
|
fl_skro_l: ["jupe décalée de la partie", "en millimètres"],
|
||||||
|
fl_nozl_s: "buse",
|
||||||
|
fl_nozl_l: ["degrés en Celsius", "réglage de sortie utilisé", "lorsque celui-ci est égal à zéro"],
|
||||||
|
fl_bedd_s: "température plateau",
|
||||||
|
fl_bedd_l: ["degrés en Celsius", "réglage de sortie utilisé", "lorsque celui-ci est égal à zéro"],
|
||||||
|
fr_spac_s: "écart radeau",
|
||||||
|
fr_spac_l: ["espacement des couches supplémentaires", "entre la 1ère couche et le radeau", "en millimètres"],
|
||||||
|
fr_nabl_s: "activer un radeau",
|
||||||
|
fr_nabl_l: ["créer un radeau sous le ", "modèle pour une meilleure adhérence", "utilise le décalage des jupes et", "désactive la sortie des jupes"],
|
||||||
|
|
||||||
|
// FDM BELT ONLY
|
||||||
|
fl_zoff_s: "décalage bande",
|
||||||
|
fl_zoff_l: ["décalage de hauteur par rapport à la bande", "de l'extrusion la plus basse", "en millimètres"],
|
||||||
|
fl_brim_s: "taille de bordure",
|
||||||
|
fl_brim_l: ["ajoute une bordure à la partie inférieure","la taille est la largeur en millimètres","0 désactive"],
|
||||||
|
fl_brmn_s: "seuil de bordure",
|
||||||
|
fl_brmn_l: ["ajout de bordures uniquement quand le segment", "face à la bande est plus court que cela", "valeur en millimètres", "0 = infini"],
|
||||||
|
fl_bled_s: "ancrage de pièce",
|
||||||
|
fl_bled_l: ["ancrage de la pièce sur la bande", "au début de l'impression", "en millimètres"],
|
||||||
|
|
||||||
|
// FDM SUPPORT
|
||||||
|
sp_menu: "support",
|
||||||
|
sp_detect: "détecter",
|
||||||
|
sp_dens_s: "densité",
|
||||||
|
sp_dens_l: ["fraction 0.0 - 1.0","recommendé 0.15","0 désactive"],
|
||||||
|
sp_size_s: "taille pilier",
|
||||||
|
sp_size_l: ["largeur du pilier","en millimètres"],
|
||||||
|
sp_offs_s: "décalage du pilier",
|
||||||
|
sp_offs_l: ["décalage par rapport à la pièce","en millimètres"],
|
||||||
|
sp_gaps_s: "écart des couches",
|
||||||
|
sp_gaps_l: ["nombre de couches","de décalage de la pièce"],
|
||||||
|
sp_span_s: "portée maximale",
|
||||||
|
sp_span_l: ["portée non soutenue nécessitant", "un nouveau soutien à générer","en millimètres"],
|
||||||
|
sp_angl_s: "angle max",
|
||||||
|
sp_angl_l: ["angle de surplomb maximum avant", "de générer un pilier de soutien"],
|
||||||
|
sp_area_s: "surface min",
|
||||||
|
sp_area_l: ["surface minimale de","la colonne support","en millimètres"],
|
||||||
|
sp_xpnd_s: "étendre",
|
||||||
|
sp_xpnd_l: ["étendre la zone de soutien", "au-delà des limites d'une pièce","en millimètres"],
|
||||||
|
sp_nozl_s: "extrudeur",
|
||||||
|
sp_nozl_l: ["dans les systèmes multi-extrudeurs", "l'extrudeur à utiliser pour", "le matériau de support"],
|
||||||
|
sp_auto_s: "automatique",
|
||||||
|
sp_auto_l: ["activer les supports générés", "utiliser la géométrie at-slice-time", "les supports n'apparaîtront", "qu'une fois le tranchage terminé"],
|
||||||
|
|
||||||
|
// LASER SLICING
|
||||||
|
ls_offs_s: "offset",
|
||||||
|
ls_offs_l: ["adjust for beam width","en millimètres"],
|
||||||
|
ls_lahi_s: "height",
|
||||||
|
ls_lahi_l: ["layer height","in millimeters","0 = auto/detect"],
|
||||||
|
ls_lahm_s: "min",
|
||||||
|
ls_lahm_l: ["layer height minimum","will merge auto slices","under this thickness","in millimeters"],
|
||||||
|
ls_sngl_s: "single",
|
||||||
|
ls_sngl_l: ["perform only one slice","at specified layer height"],
|
||||||
|
|
||||||
|
// CNC COMMON terms
|
||||||
|
cc_tool: "tool",
|
||||||
|
cc_offs_s: "offset",
|
||||||
|
cc_offs_l: ["offset tool center","from chosen path"],
|
||||||
|
cc_spnd_s: "spindle rpm",
|
||||||
|
cc_spnd_l: ["spindle speed in","revolutions / minute"],
|
||||||
|
cc_sovr_s: "step over",
|
||||||
|
cc_sovr_l: ["as a fraction of","tool diameter"],
|
||||||
|
cc_sdwn_s: "step down",
|
||||||
|
cc_sdwn_l: ["step down depth","for each pass","in workspace units","0 to disable"],
|
||||||
|
cc_feed_s: "feed rate",
|
||||||
|
cc_feed_l: ["max cutting speed in","workspace units / minute"],
|
||||||
|
cc_plng_s: "plunge rate",
|
||||||
|
cc_plng_l: ["max z axis speed in","workspace units / minute"],
|
||||||
|
cc_sngl_s: "select lines only",
|
||||||
|
cc_sngl_l: ["select only single edges","instead of connected polylines"],
|
||||||
|
|
||||||
|
// CNC COMMON
|
||||||
|
cc_menu: "limits",
|
||||||
|
cc_flip: "flip",
|
||||||
|
cc_rapd_s: "xy feed",
|
||||||
|
cc_rapd_l: ["max xy moves feedrate","in workspace units / minute"],
|
||||||
|
cc_rzpd_s: "z feed",
|
||||||
|
cc_rzpd_l: ["max z moves feedrate","in workspace units / minute"],
|
||||||
|
|
||||||
|
cc_loff_s: "offset",
|
||||||
|
cc_loff_l: ["distance from stock face","for leveling pass","in workspace units"],
|
||||||
|
|
||||||
|
// CNC ROUGHING
|
||||||
|
cr_menu: "rough",
|
||||||
|
cr_lsto_s: "leave stock",
|
||||||
|
cr_lsto_l: ["horizontal offset from vertical faces","stock to leave for finishing pass","in workspace units"],
|
||||||
|
cr_ease_s: "ease down",
|
||||||
|
cr_ease_l: ["plunge cuts will","spiral down or ease","along a linear path"],
|
||||||
|
cr_clrt_s: "clear top",
|
||||||
|
cr_clrt_l: ["run a clearing pass over","the bounding area of the part","at z = 0"],
|
||||||
|
cr_clrp_s: "clear voids",
|
||||||
|
cr_clrp_l: ["mill out through pockets","instead of just the outline"],
|
||||||
|
cr_clrf_s: "clear faces",
|
||||||
|
cr_clrf_l: ["interpolate step down to","clear any detected flat areas"],
|
||||||
|
cr_olin_s: "inside only",
|
||||||
|
cr_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
|
||||||
|
// CNC OUTLINE
|
||||||
|
co_menu: "outline",
|
||||||
|
co_dogb_s: "dogbones",
|
||||||
|
co_dogb_l: ["insert dogbone cuts","into inside corners"],
|
||||||
|
co_wide_s: "wide cutout",
|
||||||
|
co_wide_l: ["widen outside cutout paths","for deep cuts in hard material"],
|
||||||
|
co_olin_s: "inside only",
|
||||||
|
co_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
co_olot_s: "outside only",
|
||||||
|
co_olot_l: ["limit cutting to","exterior part boundaries","which can be thought of","as the shadow outline"],
|
||||||
|
co_omit_s: "omit through",
|
||||||
|
co_omit_l: "eliminate thru holes",
|
||||||
|
co_olen_s: "enable",
|
||||||
|
co_olen_l: "enabled outline cutting",
|
||||||
|
|
||||||
|
// CNC CONTOUR
|
||||||
|
cn_menu: "contour",
|
||||||
|
cf_angl_s: "max angle",
|
||||||
|
cf_angl_l: ["angles greater than this","are considered vertical"],
|
||||||
|
cf_curv_s: "curves only",
|
||||||
|
cf_curv_l: ["limit linear cleanup","to curved surfaces"],
|
||||||
|
cf_olin_s: "inside only",
|
||||||
|
cf_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
cf_linx_s: "enable y pass",
|
||||||
|
cf_linx_l: "linear y-axis finishing",
|
||||||
|
cf_liny_s: "enable x pass",
|
||||||
|
cf_liny_l: "linear x-axis finishing",
|
||||||
|
|
||||||
|
// CNC TRACE
|
||||||
|
cu_menu: "trace",
|
||||||
|
cu_type_s: "type",
|
||||||
|
cu_type_l: ["follow = tool tip follows line","right or left = tool tip","follows line offset by tool radius"],
|
||||||
|
|
||||||
|
// CNC DRILLING
|
||||||
|
cd_menu: "drill",
|
||||||
|
cd_axis: "axis",
|
||||||
|
cd_points: "points",
|
||||||
|
cd_plpr_s: "plunge per",
|
||||||
|
cd_plpr_l: ["max plunge between","dwell periods","in workspace units","0 to disable"],
|
||||||
|
cd_dwll_s: "dwell time",
|
||||||
|
cd_dwll_l: ["dwell time","between plunges in","in milliseconds"],
|
||||||
|
cd_lift_s: "drill lift",
|
||||||
|
cd_lift_l: ["lift between plunges","after dwell period","in workspace units","0 to disable"],
|
||||||
|
cd_regi_s: "register",
|
||||||
|
cd_regi_l: ["drill registration holes","for double-sided parts","independent of enable","drilling but uses same","tool and settings"],
|
||||||
|
|
||||||
|
// CNC CUTOUT TABS
|
||||||
|
ct_menu: "tabs",
|
||||||
|
ct_angl_s: "angle",
|
||||||
|
ct_angl_l: ["starting angle for tab spacing","in degrees (0-360)"],
|
||||||
|
ct_numb_s: "count",
|
||||||
|
ct_numb_l: ["number of tabs to use","will be spaced evenly","around the part"],
|
||||||
|
ct_wdth_s: "width",
|
||||||
|
ct_wdth_l: "width in workspace units",
|
||||||
|
ct_hght_s: "height",
|
||||||
|
ct_hght_l: "height in workspace units",
|
||||||
|
ct_dpth_s: "depth",
|
||||||
|
ct_dpth_l: ["distance in workspace units","that the tab projects from","the part surface"],
|
||||||
|
ct_midl_s: "midline",
|
||||||
|
ct_midl_l: ["use midline of tab","instead of z bottom","for double-sided work"],
|
||||||
|
ct_nabl_s: "auto",
|
||||||
|
ct_nabl_l: ["auto generate radial tabs","projected from part center","using count and angle offset"],
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
ou_menu: "sortie",
|
||||||
|
|
||||||
|
// LASER KNIFE
|
||||||
|
dk_menu: "knife",
|
||||||
|
dk_dpth_s: "cut depth",
|
||||||
|
dk_dpth_l: ["final cut depth","in millimeters"],
|
||||||
|
dk_pass_s: "cut passes",
|
||||||
|
dk_pass_l: ["number of passes","down to cut depth"],
|
||||||
|
dk_offs_s: "tip offset",
|
||||||
|
dk_offs_l: ["distance from blade tip","to center of tool","in millimeters"],
|
||||||
|
|
||||||
|
// OUTPUT LASER
|
||||||
|
ou_spac_s: "spacing",
|
||||||
|
ou_spac_l: ["distance between layer output","in millimeters"],
|
||||||
|
ou_scal_s: "scaling",
|
||||||
|
ou_scal_l: "multiplier (0.1 to 100)",
|
||||||
|
ou_powr_s: "power",
|
||||||
|
ou_powr_l: ["0 - 100","represents %"],
|
||||||
|
ou_sped_s: "speed",
|
||||||
|
ou_sped_l: "millimeters / minute",
|
||||||
|
ou_mrgd_s: "merged",
|
||||||
|
ou_mrgd_l: ["merge all layers using","color coding to denote","stacking depth"],
|
||||||
|
ou_grpd_s: "grouped",
|
||||||
|
ou_grpd_l: ["retain each layer as","a unified grouping","instead of separated","polygons"],
|
||||||
|
ou_layr_s: "layer order",
|
||||||
|
ou_layr_l: ["output layer order","from top right to","bottom left"],
|
||||||
|
ou_layo_s: "layer color",
|
||||||
|
ou_layo_l: ["output layer colors","for each z index","overridden by merged"],
|
||||||
|
ou_drkn_s: "drag knife",
|
||||||
|
ou_drkn_l: ["enable drag knife","output in gcode","cut radii are added","to corners with","cut down passes"],
|
||||||
|
|
||||||
|
// OUTPUT FDM
|
||||||
|
ou_nozl_s: "température buse",
|
||||||
|
ou_nozl_l: "degrés en celsius",
|
||||||
|
ou_bedd_s: "température plateau",
|
||||||
|
ou_bedd_l: "degrés en celsius",
|
||||||
|
ou_feed_s: "vitesse impression",
|
||||||
|
ou_feed_l: ["vitesse d'impression maximale","millimètres / minute"],
|
||||||
|
ou_fini_s: "vitesse coque",
|
||||||
|
ou_fini_l: ["vitesse de la coque extérieure","millimètres / minute"],
|
||||||
|
ou_move_s: "vitesse déplacement",
|
||||||
|
ou_move_l: ["vitesse de déplacement sans impression","millimètres / minute","0 = active déplacements G0"],
|
||||||
|
ou_shml_s: "débit de coque",
|
||||||
|
ou_flml_s: "débit de solidité",
|
||||||
|
ou_spml_s: "débit de remplissage",
|
||||||
|
ou_exml_l: ["multiplicateur d'extrusion","0.0 - 2.0"],
|
||||||
|
ou_fans_s: "vitesse ventilateur",
|
||||||
|
ou_fans_l: "0 - 255",
|
||||||
|
|
||||||
|
// OUTPUT CAM
|
||||||
|
ou_toll_s: "tolerance",
|
||||||
|
ou_toll_l: ["surface precision","in workspace units","lower is slower and","uses more memory","0 = automatic based","on animate preference"],
|
||||||
|
ou_zanc_s: "z anchor",
|
||||||
|
ou_zanc_l: ["controls the position of the part","when stock Z exceeds part Z"],
|
||||||
|
ou_ztof_s: "z offset",
|
||||||
|
ou_ztof_l: ["offset z anchor","in workspace units","has no effect when","anchor is middle"],
|
||||||
|
ou_zbot_s: "z bottom",
|
||||||
|
ou_zbot_l: ["offset from part bottom","to limit cutting depth","in workspace units"],
|
||||||
|
ou_zclr_s: "z clearance",
|
||||||
|
ou_zclr_l: ["safe travel offset","from top of part","in workspace units"],
|
||||||
|
ou_ztru_s: "z thru",
|
||||||
|
ou_ztru_l: ["extend cutout pass down","in workspace units"],
|
||||||
|
ou_conv_s: "conventional",
|
||||||
|
ou_conv_l: ["milling direction","uncheck for 'climb'"],
|
||||||
|
ou_depf_s: "depth first",
|
||||||
|
ou_depf_l: ["optimize pocket cuts","with depth priority"],
|
||||||
|
|
||||||
|
// CAM STOCK
|
||||||
|
cs_menu: "stock",
|
||||||
|
cs_wdth_s: "width",
|
||||||
|
cs_wdth_l: ["width (x) in workspace units","0 defaults to part size"],
|
||||||
|
cs_dpth_s: "depth",
|
||||||
|
cs_dpth_l: ["depth (y) in workspace units","0 defaults to part size"],
|
||||||
|
cs_hght_s: "height",
|
||||||
|
cs_hght_l: ["height (z) in workspace units","0 defaults to part size"],
|
||||||
|
cs_offs_s: "offset",
|
||||||
|
cs_offs_l: ["use width, depth, height","as offsets from max","part size on platform"],
|
||||||
|
cs_clip_s: "clip to",
|
||||||
|
cs_clip_l: ["rough and outline","clip cutting paths","to defined stock"],
|
||||||
|
cs_offe_s: "enable",
|
||||||
|
cs_offe_l: "enable milling stock",
|
||||||
|
|
||||||
|
// ORIGIN (CAM & LASER)
|
||||||
|
or_bnds_s: "origin bounds",
|
||||||
|
or_bnds_l: ["origin is relative to","boundary of all objects"],
|
||||||
|
or_cntr_s: "origin center",
|
||||||
|
or_cntr_l: "origin is referenced from the center",
|
||||||
|
or_topp_s: "origin top",
|
||||||
|
or_topp_l: "origin is references from the top of objects",
|
||||||
|
|
||||||
|
// FDM ADVANCED
|
||||||
|
ad_menu: "expert",
|
||||||
|
ad_rdst_s: "distance de rétraction",
|
||||||
|
ad_rdst_l: ["longueur de filament à rétracter", "pour les longs mouvements. en millimètres"],
|
||||||
|
ad_rrat_s: "vitesse de rétraction",
|
||||||
|
ad_rrat_l: ["vitesse de rétraction","du filament en mm/s"],
|
||||||
|
ad_rdwl_s: "réenclencher",
|
||||||
|
ad_wpln_s: "essuyage rétractation",
|
||||||
|
ad_wpln_l: ["mouvement sans impression", "après rétraction", "en millimètres"],
|
||||||
|
ad_rdwl_l: ["durée de réenclenchement", "filament et mouvement", "en millisecondes"],
|
||||||
|
ad_scst_s: "cabotage",
|
||||||
|
ad_scst_l: ["extrémité non imprimée", "des coques du périmètre", "en millimètres"],
|
||||||
|
ad_msol_s: "min solide",
|
||||||
|
ad_msol_l: ["aire minimale (mm^2)","requise pour rester solide","doit être > 0.1"],
|
||||||
|
ad_mins_s: "vitesse minimale",
|
||||||
|
ad_mins_l: ["vitesse minimale","des segments courts"],
|
||||||
|
ad_spol_s: "chemin court",
|
||||||
|
ad_spol_l: ["les polygones plus courts", "auront la vitesse réduite et", "seront ramenés à la vitesse minimale", "en millimètres"],
|
||||||
|
ad_arct_s: "tolérance arc",
|
||||||
|
ad_arct_l: ["convertir les lignes des facettes en arcs", "tolérance de dérive du point central", "lors de la correspondance des points d'arc", "considérer les valeurs autour de 0,15", "en millimètres", "0 désactive"],
|
||||||
|
ad_zhop_s: "décalage en Z",
|
||||||
|
ad_zhop_l: ["levée du z","sur les mouvements de rétraction", "en millimètres", "0 désactive"],
|
||||||
|
ad_abkl_s: "anti-backlash",
|
||||||
|
ad_abkl_l: ["pour une meilleure finition de la surface plane", "utiliser des micro-mouvements pour annuler", "le jeu dans la sortie de la couche solide", "en millimètres", "0 désactive", "si le firmware reconnait le M425", "l'utiliser dans l'en-tête du gcode", "et mettre à 0"],
|
||||||
|
ad_lret_s: "rétraction au changement de couche",
|
||||||
|
ad_lret_l: ["forcer la rétraction du filament", "entre les couches"],
|
||||||
|
ad_play_s: "couches de polissage",
|
||||||
|
ad_play_l: ["polir jusqu'au nombre spécifié", "# de couches à la fois"],
|
||||||
|
ad_pspd_s: "vitesse de polissage",
|
||||||
|
ad_pspd_l: ["vitesse de polissage", "en millimètres / minute"],
|
||||||
|
|
||||||
|
// CAM EXPERT
|
||||||
|
cx_fast_s: "skip shadow",
|
||||||
|
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
||||||
|
|
||||||
|
// FDM GCODE
|
||||||
|
ag_menu: "gcode",
|
||||||
|
ag_nozl_s: "buse",
|
||||||
|
ag_nozl_l: "sélectionner la buse ou la tête d'impression",
|
||||||
|
ag_paws_s: "couches de pause",
|
||||||
|
ag_paws_l: ["liste de couches séparées par des virgules", "pour injecter des commandes de pause avant"],
|
||||||
|
ag_loop_s: "couches de répétitions",
|
||||||
|
ag_loop_l: ["des plages de couches à répéter dans le format ", "premier-compte dernier,premier-compte dernier,...", "compte omis = 1"],
|
||||||
|
|
||||||
|
// SLA MENU
|
||||||
|
sa_menu: "tranchage",
|
||||||
|
sa_lahe_s: "hauteur de couche",
|
||||||
|
sa_lahe_l: ["hauteur de couche","en millimètres"],
|
||||||
|
sa_shel_s: "hollow shell",
|
||||||
|
sa_shel_l: ["shell thickness in mm","use multiple of layer height","use 0 for solid (disabled)"],
|
||||||
|
sa_otop_s: "open top",
|
||||||
|
sa_otop_l: ["if shell is enabled","results in an open top"],
|
||||||
|
sa_obas_s: "open base",
|
||||||
|
sa_obas_l: ["if shell is enabled","results in an open base","disabled with supports"],
|
||||||
|
|
||||||
|
sa_layr_m: "layers",
|
||||||
|
sa_lton_s: "light on time",
|
||||||
|
sa_lton_l: ["layer light on","time in seconds"],
|
||||||
|
sa_ltof_s: "light off time",
|
||||||
|
sa_ltof_l: ["layer light off","time in seconds"],
|
||||||
|
sa_pldi_s: "peel distance",
|
||||||
|
sa_pldi_l: ["peel distance","in millimeters"],
|
||||||
|
sa_pllr_s: "peel lift rate",
|
||||||
|
sa_pllr_l: ["peel lift speed","in mm/sec"],
|
||||||
|
sa_pldr_s: "peel drop rate",
|
||||||
|
sa_pldr_l: ["peel drop speed","in mm/sec"],
|
||||||
|
|
||||||
|
sa_base_m: "base",
|
||||||
|
sa_balc_s: "layer count",
|
||||||
|
sa_balc_l: ["number of","base layers"],
|
||||||
|
sa_bltn_l: ["base layer light on","time in seconds"],
|
||||||
|
sa_bltf_l: ["base layer light off","time in seconds"],
|
||||||
|
|
||||||
|
sa_infl_m: "infill",
|
||||||
|
sa_ifdn_s: "density",
|
||||||
|
sa_ifdn_l: ["percent infill","requires shell","0 = disabled","valid 0.0 - 1.0"],
|
||||||
|
sa_iflw_s: "line width",
|
||||||
|
sa_iflw_l: ["hatch line width","in millimeters"],
|
||||||
|
|
||||||
|
sa_supp_m: "support",
|
||||||
|
sa_slyr_s: "base layers",
|
||||||
|
sa_slyr_l: ["base support layers","value range 0-10"],
|
||||||
|
sa_slgp_s: "gap layers",
|
||||||
|
sa_slgp_l: ["number of layers between","raft and bottom of object"],
|
||||||
|
sa_sldn_s: "density",
|
||||||
|
sa_sldn_l: ["used to compute the","number of support pillars","0.0-1.0 (0 = disable)"],
|
||||||
|
sa_slsz_s: "size",
|
||||||
|
sa_slsz_l: ["max size of a","support pillar","in millimeters"],
|
||||||
|
sa_slpt_s: "points",
|
||||||
|
sa_slpt_l: ["number of points in","each support pillar","in millimeters"],
|
||||||
|
sl_slen_l: "enable supports",
|
||||||
|
|
||||||
|
sa_outp_m: "output",
|
||||||
|
sa_opzo_s: "z offset",
|
||||||
|
sa_opzo_l: ["z layer offset","almost always 0.0","0.0-1.0 in millimeters"],
|
||||||
|
sa_opaa_s: "anti alias",
|
||||||
|
sa_opaa_l: ["enable anti-aliasing","produces larger files","can blur details"]
|
||||||
|
};
|
||||||
1
web/kiri/lang/pl-help.html
Symbolic link
1
web/kiri/lang/pl-help.html
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
pl-pl-help.html
|
||||||
180
web/kiri/lang/pl-pl-help.html
Normal file
180
web/kiri/lang/pl-pl-help.html
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
<div id="help" class="f-col a-stretch">
|
||||||
|
<!-- tłumaczenie jako własność publiczna (bez licencji) -->
|
||||||
|
<div class="title f-row j-center">
|
||||||
|
<label>Kiri:Moto Pomoc dla programu do cięcia modeli trójwymiarowych</label>
|
||||||
|
<label id="kiri-version"></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="f-row">
|
||||||
|
|
||||||
|
<div id="help-sel" class="f-col">
|
||||||
|
<div class="help-label" tab="about">o programie</div>
|
||||||
|
<div class="help-label" tab="start">początki</div>
|
||||||
|
<div class="help-label" tab="controls">sterowanie</div>
|
||||||
|
<div class="help-label" tab="support">wsparcie</div>
|
||||||
|
<div class="help-label" tab="project">projekt</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tabs" class="f-grow">
|
||||||
|
<div id="help-tab-about" class="help-tab f-col a-center">
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<b>Kiri:Moto</b> jest unikalnym, opartym na przeglądarce, w pełni otwartym programem
|
||||||
|
do cięcia modeli, który zamienia modele 3d w instrukcje maszynowe dla <u>drukarek 3D</u>,
|
||||||
|
<u>frezarek CNC</u> i <u>wycinarek laserowych</u>.
|
||||||
|
</p><br>
|
||||||
|
<p>
|
||||||
|
Oparcie na przeglądarce oznacza, że <i>całe</i> przetwarzanie odbywa się w lokalnej
|
||||||
|
przeglądarce, a nie w chmurze. Twoje dane i modele pozostają <i>prywatne</i> tylko dla Ciebie.
|
||||||
|
</p><br>
|
||||||
|
<p>
|
||||||
|
Oznacza to, że Kiri zachowuje się tak samo, jak natywny program na komputerze użytkownika.
|
||||||
|
Bezpieczna tak jak bezpieczna jest piaskownica przeglądarki.
|
||||||
|
</p><br>
|
||||||
|
<p>
|
||||||
|
Kolejną zaletą działania w sieci jest to, że Kiri jest zawsze aktualny. Nowa strona
|
||||||
|
nowe funkcje, poprawki błędów i aktualizacje pojawiają się często. Jeśli chcesz uruchomić
|
||||||
|
starszą wersję Kiri lub wersję rozwojową, należy wybrać ją z menu użytkownika w prawym górnym rogu.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="grow"></div>
|
||||||
|
<i>Słowo Kiri pochodzi od kiri-e, która jest japońską sztuką wycinania papieru</i>.
|
||||||
|
<i>Moto to skrót od "Modeling Tool"</i>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="help-tab-start" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Skrócona instrukcja obsługi</b>
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<li id="help-start">obejrzyj (po angielsku) <a href="https://youtu.be/08795Sj22QE" target="youtube">The Definitive Video Guide to Kiri:Moto 2.5</a></li>
|
||||||
|
<li><button><i class="fas fa-cogs"></i></button> menu ustawienia <button><i class="fas fa-cube"></i></button> urządzenia i tryby</li>
|
||||||
|
<li><button><i class="fas fa-sliders-h"></i></button> ustawienia interfejsu użytkownika i trybów</li>
|
||||||
|
<li><button><i class="fas fa-plus"></i></button> dopasowanie parametrów urządzenia, jeśli chcesz zmienić ustawienia domyślne</li>
|
||||||
|
<li><button><i class="fas fa-folder"></i></button> otwórz plik lub <button><i class="fas fa-file-upload"></i></button> zaimportuj element do przestrzeni roboczej</li>
|
||||||
|
<li>uzyj menu po prawej stronie by dopasować parametry krojenia obiektów</li>
|
||||||
|
<li><button><i class="fas fa-bars"></i></button> aby zobaczyć jak działają parametry, pokrój obiekty</li>
|
||||||
|
<li><button><i class="fas fa-cubes"></i></button> podgląd ścieżki z pokrojonych obiektów</li>
|
||||||
|
<li><button><i class="fas fa-file-download"></i></button> eksportuj ścieżki zmian do g-kodu lub pliku svg</li>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<b class="header">Tryby pracy</b>
|
||||||
|
<p>Każdy tryb (FDM, CAM, Laser, SLA) ma inne funkcje i ustawienia.
|
||||||
|
Obejrzyj filmy na Youtube, aby dowiedzieć się więcej.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-print" class="help-tab f-col">o druku 3d</div>
|
||||||
|
<div id="help-tab-mill" class="help-tab f-col">o frezowaniu cnc</div>
|
||||||
|
<div id="help-tab-laser" class="help-tab f-col">o cięciu laserem</div>
|
||||||
|
|
||||||
|
<div id="help-tab-controls" class="help-tab f-col a-center"><div class="content">
|
||||||
|
<div class="f-row">
|
||||||
|
<table>
|
||||||
|
<tr><td colspan="2" class="header">Sterowanie klawiaturą</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Klawisz</th><th>Działanie</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Konfiguracja</td></tr>
|
||||||
|
<tr><td><label>e</label></td><td>Wybór urządzenia</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>Wybór narzędzi CAM</td></tr>
|
||||||
|
<tr><td><label>c</label></td><td>Lokalna siatka odniesienia urządzeń</td></tr>
|
||||||
|
<tr><td><label>q</label></td><td>Panel sterowania</td></tr>
|
||||||
|
<tr><td><label>l</label></td><td>Profile prac</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Tryb</td></tr>
|
||||||
|
<tr><td><label>a</label></td><td>Wyrównanie</td></tr>
|
||||||
|
<tr><td><label>s</label></td><td>Krojenie</td></tr>
|
||||||
|
<tr><td><label>p</label></td><td>Podgląd</td></tr>
|
||||||
|
<tr><td><label>g</label></td><td>Animacja</td></tr>
|
||||||
|
<tr><td><label>x</label></td><td>Eksport</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Plik</td></tr>
|
||||||
|
<tr><td><label>i</label></td><td>Import</td></tr>
|
||||||
|
<tr><td><label>r</label></td><td>Ostatnie</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Widok</td></tr>
|
||||||
|
<tr><td><label>h</label></td><td>Początek</td></tr>
|
||||||
|
<tr><td><label>t</label></td><td>Góra</td></tr>
|
||||||
|
<tr><td><label>f</label></td><td>Z przodu</td></tr>
|
||||||
|
<tr><td><label>b</label></td><td>Z tyłu</td></tr>
|
||||||
|
<tr><td><label>z</label></td><td>Przywrócenie ustawień widoku</td></tr>
|
||||||
|
<tr><td><label>< ></label></td><td>Widok cykli</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Podświetl (wyrównanie)</td></tr>
|
||||||
|
<tr><td><label>v</label></td><td>Warstwa (plastry/podgląd)</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Obiekty</td></tr>
|
||||||
|
<tr><td><label>d</label></td><td>Powiel</td></tr>
|
||||||
|
<tr><td><label>m</label></td><td>Odbij</td></tr>
|
||||||
|
<tr><td><label>o</label></td><td>Ustawienia obrotów</td></tr>
|
||||||
|
<tr><td><label>delete</label></td><td>Kasowanie</td></tr>
|
||||||
|
<tr><td><label>arrow</label></td><td>Obrót o 90°</td></tr>
|
||||||
|
<tr><td><label>shift-arrow</label></td><td>Obrót o 5°</td></tr>
|
||||||
|
<tr><td><label>option-arrow</label></td><td>Przesuń o 5mm</td></tr>
|
||||||
|
<tr><td><label>ctrl-a</label></td><td>Zaznacz wszystko</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Pomoc</td></tr>
|
||||||
|
<tr><td><label>?</label></td><td>To okno</td></tr>
|
||||||
|
<tr><td><br><br></td></tr>
|
||||||
|
<tr><td colspan="2" class="header">Ustawienia myszy</td><tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><th>Combo</th><th>Akcje</th></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Widok</td></tr>
|
||||||
|
<tr><td><label>przesuń</label> koła</td><td>Zmiana warstwy</td></tr>
|
||||||
|
<tr><td><label>meta</label> przemieść</td><td>przemieść obiekty</td></tr>
|
||||||
|
<tr><td><label>prawy-przesuń</label></td><td>przemieść obiekty</td></tr>
|
||||||
|
<tr><td><label>lewy-drag</label></td><td>Obróć</td></tr>
|
||||||
|
<tr><td><label>kółko myszy</label></td><td>Powiększ</td></tr>
|
||||||
|
<tr><td><label>środkowy-przesuń</label></td><td>Powiększ</td></tr>
|
||||||
|
<tr><td><label>meta</label> przesuń</td><td>przemieść obiekty</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
<tr><td colspan=2 class="header2">Obiekty</td></tr>
|
||||||
|
<tr><td><label>ctrl-click</label></td><td>Dopasowanie ściany do podłoża</td></tr>
|
||||||
|
<tr><td><label>meta-click</label></td><td>Dopasowanie ściany do podłoża</td></tr>
|
||||||
|
<tr><td></td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-support" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Zasoby</b>
|
||||||
|
<div class="content nounderline">
|
||||||
|
<a target="_rsc" href="https://docs.grid.space/projects/kiri-moto"><i class="fas fa-question-circle"></i> Rozszerzona dokumentacja</a>
|
||||||
|
<a target="_rsc" href="https://forum.grid.space"><i class="fab fa-discourse"></i> Forum Grid.Space</a>
|
||||||
|
<a target="_rsc" href="https://discord.gg/suyCCgr"><i class="fab fa-discord"></i> czat na Discord</a>
|
||||||
|
<a target="_rsc" href="https://www.youtube.com/playlist?list=PLRoVgyRoWZpumQIKWm7oldx3bjDivqP24"><i class="fab fa-youtube"></i> Filmy i poradniki na Youtube</a>
|
||||||
|
<a target="_rsc" href="https://twitter.com/grid_space_3d"><i class="fab fa-twitter"></i> Śledź Grid.Space na Twitterze</a>
|
||||||
|
<a target="_rsc" href="https://facebook.com/groups/kirimoto"><i class="fab fa-facebook"></i> Kiri:Moto Grupa uzytkowników na feceboku (mordoksiążce)</a>
|
||||||
|
</div>
|
||||||
|
<b class="header">Opcje w programie</b>
|
||||||
|
<p>
|
||||||
|
Pod przyciskiem <button><i class="fas fa-user-cog"></i></button> menu użytkownika w prawym górnym rogu,
|
||||||
|
jest opcja <span class="mono">eksport</span>, tworzy on kopię do pobrania profili urządzenia
|
||||||
|
(opcjonalnie również obszaru roboczego). Plik ten może być użyty do tworzenia kolejnych wersji i
|
||||||
|
przywracania pełnej migawki konfiguracji w dowolnym momencie. Można go również udostępnić programistom
|
||||||
|
lub innym użytkownikom, aby mogli odtworzyć środowisko użytkownika. Może to pomóc w usuwaniu błędów.
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div id="help-tab-project" class="help-tab f-col"><div class="content">
|
||||||
|
<b class="header">Otwarte Oprogramowanie</b>
|
||||||
|
<p>
|
||||||
|
Kiri:Moto jest w całości <a href="https://github.com/GridSpace/grid-apps" target="_github">wolnym oprogramowaniem</a>.
|
||||||
|
Sprawdź stronę projektu na Githubie. Istnieją projekty towarzyszące, zarówno sprzętowe jak i programowe.
|
||||||
|
Nowi programiści i wkłady w kod źródłowy są oczywiście mile widziane. Kod źródłowy na licencji MIT.
|
||||||
|
</p><br>
|
||||||
|
<p>
|
||||||
|
<a target="_paypal" href="https://paypal.me/gridspace3d?locale.x=en_US">Dotacje</a> mile widziane.
|
||||||
|
</p>
|
||||||
|
<br><b class="header">Integrations</b>
|
||||||
|
<p>Kiri:Moto współdziała z różnymi innymi aplikacjami jako strona internetowa</p>
|
||||||
|
<li><a target="app" href="https://appstore.onshape.com/apps/CAM/EAAEWYIOMQKBENEMYW2N7MF253CT4WYL6SUJGEY=/description"><b>Onshape</b></a> w sklepie App Store</li>
|
||||||
|
<li><a target="app" href="http://www.thingiverse.com/apps/kirimoto/"><b>Thingiverse</b></a> jako natywne 'Thing Apps'</li>
|
||||||
|
<li>Jako główny program do cięcia uzywany przez <a target="app" href="https://simplyprint.io">SimplyPrint.io</a></li>
|
||||||
|
<li><a target="app" href="https://sienci.com/camlab-help/">CAMLab</a> jest programem pochodnym poprzedniej wersji Kiri:Moto</li>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
645
web/kiri/lang/pl-pl.js
Normal file
645
web/kiri/lang/pl-pl.js
Normal file
|
|
@ -0,0 +1,645 @@
|
||||||
|
// Polish. Język polski tłumaczony na zasadach własności publicznej
|
||||||
|
kiri.lang['pl'] =
|
||||||
|
kiri.lang['pl-pl'] = {
|
||||||
|
// hasło i tłumaczenie
|
||||||
|
animate: "animacja", // CAM animate button
|
||||||
|
arrange: "rozmieść", // layout workspace objects
|
||||||
|
axis: "osie", // left object scale pop menu
|
||||||
|
clear: "wyczyść", //"czyszczenie z obiektów", // clear workspace (remove all objects)
|
||||||
|
copy: "kopiowanie",
|
||||||
|
delete: "kasowanie",
|
||||||
|
detail: "szczegóły",
|
||||||
|
done: "wykonaj",
|
||||||
|
enable: "włącz",
|
||||||
|
export: "eksport",
|
||||||
|
files: "pliki",
|
||||||
|
help: "pomoc",
|
||||||
|
ghost: "druciak", // left render pop menu (wireframe)
|
||||||
|
hide: "ukryj", // left render pop menu (invisible)
|
||||||
|
home: "początek",
|
||||||
|
import: "import",
|
||||||
|
language: "język",
|
||||||
|
machine: "maszyna", // device or machine
|
||||||
|
metric: "metryka",
|
||||||
|
name: "nazwa",
|
||||||
|
prefs: "ustawienia", // left menu "preferences"
|
||||||
|
preview: "podgląd",
|
||||||
|
recent: "recent",
|
||||||
|
render: "render", // left render pop menu
|
||||||
|
reset: "reset",
|
||||||
|
rotate: "obróć", // left rotate pop menu
|
||||||
|
save: "zapisz",
|
||||||
|
scale: "skala", // left object scale pop menu
|
||||||
|
setup: "ustaw",
|
||||||
|
settings: "ustawienia",
|
||||||
|
size: "wielkość",
|
||||||
|
slice: "plaserki",
|
||||||
|
solid: "wypełniony", // view type pop menu
|
||||||
|
start: "start",
|
||||||
|
tool: "narzędzie",
|
||||||
|
tools: "narzędzia", // CAM tool menu button
|
||||||
|
top: "góra",
|
||||||
|
type: "typ", // CAM tool type
|
||||||
|
version: "wersja",
|
||||||
|
view: "widok", // left view pop menu
|
||||||
|
wire: "druciak", // left render pop menu "wire"
|
||||||
|
|
||||||
|
acct_xpo: ["zrób backup swojego urządzenia","i profil urządzenia z","opcja by zapisać przestrzeń roboczą","obiekty i pozycje"],
|
||||||
|
|
||||||
|
// RIGHT-CLICK CONTEXT MENU
|
||||||
|
rc_clws: "wyczyść przestrzeń roboczą",
|
||||||
|
rc_xpws: "wyeksportuj przestrzeń roboczą",
|
||||||
|
rc_lafl: "ułóż płasko",
|
||||||
|
rc_mirr: "odbicie", // lustro
|
||||||
|
rc_dupl: "skopiuj",
|
||||||
|
rc_xstl: "zapisz w formacie STL",
|
||||||
|
|
||||||
|
// DEVICE MENU and related dialogs
|
||||||
|
dm_sldt: "wybierz rodzaj swojego urządzenia",
|
||||||
|
dm_stdd: "zwykłe urządzenia",
|
||||||
|
dm_mydd: "moje urządzenia",
|
||||||
|
dm_seld: "wybierz urządzenie",
|
||||||
|
dm_rcnt: "ostatnio uzywane pliki",
|
||||||
|
dm_savs: "zachowane ustawienia",
|
||||||
|
dm_appp: "Ustawienia programu",
|
||||||
|
|
||||||
|
// CAM Tool Dialog
|
||||||
|
td_tyem: "tępo zakończone", // end mill
|
||||||
|
td_tybm: "kula na końcu", // ball mill
|
||||||
|
td_tytm: "zwężający się", // taper mill
|
||||||
|
td_tonm: "narzędzie #",
|
||||||
|
td_shft: "wał (pionowy)", // endmill shaft specs
|
||||||
|
td_flut: "czołowy", // endmill flute specs
|
||||||
|
td_tapr: "zwężający się", // endmill taper specs
|
||||||
|
|
||||||
|
// DEVICE dialog groups
|
||||||
|
dv_gr_dev: "urządzenie",
|
||||||
|
dv_gr_ext: "ekstruder",
|
||||||
|
dv_gr_out: "wynik",
|
||||||
|
dv_gr_gco: "makra gkodu",
|
||||||
|
|
||||||
|
// DEVICE dialog (_s = label, _l = hover help)
|
||||||
|
dv_name_s: "nazwa",
|
||||||
|
dv_name_l: "nazwa urządzenia",
|
||||||
|
dv_fila_s: "filament",
|
||||||
|
dv_fila_l: "średnica w milimetrach",
|
||||||
|
dv_nozl_s: "dysza",
|
||||||
|
dv_nozl_l: "średnica w milimetrach",
|
||||||
|
dv_bedw_s: "szerokość",
|
||||||
|
dv_bedw_l: "pole robocze w jednostkach",
|
||||||
|
dv_bedd_s: "głębokość",
|
||||||
|
dv_bedd_l: "pole robocze w jednostkach",
|
||||||
|
dv_bedh_s: "wysokość",
|
||||||
|
dv_bedh_l: ["maksymalna wysokość budowania","w jednostkach pola roboczego"],
|
||||||
|
dv_spmx_s: "maksymalna prędkość wrzeciona",
|
||||||
|
dv_spmx_l: ["maksymalna prędkość wrzeciona w obrotach na minutę","0 wyłączone"],
|
||||||
|
dv_xtab_s: "ustawienie pozycji absolutnie",
|
||||||
|
dv_xtab_l: "absolutna wartość wypchnięcia",
|
||||||
|
dv_orgc_s: "środek odniesienia",
|
||||||
|
dv_orgc_l: "środek odniesienia na platformie",
|
||||||
|
// dv_orgt_s: "odniesienie u góry",
|
||||||
|
// dv_orgt_l: "oś z odniesienie u góry",
|
||||||
|
dv_bedc_s: "okrądła platforma drukowania",
|
||||||
|
dv_bedc_l: "platforma druku jest okrągła",
|
||||||
|
dv_belt_s: "pas na platformie",
|
||||||
|
dv_belt_l: "kontynuacja drukowania platformy",
|
||||||
|
dv_retr_s: "domyślne cofnięcie (retrakcja)",
|
||||||
|
dv_retr_l: ["firmware urządzenia wspiera kody G10/G11"],
|
||||||
|
dv_fanp_s: "zasilanie wiatraczków",
|
||||||
|
dv_fanp_l: "ustawienia zasilania wiatraczków",
|
||||||
|
dv_prog_s: "postęp",
|
||||||
|
dv_prog_l: "wynik w czasie każdego % postępu",
|
||||||
|
dv_layr_s: "warstwa",
|
||||||
|
dv_layr_l: ["output at each","layer change"],
|
||||||
|
dv_tksp_s: "token spacer",
|
||||||
|
dv_tksp_l: ["add a space between","gcode axis parameters","G0X0Y0X0","vs","G0 X0 Y0 Z0"],
|
||||||
|
dv_strc_s: "strip comments",
|
||||||
|
dv_strc_l: ["strip gcode comments","comments begin with ;"],
|
||||||
|
dv_fext_s: "rozszerzenie pliku",
|
||||||
|
dv_fext_l: "rozszerzenie pliku",
|
||||||
|
dv_dwll_s: "dwell",
|
||||||
|
dv_dwll_l: "gcode dwell script",
|
||||||
|
dv_tool_s: "zmiana narzędzia",
|
||||||
|
dv_tool_l: "skrypt zmiany narzędzia",
|
||||||
|
dv_sspd_s: "prędkość wrzeciona",
|
||||||
|
dv_sspd_l: "ustaw prędkość wrzeciona",
|
||||||
|
dv_paus_s: "pauza",
|
||||||
|
dv_paus_l: "gkod skryptu pauzy",
|
||||||
|
dv_head_s: "nagłówek (początek)",
|
||||||
|
dv_head_l: "skrypt gkod nagłówka",
|
||||||
|
dv_foot_s: "stopka (zakończenie)",
|
||||||
|
dv_foot_l: "skrypt gkod stopki",
|
||||||
|
dv_lzon_s: "laser włączony",
|
||||||
|
dv_lzon_l: "gcode laser on script",
|
||||||
|
dv_lzof_s: "laser wyłączony",
|
||||||
|
dv_lzof_l: "gcode laser off script",
|
||||||
|
dv_exts_s: "zaznacz",
|
||||||
|
dv_exts_l: "gcode run to enable this extruder",
|
||||||
|
dv_dext_s: "odznacz",
|
||||||
|
dv_dext_l: "gcode run before enabling another extruder",
|
||||||
|
dv_extd_s: "deselect",
|
||||||
|
dv_extd_l: "gcode to deselect this extruder",
|
||||||
|
dv_exox_s: "offset x",
|
||||||
|
dv_exox_l: "nozzle offset x",
|
||||||
|
dv_exoy_s: "offset y",
|
||||||
|
dv_exoy_l: "nozzle offset y",
|
||||||
|
|
||||||
|
// MODE
|
||||||
|
mo_menu: "tryb",
|
||||||
|
mo_fdmp: "FDM Druk przyrostowy",
|
||||||
|
mo_slap: "SLA Druk przyrostowy",
|
||||||
|
mo_lazr: "Ciecie laserem",
|
||||||
|
mo_cncm: "Frezowanie CNC",
|
||||||
|
|
||||||
|
// SETUP
|
||||||
|
su_menu: "ustawienia",
|
||||||
|
su_devi: "Urządzenia",
|
||||||
|
su_tool: "Narzędzia",
|
||||||
|
su_locl: "Lokalnie",
|
||||||
|
su_xprt: "Eksport",
|
||||||
|
su_help: "Pomoc",
|
||||||
|
|
||||||
|
// LOAD
|
||||||
|
fe_menu: "plik",
|
||||||
|
fn_recn: "ostatnie pliki",
|
||||||
|
fn_impo: "Importowanie",
|
||||||
|
|
||||||
|
// FUNCTION
|
||||||
|
fn_menu: "action",
|
||||||
|
fn_arra: "Arrange",
|
||||||
|
fn_slic: "Slice",
|
||||||
|
fn_prev: "Preview",
|
||||||
|
fn_expo: "Export",
|
||||||
|
|
||||||
|
// VIEW
|
||||||
|
vu_menu: "view",
|
||||||
|
vu_home: "Home",
|
||||||
|
vu_rset: "Reset",
|
||||||
|
vu_sptp: "Top",
|
||||||
|
vu_spfr: "Front",
|
||||||
|
vu_splt: "Left",
|
||||||
|
vu_sprt: "Right",
|
||||||
|
|
||||||
|
// WORKSPACE
|
||||||
|
ws_menu: "view",
|
||||||
|
ws_save: "Save",
|
||||||
|
ws_cler: "Clear",
|
||||||
|
|
||||||
|
// OPTIONS
|
||||||
|
op_menu: "interface",
|
||||||
|
op_disp: "display",
|
||||||
|
op_xprt_s: "expert",
|
||||||
|
op_xprt_l: "show more settings options",
|
||||||
|
op_decl_s: "decals",
|
||||||
|
op_decl_l: "show device decals and logos",
|
||||||
|
op_dang_s: "experimental",
|
||||||
|
op_dang_l: "show experimental parameters",
|
||||||
|
op_hopo_s: "hover pop",
|
||||||
|
op_hopo_l: ["enable menu hover","to activate"],
|
||||||
|
op_dark_s: "dark mode",
|
||||||
|
op_dark_l: "dark mode interface",
|
||||||
|
op_comp_s: "compact ui",
|
||||||
|
op_comp_l: ["compact user interface","better for small screens","and tablets"],
|
||||||
|
op_shor_s: "show origin",
|
||||||
|
op_shor_l: "show device or process origin",
|
||||||
|
op_shru_s: "show rulers",
|
||||||
|
op_shru_l: ["show axes rulers","on major gridlines"],
|
||||||
|
op_sped_s: "show speeds",
|
||||||
|
op_sped_l: ["show speed to color bar","in preview mode"],
|
||||||
|
op_auto_s: "auto layout",
|
||||||
|
op_auto_l: ["automatically layout platform","when new items added"],
|
||||||
|
op_free_s: "free layout",
|
||||||
|
op_free_l: ["permit dragable layout","no effect in laser mode"],
|
||||||
|
op_spcr_s: "spacing",
|
||||||
|
op_spcr_l: ["spacing between objects","during auto layout","in workspace units"],
|
||||||
|
op_orth_s: "orthographic",
|
||||||
|
op_orth_l: ["orthographic display","requires page refresh"],
|
||||||
|
op_invr_s: "invert zoom",
|
||||||
|
op_invr_l: ["invert mouse wheel","scroll zoom"],
|
||||||
|
op_save_s: "auto save",
|
||||||
|
op_save_l: ["preserve objects in workspace","between application reloads"],
|
||||||
|
op_line_s: "line type",
|
||||||
|
op_line_l: ["line style for path rendering","impacts 3d performance","path: 3d best","flat: 2d good","line = 1d fast"],
|
||||||
|
op_unit_s: "units",
|
||||||
|
op_unit_l: ["workspace units affects","speeds and distances"],
|
||||||
|
op_anim_s: "animate",
|
||||||
|
op_anim_l: ["animation mesh density","higher is more dense","takes more memory","and is slower"],
|
||||||
|
|
||||||
|
lo_menu: "layout",
|
||||||
|
|
||||||
|
pt_menu: "parts",
|
||||||
|
pt_deci_s: "decimate",
|
||||||
|
pt_deci_l: ["enable or disable point decimation","during port import. for faster slicing","and lower memory usage"],
|
||||||
|
pt_qual_s: "quality",
|
||||||
|
pt_qual_l: ["level of detail to retain","during slicing operations","lower is faster"],
|
||||||
|
pt_heal_s: "heal mesh",
|
||||||
|
pt_heal_l: ["attempt to heal","non-manifold meshes","adds to slicing time"],
|
||||||
|
|
||||||
|
xp_menu: "exports",
|
||||||
|
|
||||||
|
// SETTINGS
|
||||||
|
se_menu: "profile",
|
||||||
|
se_load: "load",
|
||||||
|
se_save: "save",
|
||||||
|
|
||||||
|
// FDM SLICING
|
||||||
|
sl_menu: "layers",
|
||||||
|
sl_lahi_s: "height",
|
||||||
|
sl_lahi_l: ["height of each slice","layer in millimeters"],
|
||||||
|
ad_minl_s: "height min",
|
||||||
|
ad_minl_l: ["adaptive min layer height","in millimeters","must be non-zero"],
|
||||||
|
sl_ltop_s: "top layers",
|
||||||
|
sl_ltop_l: ["number of solid layers","to enforce at the","top of the print"],
|
||||||
|
sl_lsld_s: "solid layers",
|
||||||
|
sl_lsld_l: ["solid fill areas computed","from layer deltas. see","layer pop menu"],
|
||||||
|
sl_lbot_s: "base layers",
|
||||||
|
sl_lbot_l: ["number of solid layers","to enforce at the","bottom of the print"],
|
||||||
|
ad_adap_s: "adaptive",
|
||||||
|
ad_adap_l: ["use adaptive layer heights","with 'layer height' as max","and 'layer min' as the min"],
|
||||||
|
|
||||||
|
// FDM SHELLS
|
||||||
|
sl_shel_s: "shell count",
|
||||||
|
sl_shel_l: ["number of perimeter","walls to generate"],
|
||||||
|
sl_ordr_s: "shell order",
|
||||||
|
sl_ordr_l: ["output shell order","inside to outside","or outside to inside","affects surface quality"],
|
||||||
|
sl_strt_s: "layer start",
|
||||||
|
sl_strt_l: ["layer starting point","last = last layer end","center = part center","origin = device origin"],
|
||||||
|
ad_thin_s: "thin walls",
|
||||||
|
ad_thin_l: ["detect and fill gaps","between shell walls"],
|
||||||
|
|
||||||
|
// FDM FILL
|
||||||
|
fi_menu: "infill",
|
||||||
|
fi_type: "type",
|
||||||
|
fi_pcnt_s: "fill fraction",
|
||||||
|
fi_pcnt_l: ["fill density values","0.0 - 1.0"],
|
||||||
|
fi_angl_s: "solid start",
|
||||||
|
fi_angl_l: ["starting angle in degrees","90 degrees added to ","each following layer","applies only to solid layers"],
|
||||||
|
fi_over_s: "overlap",
|
||||||
|
fi_over_l: ["overlap with shell and other fill","as fraction of nozzle diameter","0.0 - 1.0"],
|
||||||
|
// fi_rate_s: "print speed",
|
||||||
|
fi_rate_l: ["extrusion speed for infill","set to 0 to use default","output print speeds"],
|
||||||
|
|
||||||
|
// FDM FIRST LAYER
|
||||||
|
fl_menu: "base",
|
||||||
|
fl_lahi_s: "layer height",
|
||||||
|
fl_lahi_l: ["height of each slice","in millimeters","should be >= slice height"],
|
||||||
|
fl_rate_s: "shell speed",
|
||||||
|
fl_rate_l: ["shell printing max speed","in millimeters / minute"],
|
||||||
|
fl_frat_s: "fill speed",
|
||||||
|
fl_frat_l: ["fill printing max speed","in millimeters / minute"],
|
||||||
|
fl_mult_s: "flow factor",
|
||||||
|
fl_mult_l: ["extrusion multiplier","0.0 - 2.0"],
|
||||||
|
fl_sfac_s: "width factor",
|
||||||
|
fl_sfac_l: ["multiplier on nozzle size","changes line spacing"],
|
||||||
|
fl_skrt_s: "skirt count",
|
||||||
|
fl_skrt_l: ["number of first-layer offset","brims to generate"],
|
||||||
|
fl_skro_s: "skirt offset",
|
||||||
|
fl_skro_l: ["skirt offset from part","in millimeters"],
|
||||||
|
fl_nozl_s: "nozzle temp",
|
||||||
|
fl_nozl_l: ["degrees in celsius","output setting used","when this is zero"],
|
||||||
|
fl_bedd_s: "bed temp",
|
||||||
|
fl_bedd_l: ["degrees in celsius","output setting used","when this is zero"],
|
||||||
|
fr_spac_s: "raft gap",
|
||||||
|
fr_spac_l: ["additional layer spacing","between 1st layer and raft","in millimeters"],
|
||||||
|
fr_nabl_s: "raft enable",
|
||||||
|
fr_nabl_l: ["create a raft under the","model for better adhesion","uses skirt offset and","disables skirt output"],
|
||||||
|
|
||||||
|
// FDM BELT ONLY
|
||||||
|
fl_zoff_s: "belt offset",
|
||||||
|
fl_zoff_l: ["height offset from belt","of lowest extrusion","in millimeters"],
|
||||||
|
fl_brim_s: "brim size",
|
||||||
|
fl_brim_l: ["add brim to part bottom","size is width in millimeters","0 to disable"],
|
||||||
|
fl_brmn_s: "brim trigger",
|
||||||
|
fl_brmn_l: ["add brims only when segment","facing belt is shorter than this","value in millimeters","0 = Infinity"],
|
||||||
|
fl_bled_s: "part anchor",
|
||||||
|
fl_bled_l: ["belt part anchor","at start of print","in millimeters"],
|
||||||
|
|
||||||
|
// FDM SUPPORT
|
||||||
|
sp_menu: "support",
|
||||||
|
sp_detect: "detect",
|
||||||
|
sp_dens_s: "density",
|
||||||
|
sp_dens_l: ["fraction 0.0 - 1.0","recommended 0.15","0 to disable"],
|
||||||
|
sp_size_s: "pillar size",
|
||||||
|
sp_size_l: ["pillar width","in millimeters"],
|
||||||
|
sp_offs_s: "part offset",
|
||||||
|
sp_offs_l: ["offset from part","in millimeters"],
|
||||||
|
sp_gaps_s: "gap layers",
|
||||||
|
sp_gaps_l: ["number of layers","offset from part"],
|
||||||
|
sp_span_s: "max span",
|
||||||
|
sp_span_l: ["unsupported span that causes","a new support to be generated","in millimeters"],
|
||||||
|
sp_angl_s: "max angle",
|
||||||
|
sp_angl_l: ["max overhang angle before","supporting pillar is generated"],
|
||||||
|
sp_area_s: "min area",
|
||||||
|
sp_area_l: ["minimum area for","a support column","in millimeters"],
|
||||||
|
sp_xpnd_s: "expand",
|
||||||
|
sp_xpnd_l: ["expand support area","beyond part boundary","in millimeters"],
|
||||||
|
sp_nozl_s: "extruder",
|
||||||
|
sp_nozl_l: ["in multi-extruder systems","the extruder to use for","support material"],
|
||||||
|
sp_auto_s: "automatic",
|
||||||
|
sp_auto_l: ["enable generated supports","using at-slice-time geometry","supports will only appear","after slicing completes"],
|
||||||
|
|
||||||
|
// LASER SLICING
|
||||||
|
ls_offs_s: "offset",
|
||||||
|
ls_offs_l: ["adjust for beam width","in millimeters"],
|
||||||
|
ls_lahi_s: "height",
|
||||||
|
ls_lahi_l: ["layer height","in millimeters","0 = auto/detect"],
|
||||||
|
ls_lahm_s: "min",
|
||||||
|
ls_lahm_l: ["layer height minimum","will merge auto slices","under this thickness","in millimeters"],
|
||||||
|
ls_sngl_s: "single",
|
||||||
|
ls_sngl_l: ["perform only one slice","at specified layer height"],
|
||||||
|
|
||||||
|
// CNC COMMON terms
|
||||||
|
cc_tool: "tool",
|
||||||
|
cc_offs_s: "offset",
|
||||||
|
cc_offs_l: ["offset tool center","from chosen path"],
|
||||||
|
cc_spnd_s: "spindle rpm",
|
||||||
|
cc_spnd_l: ["spindle speed in","revolutions / minute"],
|
||||||
|
cc_sovr_s: "step over",
|
||||||
|
cc_sovr_l: ["as a fraction of","tool diameter"],
|
||||||
|
cc_sdwn_s: "step down",
|
||||||
|
cc_sdwn_l: ["step down depth","for each pass","in workspace units","0 to disable"],
|
||||||
|
cc_feed_s: "feed rate",
|
||||||
|
cc_feed_l: ["max cutting speed in","workspace units / minute"],
|
||||||
|
cc_plng_s: "plunge rate",
|
||||||
|
cc_plng_l: ["max z axis speed in","workspace units / minute"],
|
||||||
|
cc_sngl_s: "select lines only",
|
||||||
|
cc_sngl_l: ["select only single edges","instead of connected polylines"],
|
||||||
|
|
||||||
|
// CNC COMMON
|
||||||
|
cc_menu: "limits",
|
||||||
|
cc_flip: "flip",
|
||||||
|
cc_rapd_s: "xy feed",
|
||||||
|
cc_rapd_l: ["max xy moves feedrate","in workspace units / minute"],
|
||||||
|
cc_rzpd_s: "z feed",
|
||||||
|
cc_rzpd_l: ["max z moves feedrate","in workspace units / minute"],
|
||||||
|
|
||||||
|
cc_loff_s: "offset",
|
||||||
|
cc_loff_l: ["distance from stock face","for leveling pass","in workspace units"],
|
||||||
|
|
||||||
|
// CNC ROUGHING
|
||||||
|
cr_menu: "rough",
|
||||||
|
cr_lsto_s: "leave stock",
|
||||||
|
cr_lsto_l: ["horizontal offset from vertical faces","stock to leave for finishing pass","in workspace units"],
|
||||||
|
cr_ease_s: "ease down",
|
||||||
|
cr_ease_l: ["plunge cuts will","spiral down or ease","along a linear path"],
|
||||||
|
cr_clrt_s: "clear top",
|
||||||
|
cr_clrt_l: ["run a clearing pass over","the bounding area of the part","at z = 0"],
|
||||||
|
cr_clrp_s: "clear voids",
|
||||||
|
cr_clrp_l: ["mill out through pockets","instead of just the outline"],
|
||||||
|
cr_clrf_s: "clear faces",
|
||||||
|
cr_clrf_l: ["interpolate step down to","clear any detected flat areas"],
|
||||||
|
cr_olin_s: "inside only",
|
||||||
|
cr_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
|
||||||
|
// CNC OUTLINE
|
||||||
|
co_menu: "outline",
|
||||||
|
co_dogb_s: "dogbones",
|
||||||
|
co_dogb_l: ["insert dogbone cuts","into inside corners"],
|
||||||
|
co_wide_s: "wide cutout",
|
||||||
|
co_wide_l: ["widen outside cutout paths","for deep cuts in hard material"],
|
||||||
|
co_olin_s: "inside only",
|
||||||
|
co_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
co_olot_s: "outside only",
|
||||||
|
co_olot_l: ["limit cutting to","exterior part boundaries","which can be thought of","as the shadow outline"],
|
||||||
|
co_omit_s: "omit through",
|
||||||
|
co_omit_l: "eliminate thru holes",
|
||||||
|
co_olen_s: "enable",
|
||||||
|
co_olen_l: "enabled outline cutting",
|
||||||
|
|
||||||
|
// CNC CONTOUR
|
||||||
|
cn_menu: "contour",
|
||||||
|
cf_angl_s: "max angle",
|
||||||
|
cf_angl_l: ["angles greater than this","are considered vertical"],
|
||||||
|
cf_curv_s: "curves only",
|
||||||
|
cf_curv_l: ["limit linear cleanup","to curved surfaces"],
|
||||||
|
cf_olin_s: "inside only",
|
||||||
|
cf_olin_l: ["limit cutting to","inside part boundaries"],
|
||||||
|
cf_linx_s: "enable y pass",
|
||||||
|
cf_linx_l: "linear y-axis finishing",
|
||||||
|
cf_liny_s: "enable x pass",
|
||||||
|
cf_liny_l: "linear x-axis finishing",
|
||||||
|
|
||||||
|
// CNC TRACE
|
||||||
|
cu_menu: "trace",
|
||||||
|
cu_type_s: "type",
|
||||||
|
cu_type_l: ["follow = tool tip follows line","right or left = tool tip","follows line offset by tool radius"],
|
||||||
|
|
||||||
|
// CNC DRILLING
|
||||||
|
cd_menu: "drill",
|
||||||
|
cd_axis: "axis",
|
||||||
|
cd_points: "points",
|
||||||
|
cd_plpr_s: "plunge per",
|
||||||
|
cd_plpr_l: ["max plunge between","dwell periods","in workspace units","0 to disable"],
|
||||||
|
cd_dwll_s: "dwell time",
|
||||||
|
cd_dwll_l: ["dwell time","between plunges in","in milliseconds"],
|
||||||
|
cd_lift_s: "drill lift",
|
||||||
|
cd_lift_l: ["lift between plunges","after dwell period","in workspace units","0 to disable"],
|
||||||
|
cd_regi_s: "register",
|
||||||
|
cd_regi_l: ["drill registration holes","for double-sided parts","independent of enable","drilling but uses same","tool and settings"],
|
||||||
|
|
||||||
|
// CNC CUTOUT TABS
|
||||||
|
ct_menu: "tabs",
|
||||||
|
ct_angl_s: "angle",
|
||||||
|
ct_angl_l: ["starting angle for tab spacing","in degrees (0-360)"],
|
||||||
|
ct_numb_s: "count",
|
||||||
|
ct_numb_l: ["number of tabs to use","will be spaced evenly","around the part"],
|
||||||
|
ct_wdth_s: "width",
|
||||||
|
ct_wdth_l: "width in workspace units",
|
||||||
|
ct_hght_s: "height",
|
||||||
|
ct_hght_l: "height in workspace units",
|
||||||
|
ct_dpth_s: "depth",
|
||||||
|
ct_dpth_l: ["distance in workspace units","that the tab projects from","the part surface"],
|
||||||
|
ct_midl_s: "midline",
|
||||||
|
ct_midl_l: ["use midline of tab","instead of z bottom","for double-sided work"],
|
||||||
|
ct_nabl_s: "auto",
|
||||||
|
ct_nabl_l: ["auto generate radial tabs","projected from part center","using count and angle offset"],
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
ou_menu: "output",
|
||||||
|
|
||||||
|
// LASER KNIFE
|
||||||
|
dk_menu: "knife",
|
||||||
|
dk_dpth_s: "cut depth",
|
||||||
|
dk_dpth_l: ["final cut depth","in millimeters"],
|
||||||
|
dk_pass_s: "cut passes",
|
||||||
|
dk_pass_l: ["number of passes","down to cut depth"],
|
||||||
|
dk_offs_s: "tip offset",
|
||||||
|
dk_offs_l: ["distance from blade tip","to center of tool","in millimeters"],
|
||||||
|
|
||||||
|
// OUTPUT LASER
|
||||||
|
ou_spac_s: "spacing",
|
||||||
|
ou_spac_l: ["distance between layer output","in millimeters"],
|
||||||
|
ou_scal_s: "scaling",
|
||||||
|
ou_scal_l: "multiplier (0.1 to 100)",
|
||||||
|
ou_powr_s: "power",
|
||||||
|
ou_powr_l: ["0 - 100","represents %"],
|
||||||
|
ou_sped_s: "speed",
|
||||||
|
ou_sped_l: "millimeters / minute",
|
||||||
|
ou_mrgd_s: "merged",
|
||||||
|
ou_mrgd_l: ["merge all layers using","color coding to denote","stacking depth"],
|
||||||
|
ou_grpd_s: "grouped",
|
||||||
|
ou_grpd_l: ["retain each layer as","a unified grouping","instead of separated","polygons"],
|
||||||
|
ou_layr_s: "layer order",
|
||||||
|
ou_layr_l: ["output layer order","from top right to","bottom left"],
|
||||||
|
ou_layo_s: "layer color",
|
||||||
|
ou_layo_l: ["output layer colors","for each z index","overridden by merged"],
|
||||||
|
ou_drkn_s: "drag knife",
|
||||||
|
ou_drkn_l: ["enable drag knife","output in gcode","cut radii are added","to corners with","cut down passes"],
|
||||||
|
|
||||||
|
// OUTPUT FDM
|
||||||
|
ou_nozl_s: "nozzle temp",
|
||||||
|
ou_nozl_l: "degrees in celsius",
|
||||||
|
ou_bedd_s: "bed temp",
|
||||||
|
ou_bedd_l: "degrees in celsius",
|
||||||
|
ou_feed_s: "print speed",
|
||||||
|
ou_feed_l: ["max print speed","millimeters / minute"],
|
||||||
|
ou_fini_s: "finish speed",
|
||||||
|
ou_fini_l: ["outermost shell speed","millimeters / minute"],
|
||||||
|
ou_move_s: "move speed",
|
||||||
|
ou_move_l: ["non-print move speed","millimeters / minute","0 = enable G0 moves"],
|
||||||
|
ou_shml_s: "shell factor",
|
||||||
|
ou_flml_s: "solid factor",
|
||||||
|
ou_spml_s: "infill factor",
|
||||||
|
ou_exml_l: ["extrusion multiplier","0.0 - 2.0"],
|
||||||
|
ou_fans_s: "fan speed",
|
||||||
|
ou_fans_l: "0 - 255",
|
||||||
|
|
||||||
|
// OUTPUT CAM
|
||||||
|
ou_toll_s: "tolerance",
|
||||||
|
ou_toll_l: ["surface precision","in workspace units","lower is slower and","uses more memory","0 = automatic based","on animate preference"],
|
||||||
|
ou_zanc_s: "z anchor",
|
||||||
|
ou_zanc_l: ["controls the position of the part","when stock Z exceeds part Z"],
|
||||||
|
ou_ztof_s: "z offset",
|
||||||
|
ou_ztof_l: ["offset z anchor","in workspace units","has no effect when","anchor is middle"],
|
||||||
|
ou_zbot_s: "z bottom",
|
||||||
|
ou_zbot_l: ["offset from part bottom","to limit cutting depth","in workspace units"],
|
||||||
|
ou_zclr_s: "z clearance",
|
||||||
|
ou_zclr_l: ["safe travel offset","from top of part","in workspace units"],
|
||||||
|
ou_ztru_s: "z thru",
|
||||||
|
ou_ztru_l: ["extend cutout pass down","in workspace units"],
|
||||||
|
ou_conv_s: "conventional",
|
||||||
|
ou_conv_l: ["milling direction","uncheck for 'climb'"],
|
||||||
|
ou_depf_s: "depth first",
|
||||||
|
ou_depf_l: ["optimize pocket cuts","with depth priority"],
|
||||||
|
|
||||||
|
// CAM STOCK
|
||||||
|
cs_menu: "stock",
|
||||||
|
cs_wdth_s: "width",
|
||||||
|
cs_wdth_l: ["width (x) in workspace units","0 defaults to part size"],
|
||||||
|
cs_dpth_s: "depth",
|
||||||
|
cs_dpth_l: ["depth (y) in workspace units","0 defaults to part size"],
|
||||||
|
cs_hght_s: "height",
|
||||||
|
cs_hght_l: ["height (z) in workspace units","0 defaults to part size"],
|
||||||
|
cs_offs_s: "offset",
|
||||||
|
cs_offs_l: ["use width, depth, height","as offsets from max","part size on platform"],
|
||||||
|
cs_clip_s: "clip to",
|
||||||
|
cs_clip_l: ["rough and outline","clip cutting paths","to defined stock"],
|
||||||
|
cs_offe_s: "enable",
|
||||||
|
cs_offe_l: "enable milling stock",
|
||||||
|
|
||||||
|
// ORIGIN (CAM & LASER)
|
||||||
|
or_bnds_s: "origin bounds",
|
||||||
|
or_bnds_l: ["origin is relative to","boundary of all objects"],
|
||||||
|
or_cntr_s: "origin center",
|
||||||
|
or_cntr_l: "origin is referenced from the center",
|
||||||
|
or_topp_s: "origin top",
|
||||||
|
or_topp_l: "origin is references from the top of objects",
|
||||||
|
|
||||||
|
// FDM ADVANCED
|
||||||
|
ad_menu: "expert",
|
||||||
|
ad_rdst_s: "retract dist",
|
||||||
|
ad_rdst_l: ["amount to retract filament","for long moves. in millimeters"],
|
||||||
|
ad_rrat_s: "retract rate",
|
||||||
|
ad_rrat_l: ["speed of filament","retraction in mm/s"],
|
||||||
|
ad_rdwl_s: "engage dwell",
|
||||||
|
ad_wpln_s: "retract wipe",
|
||||||
|
ad_wpln_l: ["non-printing move","after retraction","in millimeters"],
|
||||||
|
ad_rdwl_l: ["time between re-engaging","filament and movement","in milliseconds"],
|
||||||
|
ad_scst_s: "shell coast",
|
||||||
|
ad_scst_l: ["non-printing end","of perimeter shells","in millimeters"],
|
||||||
|
ad_msol_s: "min solid",
|
||||||
|
ad_msol_l: ["minimum area (mm^2)","required to keep solid","must be > 0.1"],
|
||||||
|
ad_mins_s: "min speed",
|
||||||
|
ad_mins_l: ["minimum speed","for short segments"],
|
||||||
|
ad_spol_s: "short path",
|
||||||
|
ad_spol_l: ["polygons shorter than this","will have their print speed","scaled down to min speed","in millimeters"],
|
||||||
|
ad_arct_s: "arc tolerance",
|
||||||
|
ad_arct_l: ["convert faceted lines to arcs","center point drift tolerance","when matching arc points","consider values around 0.15","in millimeters","0 to disable"],
|
||||||
|
ad_zhop_s: "z hop dist",
|
||||||
|
ad_zhop_l: ["amount to raise z","on retraction moves","in millimeters","0 to disable"],
|
||||||
|
ad_abkl_s: "anti-backlash",
|
||||||
|
ad_abkl_l: ["for better flat surface finish","use micro-movements to cancel","backlash in solid layer output","in millimeters","0 to disable","if your firmware has M425","put that in the gcode header","and leave this as 0"],
|
||||||
|
ad_lret_s: "layer retract",
|
||||||
|
ad_lret_l: ["force filament retraction","between layers"],
|
||||||
|
ad_play_s: "polish layers",
|
||||||
|
ad_play_l: ["polish up to specified","# of layers at a time"],
|
||||||
|
ad_pspd_s: "polish speed",
|
||||||
|
ad_pspd_l: ["polishing speed","in millimeters / minute"],
|
||||||
|
|
||||||
|
// CAM EXPERT
|
||||||
|
cx_fast_s: "skip shadow",
|
||||||
|
cx_fast_l: ["disable overhang detection","can be faster and use less","memory with complex models","but fails with overhangs","try enabling if slicing","hangs during shadowing"],
|
||||||
|
|
||||||
|
// FDM GCODE
|
||||||
|
ag_menu: "gcode",
|
||||||
|
ag_nozl_s: "nozzle",
|
||||||
|
ag_nozl_l: "select output nozzle or head",
|
||||||
|
ag_paws_s: "pause layers",
|
||||||
|
ag_paws_l: ["comma-separated list of layers","to inject pause commands before"],
|
||||||
|
ag_loop_s: "loop layers",
|
||||||
|
ag_loop_l: ["layer ranges to repeat in the format","first-last-count,first-last-count,...","omitted count = 1"],
|
||||||
|
|
||||||
|
// SLA MENU
|
||||||
|
sa_menu: "slicing",
|
||||||
|
sa_lahe_s: "layer height",
|
||||||
|
sa_lahe_l: ["layer height","in millimeters"],
|
||||||
|
sa_shel_s: "hollow shell",
|
||||||
|
sa_shel_l: ["shell thickness in mm","use multiple of layer height","use 0 for solid (disabled)"],
|
||||||
|
sa_otop_s: "open top",
|
||||||
|
sa_otop_l: ["if shell is enabled","results in an open top"],
|
||||||
|
sa_obas_s: "open base",
|
||||||
|
sa_obas_l: ["if shell is enabled","results in an open base","disabled with supports"],
|
||||||
|
|
||||||
|
sa_layr_m: "layers",
|
||||||
|
sa_lton_s: "light on time",
|
||||||
|
sa_lton_l: ["layer light on","time in seconds"],
|
||||||
|
sa_ltof_s: "light off time",
|
||||||
|
sa_ltof_l: ["layer light off","time in seconds"],
|
||||||
|
sa_pldi_s: "peel distance",
|
||||||
|
sa_pldi_l: ["peel distance","in millimeters"],
|
||||||
|
sa_pllr_s: "peel lift rate",
|
||||||
|
sa_pllr_l: ["peel lift speed","in mm/sec"],
|
||||||
|
sa_pldr_s: "peel drop rate",
|
||||||
|
sa_pldr_l: ["peel drop speed","in mm/sec"],
|
||||||
|
|
||||||
|
sa_base_m: "base",
|
||||||
|
sa_balc_s: "layer count",
|
||||||
|
sa_balc_l: ["number of","base layers"],
|
||||||
|
sa_bltn_l: ["base layer light on","time in seconds"],
|
||||||
|
sa_bltf_l: ["base layer light off","time in seconds"],
|
||||||
|
|
||||||
|
sa_infl_m: "infill",
|
||||||
|
sa_ifdn_s: "density",
|
||||||
|
sa_ifdn_l: ["percent infill","requires shell","0 = disabled","valid 0.0 - 1.0"],
|
||||||
|
sa_iflw_s: "line width",
|
||||||
|
sa_iflw_l: ["hatch line width","in millimeters"],
|
||||||
|
|
||||||
|
sa_supp_m: "support",
|
||||||
|
sa_slyr_s: "base layers",
|
||||||
|
sa_slyr_l: ["base support layers","value range 0-10"],
|
||||||
|
sa_slgp_s: "gap layers",
|
||||||
|
sa_slgp_l: ["number of layers between","raft and bottom of object"],
|
||||||
|
sa_sldn_s: "density",
|
||||||
|
sa_sldn_l: ["used to compute the","number of support pillars","0.0-1.0 (0 = disable)"],
|
||||||
|
sa_slsz_s: "size",
|
||||||
|
sa_slsz_l: ["max size of a","support pillar","in millimeters"],
|
||||||
|
sa_slpt_s: "points",
|
||||||
|
sa_slpt_l: ["number of points in","each support pillar","in millimeters"],
|
||||||
|
sl_slen_l: "enable supports",
|
||||||
|
|
||||||
|
sa_outp_m: "output",
|
||||||
|
sa_opzo_s: "przesunięcie osi Z",
|
||||||
|
sa_opzo_l: ["z layer offset","almost always 0.0","0.0-1.0 in millimeters"],
|
||||||
|
sa_opaa_s: "antyaliasing",
|
||||||
|
sa_opaa_l: ["włączenie tej opcji","tworzy większe pliki","ale pokazuje przejścia tonalne"]
|
||||||
|
};
|
||||||
1
web/kiri/lang/pl.js
Symbolic link
1
web/kiri/lang/pl.js
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
pl-pl.js
|
||||||
Loading…
Reference in a new issue