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:
parent
7072afb613
commit
e2ef4ff7e2
10 changed files with 246 additions and 156 deletions
|
|
@ -38,8 +38,8 @@
|
|||
let count = 0;
|
||||
if (tracker)
|
||||
for (let p of promises) {
|
||||
p.then(() => {
|
||||
tracker(count++, promises.length);
|
||||
p.then(data => {
|
||||
tracker(count++, promises.length, data);
|
||||
});
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ const funcs = {
|
|||
realp[p++] = BASE.newPoint(points[i++], points[i++], points[i++]);
|
||||
}
|
||||
let output = [];
|
||||
for (let slice of slices) {
|
||||
for (let params of slices) {
|
||||
output.push({
|
||||
slice,
|
||||
tops: KIRI.slicer.sliceZ(slice.z, realp, options).tops
|
||||
params,
|
||||
data: { tops: KIRI.slicer.sliceZ(params.z, realp, options, params).tops }
|
||||
});
|
||||
}
|
||||
reply({ seq, output: CODEC.encode(output) });
|
||||
|
|
|
|||
|
|
@ -176,9 +176,21 @@
|
|||
}
|
||||
|
||||
PRO.addTop = function(poly) {
|
||||
let top = new Top(poly);
|
||||
this.tops.push(top);
|
||||
return top;
|
||||
if (poly.length) {
|
||||
let top = new Top(poly);
|
||||
this.tops.push(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) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Slicing engine used by FDM, Laser, and SLA
|
||||
*/
|
||||
(function() {
|
||||
|
||||
if (self.kiri.slicer) return;
|
||||
|
|
@ -10,7 +13,8 @@
|
|||
slice,
|
||||
sliceZ,
|
||||
sliceWidget,
|
||||
connectLines
|
||||
connectLines,
|
||||
createSlice
|
||||
};
|
||||
|
||||
let KIRI = self.kiri,
|
||||
|
|
@ -138,8 +142,8 @@
|
|||
if (concurrent > 1) {
|
||||
if (bucketCount < concurrent) {
|
||||
bucketCount = concurrent;
|
||||
} else if (bucketCount > 128) {
|
||||
bucketCount = 128;
|
||||
} else if (bucketCount > 100) {
|
||||
bucketCount = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,42 +306,65 @@
|
|||
|
||||
function bucketZ(index, z, height, thick) {
|
||||
buckets[Math.floor(z * zScale)].slices.push({
|
||||
index, z, height, thick
|
||||
index, z, height, thick, total: zIndexes.length
|
||||
});
|
||||
}
|
||||
|
||||
async function sliceBuckets() {
|
||||
let output = [];
|
||||
// console.log({buckets});
|
||||
if (concurrent < 2) {
|
||||
sliceBucketsLocal(buckets, output);
|
||||
} else {
|
||||
let promises = [];
|
||||
for (let bucket of buckets) {
|
||||
promises.push(KIRI.minions.sliceBucket(bucket, options, output));
|
||||
}
|
||||
await tracker(promises, (i,t) => {
|
||||
if (concurrent) {
|
||||
let promises = buckets.map(
|
||||
bucket => KIRI.minions.sliceBucket(bucket, options, output)
|
||||
);
|
||||
await tracker(promises, (i,t,d) => {
|
||||
onupdate(0.1 + (i / t) * 0.9);
|
||||
});
|
||||
} else {
|
||||
let count = 0;
|
||||
for (let bucket of buckets) {
|
||||
for (let params of bucket.slices) {
|
||||
output.push(createSlice(
|
||||
params,
|
||||
sliceZ(params.z, bucket.points, options, params),
|
||||
options
|
||||
));
|
||||
onupdate(0.1 + (count++ / zIndexes.length) * 0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function sliceBucketsLocal(buckets, output) {
|
||||
let count = 0;
|
||||
for (let bucket of buckets) {
|
||||
for (let slice of bucket.slices) {
|
||||
let { index, z, height, thick } = slice;
|
||||
let { lines, groups, tops } = sliceZ(z, bucket.points, options);
|
||||
slice = newSlice(z).addTops(tops);
|
||||
slice.height = height;
|
||||
slice.index = index;
|
||||
slice.thick = thick;
|
||||
output.push(slice);
|
||||
onupdate(0.1 + (count++ / zIndexes.length) * 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
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 ***** */
|
||||
|
|
@ -421,7 +448,7 @@
|
|||
* @param {number} z
|
||||
* @param {number} [height] optional real height (fdm)
|
||||
*/
|
||||
function sliceZ(z, points, options = {}) {
|
||||
function sliceZ(z, points, options = {}, params = {}) {
|
||||
let phash = {},
|
||||
lines = [],
|
||||
p1, p2, p3;
|
||||
|
|
@ -477,28 +504,18 @@
|
|||
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 data = { lines, groups, tops };
|
||||
|
||||
// identify and add tops to slice
|
||||
// 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);
|
||||
// }
|
||||
// });
|
||||
// look for driver-specific slice post-processor
|
||||
if (options.mode) {
|
||||
let fn = KIRI.driver[options.mode].slicePost;
|
||||
if (fn) {
|
||||
fn(data, options, params);
|
||||
}
|
||||
}
|
||||
|
||||
return { lines, groups, tops };
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Slicing engine used by CAM
|
||||
*/
|
||||
(function() {
|
||||
|
||||
let KIRI = self.kiri,
|
||||
|
|
|
|||
|
|
@ -145,16 +145,12 @@ KIRI.minions = {
|
|||
slices,
|
||||
options
|
||||
}, data => {
|
||||
for (let rec of KIRI.codec.decode(data.output)) {
|
||||
let { slice, tops } = rec;
|
||||
let newSlice = KIRI.newSlice(slice.z);
|
||||
newSlice.index = slice.index;
|
||||
newSlice.thick = slice.thick;
|
||||
newSlice.height = slice.height;
|
||||
newSlice.addTops(tops);
|
||||
output.push(newSlice);
|
||||
let recs = KIRI.codec.decode(data.output);
|
||||
for (let rec of recs) {
|
||||
let { params, data } = rec;
|
||||
output.push(KIRI.slicer.createSlice(params, data));
|
||||
}
|
||||
resolve();
|
||||
resolve(recs);
|
||||
}, [ floatP.buffer ]);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@
|
|||
return settings;
|
||||
}
|
||||
|
||||
function getRangeParameters(settings, index) {
|
||||
function getRangeParameters(process, index) {
|
||||
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)) {
|
||||
return settings.process;
|
||||
return process;
|
||||
}
|
||||
let params = Object.clone(settings.process);
|
||||
let params = Object.clone(process);
|
||||
for (let range of ranges) {
|
||||
if (index >= range.lo && index <= range.hi) {
|
||||
for (let [key,value] of Object.entries(range.fields)) {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
|
||||
// smallish band-aid. refactor above to remove redundancy
|
||||
function updateParams(layer) {
|
||||
let process = getRangeParameters(settings, layer);
|
||||
let process = getRangeParameters(process, layer);
|
||||
zhop = process.zHopDistance || 0; // range
|
||||
retDist = process.outputRetractDist || 0; // range
|
||||
retSpeed = process.outputRetractSpeed * 60 || 1; // range
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@
|
|||
return a.dst - b.dst;
|
||||
});
|
||||
let { z, slice, offset } = order[0];
|
||||
let params = getRangeParameters(settings, slice.index);
|
||||
let params = getRangeParameters(process, slice.index);
|
||||
slice.prep = true;
|
||||
// retract between widgets or layers (when set)
|
||||
if (layerout.length && slice.widget !== lastWidget) {
|
||||
|
|
@ -474,7 +474,7 @@
|
|||
// iterate over layers, find extrusion on belt and
|
||||
// apply corrections and add brim when specified
|
||||
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 firstLayerBrim = Math.abs(params.firstLayerBrim);
|
||||
let firstLayerBrimIn = params.firstLayerBrimIn;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
PROTO = Object.clone(COLOR),
|
||||
bwcomp = (1 / Math.cos(Math.PI/4)),
|
||||
getRangeParameters = FDM.getRangeParameters,
|
||||
slicePost = true,
|
||||
debug = false;
|
||||
|
||||
let isThin = false; // force line rendering
|
||||
|
|
@ -46,6 +47,49 @@
|
|||
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
|
||||
*
|
||||
|
|
@ -62,32 +106,31 @@
|
|||
FDM.slice = function(settings, widget, onupdate, ondone) {
|
||||
FDM.fixExtruders(settings);
|
||||
let render = settings.render !== false,
|
||||
ctrl = settings.controller,
|
||||
spro = settings.process,
|
||||
sdev = settings.device,
|
||||
isBelt = sdev.bedBelt,
|
||||
{ process, device, controller } = settings,
|
||||
isBelt = device.bedBelt,
|
||||
isSynth = widget.track.synth,
|
||||
minSolid = spro.sliceSolidMinArea,
|
||||
solidLayers = spro.sliceSolidLayers,
|
||||
vaseMode = spro.sliceFillType === 'vase' && !isSynth,
|
||||
isDanger = controller.danger,
|
||||
minSolid = process.sliceSolidMinArea,
|
||||
solidLayers = process.sliceSolidLayers,
|
||||
vaseMode = process.sliceFillType === 'vase' && !isSynth,
|
||||
doSolidLayers = solidLayers && !vaseMode && !isSynth,
|
||||
metadata = settings.widget[widget.id] || {},
|
||||
extruder = metadata.extruder || 0,
|
||||
sliceHeight = spro.sliceHeight,
|
||||
firstSliceHeight = isBelt ? sliceHeight : spro.firstSliceHeight,
|
||||
nozzleSize = sdev.extruders[extruder].extNozzle,
|
||||
lineWidth = spro.sliceLineWidth || nozzleSize,
|
||||
fillOffsetMult = 1.0 - bound(spro.sliceFillOverlap, 0, 0.8),
|
||||
sliceHeight = process.sliceHeight,
|
||||
firstSliceHeight = isBelt ? sliceHeight : process.firstSliceHeight,
|
||||
nozzleSize = device.extruders[extruder].extNozzle,
|
||||
lineWidth = process.sliceLineWidth || nozzleSize,
|
||||
fillOffsetMult = 1.0 - bound(process.sliceFillOverlap, 0, 0.8),
|
||||
shellOffset = lineWidth,
|
||||
fillSpacing = lineWidth,
|
||||
fillOffset = lineWidth * fillOffsetMult,
|
||||
sliceFillAngle = spro.sliceFillAngle,
|
||||
supportDensity = spro.sliceSupportDensity,
|
||||
sliceFillAngle = process.sliceFillAngle,
|
||||
supportDensity = process.sliceSupportDensity,
|
||||
beltfact = Math.cos(Math.PI/4),
|
||||
doConcurrent = ctrl.threaded && KIRI.minions.concurrent;
|
||||
doConcurrent = controller.threaded && KIRI.minions.concurrent;
|
||||
|
||||
isFlat = ctrl.lineType === "flat";
|
||||
isThin = !isFlat && ctrl.lineType === "line";
|
||||
isFlat = controller.lineType === "flat";
|
||||
isThin = !isFlat && controller.lineType === "line";
|
||||
offset = lineWidth / 2;
|
||||
|
||||
if (isFlat) {
|
||||
|
|
@ -117,8 +160,8 @@
|
|||
firstSliceHeight = sliceHeight;
|
||||
}
|
||||
|
||||
const sliceMinHeight = spro.sliceAdaptive && spro.sliceMinHeight > 0 ?
|
||||
Math.min(spro.sliceMinHeight, sliceHeight) : 0;
|
||||
const sliceMinHeight = process.sliceAdaptive && process.sliceMinHeight > 0 ?
|
||||
Math.min(process.sliceMinHeight, sliceHeight) : 0;
|
||||
|
||||
if (firstSliceHeight < sliceHeight) {
|
||||
DBUG.log("invalid first layer height < slice height");
|
||||
|
|
@ -127,15 +170,25 @@
|
|||
}
|
||||
|
||||
SLICER.sliceWidget(widget, {
|
||||
mode: 'FDM',
|
||||
height: sliceHeight,
|
||||
minHeight: sliceMinHeight,
|
||||
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,
|
||||
// xray: 3,
|
||||
// view: view,
|
||||
indices: spro.indices,
|
||||
concurrent: doConcurrent
|
||||
// xray: 3,
|
||||
}, onSliceDone, onSliceUpdate);
|
||||
|
||||
function onSliceUpdate(update) {
|
||||
|
|
@ -169,8 +222,8 @@
|
|||
shadow = doConcurrent ?
|
||||
await KIRI.minions.union(alltops, 0.1) :
|
||||
POLY.union(alltops, 0.1, true);
|
||||
if (spro.sliceSupportExtra) {
|
||||
shadow = POLY.offset(shadow, spro.sliceSupportExtra);
|
||||
if (process.sliceSupportExtra) {
|
||||
shadow = POLY.offset(shadow, process.sliceSupportExtra);
|
||||
}
|
||||
widget.shadow = POLY.setZ(shadow, 0);
|
||||
// slices[0].output()
|
||||
|
|
@ -198,7 +251,7 @@
|
|||
}
|
||||
|
||||
// create shadow for non-belt supports
|
||||
if (!isBelt && (isSynth || (!isSynth && supportDensity && spro.sliceSupportEnable))) {
|
||||
if (!isBelt && (isSynth || (!isSynth && supportDensity && process.sliceSupportEnable))) {
|
||||
await doShadow(slices);
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +267,7 @@
|
|||
slice.addTop(u);
|
||||
}
|
||||
}
|
||||
let gap = sliceHeight * (isBelt ? 0 : spro.sliceSupportGap);
|
||||
let gap = sliceHeight * (isBelt ? 0 : process.sliceSupportGap);
|
||||
// clip tops to other widgets in group
|
||||
tops = slice.topPolys();
|
||||
for (let peer of widget.group) {
|
||||
|
|
@ -226,9 +279,9 @@
|
|||
if (Math.abs(Math.abs(pslice.z - slice.z) - gap) > 0.1) {
|
||||
continue;
|
||||
}
|
||||
// offset pslice tops by spro.sliceSupportOffset
|
||||
// offset pslice tops by process.sliceSupportOffset
|
||||
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 ntops = [];
|
||||
|
|
@ -276,7 +329,7 @@
|
|||
}
|
||||
|
||||
// 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
|
||||
// and other annotations
|
||||
|
|
@ -286,46 +339,48 @@
|
|||
slice.solids = [];
|
||||
});
|
||||
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
// create shells and diff inner fillable areas
|
||||
forSlices(0.0, promises ? 0.05 : 0.15, slice => {
|
||||
let params = slice.params = getRangeParameters(settings, slice.index);
|
||||
let shellFrac = (params.sliceShells - (params.sliceShells | 0));
|
||||
let sliceShells = params.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 = slice.index % parts;
|
||||
let trg = shellFrac > 0.5 ? 1 : parts - 1;
|
||||
sliceShells += rem >= trg ? 1 : 0;
|
||||
if (!slicePost) {
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
forSlices(0.0, promises ? 0.05 : 0.15, slice => {
|
||||
let params = slice.params = getRangeParameters(process, slice.index);
|
||||
let shellFrac = (params.sliceShells - (params.sliceShells | 0));
|
||||
let sliceShells = params.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 = slice.index % parts;
|
||||
let trg = shellFrac > 0.5 ? 1 : parts - 1;
|
||||
sliceShells += rem >= trg ? 1 : 0;
|
||||
}
|
||||
let first = slice.index === 0;
|
||||
let spaceMult = first ? process.firstLayerLineMult || 1 : 1;
|
||||
let isBottom = slice.index < process.sliceBottomLayers;
|
||||
let isTop = slice.index > slices.length - process.sliceTopLayers-1;
|
||||
let isDense = params.sliceFillSparse > 0.98;
|
||||
let solidWidth = params.sliceFillWidth || 1;
|
||||
if ((isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth) {
|
||||
slice.solid = {
|
||||
solidWidth,
|
||||
spaceMult
|
||||
};
|
||||
}
|
||||
let offset = shellOffset * spaceMult;
|
||||
let fillOff = fillOffset * spaceMult;
|
||||
let count = isSynth ? 1 : sliceShells;
|
||||
doShells(slice, count, offset, fillOff, {
|
||||
vase: vaseMode,
|
||||
thin: process.detectThinWalls && !isSynth,
|
||||
danger: controller.danger
|
||||
}, promises);
|
||||
}, "shells");
|
||||
if (promises) {
|
||||
// await Promise.all(promises);
|
||||
await tracker(promises, (i, t) => {
|
||||
trackupdate(i / t, 0.05, 0.15);
|
||||
});
|
||||
}
|
||||
let first = slice.index === 0;
|
||||
let spaceMult = first ? spro.firstLayerLineMult || 1 : 1;
|
||||
let isBottom = slice.index < spro.sliceBottomLayers;
|
||||
let isTop = slice.index > slices.length - spro.sliceTopLayers-1;
|
||||
let isDense = params.sliceFillSparse > 0.98;
|
||||
let solidWidth = params.sliceFillWidth || 1;
|
||||
if ((isBottom || ((isTop || isDense) && !vaseMode)) && !isSynth) {
|
||||
slice.solid = {
|
||||
solidWidth,
|
||||
spaceMult
|
||||
};
|
||||
}
|
||||
let offset = shellOffset * spaceMult;
|
||||
let fillOff = fillOffset * spaceMult;
|
||||
let count = isSynth ? 1 : sliceShells;
|
||||
doShells(slice, count, offset, fillOff, {
|
||||
vase: vaseMode,
|
||||
thin: spro.detectThinWalls && !isSynth,
|
||||
danger: ctrl.danger
|
||||
}, promises);
|
||||
}, "shells");
|
||||
if (promises) {
|
||||
// await Promise.all(promises);
|
||||
await tracker(promises, (i, t) => {
|
||||
trackupdate(i / t, 0.05, 0.15);
|
||||
});
|
||||
}
|
||||
|
||||
// just the top/bottom special solid layers
|
||||
|
|
@ -335,7 +390,7 @@
|
|||
doSolidLayerFill(slice, fillSpace, sliceFillAngle);
|
||||
}
|
||||
sliceFillAngle += 90.0;
|
||||
}, "shells");
|
||||
}, "solid layers");
|
||||
|
||||
// add lead in when specified in belt mode
|
||||
if (!isSynth && isBelt) {
|
||||
|
|
@ -374,13 +429,13 @@
|
|||
if (!start) start = slice;
|
||||
}
|
||||
}
|
||||
let offset = spro.firstLayerBeltLead * beltfact;
|
||||
let offset = process.firstLayerBeltLead * beltfact;
|
||||
// ensure we start against a layer with shells
|
||||
while (start.up && start.topShells().length === 0) {
|
||||
start = start.up;
|
||||
}
|
||||
// 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) {
|
||||
minx -= brim;
|
||||
maxx += brim;
|
||||
|
|
@ -414,7 +469,7 @@
|
|||
offset -= sliceHeight;
|
||||
}
|
||||
// add anchor bump
|
||||
let bump = spro.firstLayerBeltBump;
|
||||
let bump = process.firstLayerBeltBump;
|
||||
if (bump) {
|
||||
adds = adds.reverse().slice(1, adds.length - 1);
|
||||
let count = 1;
|
||||
|
|
@ -456,7 +511,7 @@
|
|||
// console.log('start'); await BASE.util.ptimer(1000);
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
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 solidWidth = params.sliceFillWidth || 1;
|
||||
let spaceMult = first ? params.firstLayerLineMult || 1 : 1;
|
||||
|
|
@ -477,16 +532,16 @@
|
|||
let lastType;
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
forSlices(0.5, promises ? 0.55 : 0.7, slice => {
|
||||
let params = slice.params || spro;
|
||||
let params = slice.params || process;
|
||||
if (vaseMode || !params.sliceFillSparse) {
|
||||
return;
|
||||
}
|
||||
let newType = params.sliceFillType;
|
||||
doSparseLayerFill(slice, {
|
||||
settings: settings,
|
||||
process: spro,
|
||||
device: sdev,
|
||||
lineWidth: lineWidth,
|
||||
settings,
|
||||
process,
|
||||
device,
|
||||
lineWidth,
|
||||
spacing: fillOffset,
|
||||
density: params.sliceFillSparse,
|
||||
bounds: widget.getBoundingBox(),
|
||||
|
|
@ -505,7 +560,7 @@
|
|||
} else if (isSynth) {
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
forSlices(0.5, promises ? 0.6 : 0.7, slice => {
|
||||
let params = slice.params || spro;
|
||||
let params = slice.params || process;
|
||||
let density = params.sliceSupportDensity;
|
||||
if (density)
|
||||
for (let top of slice.tops) {
|
||||
|
|
@ -523,16 +578,16 @@
|
|||
}
|
||||
|
||||
// auto support generation
|
||||
if (!isBelt && !isSynth && supportDensity && spro.sliceSupportEnable) {
|
||||
if (!isBelt && !isSynth && supportDensity && process.sliceSupportEnable) {
|
||||
doShadow(slices);
|
||||
// console.log('start'); await BASE.util.ptimer(1000);
|
||||
forSlices(0.7, 0.8, slice => {
|
||||
doSupport(slice, spro, widget.shadow, ctrl.danger);
|
||||
doSupport(slice, process, widget.shadow, controller.danger);
|
||||
}, "support");
|
||||
// console.log('stop'); await BASE.util.ptimer(1000);
|
||||
let promises = doConcurrent ? [] : undefined;
|
||||
forSlices(0.8, promises ? 0.88 : 0.9, slice => {
|
||||
doSupportFill(promises, slice, lineWidth, supportDensity, spro.sliceSupportArea);
|
||||
doSupportFill(promises, slice, lineWidth, supportDensity, process.sliceSupportArea);
|
||||
}, "support");
|
||||
if (promises) {
|
||||
await tracker(promises, (i, t) => {
|
||||
|
|
@ -544,8 +599,8 @@
|
|||
// render if not explicitly disabled
|
||||
if (render) {
|
||||
forSlices(0.9, 1.0, slice => {
|
||||
let params = slice.params || spro;
|
||||
doRender(slice, isSynth, params, ctrl.devel);
|
||||
let params = slice.params || process;
|
||||
doRender(slice, isSynth, params, controller.devel);
|
||||
}, "render");
|
||||
}
|
||||
|
||||
|
|
@ -631,7 +686,7 @@
|
|||
// console.log(slice.index, slice.render.stats);
|
||||
}
|
||||
|
||||
// shared with SLA driver
|
||||
// shared with SLA driver and minions
|
||||
FDM.share = {
|
||||
doShells,
|
||||
doTopShells,
|
||||
|
|
@ -682,6 +737,11 @@
|
|||
}
|
||||
|
||||
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 ];
|
||||
|
||||
if (opt.vase) {
|
||||
|
|
@ -801,6 +861,8 @@
|
|||
|
||||
// for diffing
|
||||
top.last = last;
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue