add profiling. use simple tops for support clipping

This commit is contained in:
Stewart Allen 2021-06-24 22:23:42 -04:00
commit 80e8f1c8e6
3 changed files with 55 additions and 35 deletions

View file

@ -292,7 +292,7 @@
* @param {number} [minArea] * @param {number} [minArea]
* @returns {Polygon[]} out * @returns {Polygon[]} out
*/ */
function subtract(setA, setB, outA, outB, z, minArea) { function subtract(setA, setB, outA, outB, z, minArea, opt = {}) {
let min = minArea || 0.1, let min = minArea || 0.1,
out = []; out = [];
@ -306,7 +306,25 @@
return to; return to;
} }
if (true) { if (opt.prof) {
if (setA.length === 0 || setB.length === 0) {
console.log('sub_zero', {setA, setB});
}
opt.prof.pin = (opt.prof.pin || 0) + points(setA) + points(setB);
opt.prof.call = (opt.prof.call || 0) + 1;
}
if (opt.wasm) {
let oA = outA ? [] : undefined;
let oB = outB ? [] : undefined;
geo.wasm.js.diff(setA, setB, z, oA, oB);
if (oA) {
outA.appendAll(filter(oA));
}
if (oB) {
outB.appendAll(filter(oB));
}
} else {
let clib = self.ClipperLib, let clib = self.ClipperLib,
ctyp = clib.ClipType, ctyp = clib.ClipType,
ptyp = clib.PolyType, ptyp = clib.PolyType,
@ -338,16 +356,10 @@
filter(fromClipperTree(ctre, z, null, null, min), outB); filter(fromClipperTree(ctre, z, null, null, min), outB);
} }
} }
} else {
let oA = outA ? [] : undefined;
let oB = outB ? [] : undefined;
geo.wasm.js.diff(setA, setB, z, oA, oB);
if (oA) {
outA.appendAll(filter(oA));
}
if (oB) {
outB.appendAll(filter(oB));
} }
if (opt.prof) {
opt.prof.pout = (opt.prof.pout || 0) + points(out);
} }
return out; return out;

View file

@ -106,6 +106,10 @@
return this.tops.map(top => top.poly); return this.tops.map(top => top.poly);
}; };
PRO.topSimples = function() {
return this.tops.map(top => top.simple);
};
// FDM top intersect optimization // FDM top intersect optimization
PRO.topPolysFlat = function() { PRO.topPolysFlat = function() {
if (this.topFlatPolys) { if (this.topFlatPolys) {
@ -188,7 +192,7 @@
top.fill_off = poly.fill_off; top.fill_off = poly.fill_off;
top.last = poly.last; top.last = poly.last;
top.shells = poly.shells; top.shells = poly.shells;
top.shadow = poly.shadow; top.simple = poly.simple;
this.tops.push(top); this.tops.push(top);
return top; return top;
} }

View file

@ -28,6 +28,10 @@
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,
noop = function() {},
profile = false,
profileStart = profile ? console.profile : noop,
profileEnd = profile ? console.profileEnd : noop,
debug = false; debug = false;
let isThin = false, // force line rendering let isThin = false, // force line rendering
@ -88,9 +92,9 @@
danger: isDanger danger: isDanger
})); }));
} }
// add shadow (low rez poly) if needed // add simple (low rez poly) where less accuracy is OK
for (let top of nutops) { for (let top of nutops) {
top.shadow = top.poly.clean(true, undefined, CONF.clipper / 10); top.simple = top.poly.clean(true, undefined, CONF.clipper / 10);
} }
data.tops = nutops; data.tops = nutops;
}; };
@ -203,7 +207,7 @@
// create shadow for clipping supports // create shadow for clipping supports
let alltops = widget.group let alltops = widget.group
.map(w => w.slices).flat() .map(w => w.slices).flat()
.map(s => s.tops).flat().map(t => t.shadow); .map(s => s.tops).flat().map(t => t.simple);
let shadow = isConcurrent ? let shadow = isConcurrent ?
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);
@ -281,16 +285,6 @@
} }
// trim to group's shadow if not in belt mode // trim to group's shadow if not in belt mode
if (!isBelt) { if (!isBelt) {
// let group = widget.group[0];
// if (!group.shadow) {
// let gs = [];
// for (let w of group) {
// if (w.shadow) {
// gs = POLY.union([w.shadow,...gs],null,0.1);
// }
// }
// group.shadow = gs;
// }
tops = POLY.setZ(POLY.trimTo(tops, widget.shadow), slice.z); tops = POLY.setZ(POLY.trimTo(tops, widget.shadow), slice.z);
} }
} }
@ -452,14 +446,18 @@
// calculations only relevant when solid layers are used // calculations only relevant when solid layers are used
if (solidLayers && !vaseMode && !isSynth) { if (solidLayers && !vaseMode && !isSynth) {
profileStart("delta");
forSlices(0.2, 0.34, slice => { forSlices(0.2, 0.34, slice => {
if (slice.index > 0) doDiff(slice, solidMinArea); if (slice.index > 0) doDiff(slice, solidMinArea);
}, "layer deltas"); }, "layer deltas");
profileEnd();
profileStart("delta-project");
forSlices(0.34, 0.35, slice => { forSlices(0.34, 0.35, slice => {
projectFlats(slice, solidLayers); projectFlats(slice, solidLayers);
projectBridges(slice, solidLayers); projectBridges(slice, solidLayers);
}, "layer deltas"); }, "layer deltas");
// console.log('start'); await BASE.util.ptimer(1000); profileEnd();
profileStart("solid-fill")
let promises = isConcurrent ? [] : undefined; let promises = isConcurrent ? [] : undefined;
forSlices(0.35, promises ? 0.4 : 0.5, slice => { forSlices(0.35, promises ? 0.4 : 0.5, slice => {
let params = slice.params || process; let params = slice.params || process;
@ -475,7 +473,7 @@
trackupdate(i / t, 0.4, 0.5); trackupdate(i / t, 0.4, 0.5);
}); });
} }
// console.log('stop'); await BASE.util.ptimer(1000); profileEnd();
} }
if (!isSynth && !vaseMode) { if (!isSynth && !vaseMode) {
@ -532,15 +530,16 @@
// auto support generation // auto support generation
if (!isBelt && !isSynth && supportDensity && process.sliceSupportEnable) { if (!isBelt && !isSynth && supportDensity && process.sliceSupportEnable) {
doShadow(slices); doShadow(slices);
// console.log('start'); await BASE.util.ptimer(1000); profileStart("support");
let promises = []; let promises = [];
forSlices(0.7, 0.75, slice => { forSlices(0.7, 0.75, slice => {
promises.push(doSupport(slice, process, widget.shadow, controller.danger)); promises.push(doSupport(slice, process, widget.shadow, { exp: isDanger }));
}, "support"); }, "support");
await tracker(promises, (i, t) => { await tracker(promises, (i, t) => {
trackupdate(i / t, 0.75, 0.8); trackupdate(i / t, 0.75, 0.8);
}); });
// console.log('stop'); await BASE.util.ptimer(1000); profileEnd();
profileStart("support-fill");
promises = false && isConcurrent ? [] : undefined; promises = false && isConcurrent ? [] : undefined;
forSlices(0.8, promises ? 0.88 : 0.9, slice => { forSlices(0.8, promises ? 0.88 : 0.9, slice => {
doSupportFill(promises, slice, lineWidth, supportDensity, process.sliceSupportArea); doSupportFill(promises, slice, lineWidth, supportDensity, process.sliceSupportArea);
@ -550,6 +549,7 @@
trackupdate(i / t, 0.88, 0.9); trackupdate(i / t, 0.88, 0.9);
}); });
} }
profileEnd();
} }
// render if not explicitly disabled // render if not explicitly disabled
@ -796,6 +796,7 @@
// for diffing // for diffing
top.last = last; top.last = last;
// top.last_simple = last.map(p => p.clean(true, undefined, CONF.clipper / 10));
return top; return top;
} }
@ -1155,7 +1156,7 @@
/** /**
* calculate external overhangs requiring support * calculate external overhangs requiring support
*/ */
async function doSupport(slice, proc, shadow, experimental) { async function doSupport(slice, proc, shadow, opt = {}) {
let maxBridge = proc.sliceSupportSpan || 5, let maxBridge = proc.sliceSupportSpan || 5,
minArea = proc.supportMinArea, minArea = proc.supportMinArea,
pillarSize = proc.sliceSupportSize, pillarSize = proc.sliceSupportSize,
@ -1179,11 +1180,11 @@
down_tops = down ? down.topPolys() : null, down_tops = down ? down.topPolys() : null,
down_traces = down ? POLY.flatten(down.topShells().clone(true)) : null; down_traces = down ? POLY.flatten(down.topShells().clone(true)) : null;
if (experimental && down_tops) { if (opt.exp && down_tops) {
let points = down_tops.map(p => p.deepLength).reduce((a,v)=>a+v); let points = down_tops.map(p => p.deepLength).reduce((a,v)=>a+v);
if (points > 200) { if (points > 200) {
// use de-rez'd top shadow instead // use de-rez'd top shadow instead
down_tops = down.tops.map(t => t.shadow); down_tops = down.topSimples();
// de-rez trace polys because it's not that important for supports // de-rez trace polys because it's not that important for supports
down_traces = down_traces.map(p => p.clean(true, undefined, CONF.clipper / 10)); down_traces = down_traces.map(p => p.clean(true, undefined, CONF.clipper / 10));
} }
@ -1271,7 +1272,10 @@
let trimmed = [], culled = []; let trimmed = [], culled = [];
// clip supports to shell offsets // clip supports to shell offsets
POLY.subtract(supports, down.topPolys(), trimmed, null, slice.z, min); POLY.subtract(supports, down.topSimples(), trimmed, null, slice.z, min, {
prof: opt.prof,
wasm: false
});
// set depth hint on support polys for infill density // set depth hint on support polys for infill density
trimmed.forEach(function(trim) { trimmed.forEach(function(trim) {