move shell generation into slice (new) post-processor which means it can be distributed and co-located with slicing in minion

This commit is contained in:
Stewart Allen 2021-06-23 22:31:27 -04:00
commit e2ef4ff7e2
10 changed files with 246 additions and 156 deletions

View file

@ -38,8 +38,8 @@
let count = 0; let count = 0;
if (tracker) if (tracker)
for (let p of promises) { for (let p of promises) {
p.then(() => { p.then(data => {
tracker(count++, promises.length); tracker(count++, promises.length, data);
}); });
} }
await Promise.all(promises); await Promise.all(promises);

View file

@ -92,10 +92,10 @@ const funcs = {
realp[p++] = BASE.newPoint(points[i++], points[i++], points[i++]); realp[p++] = BASE.newPoint(points[i++], points[i++], points[i++]);
} }
let output = []; let output = [];
for (let slice of slices) { for (let params of slices) {
output.push({ output.push({
slice, params,
tops: KIRI.slicer.sliceZ(slice.z, realp, options).tops data: { tops: KIRI.slicer.sliceZ(params.z, realp, options, params).tops }
}); });
} }
reply({ seq, output: CODEC.encode(output) }); reply({ seq, output: CODEC.encode(output) });

View file

@ -176,9 +176,21 @@
} }
PRO.addTop = function(poly) { PRO.addTop = function(poly) {
if (poly.length) {
let top = new Top(poly); let top = new Top(poly);
this.tops.push(top); this.tops.push(top);
return top; return top;
} else {
let top = new Top(poly.poly);
top.fill_lines = poly.fill_lines;
top.fill_off = poly.fill_off;
top.last = poly.last;
top.shells = poly.shells;
this.tops.push(top);
return top;
}
console.log('top', poly);
throw "invalid top";
}; };
PRO.findClosestPointTo = function(target) { PRO.findClosestPointTo = function(target) {

View file

@ -2,6 +2,9 @@
"use strict"; "use strict";
/**
* Slicing engine used by FDM, Laser, and SLA
*/
(function() { (function() {
if (self.kiri.slicer) return; if (self.kiri.slicer) return;
@ -10,7 +13,8 @@
slice, slice,
sliceZ, sliceZ,
sliceWidget, sliceWidget,
connectLines connectLines,
createSlice
}; };
let KIRI = self.kiri, let KIRI = self.kiri,
@ -138,8 +142,8 @@
if (concurrent > 1) { if (concurrent > 1) {
if (bucketCount < concurrent) { if (bucketCount < concurrent) {
bucketCount = concurrent; bucketCount = concurrent;
} else if (bucketCount > 128) { } else if (bucketCount > 100) {
bucketCount = 128; bucketCount = 100;
} }
} }
@ -302,42 +306,65 @@
function bucketZ(index, z, height, thick) { function bucketZ(index, z, height, thick) {
buckets[Math.floor(z * zScale)].slices.push({ buckets[Math.floor(z * zScale)].slices.push({
index, z, height, thick index, z, height, thick, total: zIndexes.length
}); });
} }
async function sliceBuckets() { async function sliceBuckets() {
let output = []; let output = [];
// console.log({buckets}); if (concurrent) {
if (concurrent < 2) { let promises = buckets.map(
sliceBucketsLocal(buckets, output); bucket => KIRI.minions.sliceBucket(bucket, options, output)
} else { );
let promises = []; await tracker(promises, (i,t,d) => {
for (let bucket of buckets) {
promises.push(KIRI.minions.sliceBucket(bucket, options, output));
}
await tracker(promises, (i,t) => {
onupdate(0.1 + (i / t) * 0.9); onupdate(0.1 + (i / t) * 0.9);
}); });
} } else {
return output;
}
function sliceBucketsLocal(buckets, output) {
let count = 0; let count = 0;
for (let bucket of buckets) { for (let bucket of buckets) {
for (let slice of bucket.slices) { for (let params of bucket.slices) {
let { index, z, height, thick } = slice; output.push(createSlice(
let { lines, groups, tops } = sliceZ(z, bucket.points, options); params,
slice = newSlice(z).addTops(tops); sliceZ(params.z, bucket.points, options, params),
slice.height = height; options
slice.index = index; ));
slice.thick = thick;
output.push(slice);
onupdate(0.1 + (count++ / zIndexes.length) * 0.9); onupdate(0.1 + (count++ / zIndexes.length) * 0.9);
} }
} }
} }
return output;
}
}
function createSlice(params, data, options = {}) {
let { index, z, height, thick } = params;
let { lines, groups, tops } = data;
let slice = newSlice(z).addTops(tops);
slice.height = height;
slice.index = index;
slice.thick = thick;
// debugging (non-threaded mode only)
let { debug, xray, view } = options;
if (view && (debug || xray)) {
if ((debug && lines.excessive) || xray) {
const dash = xray || 3;
lines.forEach((line, i) => {
const group = i % dash;
const color = [ 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff ][group];
slice.output().setLayer(`xl-${group}`, color).addLine(line.p1, line.p2);
});
}
POLY.nest(groups).forEach((poly, i) => {
slice.addTop(poly);
if (xray) {
const group = i % (xray || 3);
const color = [ 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff ][group];
slice.output().setLayer(`xg-${group}`, color).addPoly(poly);
}
});
}
return slice;
} }
/** ***** SLICING FUNCTIONS ***** */ /** ***** SLICING FUNCTIONS ***** */
@ -421,7 +448,7 @@
* @param {number} z * @param {number} z
* @param {number} [height] optional real height (fdm) * @param {number} [height] optional real height (fdm)
*/ */
function sliceZ(z, points, options = {}) { function sliceZ(z, points, options = {}, params = {}) {
let phash = {}, let phash = {},
lines = [], lines = [],
p1, p2, p3; p1, p2, p3;
@ -477,28 +504,18 @@
groups = POLY.flatten(POLY.union(POLY.nest(groups), null, true), null, true); groups = POLY.flatten(POLY.union(POLY.nest(groups), null, true), null, true);
} }
// if ((debug && lines.excessive) || xray) {
// const dash = xray || 3;
// lines.forEach((line, i) => {
// const group = i % dash;
// const color = [ 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff ][group];
// slice.output().setLayer(`xl-${group}`, color).addLine(line.p1, line.p2);
// });
// }
let tops = POLY.nest(groups); let tops = POLY.nest(groups);
let data = { lines, groups, tops };
// identify and add tops to slice // look for driver-specific slice post-processor
// POLY.nest(groups).forEach((poly, i) => { if (options.mode) {
// slice.addTop(poly); let fn = KIRI.driver[options.mode].slicePost;
// if (xray) { if (fn) {
// const group = i % (xray || 3); fn(data, options, params);
// const color = [ 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff ][group]; }
// slice.output().setLayer(`xg-${group}`, color).addPoly(poly); }
// }
// });
return { lines, groups, tops }; return data;
} }
/** /**

View file

@ -2,6 +2,9 @@
"use strict"; "use strict";
/**
* Slicing engine used by CAM
*/
(function() { (function() {
let KIRI = self.kiri, let KIRI = self.kiri,

View file

@ -145,16 +145,12 @@ KIRI.minions = {
slices, slices,
options options
}, data => { }, data => {
for (let rec of KIRI.codec.decode(data.output)) { let recs = KIRI.codec.decode(data.output);
let { slice, tops } = rec; for (let rec of recs) {
let newSlice = KIRI.newSlice(slice.z); let { params, data } = rec;
newSlice.index = slice.index; output.push(KIRI.slicer.createSlice(params, data));
newSlice.thick = slice.thick;
newSlice.height = slice.height;
newSlice.addTops(tops);
output.push(newSlice);
} }
resolve(); resolve(recs);
}, [ floatP.buffer ]); }, [ floatP.buffer ]);
}); });
}, },

View file

@ -29,15 +29,15 @@
return settings; return settings;
} }
function getRangeParameters(settings, index) { function getRangeParameters(process, index) {
if (index === undefined || index === null || index < 0) { if (index === undefined || index === null || index < 0) {
return settings.process; return process;
} }
let ranges = settings.process.ranges; let ranges = process.ranges;
if (!(ranges && ranges.length)) { if (!(ranges && ranges.length)) {
return settings.process; return process;
} }
let params = Object.clone(settings.process); let params = Object.clone(process);
for (let range of ranges) { for (let range of ranges) {
if (index >= range.lo && index <= range.hi) { if (index >= range.lo && index <= range.hi) {
for (let [key,value] of Object.entries(range.fields)) { for (let [key,value] of Object.entries(range.fields)) {

View file

@ -113,7 +113,7 @@
// smallish band-aid. refactor above to remove redundancy // smallish band-aid. refactor above to remove redundancy
function updateParams(layer) { function updateParams(layer) {
let process = getRangeParameters(settings, layer); let process = getRangeParameters(process, layer);
zhop = process.zHopDistance || 0; // range zhop = process.zHopDistance || 0; // range
retDist = process.outputRetractDist || 0; // range retDist = process.outputRetractDist || 0; // range
retSpeed = process.outputRetractSpeed * 60 || 1; // range retSpeed = process.outputRetractSpeed * 60 || 1; // range

View file

@ -374,7 +374,7 @@
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); let params = getRangeParameters(process, slice.index);
slice.prep = true; slice.prep = true;
// retract between widgets or layers (when set) // retract between widgets or layers (when set)
if (layerout.length && slice.widget !== lastWidget) { if (layerout.length && slice.widget !== lastWidget) {
@ -474,7 +474,7 @@
// 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
for (let layer of output) { for (let layer of output) {
let params = getRangeParameters(settings, layer.layer || 0); let params = getRangeParameters(process, layer.layer || 0);
let brimHalf = params.firstLayerBrim < 0; let brimHalf = params.firstLayerBrim < 0;
let firstLayerBrim = Math.abs(params.firstLayerBrim); let firstLayerBrim = Math.abs(params.firstLayerBrim);
let firstLayerBrimIn = params.firstLayerBrimIn; let firstLayerBrimIn = params.firstLayerBrimIn;

View file

@ -28,6 +28,7 @@
PROTO = Object.clone(COLOR), PROTO = Object.clone(COLOR),
bwcomp = (1 / Math.cos(Math.PI/4)), bwcomp = (1 / Math.cos(Math.PI/4)),
getRangeParameters = FDM.getRangeParameters, getRangeParameters = FDM.getRangeParameters,
slicePost = true,
debug = false; debug = false;
let isThin = false; // force line rendering let isThin = false; // force line rendering
@ -46,6 +47,49 @@
return opt; return opt;
} }
// console.log('slicing', {debug, 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.
*/
FDM.slicePost = slicePost ? function(data, options, params) {
let { lines, groups, tops } = data;
let { z, index, total, height, thick } = params;
let { process, isSynth, isDanger, vaseMode, shellOffset, fillOffset } = options.post;
let range = getRangeParameters(process, index);
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;
}
let spaceMult = index === 0 ? process.firstLayerLineMult || 1 : 1;
let isBottom = index < process.sliceBottomLayers;
let isTop = index > total - process.sliceTopLayers - 1;
let isDense = range.sliceFillSparse > 0.98;
let isSolid = (isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth;
let solidWidth = isSolid ? range.sliceFillWidth || 1 : 0;
let count = isSynth ? 1 : sliceShells;
let offset = shellOffset * spaceMult;
let fillOff = fillOffset * spaceMult;
let nutops = [];
for (let top of tops) {
nutops.push(FDM.share.doTopShells(z, top, count, offset/2, offset, fillOff, {
vase: vaseMode,
thin: process.detectThinWalls && !isSynth,
danger: isDanger
}));
}
data.tops = nutops;
} : undefined;
/** /**
* DRIVER SLICE CONTRACT * DRIVER SLICE CONTRACT
* *
@ -62,32 +106,31 @@
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, { process, device, controller } = settings,
spro = settings.process, isBelt = device.bedBelt,
sdev = settings.device,
isBelt = sdev.bedBelt,
isSynth = widget.track.synth, isSynth = widget.track.synth,
minSolid = spro.sliceSolidMinArea, isDanger = controller.danger,
solidLayers = spro.sliceSolidLayers, minSolid = process.sliceSolidMinArea,
vaseMode = spro.sliceFillType === 'vase' && !isSynth, solidLayers = process.sliceSolidLayers,
vaseMode = process.sliceFillType === 'vase' && !isSynth,
doSolidLayers = solidLayers && !vaseMode && !isSynth, 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 = process.sliceHeight,
firstSliceHeight = isBelt ? sliceHeight : spro.firstSliceHeight, firstSliceHeight = isBelt ? sliceHeight : process.firstSliceHeight,
nozzleSize = sdev.extruders[extruder].extNozzle, nozzleSize = device.extruders[extruder].extNozzle,
lineWidth = spro.sliceLineWidth || nozzleSize, lineWidth = process.sliceLineWidth || nozzleSize,
fillOffsetMult = 1.0 - bound(spro.sliceFillOverlap, 0, 0.8), fillOffsetMult = 1.0 - bound(process.sliceFillOverlap, 0, 0.8),
shellOffset = lineWidth, shellOffset = lineWidth,
fillSpacing = lineWidth, fillSpacing = lineWidth,
fillOffset = lineWidth * fillOffsetMult, fillOffset = lineWidth * fillOffsetMult,
sliceFillAngle = spro.sliceFillAngle, sliceFillAngle = process.sliceFillAngle,
supportDensity = spro.sliceSupportDensity, supportDensity = process.sliceSupportDensity,
beltfact = Math.cos(Math.PI/4), beltfact = Math.cos(Math.PI/4),
doConcurrent = ctrl.threaded && KIRI.minions.concurrent; doConcurrent = controller.threaded && KIRI.minions.concurrent;
isFlat = ctrl.lineType === "flat"; isFlat = controller.lineType === "flat";
isThin = !isFlat && ctrl.lineType === "line"; isThin = !isFlat && controller.lineType === "line";
offset = lineWidth / 2; offset = lineWidth / 2;
if (isFlat) { if (isFlat) {
@ -117,8 +160,8 @@
firstSliceHeight = sliceHeight; firstSliceHeight = sliceHeight;
} }
const sliceMinHeight = spro.sliceAdaptive && spro.sliceMinHeight > 0 ? const sliceMinHeight = process.sliceAdaptive && process.sliceMinHeight > 0 ?
Math.min(spro.sliceMinHeight, sliceHeight) : 0; Math.min(process.sliceMinHeight, sliceHeight) : 0;
if (firstSliceHeight < sliceHeight) { if (firstSliceHeight < sliceHeight) {
DBUG.log("invalid first layer height < slice height"); DBUG.log("invalid first layer height < slice height");
@ -127,15 +170,25 @@
} }
SLICER.sliceWidget(widget, { SLICER.sliceWidget(widget, {
mode: 'FDM',
height: sliceHeight, height: sliceHeight,
minHeight: sliceMinHeight, minHeight: sliceMinHeight,
firstHeight: firstSliceHeight, firstHeight: firstSliceHeight,
union: ctrl.healMesh, union: controller.healMesh,
indices: process.indices,
concurrent: doConcurrent,
post: slicePost ? {
shellOffset,
fillOffset,
lineWidth,
vaseMode,
isSynth,
process,
isDanger
} : undefined
// debug: true, // debug: true,
// xray: 3,
// view: view, // view: view,
indices: spro.indices, // xray: 3,
concurrent: doConcurrent
}, onSliceDone, onSliceUpdate); }, onSliceDone, onSliceUpdate);
function onSliceUpdate(update) { function onSliceUpdate(update) {
@ -169,8 +222,8 @@
shadow = doConcurrent ? shadow = doConcurrent ?
await KIRI.minions.union(alltops, 0.1) : await KIRI.minions.union(alltops, 0.1) :
POLY.union(alltops, 0.1, true); POLY.union(alltops, 0.1, true);
if (spro.sliceSupportExtra) { if (process.sliceSupportExtra) {
shadow = POLY.offset(shadow, spro.sliceSupportExtra); shadow = POLY.offset(shadow, process.sliceSupportExtra);
} }
widget.shadow = POLY.setZ(shadow, 0); widget.shadow = POLY.setZ(shadow, 0);
// slices[0].output() // slices[0].output()
@ -198,7 +251,7 @@
} }
// create shadow for non-belt supports // create shadow for non-belt supports
if (!isBelt && (isSynth || (!isSynth && supportDensity && spro.sliceSupportEnable))) { if (!isBelt && (isSynth || (!isSynth && supportDensity && process.sliceSupportEnable))) {
await doShadow(slices); await doShadow(slices);
} }
@ -214,7 +267,7 @@
slice.addTop(u); slice.addTop(u);
} }
} }
let gap = sliceHeight * (isBelt ? 0 : spro.sliceSupportGap); let gap = sliceHeight * (isBelt ? 0 : process.sliceSupportGap);
// clip tops to other widgets in group // clip tops to other widgets in group
tops = slice.topPolys(); tops = slice.topPolys();
for (let peer of widget.group) { for (let peer of widget.group) {
@ -226,9 +279,9 @@
if (Math.abs(Math.abs(pslice.z - slice.z) - gap) > 0.1) { if (Math.abs(Math.abs(pslice.z - slice.z) - gap) > 0.1) {
continue; continue;
} }
// offset pslice tops by spro.sliceSupportOffset // offset pslice tops by process.sliceSupportOffset
if (!pslice.synth_off) { if (!pslice.synth_off) {
pslice.synth_off = POLY.offset(pslice.topPolys(), spro.sliceSupportOffset); pslice.synth_off = POLY.offset(pslice.topPolys(), process.sliceSupportOffset);
} }
let ptops = pslice.synth_off; let ptops = pslice.synth_off;
let ntops = []; let ntops = [];
@ -276,7 +329,7 @@
} }
// do not hint polygin fill longer than a max span length // do not hint polygin fill longer than a max span length
CONF.hint_len_max = UTIL.sqr(spro.sliceBridgeMax); CONF.hint_len_max = UTIL.sqr(process.sliceBridgeMax);
// reset for solids, support projections // reset for solids, support projections
// and other annotations // and other annotations
@ -286,10 +339,11 @@
slice.solids = []; slice.solids = [];
}); });
let promises = doConcurrent ? [] : undefined;
// create shells and diff inner fillable areas // create shells and diff inner fillable areas
if (!slicePost) {
let promises = doConcurrent ? [] : undefined;
forSlices(0.0, promises ? 0.05 : 0.15, slice => { forSlices(0.0, promises ? 0.05 : 0.15, slice => {
let params = slice.params = getRangeParameters(settings, slice.index); let params = slice.params = getRangeParameters(process, slice.index);
let shellFrac = (params.sliceShells - (params.sliceShells | 0)); let shellFrac = (params.sliceShells - (params.sliceShells | 0));
let sliceShells = params.sliceShells | 0; let sliceShells = params.sliceShells | 0;
if (shellFrac) { if (shellFrac) {
@ -301,9 +355,9 @@
sliceShells += rem >= trg ? 1 : 0; sliceShells += rem >= trg ? 1 : 0;
} }
let first = slice.index === 0; let first = slice.index === 0;
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1; let spaceMult = first ? process.firstLayerLineMult || 1 : 1;
let isBottom = slice.index < spro.sliceBottomLayers; let isBottom = slice.index < process.sliceBottomLayers;
let isTop = slice.index > slices.length - spro.sliceTopLayers-1; let isTop = slice.index > slices.length - process.sliceTopLayers-1;
let isDense = params.sliceFillSparse > 0.98; let isDense = params.sliceFillSparse > 0.98;
let solidWidth = params.sliceFillWidth || 1; let solidWidth = params.sliceFillWidth || 1;
if ((isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth) { if ((isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth) {
@ -317,8 +371,8 @@
let count = isSynth ? 1 : sliceShells; let count = isSynth ? 1 : sliceShells;
doShells(slice, count, offset, fillOff, { doShells(slice, count, offset, fillOff, {
vase: vaseMode, vase: vaseMode,
thin: spro.detectThinWalls && !isSynth, thin: process.detectThinWalls && !isSynth,
danger: ctrl.danger danger: controller.danger
}, promises); }, promises);
}, "shells"); }, "shells");
if (promises) { if (promises) {
@ -327,6 +381,7 @@
trackupdate(i / t, 0.05, 0.15); trackupdate(i / t, 0.05, 0.15);
}); });
} }
}
// just the top/bottom special solid layers // just the top/bottom special solid layers
forSlices(0.15, 0.2, slice => { forSlices(0.15, 0.2, slice => {
@ -335,7 +390,7 @@
doSolidLayerFill(slice, fillSpace, sliceFillAngle); doSolidLayerFill(slice, fillSpace, sliceFillAngle);
} }
sliceFillAngle += 90.0; sliceFillAngle += 90.0;
}, "shells"); }, "solid layers");
// add lead in when specified in belt mode // add lead in when specified in belt mode
if (!isSynth && isBelt) { if (!isSynth && isBelt) {
@ -374,13 +429,13 @@
if (!start) start = slice; if (!start) start = slice;
} }
} }
let offset = spro.firstLayerBeltLead * beltfact; let offset = process.firstLayerBeltLead * beltfact;
// ensure we start against a layer with shells // ensure we start against a layer with shells
while (start.up && start.topShells().length === 0) { while (start.up && start.topShells().length === 0) {
start = start.up; start = start.up;
} }
// if a brim applies, add that width to anchor // if a brim applies, add that width to anchor
let brim = getRangeParameters(settings, 0).firstLayerBrim || 0; let brim = getRangeParameters(process, 0).firstLayerBrim || 0;
if (brim) { if (brim) {
minx -= brim; minx -= brim;
maxx += brim; maxx += brim;
@ -414,7 +469,7 @@
offset -= sliceHeight; offset -= sliceHeight;
} }
// add anchor bump // add anchor bump
let bump = spro.firstLayerBeltBump; let bump = process.firstLayerBeltBump;
if (bump) { if (bump) {
adds = adds.reverse().slice(1, adds.length - 1); adds = adds.reverse().slice(1, adds.length - 1);
let count = 1; let count = 1;
@ -456,7 +511,7 @@
// console.log('start'); await BASE.util.ptimer(1000); // console.log('start'); await BASE.util.ptimer(1000);
let promises = doConcurrent ? [] : undefined; let promises = doConcurrent ? [] : undefined;
forSlices(0.35, promises ? 0.4 : 0.5, slice => { forSlices(0.35, promises ? 0.4 : 0.5, slice => {
let params = slice.params || spro; let params = slice.params || process;
let first = slice.index === 0; let first = slice.index === 0;
let solidWidth = params.sliceFillWidth || 1; let solidWidth = params.sliceFillWidth || 1;
let spaceMult = first ? params.firstLayerLineMult || 1 : 1; let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
@ -477,16 +532,16 @@
let lastType; let lastType;
let promises = doConcurrent ? [] : undefined; let promises = doConcurrent ? [] : undefined;
forSlices(0.5, promises ? 0.55 : 0.7, slice => { forSlices(0.5, promises ? 0.55 : 0.7, slice => {
let params = slice.params || spro; let params = slice.params || process;
if (vaseMode || !params.sliceFillSparse) { if (vaseMode || !params.sliceFillSparse) {
return; return;
} }
let newType = params.sliceFillType; let newType = params.sliceFillType;
doSparseLayerFill(slice, { doSparseLayerFill(slice, {
settings: settings, settings,
process: spro, process,
device: sdev, device,
lineWidth: lineWidth, lineWidth,
spacing: fillOffset, spacing: fillOffset,
density: params.sliceFillSparse, density: params.sliceFillSparse,
bounds: widget.getBoundingBox(), bounds: widget.getBoundingBox(),
@ -505,7 +560,7 @@
} else if (isSynth) { } else if (isSynth) {
let promises = doConcurrent ? [] : undefined; let promises = doConcurrent ? [] : undefined;
forSlices(0.5, promises ? 0.6 : 0.7, slice => { forSlices(0.5, promises ? 0.6 : 0.7, slice => {
let params = slice.params || spro; let params = slice.params || process;
let density = params.sliceSupportDensity; let density = params.sliceSupportDensity;
if (density) if (density)
for (let top of slice.tops) { for (let top of slice.tops) {
@ -523,16 +578,16 @@
} }
// auto support generation // auto support generation
if (!isBelt && !isSynth && supportDensity && spro.sliceSupportEnable) { if (!isBelt && !isSynth && supportDensity && process.sliceSupportEnable) {
doShadow(slices); doShadow(slices);
// console.log('start'); await BASE.util.ptimer(1000); // console.log('start'); await BASE.util.ptimer(1000);
forSlices(0.7, 0.8, slice => { forSlices(0.7, 0.8, slice => {
doSupport(slice, spro, widget.shadow, ctrl.danger); doSupport(slice, process, widget.shadow, controller.danger);
}, "support"); }, "support");
// console.log('stop'); await BASE.util.ptimer(1000); // console.log('stop'); await BASE.util.ptimer(1000);
let promises = doConcurrent ? [] : undefined; let promises = doConcurrent ? [] : undefined;
forSlices(0.8, promises ? 0.88 : 0.9, slice => { forSlices(0.8, promises ? 0.88 : 0.9, slice => {
doSupportFill(promises, slice, lineWidth, supportDensity, spro.sliceSupportArea); doSupportFill(promises, slice, lineWidth, supportDensity, process.sliceSupportArea);
}, "support"); }, "support");
if (promises) { if (promises) {
await tracker(promises, (i, t) => { await tracker(promises, (i, t) => {
@ -544,8 +599,8 @@
// 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 => {
let params = slice.params || spro; let params = slice.params || process;
doRender(slice, isSynth, params, ctrl.devel); doRender(slice, isSynth, params, controller.devel);
}, "render"); }, "render");
} }
@ -631,7 +686,7 @@
// console.log(slice.index, slice.render.stats); // console.log(slice.index, slice.render.stats);
} }
// shared with SLA driver // shared with SLA driver and minions
FDM.share = { FDM.share = {
doShells, doShells,
doTopShells, doTopShells,
@ -682,6 +737,11 @@
} }
function doTopShells(z, top, 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 };
}
let top_poly = [ top.poly ]; let top_poly = [ top.poly ];
if (opt.vase) { if (opt.vase) {
@ -801,6 +861,8 @@
// for diffing // for diffing
top.last = last; top.last = last;
return top;
} }
/** /**