move src2 -> src, web2 -> web, remove old module system, fix deps

This commit is contained in:
Stewart Allen 2025-07-06 23:44:33 -04:00
commit ce4f5d6e78
488 changed files with 26179 additions and 26609 deletions

View file

@ -1,25 +1,20 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { $ } from '../../moto/webui.js';
import { api } from '../../kiri/api.js';
import { conf } from '../../kiri/conf.js';
import { util } from '../../geo/base.js';
import { client } from '../../kiri/client.js';
import { addbox, delbox, getlastbox } from '../../kiri/boxes.js';
import { Layers } from '../../kiri/layers.js';
import { Stack } from '../../kiri/stack.js';
import { Widget, newWidget } from '../../kiri/widget.js';
import { space } from '../../moto/space.js';
// dep: add.three
// dep: geo.base
// dep: moto.space
// dep: kiri.api
// dep: kiri.lang
// dep: kiri.consts
// dep: kiri-mode.fdm.driver
gapp.register("kiri-mode.fdm.client", [], (root, exports) => {
const { Matrix4, Vector3, BufferAttribute, BufferGeometryUtils, Raycaster, Euler } = THREE;
const { VIEWS } = api.const;
const { Quaternion, Matrix4, Vector3, BufferAttribute, BufferGeometryUtils } = THREE;
const { Mesh, BoxGeometry, MeshPhongMaterial, Raycaster, Euler } = THREE;
const { base, kiri, moto } = root;
const { util } = base;
const { api, consts, lang } = kiri;
const { FDM } = kiri.driver;
const { VIEWS } = consts;
const { space } = moto;
const LANG = lang.current;
const LANG = api.language.current;
let lastBox, lastMode, lastView, lastPillar, fromPillar,
addingSupports = false,
@ -27,12 +22,11 @@ let lastBox, lastMode, lastView, lastPillar, fromPillar,
nextID = Date.now(),
p1, p2, iw,
alert = [],
boxes = {},
func = {};
FDM.init = function(kiri, api) {
const proc_keys = Object.keys(kiri.conf.defaults.fdm.p);
const { ui, uc } = api;
export function init() {
const { ui } = api;
const proc_keys = Object.keys(conf.defaults.fdm.p);
const rangeVars = {
// slice
// "sliceHeight": LANG.sl_lahi_s,
@ -92,8 +86,8 @@ FDM.init = function(kiri, api) {
function filterSynth() {
api.widgets.filter((widget) => {
if (widget.track.synth) {
kiri.space.world.remove(widget.mesh);
kiri.Widget.Groups.remove(widget);
space.world.remove(widget.mesh);
Widget.Groups.remove(widget);
}
return !widget.track.synth
});
@ -209,7 +203,7 @@ FDM.init = function(kiri, api) {
}
}
alerts.push(api.show.alert("analyzing part(s)...", 1000));
FDM.support_generate(array => {
support_generate(array => {
func.sclear();
api.hide.alert(undefined,alerts);
for (let rec of array) {
@ -266,7 +260,7 @@ FDM.init = function(kiri, api) {
updateSupportVisiblity();
// synth support widget for each widget group
// iow, create support meshes based on support widget annotation
for (let group of kiri.Widget.Groups.list()) {
for (let group of Widget.Groups.list()) {
let merge = group.filter(w => w.sups).map(w => Object.values(w.sups)).flat();
if (!merge.length) {
continue;
@ -281,14 +275,14 @@ FDM.init = function(kiri, api) {
box.setAttribute('uv',new BufferAttribute(new Float32Array(0), 3));
}
let bbg = BufferGeometryUtils.mergeGeometries(boxen);
let sw = kiri.newWidget(null, group);
let sw = 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;
sw.track.support = true;
kiri.space.world.add(sw.mesh);
space.world.add(sw.mesh);
}
});
@ -378,6 +372,7 @@ FDM.init = function(kiri, api) {
removeWidgetSupport(lastPillar.widget, lastPillar);
return;
}
lastBox = getlastbox();
if (!(iw && lastBox)) return;
let { point, dim } = lastBox;
p1.y = Math.max(0, p1.y);
@ -518,7 +513,7 @@ FDM.init = function(kiri, api) {
poly.addObj(rec);
}
let layers = new kiri.Layers();
let layers = new Layers();
let layer = layers.setLayer("arcq", { line: 0xff00ff, face: 0xff00ff, opacity: 1 });
layer.addPoly(poly, {thin:true});
@ -530,7 +525,7 @@ FDM.init = function(kiri, api) {
));
}
xpdebug = new kiri.Stack(space.world, false);
xpdebug = new Stack(space.world, false);
xpdebug.addLayers(layers);
xpdebug.setVisible(0,Infinity);
xpdebug.show();
@ -546,6 +541,23 @@ let xpdebug;
let supsave = {};
let suptimer;
function support_generate(ondone) {
client.clear();
client.sync();
const settings = api.conf.get();
const widgets = api.widgets.map();
client.send("fdm_support_generate", { settings }, (gen) => {
if (gen && gen.error) {
api.show.alert('support generation canceled');
return ondone([]);
}
for (let g of gen) {
g.widget = widgets[g.id];
}
ondone(gen);
});
};
function scheduleSupportSave(widget) {
clearTimeout(suptimer);
supsave[widget.id] = widget;
@ -556,7 +568,7 @@ function scheduleSupportSave(widget) {
}, 50);
}
function restoreSupports(widgets) {
export function restoreSupports(widgets) {
widgets.forEach(widget => {
const supports = api.widgets.annotate(widget.id).support || [];
supports.forEach(pos => {
@ -633,49 +645,3 @@ function clearWidgetSupports(widget) {
scheduleSupportSave(widget);
return cleared;
}
function delbox(name) {
const old = boxes[name];
if (old) {
old.groupTo.remove(old);
}
}
function addbox(point, color, name, dim = {x:1,y:1,z:1,rz:0}, opt = {}) {
delbox(name);
const box = boxes[name] = new Mesh(
new BoxGeometry(dim.x, dim.y, dim.z),
new MeshPhongMaterial({
transparent: true,
opacity: opt.opacity || 0.5,
color
})
);
box.position.x = point.x;
box.position.y = point.y;
box.position.z = point.z;
lastBox = {point, dim};
const group = opt.group || space.scene
group.add(box);
box.groupTo = group;
if (dim.rz) {
opt.rotate = new Quaternion().setFromAxisAngle(new Vector3(0,0,1), dim.rz);
}
if (opt.rotate) {
opt.matrix = new Matrix4().makeRotationFromQuaternion(opt.rotate);
}
if (opt.matrix) {
box.geometry.applyMatrix4(opt.matrix);
}
return box;
}
FDM.delbox = delbox;
FDM.addbox = addbox;
FDM.restoreSupports = restoreSupports;
});

View file

@ -0,0 +1,44 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
import { util } from '../../geo/base.js';
import { fdm_slice } from './slice.js';
import { fdm_prepare } from './prepare.js';
import { fdm_export } from './export.js';
// noz = nozzle diameter
// fil = filament diameter
// slice = slice height
function extrudePerMM(noz, fil, slice) {
return ((Math.PI * util.sqr(noz / 2)) / (Math.PI * util.sqr(fil / 2))) * (slice / noz);
};
// dist = distance between extrusion points
// perMM = amount extruded per MM (from extrudePerMM)
// factor = scaling factor (usually 1.0)
function extrudeMM(dist, perMM, factor) {
return dist * perMM * factor;
}
// defer loading until client and worker exist
function init(worker) {
worker.dispatch.fdm_support_generate = function(data, send) {
const { settings } = data;
const widgets = Object.values(worker.cache);
const fresh = widgets.filter(widget => FDM.supports(settings, widget));
send.done(kiri.codec.encode(fresh.map(widget => { return {
id: widget.id,
supports: widget.supports,
} } )));
};
}
export const FDM = {
init,
extrudePerMM,
extrudeMM,
slice: fdm_slice,
prepare: fdm_prepare,
export: fdm_export
};

View file

@ -1,16 +1,7 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
gapp.register("kiri-mode.fdm.driver", [], (root, exports) => {
const { base, kiri } = root;
const { driver } = kiri;
const { util } = base;
const FDM = driver.FDM = { getRangeParameters, extrudePerMM, extrudeMM };
// shared by client and worker contexts
function getRangeParameters(process, index) {
export function getRangeParameters(process, index) {
if (index === undefined || index === null || index < 0) {
return process;
}
@ -29,57 +20,3 @@ function getRangeParameters(process, index) {
}
return params;
}
// noz = nozzle diameter
// fil = filament diameter
// slice = slice height
function extrudePerMM(noz, fil, slice) {
return ((Math.PI * util.sqr(noz / 2)) / (Math.PI * util.sqr(fil / 2))) * (slice / noz);
};
// dist = distance between extrusion points
// perMM = amount extruded per MM (from extrudePerMM)
// factor = scaling factor (usually 1.0)
function extrudeMM(dist, perMM, factor) {
return dist * perMM * factor;
}
// defer loading until client and worker exist
kiri.load(api => {
const { client, worker } = kiri;
if (client) {
FDM.support_generate = function(ondone) {
client.clear();
client.sync();
const settings = api.conf.get();
const widgets = api.widgets.map();
client.send("fdm_support_generate", { settings }, (gen) => {
if (gen && gen.error) {
api.show.alert('support generation canceled');
return ondone([]);
}
for (let g of gen) {
g.widget = widgets[g.id];
}
ondone(gen);
});
};
}
if (worker) {
worker.fdm_support_generate = function(data, send) {
const { settings } = data;
const widgets = Object.values(worker.cache);
const fresh = widgets.filter(widget => FDM.supports(settings, widget));
send.done(kiri.codec.encode(fresh.map(widget => { return {
id: widget.id,
supports: widget.supports,
} } )));
};
}
});
});

View file

@ -1,19 +1,14 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { base, util } from '../../geo/base.js';
import { getRangeParameters } from './driver.js';
import { FDM } from './driver-be.js';
import { version } from '../../moto/license.js';
// dep: geo.base
// dep: kiri.utils
// dep: kiri-mode.fdm.driver
gapp.register("kiri-mode.fdm.export", [], (root, exports) => {
const { base, kiri } = root;
const { util, config } = base;
const { FDM } = kiri.driver;
const { getRangeParameters } = FDM;
const { config } = base;
const debug = false;
FDM.export = function(print, online, ondone, ondebug) {
export function fdm_export(print, online, ondone, ondebug) {
const { widgets, settings, belty, tools, firstTool } = print;
const { bounds, controller, device, process, filter, mode } = settings;
const { extruders, fwRetract } = device;
@ -30,6 +25,7 @@ FDM.export = function(print, online, ondone, ondebug) {
isBambu = extras.bbl,
{ extrudeAbs } = device,
{ exportThumb } = controller,
{ extrudeMM, extrudePerMM } = FDM,
extused = Object.keys(print.extruders).map(v => parseInt(v)),
timeFactor = (device.gcodeTime || 1) * 1.5,
decimals = config.gcode_decimals || 4,
@ -126,9 +122,7 @@ FDM.export = function(print, online, ondone, ondebug) {
arcQ = [],
minz = { x: Infinity, y: Infinity, z: Infinity },
// lenghts of each filament (by nozzle) consumed
segments = [],
extrudeMM = FDM.extrudeMM,
extrudePerMM = FDM.extrudePerMM;
segments = [];
let tools_used = Object.keys(tools);
for (let tool of tools_used) {
@ -292,7 +286,7 @@ FDM.export = function(print, online, ondone, ondebug) {
}
function preamble() {
append(`; Generated by Kiri:Moto ${kiri.version}`);
append(`; Generated by Kiri:Moto ${version}`);
append(`; ${new Date().toString()}`);
appendSub("; Bed left:{left} right:{right} top:{top} bottom:{bottom}");
append(`; Bed type: ${bedType}`);
@ -995,5 +989,3 @@ FDM.export = function(print, online, ondone, ondebug) {
console.log('minz', minz);
}
};
});

View file

@ -1,29 +1,24 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { base, util } from '../../geo/base.js';
import { slice as gyroid_slice } from '../../geo/gyroid.js';
// dep: geo.base
// dep: geo.gyroid
// dep: kiri-mode.fdm.driver
gapp.register("kiri-mode.fdm.fill", [], (root, exports) => {
export const fill_fixed = {
hex: fillHexFull,
grid: fillGrid,
triangle: fillTriangle
};
const { base, kiri } = root;
const { util } = base;
export const fill = {
hex: fillHexFull,
grid: fillGrid,
gyroid: fillGyroid,
triangle: fillTriangle,
linear: fillLinear,
cubic: fillCubic
};
const DEG2RAD = Math.PI / 180,
FILL = kiri.fill = {
hex: fillHexFull,
grid: fillGrid,
gyroid: fillGyroid,
triangle: fillTriangle,
linear: fillLinear,
cubic: fillCubic
},
CACHE = kiri.fill_fixed = {
hex: fillHexFull,
grid: fillGrid,
triangle: fillTriangle
};
const DEG2RAD = Math.PI / 180;
function fillHexFull(target) {
fillHex(target, true);
@ -109,13 +104,13 @@ function fillGyroid(target) {
let tile_x = span_x / tile;
let tile_y = span_y / tile;
let tile_z = 1 / tile;
let gyroid = base.gyroid.slice(target.zValue() * tile_z, (1 - density) * 500);
let gen = gyroid_slice(target.zValue() * tile_z, (1 - density) * 500);
let polys = [];
if (gyroid.dir == 'lr') {
if (gen.dir == 'lr') {
for (let ty=0; ty<=tile_y; ty++) {
for (let tx=0; tx<=tile_x; tx++) {
for (let poly of gyroid.polys) {
for (let poly of gen.polys) {
target.newline();
let points = poly.map(el => {
return {
@ -132,7 +127,7 @@ function fillGyroid(target) {
} else {
for (let tx=0; tx<=tile_x; tx++) {
for (let ty=0; ty<=tile_y; ty++) {
for (let poly of gyroid.polys) {
for (let poly of gen.polys) {
target.newline();
let points = poly.map(el => {
return {
@ -323,5 +318,3 @@ function fillTriangle(target) {
target.emit(xp, bounds.max.y);
}
}
});

View file

@ -1,26 +1,18 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { base } from '../../geo/base.js';
import { polygons as POLY, fillArea } from '../../geo/polygons.js';
import { getRangeParameters } from './driver.js';
import { slicer } from '../../geo/slicer.js';
// 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;
slicer.slicePost.FDM = slicePost;
/**
* 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) {
export function slicePost(data, options) {
const { z, lines, groups } = data;
const { useAssembly, post_args, zIndexes } = options;
const { process, isSynth, vaseMode } = post_args;
@ -40,7 +32,7 @@ base.slicePost.FDM = function(data, options) {
return;
}
const index = zIndexes.indexOf(z);
const range = FDM.getRangeParameters(process, index);
const range = getRangeParameters(process, index);
// calculate fractional shells
let shellFrac = (range.sliceShells - (range.sliceShells | 0));
let sliceShells = range.sliceShells | 0;
@ -62,7 +54,7 @@ base.slicePost.FDM = function(data, options) {
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, {
nutops.push(doTopShells(z, top, count, offset/2, offset, fillOff, {
thinType,
vaseMode,
useAssembly
@ -193,7 +185,7 @@ function thin_type_3(params) {
* may run in minion or worker context. performs shell offsetting
* including thin wall detection when enabled
*/
FDM.doTopShells = function(z, top, count, offset1, offsetN, fillOffset, opt = {}) {
export function doTopShells(z, top, count, offset1, offsetN, fillOffset, opt = {}) {
// pretend we're a top object in minions
if (!top.poly) {
top = { poly: top };
@ -319,5 +311,3 @@ function cullIntersections() {
}
return good.length > 2 ? good : [];
}
});

View file

@ -1,28 +1,18 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { base, util } from '../../geo/base.js';
import { poly2polyEmit, tip2tipEmit } from '../../geo/paths.js';
import { newBounds } from '../../geo/bounds.js';
import { newPoint } from '../../geo/point.js';
import { newPolygon, Polygon } from '../../geo/polygon.js';
import { polygons as POLY, fillArea } from '../../geo/polygons.js';
import { newPrint } from '../../kiri/print.js';
import { newSlice } from '../../kiri/slice.js';
import { newWidget } from '../../kiri/widget.js';
import { render } from '../../kiri/render.js';
import { getRangeParameters } from './driver.js';
// dep: geo.base
// dep: geo.paths
// dep: geo.point
// dep: geo.polygons
// dep: kiri.utils
// dep: kiri.slice
// dep: kiri.consts
// dep: kiri.render
// dep: kiri-mode.fdm.driver
gapp.register("kiri-mode.fdm.prepare", [], (root, exports) => {
const { base, kiri } = root;
const { consts, driver, newSlice, render } = kiri;
const { polygons, paths, util, newPoint, newPolygon, Polygon } = base;
const { poly2polyEmit, tip2tipEmit } = paths;
const { numOrDefault } = util;
const { fillArea } = polygons;
const { beltfact } = consts;
const { FDM } = driver;
const { getRangeParameters } = FDM;
const POLY = polygons;
/**
* DRIVER PRINT CONTRACT
@ -30,7 +20,7 @@ const POLY = polygons;
* @param {Function} update progress callback
* @returns {Object[]} returns array of render objects
*/
FDM.prepare = async function(widgets, settings, update) {
export async function fdm_prepare(widgets, settings, update) {
// filter ignored widgets
widgets = widgets.filter(w => !w.track.ignore && !w.meta.disabled);
@ -40,7 +30,7 @@ FDM.prepare = async function(widgets, settings, update) {
{ bedWidth, bedDepth } = device,
{ lineType } = controller,
printPoint = newPoint(0,0,0),
print = self.worker.print = kiri.newPrint(settings, widgets),
print = self.kiri_worker.current.print = newPrint(settings, widgets),
nozzle = process.sliceLineWidth || device.extruders[0].extNozzle,
isBelt = device.bedBelt,
isThin = lineType === "line",
@ -213,7 +203,7 @@ FDM.prepare = async function(widgets, settings, update) {
}
}
// recompute bounds for purge block offsets
let bbounds = base.newBounds();
let bbounds = newBounds();
brims.forEach(brim => {
bbounds.merge(brim.bounds);
});
@ -244,7 +234,7 @@ FDM.prepare = async function(widgets, settings, update) {
sslices.push(sslice);
}
if (sslices.length) {
let swidget = kiri.newWidget(null,widget.group);
let swidget = newWidget(null,widget.group);
swidget.slices = sslices;
swidget.support = true;
swidget.belt = widget.belt;
@ -1512,5 +1502,3 @@ function slicePrintPath(print, slice, startPoint, offset, output, opt = {}) {
return startPoint.add(offset);
}
});

View file

@ -1,28 +1,19 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
import { base, util } from '../../geo/base.js';
import { newBounds } from '../../geo/bounds.js';
import { newPolygon } from '../../geo/polygon.js';
import { polygons as POLY } from '../../geo/polygons.js';
import { newPoint } from '../../geo/point.js';
import { slice, sliceZ } from '../../geo/slicer.js';
import { newSlice } from '../../kiri/slice.js';
import { fill, fill_fixed } from './fill.js';
import { getRangeParameters } from './driver.js';
import { doTopShells } from './post.js';
// dep: geo.base
// dep: geo.slicer
// dep: geo.polygons
// dep: kiri.utils
// dep: kiri.consts
// dep: kiri-mode.fdm.driver
// dep: kiri-mode.fdm.post
// use: kiri-mode.fdm.fill
// use: ext.clip2
// use: add.three
gapp.register("kiri-mode.fdm.slice", [], (root, exports) => {
const { config } = base;
const { base, kiri, noop } = root;
const { consts, driver, fill, fill_fixed, newSlice, utils } = kiri;
const { config, polygons, util, newPoint } = base;
const { fillArea } = polygons;
const { FDM } = driver;
const { doTopShells, getRangeParameters } = FDM;
const POLY = polygons,
tracker = util.pwait,
let tracker = util.pwait,
lopacity = 0.6,
opacity = 1,
fat = 1.5,
@ -44,6 +35,7 @@ const POLY = polygons,
part: { line: 0x777777, check: 0x777777, face: 0 },
thin: { check: 0xbb8800, face: 0xbb8800, line: 0xbb8800, opacity, lopacity, fat },
}),
noop = () => {},
PROTO = Object.clone(COLOR),
profile = false,
profileStart = profile ? console.profile : noop,
@ -66,9 +58,9 @@ function vopt(opt) {
return opt;
}
FDM.sliceAll = function(settings, onupdate) {
export function sliceAll(settings, onupdate) {
// future home of brim and anchor generation
let widgets = Object.values(kiri.worker.cache)
let widgets = Object.values(self.kiri_worker.cache)
.filter(w => !w.meta.disabled)
.sort((a,b) => {
return a.slices[0].z - b.slices[0].z
@ -123,15 +115,16 @@ FDM.sliceAll = function(settings, onupdate) {
* @param {Function} onupdate (called with % complete and optional message)
* @param {Function} ondone (called when complete with an array of Slice objects)
*/
FDM.slice = function(settings, widget, onupdate, ondone) {
export function fdm_slice(settings, widget, onupdate, ondone) {
let render = settings.render !== false,
{ minions } = self.kiri_worker,
{ process, device, controller } = settings,
isBelt = device.bedBelt,
isBrick = controller.devel && process.sliceZInterleave,
isSynth = widget.track.synth,
isSupport = widget.track.support,
useAssembly = controller.assembly,
isConcurrent = controller.threaded && kiri.minions.concurrent,
isConcurrent = controller.threaded && minions.concurrent,
topLayers = process.sliceTopLayers || 0,
bottomLayers = process.sliceBottomLayers || 0,
vaseMode = process.sliceFillType === 'vase' && !isSynth,
@ -226,7 +219,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
}
}
base.slice(points, {
slice(points, {
debug: process.xray,
xray: process.xray,
zMin: bounds.min.z,
@ -329,7 +322,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
// slicer function (worker local or minion distributed)
slicer(z, points, opts) {
// opts.debug = opts.debug || isSynth;
return (isConcurrent ? kiri.minions.sliceZ : base.sliceZ)(z, points, opts);
return (isConcurrent ? minions.sliceZ : sliceZ)(z, points, opts);
},
onupdate(update) {
return onupdate(0.0 + update * 0.5)
@ -380,7 +373,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
.map(w => w.slices).flat()
.map(s => s.tops).flat().map(t => t.simple);
let shadow = isConcurrent ?
await kiri.minions.union(alltops, 0.1) :
await minions.union(alltops, 0.1) :
POLY.union(alltops, 0.1, true);
// expand shadow when requested (support clipping)
if (process.sliceSupportExtra) {
@ -584,7 +577,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
addto.belt.touch = false;
let z = addto.z;
let y = (slope * z) - smin - (lineWidth / 2);
let splat = base.newPolygon().add(minx, y, z).add(maxx, y, z).setOpen();
let splat = newPolygon().add(minx, y, z).add(maxx, y, z).setOpen();
let snew = addto.addTop(splat).fill_sparse = [ splat ];
adds.push(snew);
start = addto;
@ -617,7 +610,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
let fz = first.z;
let n2 = lineWidth / 2;
for (let x = mp - dx; x <= mp + dx ; x += 3) {
add.push( base.newPolygon().add(x, fy - n2, fz).add(x, fy + y + n2, fz).setOpen() );
add.push(newPolygon().add(x, fy - n2, fz).add(x, fy + y + n2, fz).setOpen() );
}
}
}
@ -711,7 +704,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
let z = slice.z;
let y = z - smin - (lineWidth / 2);
for (let line of lines) {
supps.push(base.newPolygon()
supps.push(newPolygon()
.add(minX + line.start / 2, y, z)
.add(minX + line.end / 2, y, z)
.setOpen()
@ -939,7 +932,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
}
if (isBelt) {
let bounds = base.newBounds();
let bounds = newBounds();
let slice = slices[0];
if (slice.tops) {
for (let top of slice.tops) {
@ -1081,15 +1074,6 @@ function doRender(slice, isSynth, params, opt = {}) {
// console.log(slice.index, slice.render.stats);
}
// shared with SLA driver and minions
FDM.share = {
doShells,
doTopShells,
doDiff,
projectFlats,
projectBridges
};
/**
* Compute offset shell polygons. For FDM, the first offset is usually half
* of the nozzle width. Each subsequent offset is a full nozzle width. User
@ -1104,7 +1088,7 @@ FDM.share = {
* @param {number} fillOffset
* @param {Obejct} options
*/
function doShells(slice, count, offset1, offsetN, fillOffset, opt = {}) {
export function doShells(slice, count, offset1, offsetN, fillOffset, opt = {}) {
for (let top of slice.tops) {
doTopShells(slice.z, top, count, offset1, offsetN, fillOffset, opt);
}
@ -1130,7 +1114,7 @@ function doShells(slice, count, offset1, offsetN, fillOffset, opt = {}) {
slice.tops.forEach(function(top) {
if (!top.fill_off) return; // missing for inner brick layers
let lines = fillArea(top.fill_off, angle, spacing, null);
let lines = POLY.fillArea(top.fill_off, angle, spacing, null);
top.fill_lines.appendAll(lines);
});
@ -1290,7 +1274,7 @@ function doSparseLayerFill(slice, options = {}) {
}
if (options.promises) {
options.promises.push(kiri.minions.clip(slice, polys, lines));
options.promises.push(self.kiri_worker.minions.clip(slice, polys, lines));
return;
}
@ -1316,7 +1300,7 @@ function doSparseLayerFill(slice, options = {}) {
* Used to calculate bridges, flats and then solid projections.
* 'expand' is used for top offsets in SLA mode
*/
function doDiff(slice, options = {}) {
export function doDiff(slice, options = {}) {
const { sla, fakedown, grow, min } = options;
if ((slice.index <= 0 && !fakedown) || slice.xray) {
return;
@ -1372,7 +1356,7 @@ function addSolidFills(slice, polys) {
/**
* project bottom flats down
*/
function projectFlats(slice, count, expand) {
export function projectFlats(slice, count, expand) {
if (!slice.down || !slice.flats) return;
// these flats are marked for finishing print speed
if (slice.flats.length) slice.finishSolids = true;
@ -1385,7 +1369,7 @@ function projectFlats(slice, count, expand) {
/**
* project top bridges up
*/
function projectBridges(slice, count) {
export function projectBridges(slice, count) {
if (!slice.up || !slice.bridges) return;
// these flats are marked for finishing print speed
if (slice.bridges.length) slice.finishSolids = true;
@ -1516,7 +1500,7 @@ function doSolidsFill(slice, spacing, angle, minArea, fillQ) {
function doFillArea(fillQ, polys, angle, spacing, output, minLen, maxLen) {
if (fillQ) {
fillQ.push(kiri.minions.fill(polys, angle, spacing, output, minLen, maxLen));
fillQ.push(self.kiri_worker.minions.fill(polys, angle, spacing, output, minLen, maxLen));
} else {
POLY.fillArea(polys, angle, spacing, output, minLen, maxLen);
}
@ -1526,7 +1510,8 @@ function doFillArea(fillQ, polys, angle, spacing, output, minLen, maxLen) {
* calculate external overhangs requiring support
*/
async function doSupport(slice, proc, shadow, opt = {}) {
let maxBridge = proc.sliceSupportSpan || 5,
let { minions } = self.kiri_worker,
maxBridge = proc.sliceSupportSpan || 5,
minArea = proc.supportMinArea || 0.1,
pillarSize = proc.sliceSupportSize,
offset = proc.sliceSupportOffset || 0,
@ -1615,26 +1600,26 @@ async function doSupport(slice, proc, shadow, opt = {}) {
// for each point, create a bounding rectangle
points.forEach(function(point) {
pillars.push(base.newPolygon().centerRectangle(point, size/2, size/2));
pillars.push(newPolygon().centerRectangle(point, size/2, size/2));
});
supports.appendAll(POLY.union(pillars, null, true, { wasm: false }));
// merge pillars and replace with convex hull of outer points (aka smoothing)
pillars = POLY.union(pillars, null, true, { wasm: false }).forEach(function(pillar) {
supports.push(base.newPolygon().createConvexHull(pillar.points));
supports.push(newPolygon().createConvexHull(pillar.points));
});
})();
// DEBUG code
if (SDBG && down_traces) slice.output()
.setLayer('cks', { line: 0xee5533, check: 0xee5533 })
.addPolys(cks.map(p => base.newPolygon().centerRectangle(p, 0.25, 0.25)))
.addPolys(cks.map(p => newPolygon().centerRectangle(p, 0.25, 0.25)))
.setLayer('pip', { line: 0xdd4422, check: 0xdd4422 })
.addPolys(pip.map(p => base.newPolygon().centerRectangle(p, 0.4, 0.4)))
.addPolys(pip.map(p => newPolygon().centerRectangle(p, 0.4, 0.4)))
.setLayer('pcl', { line: 0xcc3311, check: 0xcc3311 })
.addPolys(pcl.map(p => base.newPolygon().centerRectangle(p, 0.3, 0.3)))
.addPolys(pcl.map(p => newPolygon().centerRectangle(p, 0.3, 0.3)))
.setLayer('pts', { line: 0xdd33dd, check: 0xdd33dd })
.addPolys(points.map(p => base.newPolygon().centerRectangle(p, 0.8, 0.8)))
.addPolys(points.map(p => newPolygon().centerRectangle(p, 0.8, 0.8)))
.setLayer('dtr', { line: 0x0, check: 0x0 })
.addPolys(POLY.setZ(down_traces.clone(true),slice.z));
;
@ -1645,7 +1630,7 @@ async function doSupport(slice, proc, shadow, opt = {}) {
// then union supports
if (supports.length > 10) {
supports = await kiri.minions.union(supports);
supports = await minions.union(supports);
} else {
supports = POLY.union(supports, null, true, { wasm: false });
}
@ -1763,7 +1748,7 @@ function projectSolid(slice, polys, count, up, first) {
}
}
FDM.supports = function(settings, widget) {
export function supports(settings, widget) {
let isBelt = settings.device.bedBelt;
let process = settings.process;
let size = process.sliceSupportSize;
@ -1924,7 +1909,7 @@ class Coplanars {
// convert groups of faces to contiguous polygon groups
groups = groups.map(group => {
let parr = group.map(arr => {
return base.newPolygon()
return newPolygon()
.add(arr[0].x, arr[0].y, arr[0].z)
.add(arr[1].x, arr[1].y, arr[1].z)
.add(arr[2].x, arr[2].y, arr[2].z);
@ -1942,5 +1927,3 @@ class Coplanars {
return out;
}
}
});