improve performance of threaded infill clipper with better encoding and zerocopy

This commit is contained in:
Stewart Allen 2022-10-15 17:32:12 -04:00
commit 96047dc958
4 changed files with 63 additions and 13 deletions

View file

@ -733,8 +733,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) {
// sparse layers only present when non-vase mose and sparse % > 0 // sparse layers only present when non-vase mose and sparse % > 0
if (!isSynth && !vaseMode) { if (!isSynth && !vaseMode) {
let lastType; let lastType;
// disabled until memory issue tracked down let promises = isConcurrent ? [] : undefined;
let promises = false && isConcurrent ? [] : undefined;
forSlices(0.5, promises ? 0.55 : 0.7, slice => { forSlices(0.5, promises ? 0.55 : 0.7, slice => {
let params = slice.params || process; let params = slice.params || process;
if (!params.sliceFillSparse) { if (!params.sliceFillSparse) {

View file

@ -91,20 +91,29 @@ const funcs = {
}, },
clip: (data, seq) => { clip: (data, seq) => {
let clip = new clib.Clipper(); const clip = new clib.Clipper();
let ctre = new clib.PolyTree(); const ctre = new clib.PolyTree();
let clips = []; const clips = [];
const M = base.config.clipper;
clip.AddPaths(data.lines, ptyp.ptSubject, false); let lines = data.lines.map(array => {
clip.AddPaths(data.polys, ptyp.ptClip, true); return codec.decodePointArray2D(array, data.z, (X, Y) => { return {X: X*M, Y: Y*M} })
});
let polys = data.polys.map(array => {
return codec.decodePointArray2D(array, data.z, (X, Y) => { return {X: X*M, Y: Y*M} })
});
clip.AddPaths(lines, ptyp.ptSubject, false);
clip.AddPaths(polys, ptyp.ptClip, true);
const state = { zeros: [] };
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), state.zeros));
} }
} }
reply({ seq, clips }); reply({ seq, clips }, state.zeros);
}, },
sliceZ: (data, seq) => { sliceZ: (data, seq) => {

View file

@ -113,7 +113,7 @@ kiri.minions = {
minwork.queue({ minwork.queue({
cmd: "union", cmd: "union",
minarea, minarea,
polys: codec.encode(polys.slice(i, i + polyper)) polys: codec.encode(polys.slice(i, i + polyper), state)
}, receiver, state.zeros); }, receiver, state.zeros);
} }
}); });
@ -149,10 +149,12 @@ kiri.minions = {
if (concurrent < 2) { if (concurrent < 2) {
reject("concurrent clip unavailable"); reject("concurrent clip unavailable");
} }
const state = { zeros: [] };
minwork.queue({ minwork.queue({
cmd: "clip", cmd: "clip",
polys: POLY.toClipper(polys), polys: codec.encode(polys.map(poly => codec.encodePointArray2D(poly.points, state)), state),
lines: lines.map(a => a.map(p => p.toClipper())), lines: codec.encode(lines.map(array => codec.encodePointArray2D(array, state)), state),
z: slice.z z: slice.z
}, data => { }, data => {
let polys = codec.decode(data.clips); let polys = codec.decode(data.clips);
@ -164,7 +166,7 @@ kiri.minions = {
} }
} }
resolve(polys); resolve(polys);
}); }, state.zeros);
}); });
}, },

View file

@ -22,6 +22,8 @@ const codec = exports({
allocFloat32Array: allocFloat32Array, allocFloat32Array: allocFloat32Array,
encodePointArray, encodePointArray,
decodePointArray, decodePointArray,
encodePointArray2D,
decodePointArray2D,
toCodable toCodable
}); });
@ -173,6 +175,29 @@ function encodePointArray(points, state, z) {
return array; return array;
} }
function encodePointArray2D(points, state) {
if (!points) {
return null;
}
const length = points.length;
if (length === 0) {
return points;
}
const array = codec.allocFloat32Array(length * 2, state.zeros);
for (let i=0, pos=0, point; i<length; i++) {
point = points[i];
array[pos++] = point.x;
array[pos++] = point.y;
}
return array;
}
function decodePointArray(array) { function decodePointArray(array) {
if (!array) return null; if (!array) return null;
@ -186,6 +211,21 @@ function decodePointArray(array) {
return points; return points;
} }
function decodePointArray2D(array, z, fn) {
if (!array) return null;
const length = array.length;
const points = new Array(length / 2);
for (let vid=0, pid=0; vid < length; ) {
points[pid++] = fn ?
fn(array[vid++], array[vid++]) :
base.newPoint(array[vid++], array[vid++], z);
}
return points;
}
// ----- Widget Codec ----- // ----- Widget Codec -----
kiri.Widget.prototype.encode = function(state) { kiri.Widget.prototype.encode = function(state) {