pool and engine now use dependency injection
This commit is contained in:
parent
195ad046b9
commit
9a149d720c
8 changed files with 258 additions and 287 deletions
71
app.js
71
app.js
|
|
@ -205,6 +205,7 @@ function init(mod) {
|
||||||
// val.splice(1, 0, ...roots);
|
// val.splice(1, 0, ...roots);
|
||||||
if (xxxx) console.log({key, cache, refs, paths, roots, val});
|
if (xxxx) console.log({key, cache, refs, paths, roots, val});
|
||||||
script[key] = val.map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p);
|
script[key] = val.map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p);
|
||||||
|
// console.log({script: key, files: script[key]});
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.on.test((req) => {
|
mod.on.test((req) => {
|
||||||
|
|
@ -332,13 +333,7 @@ function initModule(mod, file, dir) {
|
||||||
return logger.log(`inject missing target "${code}"`);
|
return logger.log(`inject missing target "${code}"`);
|
||||||
}
|
}
|
||||||
const path = `${dir}/${file}`;
|
const path = `${dir}/${file}`;
|
||||||
if (opt.end) {
|
codelist.push(path);
|
||||||
codelist.push(path);
|
|
||||||
} else {
|
|
||||||
codelist.push(path);
|
|
||||||
// let io = Math.max(0, codelist.indexOf('@inject'));
|
|
||||||
// codelist.splice(io, 0, path);
|
|
||||||
}
|
|
||||||
if (opt.cachever) {
|
if (opt.cachever) {
|
||||||
cachever[path] = opt.cachever;
|
cachever[path] = opt.cachever;
|
||||||
}
|
}
|
||||||
|
|
@ -388,7 +383,6 @@ function initModule(mod, file, dir) {
|
||||||
|
|
||||||
const script = {
|
const script = {
|
||||||
kiri : [
|
kiri : [
|
||||||
"@inject",
|
|
||||||
"@devices",
|
"@devices",
|
||||||
"@icons",
|
"@icons",
|
||||||
"kiri/ui",
|
"kiri/ui",
|
||||||
|
|
@ -396,74 +390,21 @@ const script = {
|
||||||
"&kiri/lang-en"
|
"&kiri/lang-en"
|
||||||
],
|
],
|
||||||
kiri_work : [
|
kiri_work : [
|
||||||
"@inject",
|
|
||||||
"kiri-run/worker",
|
"kiri-run/worker",
|
||||||
"&main/kiri",
|
"&main/kiri",
|
||||||
],
|
],
|
||||||
kiri_pool : [
|
kiri_pool : [
|
||||||
"moto/license",
|
"&kiri-run/minion",
|
||||||
"@inject",
|
"&main/kiri",
|
||||||
"ext/clip2",
|
|
||||||
"ext/earcut",
|
|
||||||
"add/array",
|
|
||||||
"add/class",
|
|
||||||
"geo/base",
|
|
||||||
"geo/wasm",
|
|
||||||
"geo/point",
|
|
||||||
"geo/points",
|
|
||||||
"geo/slope",
|
|
||||||
"geo/line",
|
|
||||||
"geo/bounds",
|
|
||||||
"geo/polygons",
|
|
||||||
"geo/polygon",
|
|
||||||
"geo/gyroid",
|
|
||||||
"geo/slicer",
|
|
||||||
"kiri/consts",
|
|
||||||
"kiri-mode/fdm/driver",
|
|
||||||
"kiri-mode/fdm/slice",
|
|
||||||
"kiri/utils",
|
|
||||||
"kiri/slice",
|
|
||||||
"kiri/layers",
|
|
||||||
"kiri/widget",
|
|
||||||
"kiri/codec",
|
|
||||||
"kiri-run/minion",
|
|
||||||
"main/kiri",
|
|
||||||
],
|
],
|
||||||
engine : [
|
engine : [
|
||||||
"moto/license",
|
"&kiri-run/engine",
|
||||||
"@inject",
|
"&main/kiri",
|
||||||
"ext/clip2",
|
|
||||||
"data/local",
|
|
||||||
"ext/three",
|
|
||||||
"add/array",
|
|
||||||
"add/three",
|
|
||||||
"geo/base",
|
|
||||||
"geo/point",
|
|
||||||
"geo/points",
|
|
||||||
"geo/paths",
|
|
||||||
"geo/slope",
|
|
||||||
"geo/line",
|
|
||||||
"geo/bounds",
|
|
||||||
"geo/polygon",
|
|
||||||
"geo/polygons",
|
|
||||||
"moto/broker",
|
|
||||||
"load/obj",
|
|
||||||
"load/stl",
|
|
||||||
"kiri/conf",
|
|
||||||
"kiri/utils",
|
|
||||||
"kiri/client",
|
|
||||||
"kiri/slice",
|
|
||||||
"kiri/layers",
|
|
||||||
"kiri/widget",
|
|
||||||
"kiri/codec",
|
|
||||||
"kiri-run/engine",
|
|
||||||
"main/kiri",
|
|
||||||
],
|
],
|
||||||
frame : [
|
frame : [
|
||||||
"kiri-run/frame"
|
"kiri-run/frame"
|
||||||
],
|
],
|
||||||
meta : [
|
meta : [
|
||||||
"moto/license",
|
|
||||||
"main/meta",
|
"main/meta",
|
||||||
],
|
],
|
||||||
mesh : [
|
mesh : [
|
||||||
|
|
|
||||||
213
src/kiri-mode/fdm/post.js
Normal file
213
src/kiri-mode/fdm/post.js
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// dep: geo.base
|
||||||
|
// dep: geo.polygons
|
||||||
|
// dep: kiri-mode.fdm.driver
|
||||||
|
gapp.register("kiri-mode.fdm.post", [], (root, exports) => {
|
||||||
|
|
||||||
|
const { base, kiri } = root;
|
||||||
|
const { driver } = kiri;
|
||||||
|
const { polygons } = base;
|
||||||
|
const { fillArea } = polygons;
|
||||||
|
const { FDM } = driver;
|
||||||
|
|
||||||
|
const POLY = polygons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* may run in minion or worker context. do not create objects
|
||||||
|
* that will not quickly encode in threaded mode. add to existing
|
||||||
|
* data object. return is ignored.
|
||||||
|
*/
|
||||||
|
base.slicePost.FDM = function(data, options) {
|
||||||
|
const { z, lines, groups } = data;
|
||||||
|
const { useAssembly, post_args, zIndexes } = options;
|
||||||
|
const { process, isSynth, isDanger, vaseMode } = post_args;
|
||||||
|
const { shellOffset, fillOffset, clipOffset } = post_args;
|
||||||
|
data.tops = POLY.nest(groups);
|
||||||
|
if (isSynth) {
|
||||||
|
// do not shell synth widgets because
|
||||||
|
// they will be clipped against peers later
|
||||||
|
// which requires shelling post-clip
|
||||||
|
// but we still need to generate tops
|
||||||
|
delete data.groups;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const index = zIndexes.indexOf(z);
|
||||||
|
const range = FDM.getRangeParameters(process, index);
|
||||||
|
// calculate fractional shells
|
||||||
|
let shellFrac = (range.sliceShells - (range.sliceShells | 0));
|
||||||
|
let sliceShells = range.sliceShells | 0;
|
||||||
|
if (shellFrac) {
|
||||||
|
let v1 = shellFrac > 0.5 ? 1 - shellFrac : shellFrac;
|
||||||
|
let v2 = 1 - v1;
|
||||||
|
let parts = Math.round(v2/v1) + 1;
|
||||||
|
let rem = index % parts;
|
||||||
|
let trg = shellFrac > 0.5 ? 1 : parts - 1;
|
||||||
|
sliceShells += rem >= trg ? 1 : 0;
|
||||||
|
}
|
||||||
|
const isFirst = index === 0;
|
||||||
|
const height = process.sliceHeight;
|
||||||
|
const spaceMult = isFirst ? process.firstLayerLineMult || 1 : 1;
|
||||||
|
const count = isSynth ? 1 : sliceShells;
|
||||||
|
const offset = shellOffset * spaceMult;
|
||||||
|
const fillOff = fillOffset * spaceMult;
|
||||||
|
const nutops = [];
|
||||||
|
// co-locate shell processing with top generation in slicer
|
||||||
|
for (let top of data.tops) {
|
||||||
|
nutops.push(FDM.doTopShells(z, top, count, offset/2, offset, fillOff, {
|
||||||
|
vase: vaseMode,
|
||||||
|
thin: process.detectThinWalls && !isSynth,
|
||||||
|
wasm: useAssembly,
|
||||||
|
danger: isDanger
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
data.clip = clipOffset ? POLY.offset(nutops.map(t => t.simple), clipOffset) : undefined;
|
||||||
|
data.tops = nutops;
|
||||||
|
delete data.groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* may run in minion or worker context. performes shell offsetting
|
||||||
|
* including thin wall detection when enabled
|
||||||
|
*/
|
||||||
|
FDM.doTopShells = function(z, top, count, offset1, offsetN, fillOffset, opt = {}) {
|
||||||
|
// pretend we're a top object in minions
|
||||||
|
if (!top.poly) {
|
||||||
|
top = { poly: top };
|
||||||
|
}
|
||||||
|
|
||||||
|
// add simple (low rez poly) where less accuracy is OK
|
||||||
|
top.simple = top.poly.simple();
|
||||||
|
|
||||||
|
let wasm = opt.wasm;
|
||||||
|
let top_poly = [ top.poly ];
|
||||||
|
|
||||||
|
if (opt.vase) {
|
||||||
|
// remove top poly inners in vase mode
|
||||||
|
top.poly = top.poly.clone(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
top.shells = [];
|
||||||
|
top.fill_off = [];
|
||||||
|
top.fill_lines = [];
|
||||||
|
|
||||||
|
let last = [],
|
||||||
|
gaps = [];
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
// permit offset of 0 for laser and drag knife
|
||||||
|
if (offset1 === 0 && count === 1) {
|
||||||
|
last = top_poly.clone(true);
|
||||||
|
top.shells = last;
|
||||||
|
} else {
|
||||||
|
// heal top open polygons if the ends are close (benchy tilt test)
|
||||||
|
top_poly.forEach(p => { if (p.open) {
|
||||||
|
let dist = p.first().distTo2D(p.last());
|
||||||
|
if (dist < 1) p.open = false;
|
||||||
|
} });
|
||||||
|
if (opt.danger && opt.thin) {
|
||||||
|
top.thin_fill = [];
|
||||||
|
top.fill_sparse = [];
|
||||||
|
let layers = POLY.inset(top_poly, offsetN, count, z, true);
|
||||||
|
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 = [];
|
||||||
|
let oso = {z, count, gaps: [], outs: [], minArea: 0.05, wasm};
|
||||||
|
POLY.offset(top_poly, [-offset1, -offsetN], oso);
|
||||||
|
|
||||||
|
oso.outs.forEach((polys, i) => {
|
||||||
|
polys.forEach(p => {
|
||||||
|
p.depth = i;
|
||||||
|
if (p.fill_off) {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
last = polys;
|
||||||
|
});
|
||||||
|
|
||||||
|
// slice.solids.trimmed = slice.solids.trimmed || [];
|
||||||
|
oso.gaps.forEach((polys, i) => {
|
||||||
|
let off = (i == 0 ? offset1 : offsetN);
|
||||||
|
polys = POLY.offset(polys, -off * 0.8, {z, minArea: 0, wasm});
|
||||||
|
top.thin_fill.appendAll(cullIntersections(
|
||||||
|
fillArea(polys, 45, off/2, [], 0.01, off*2),
|
||||||
|
fillArea(polys, 135, off/2, [], 0.01, off*2),
|
||||||
|
));
|
||||||
|
gaps = polys;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// standard wall offsetting strategy
|
||||||
|
POLY.offset(
|
||||||
|
top_poly,
|
||||||
|
[-offset1, -offsetN],
|
||||||
|
{
|
||||||
|
z,
|
||||||
|
wasm,
|
||||||
|
count,
|
||||||
|
outs: top.shells,
|
||||||
|
flat: true,
|
||||||
|
call: (polys, onCount) => {
|
||||||
|
last = polys;
|
||||||
|
// mark each poly with depth (offset #) starting at 0
|
||||||
|
for (let p of polys) {
|
||||||
|
p.depth = count - onCount;
|
||||||
|
if (p.fill_off) p.fill_off.forEach(function(pi) {
|
||||||
|
// use negative offset for inners
|
||||||
|
pi.depth = -(count - onCount);
|
||||||
|
});
|
||||||
|
// mark inner depth to match parent
|
||||||
|
if (p.inner) {
|
||||||
|
for (let pi of p.inner) {
|
||||||
|
pi.depth = p.depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no shells, just infill, is permitted
|
||||||
|
last = [top.poly];
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate fill offset poly set from last offset to top.fill_off
|
||||||
|
if (fillOffset && last.length > 0) {
|
||||||
|
// if gaps present, remove that area from fill inset
|
||||||
|
if (gaps.length) {
|
||||||
|
let nulast = [];
|
||||||
|
POLY.subtract(last, gaps, nulast, null, z);
|
||||||
|
last = nulast;
|
||||||
|
}
|
||||||
|
last.forEach(function(inner) {
|
||||||
|
POLY.offset([inner], -fillOffset, {outs: top.fill_off, flat: true, z});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// for diffing
|
||||||
|
top.last = last;
|
||||||
|
// top.last_simple = last.map(p => p.clean(true, undefined, config.clipper / 10));
|
||||||
|
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
// dep: kiri.utils
|
// dep: kiri.utils
|
||||||
// dep: kiri.consts
|
// dep: kiri.consts
|
||||||
// dep: kiri-mode.fdm.driver
|
// dep: kiri-mode.fdm.driver
|
||||||
|
// dep: kiri-mode.fdm.post
|
||||||
// use: kiri-mode.fdm.fill
|
// use: kiri-mode.fdm.fill
|
||||||
// use: ext.clip2
|
// use: ext.clip2
|
||||||
// use: add.three
|
// use: add.three
|
||||||
|
|
@ -19,7 +20,7 @@ const { config, polygons, util, newPoint } = base;
|
||||||
const { fillArea } = polygons;
|
const { fillArea } = polygons;
|
||||||
const { beltfact } = consts;
|
const { beltfact } = consts;
|
||||||
const { FDM } = driver;
|
const { FDM } = driver;
|
||||||
const { getRangeParameters } = FDM;
|
const { doTopShells, getRangeParameters } = FDM;
|
||||||
|
|
||||||
const POLY = polygons,
|
const POLY = polygons,
|
||||||
tracker = util.pwait,
|
tracker = util.pwait,
|
||||||
|
|
@ -55,59 +56,6 @@ function vopt(opt) {
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* may run in minion or worker context. do not create objects
|
|
||||||
* that will not quickly encode in threaded mode. add to existing
|
|
||||||
* data object. return is ignored.
|
|
||||||
*/
|
|
||||||
base.slicePost.FDM = function(data, options) {
|
|
||||||
const { z, lines, groups } = data;
|
|
||||||
const { useAssembly, post_args, zIndexes } = options;
|
|
||||||
const { process, isSynth, isDanger, vaseMode } = post_args;
|
|
||||||
const { shellOffset, fillOffset, clipOffset } = post_args;
|
|
||||||
data.tops = POLY.nest(groups);
|
|
||||||
if (isSynth) {
|
|
||||||
// do not shell synth widgets because
|
|
||||||
// they will be clipped against peers later
|
|
||||||
// which requires shelling post-clip
|
|
||||||
// but we still need to generate tops
|
|
||||||
delete data.groups;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const index = zIndexes.indexOf(z);
|
|
||||||
const range = getRangeParameters(process, index);
|
|
||||||
// calculate fractional shells
|
|
||||||
let shellFrac = (range.sliceShells - (range.sliceShells | 0));
|
|
||||||
let sliceShells = range.sliceShells | 0;
|
|
||||||
if (shellFrac) {
|
|
||||||
let v1 = shellFrac > 0.5 ? 1 - shellFrac : shellFrac;
|
|
||||||
let v2 = 1 - v1;
|
|
||||||
let parts = Math.round(v2/v1) + 1;
|
|
||||||
let rem = index % parts;
|
|
||||||
let trg = shellFrac > 0.5 ? 1 : parts - 1;
|
|
||||||
sliceShells += rem >= trg ? 1 : 0;
|
|
||||||
}
|
|
||||||
const isFirst = index === 0;
|
|
||||||
const height = process.sliceHeight;
|
|
||||||
const spaceMult = isFirst ? process.firstLayerLineMult || 1 : 1;
|
|
||||||
const count = isSynth ? 1 : sliceShells;
|
|
||||||
const offset = shellOffset * spaceMult;
|
|
||||||
const fillOff = fillOffset * spaceMult;
|
|
||||||
const nutops = [];
|
|
||||||
// co-locate shell processing with top generation in slicer
|
|
||||||
for (let top of data.tops) {
|
|
||||||
nutops.push(FDM.share.doTopShells(z, top, count, offset/2, offset, fillOff, {
|
|
||||||
vase: vaseMode,
|
|
||||||
thin: process.detectThinWalls && !isSynth,
|
|
||||||
wasm: useAssembly,
|
|
||||||
danger: isDanger
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
data.clip = clipOffset ? POLY.offset(nutops.map(t => t.simple), clipOffset) : undefined;
|
|
||||||
data.tops = nutops;
|
|
||||||
delete data.groups;
|
|
||||||
};
|
|
||||||
|
|
||||||
FDM.sliceAll = function(settings, onupdate) {
|
FDM.sliceAll = function(settings, onupdate) {
|
||||||
// future home of brim and anchor generation
|
// future home of brim and anchor generation
|
||||||
let widgets = Object.values(kiri.worker.cache)
|
let widgets = Object.values(kiri.worker.cache)
|
||||||
|
|
@ -913,144 +861,6 @@ function doShells(slice, count, offset1, offsetN, fillOffset, opt = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {}) {
|
|
||||||
// pretend we're a top object in minions
|
|
||||||
if (!top.poly) {
|
|
||||||
top = { poly: top };
|
|
||||||
}
|
|
||||||
|
|
||||||
// add simple (low rez poly) where less accuracy is OK
|
|
||||||
top.simple = top.poly.simple();
|
|
||||||
|
|
||||||
let wasm = opt.wasm;
|
|
||||||
let top_poly = [ top.poly ];
|
|
||||||
|
|
||||||
if (opt.vase) {
|
|
||||||
// remove top poly inners in vase mode
|
|
||||||
top.poly = top.poly.clone(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
top.shells = [];
|
|
||||||
top.fill_off = [];
|
|
||||||
top.fill_lines = [];
|
|
||||||
|
|
||||||
let last = [],
|
|
||||||
gaps = [];
|
|
||||||
|
|
||||||
if (count) {
|
|
||||||
// permit offset of 0 for laser and drag knife
|
|
||||||
if (offset1 === 0 && count === 1) {
|
|
||||||
last = top_poly.clone(true);
|
|
||||||
top.shells = last;
|
|
||||||
} else {
|
|
||||||
// heal top open polygons if the ends are close (benchy tilt test)
|
|
||||||
top_poly.forEach(p => { if (p.open) {
|
|
||||||
let dist = p.first().distTo2D(p.last());
|
|
||||||
if (dist < 1) p.open = false;
|
|
||||||
} });
|
|
||||||
if (opt.danger && opt.thin) {
|
|
||||||
top.thin_fill = [];
|
|
||||||
top.fill_sparse = [];
|
|
||||||
let layers = POLY.inset(top_poly, offsetN, count, z, true);
|
|
||||||
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 = [];
|
|
||||||
let oso = {z, count, gaps: [], outs: [], minArea: 0.05, wasm};
|
|
||||||
POLY.offset(top_poly, [-offset1, -offsetN], oso);
|
|
||||||
|
|
||||||
oso.outs.forEach((polys, i) => {
|
|
||||||
polys.forEach(p => {
|
|
||||||
p.depth = i;
|
|
||||||
if (p.fill_off) {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
last = polys;
|
|
||||||
});
|
|
||||||
|
|
||||||
// slice.solids.trimmed = slice.solids.trimmed || [];
|
|
||||||
oso.gaps.forEach((polys, i) => {
|
|
||||||
let off = (i == 0 ? offset1 : offsetN);
|
|
||||||
polys = POLY.offset(polys, -off * 0.8, {z, minArea: 0, wasm});
|
|
||||||
top.thin_fill.appendAll(cullIntersections(
|
|
||||||
fillArea(polys, 45, off/2, [], 0.01, off*2),
|
|
||||||
fillArea(polys, 135, off/2, [], 0.01, off*2),
|
|
||||||
));
|
|
||||||
gaps = polys;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// standard wall offsetting strategy
|
|
||||||
POLY.offset(
|
|
||||||
top_poly,
|
|
||||||
[-offset1, -offsetN],
|
|
||||||
{
|
|
||||||
z,
|
|
||||||
wasm,
|
|
||||||
count,
|
|
||||||
outs: top.shells,
|
|
||||||
flat: true,
|
|
||||||
call: (polys, onCount) => {
|
|
||||||
last = polys;
|
|
||||||
// mark each poly with depth (offset #) starting at 0
|
|
||||||
for (let p of polys) {
|
|
||||||
p.depth = count - onCount;
|
|
||||||
if (p.fill_off) p.fill_off.forEach(function(pi) {
|
|
||||||
// use negative offset for inners
|
|
||||||
pi.depth = -(count - onCount);
|
|
||||||
});
|
|
||||||
// mark inner depth to match parent
|
|
||||||
if (p.inner) {
|
|
||||||
for (let pi of p.inner) {
|
|
||||||
pi.depth = p.depth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no shells, just infill, is permitted
|
|
||||||
last = [top.poly];
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate fill offset poly set from last offset to top.fill_off
|
|
||||||
if (fillOffset && last.length > 0) {
|
|
||||||
// if gaps present, remove that area from fill inset
|
|
||||||
if (gaps.length) {
|
|
||||||
let nulast = [];
|
|
||||||
POLY.subtract(last, gaps, nulast, null, z);
|
|
||||||
last = nulast;
|
|
||||||
}
|
|
||||||
last.forEach(function(inner) {
|
|
||||||
POLY.offset([inner], -fillOffset, {outs: top.fill_off, flat: true, z});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// for diffing
|
|
||||||
top.last = last;
|
|
||||||
// top.last_simple = last.map(p => p.clean(true, undefined, config.clipper / 10));
|
|
||||||
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an entirely solid layer by filling all top polygons
|
* Create an entirely solid layer by filling all top polygons
|
||||||
* with an alternating pattern.
|
* with an alternating pattern.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// dep: moto.license
|
||||||
|
// dep: load.stl
|
||||||
|
// dep: kiri.conf
|
||||||
|
// dep: kiri.client
|
||||||
|
// dep: kiri.widget
|
||||||
|
// use: add.three
|
||||||
gapp.register("kiri-run.engine", [], (root, exports) => {
|
gapp.register("kiri-run.engine", [], (root, exports) => {
|
||||||
|
|
||||||
const { kiri } = root;
|
const { kiri } = root;
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,26 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// dep: moto.license
|
// dep: moto.license
|
||||||
|
// dep: geo.base
|
||||||
|
// dep: geo.polygons
|
||||||
|
// dep: geo.slicer
|
||||||
|
// dep: geo.wasm
|
||||||
|
// dep: kiri.codec
|
||||||
|
// dep: kiri-mode.fdm.post
|
||||||
|
// dep: ext.clip2
|
||||||
gapp.register("kiri-run.minion", [], (root, exports) => {
|
gapp.register("kiri-run.minion", [], (root, exports) => {
|
||||||
|
|
||||||
let BASE = self.base,
|
const { base, kiri } = root;
|
||||||
KIRI = self.kiri,
|
const { polygons } = base;
|
||||||
UTIL = BASE.util,
|
const { codec } = kiri;
|
||||||
POLY = BASE.polygons,
|
|
||||||
CODEC = KIRI.codec,
|
const POLY = polygons;
|
||||||
clib = self.ClipperLib,
|
const clib = self.ClipperLib;
|
||||||
ctyp = clib.ClipType,
|
const ctyp = clib.ClipType;
|
||||||
ptyp = clib.PolyType,
|
const ptyp = clib.PolyType;
|
||||||
cfil = clib.PolyFillType,
|
const cfil = clib.PolyFillType;
|
||||||
name = "unknown";
|
|
||||||
|
let name = "unknown";
|
||||||
|
|
||||||
// catch clipper alerts and convert to console messages
|
// catch clipper alerts and convert to console messages
|
||||||
self.alert = function(o) {
|
self.alert = function(o) {
|
||||||
|
|
@ -42,7 +50,7 @@ const funcs = {
|
||||||
|
|
||||||
config: data => {
|
config: data => {
|
||||||
if (data.base) {
|
if (data.base) {
|
||||||
Object.assign(BASE.config, data.base);
|
Object.assign(base.config, data.base);
|
||||||
} else {
|
} else {
|
||||||
log({invalid: data});
|
log({invalid: data});
|
||||||
}
|
}
|
||||||
|
|
@ -50,23 +58,23 @@ const funcs = {
|
||||||
|
|
||||||
union: (data, seq) => {
|
union: (data, seq) => {
|
||||||
if (!(data.polys && data.polys.length)) {
|
if (!(data.polys && data.polys.length)) {
|
||||||
reply({ seq, union: CODEC.encode([]) });
|
reply({ seq, union: codec.encode([]) });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let polys = CODEC.decode(data.polys);
|
let polys = codec.decode(data.polys);
|
||||||
let union = POLY.union(polys, data.minarea || 0, true);
|
let union = POLY.union(polys, data.minarea || 0, true);
|
||||||
reply({ seq, union: CODEC.encode(union) });
|
reply({ seq, union: codec.encode(union) });
|
||||||
},
|
},
|
||||||
|
|
||||||
topShells: (data, seq) => {
|
topShells: (data, seq) => {
|
||||||
let top = CODEC.decode(data.top, {full: true});
|
let top = codec.decode(data.top, {full: true});
|
||||||
let {z, count, offset1, offsetN, fillOffset, opt} = data;
|
let {z, count, offset1, offsetN, fillOffset, opt} = data;
|
||||||
KIRI.driver.FDM.share.doTopShells(z, top, count, offset1, offsetN, fillOffset, opt);
|
kiri.driver.FDM.doTopShells(z, top, count, offset1, offsetN, fillOffset, opt);
|
||||||
reply({ seq, top: CODEC.encode(top, {full: true}) });
|
reply({ seq, top: codec.encode(top, {full: true}) });
|
||||||
},
|
},
|
||||||
|
|
||||||
fill: (data, seq) => {
|
fill: (data, seq) => {
|
||||||
let polys = CODEC.decode(data.polys);
|
let polys = codec.decode(data.polys);
|
||||||
let { angle, spacing, minLen, maxLen } = data;
|
let { angle, spacing, minLen, maxLen } = data;
|
||||||
let fill = POLY.fillArea(polys, angle, spacing, [], minLen, maxLen);
|
let fill = POLY.fillArea(polys, angle, spacing, [], minLen, maxLen);
|
||||||
let arr = new Float32Array(fill.length * 4);
|
let arr = new Float32Array(fill.length * 4);
|
||||||
|
|
@ -90,7 +98,7 @@ const funcs = {
|
||||||
|
|
||||||
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) {
|
if (clip.Execute(ctyp.ctIntersection, ctre, cfil.pftNonZero, cfil.pftEvenOdd)) {
|
||||||
for (let node of ctre.m_AllPolys) {
|
for (let node of ctre.m_AllPolys) {
|
||||||
clips.push(CODEC.encode(POLY.fromClipperNode(node, data.z)));
|
clips.push(codec.encode(POLY.fromClipperNode(node, data.z)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,10 +109,10 @@ const funcs = {
|
||||||
let { z, points, options } = data;
|
let { z, points, options } = data;
|
||||||
let i = 0, p = 0, realp = new Array(points.length / 3);
|
let i = 0, p = 0, realp = new Array(points.length / 3);
|
||||||
while (i < points.length) {
|
while (i < points.length) {
|
||||||
realp[p++] = BASE.newPoint(points[i++], points[i++], points[i++]).round(3);
|
realp[p++] = base.newPoint(points[i++], points[i++], points[i++]).round(3);
|
||||||
}
|
}
|
||||||
let output = [];
|
let output = [];
|
||||||
BASE.sliceZ(z, realp, {
|
base.sliceZ(z, realp, {
|
||||||
...options,
|
...options,
|
||||||
each(out) { output.push(out) }
|
each(out) { output.push(out) }
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|
@ -112,7 +120,7 @@ const funcs = {
|
||||||
// lines do not pass codec properly (for now)
|
// lines do not pass codec properly (for now)
|
||||||
delete rec.lines;
|
delete rec.lines;
|
||||||
}
|
}
|
||||||
reply({ seq, output: CODEC.encode(output) });
|
reply({ seq, output: codec.encode(output) });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,14 @@
|
||||||
// dep: kiri.codec
|
// dep: kiri.codec
|
||||||
// dep: kiri.slice
|
// dep: kiri.slice
|
||||||
// dep: moto.license
|
// dep: moto.license
|
||||||
// use: kiri-mode.cam.driver
|
|
||||||
// use: kiri-mode.cam.animate
|
// use: kiri-mode.cam.animate
|
||||||
// use: kiri-mode.cam.slice
|
// use: kiri-mode.cam.slice
|
||||||
// use: kiri-mode.cam.prepare
|
// use: kiri-mode.cam.prepare
|
||||||
// use: kiri-mode.cam.export
|
// use: kiri-mode.cam.export
|
||||||
// use: kiri-mode.cam.tool
|
// use: kiri-mode.cam.tool
|
||||||
// use: kiri-mode.fdm.driver
|
|
||||||
// use: kiri-mode.fdm.slice
|
// use: kiri-mode.fdm.slice
|
||||||
// use: kiri-mode.fdm.prepare
|
// use: kiri-mode.fdm.prepare
|
||||||
// use: kiri-mode.fdm.export
|
// use: kiri-mode.fdm.export
|
||||||
// use: kiri-mode.sla.driver
|
|
||||||
// use: kiri-mode.sla.slice
|
// use: kiri-mode.sla.slice
|
||||||
// use: kiri-mode.sla.export
|
// use: kiri-mode.sla.export
|
||||||
// use: kiri-mode.fdm.slice
|
// use: kiri-mode.fdm.slice
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
// dep: data.local
|
// dep: data.local
|
||||||
// dep: kiri.utils
|
// dep: kiri.utils
|
||||||
// dep: kiri.consts
|
// dep: kiri.consts
|
||||||
// use: kiri.client
|
|
||||||
// use: kiri.settings
|
|
||||||
gapp.register("kiri.api", [], (root, exports) => {
|
gapp.register("kiri.api", [], (root, exports) => {
|
||||||
|
|
||||||
const { data, kiri, noop } = root;
|
const { data, kiri, noop } = root;
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,11 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// dep: kiri.api
|
// dep: kiri.api
|
||||||
|
// dep: kiri.client
|
||||||
// dep: kiri.export
|
// dep: kiri.export
|
||||||
// dep: moto.space
|
// dep: moto.space
|
||||||
// dep: kiri-mode.cam.driver
|
|
||||||
// use: kiri-mode.cam.client
|
// use: kiri-mode.cam.client
|
||||||
// dep: kiri-mode.fdm.driver
|
|
||||||
// dep: kiri-mode.fdm.client
|
// dep: kiri-mode.fdm.client
|
||||||
// dep: kiri-mode.sla.driver
|
|
||||||
// dep: kiri-mode.sla.client
|
// dep: kiri-mode.sla.client
|
||||||
// dep: kiri-mode.laser.driver
|
// dep: kiri-mode.laser.driver
|
||||||
gapp.register("kiri.function", [], (root, exports) => {
|
gapp.register("kiri.function", [], (root, exports) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue