From 96047dc958522884baff8b7080ec89fb63b51eff Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 15 Oct 2022 17:32:12 -0400 Subject: [PATCH] improve performance of threaded infill clipper with better encoding and zerocopy --- src/kiri-mode/fdm/slice.js | 3 +-- src/kiri-run/minion.js | 23 +++++++++++++++------- src/kiri-run/worker.js | 10 ++++++---- src/kiri/codec.js | 40 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/kiri-mode/fdm/slice.js b/src/kiri-mode/fdm/slice.js index 955d234f..9305fbdb 100644 --- a/src/kiri-mode/fdm/slice.js +++ b/src/kiri-mode/fdm/slice.js @@ -733,8 +733,7 @@ FDM.slice = function(settings, widget, onupdate, ondone) { // sparse layers only present when non-vase mose and sparse % > 0 if (!isSynth && !vaseMode) { let lastType; - // disabled until memory issue tracked down - let promises = false && isConcurrent ? [] : undefined; + let promises = isConcurrent ? [] : undefined; forSlices(0.5, promises ? 0.55 : 0.7, slice => { let params = slice.params || process; if (!params.sliceFillSparse) { diff --git a/src/kiri-run/minion.js b/src/kiri-run/minion.js index 98f2765d..5bc83274 100644 --- a/src/kiri-run/minion.js +++ b/src/kiri-run/minion.js @@ -91,20 +91,29 @@ const funcs = { }, clip: (data, seq) => { - let clip = new clib.Clipper(); - let ctre = new clib.PolyTree(); - let clips = []; + const clip = new clib.Clipper(); + const ctre = new clib.PolyTree(); + const clips = []; + const M = base.config.clipper; - clip.AddPaths(data.lines, ptyp.ptSubject, false); - clip.AddPaths(data.polys, ptyp.ptClip, true); + let lines = data.lines.map(array => { + 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)) { 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) => { diff --git a/src/kiri-run/worker.js b/src/kiri-run/worker.js index 184bf086..a1a3dad8 100644 --- a/src/kiri-run/worker.js +++ b/src/kiri-run/worker.js @@ -113,7 +113,7 @@ kiri.minions = { minwork.queue({ cmd: "union", minarea, - polys: codec.encode(polys.slice(i, i + polyper)) + polys: codec.encode(polys.slice(i, i + polyper), state) }, receiver, state.zeros); } }); @@ -149,10 +149,12 @@ kiri.minions = { if (concurrent < 2) { reject("concurrent clip unavailable"); } + const state = { zeros: [] }; + minwork.queue({ cmd: "clip", - polys: POLY.toClipper(polys), - lines: lines.map(a => a.map(p => p.toClipper())), + polys: codec.encode(polys.map(poly => codec.encodePointArray2D(poly.points, state)), state), + lines: codec.encode(lines.map(array => codec.encodePointArray2D(array, state)), state), z: slice.z }, data => { let polys = codec.decode(data.clips); @@ -164,7 +166,7 @@ kiri.minions = { } } resolve(polys); - }); + }, state.zeros); }); }, diff --git a/src/kiri/codec.js b/src/kiri/codec.js index 19d546ae..c476f8fa 100644 --- a/src/kiri/codec.js +++ b/src/kiri/codec.js @@ -22,6 +22,8 @@ const codec = exports({ allocFloat32Array: allocFloat32Array, encodePointArray, decodePointArray, + encodePointArray2D, + decodePointArray2D, toCodable }); @@ -173,6 +175,29 @@ function encodePointArray(points, state, z) { 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