diff --git a/src/geo/polygons.js b/src/geo/polygons.js index 9cc5efaa..5d4e17a1 100644 --- a/src/geo/polygons.js +++ b/src/geo/polygons.js @@ -309,45 +309,40 @@ return to; } - // expensive but worth it? - clip.StrictlySimple = true; - const JS = true; - if (outA) { - if (JS) { + if (JS) { + // expensive but worth it? + clip.StrictlySimple = true; + if (outA) { clip.AddPaths(sp1, ptyp.ptSubject, true); clip.AddPaths(sp2, ptyp.ptClip, true); - if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) { cleanClipperTree(ctre); filter(fromClipperTree(ctre, z, null, null, min), outA); } - } else { - let woutA = filter(geo.poly.diff(setA, setB, z)); - outA.appendAll(woutA); - // console.log({outA, woutA}); } - } - - if (outB) { - if (outA) { - ctre.Clear(); - clip.Clear(); - } - - if (JS) { + if (outB) { + if (outA) { + ctre.Clear(); + clip.Clear(); + } clip.AddPaths(sp2, ptyp.ptSubject, true); clip.AddPaths(sp1, ptyp.ptClip, true); - if (clip.Execute(ctyp.ctDifference, ctre, cfil.pftEvenOdd, cfil.pftEvenOdd)) { cleanClipperTree(ctre); filter(fromClipperTree(ctre, z, null, null, min), outB); } - } else { - let woutB = filter(geo.poly.diff(setB, setA, z)); - outB.appendAll(woutB); - // console.log({outB, woutB}); + } + } 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)); } } diff --git a/src/geo/wasm.js b/src/geo/wasm.js index 243c9f6e..8d2cc03e 100644 --- a/src/geo/wasm.js +++ b/src/geo/wasm.js @@ -11,12 +11,6 @@ if (!self.window) (function() { const geo = self.geo; const debug = false; - geo.poly = { - diff: polyDiff, - union: polyUnion, - offset: polyOffset - }; - function log() { console.log(...arguments); } @@ -76,34 +70,36 @@ if (!self.window) (function() { function polyOffset(polys, offset, z) { let wasm = geo.wasm, - memat = wasm.malloc(1024 * 128), - pcount = writePolys(new DataWriter(wasm.heap, memat), polys), - resat = wasm.offset(memat, pcount, offset * factor), + buffer = geo.wasm.shared, + pcount = writePolys(new DataWriter(wasm.heap, buffer), polys), + resat = wasm.fn.offset(buffer, pcount, offset * factor), out = readPolys(new DataReader(wasm.heap, resat), z); - wasm.free(memat); return polyNest(out); } function polyUnion(polys, z) { let wasm = geo.wasm, - memat = wasm.malloc(1024 * 128), - pcount = writePolys(new DataWriter(wasm.heap, memat), polys), - resat = wasm.union(memat, pcount), + buffer = geo.wasm.shared, + pcount = writePolys(new DataWriter(wasm.heap, buffer), polys), + resat = wasm.fn.union(buffer, pcount), out = readPolys(new DataReader(wasm.heap, resat), z); - wasm.free(memat); return polyNest(out); } - function polyDiff(polysA, polysB, z) { + function polyDiff(polysA, polysB, z, AB, BA) { let wasm = geo.wasm, - memat = wasm.malloc(1024 * 128), - writer = new DataWriter(wasm.heap, memat), + buffer = geo.wasm.shared, + writer = new DataWriter(wasm.heap, buffer), pcountA = writePolys(writer, polysA), pcountB = writePolys(writer, polysB), - resat = wasm.diff(memat, pcountA, pcountB, 1, 0), - out = readPolys(new DataReader(wasm.heap, resat), z); - wasm.free(memat); - return polyNest(out); + resat = wasm.fn.diff(buffer, pcountA, pcountB, AB?1:0, BA?1:0, base.config.clipperClean), + reader = new DataReader(wasm.heap, resat); + if (AB) { + AB.appendAll(polyNest(readPolys(reader, z))); + } + if (BA) { + BA.appendAll(polyNest(readPolys(reader, z))); + } } // nest closed polygons without existing parent / child relationships @@ -138,10 +134,11 @@ if (!self.window) (function() { let newPolygon = self.base.newPolygon; let p1 = newPolygon().add(0,0).add(4,0).add(4,4).add(0,4); let p2 = p1.clone().setZ(0).move({x:2, y:2}); - let d1 = geo.poly.diff([p1], [p2], 0); - let d2 = geo.poly.diff([p2], [p1], 0); + let d1 = []; + let d2 = []; + geo.wasm.js.diff([p1], [p2], 0, d1, d2); console.log('diff',{p1:p1.points, p2:p2.points, d1:d1[0].points, d2:d2[0].points}); - let o1 = geo.poly.offset([p1], 1, 0); + let o1 = geo.wasm.js.offset([p1], 1, 0); console.log('offs',{o1:o1[0].points}); } @@ -162,8 +159,8 @@ if (!self.window) (function() { } })) .then(results => { - let {module, instance} = results; - let {exports} = instance; + let { module, instance } = results; + let { exports } = instance; let heap = new DataView(exports.memory.buffer); let wasm = geo.wasm = { heap, @@ -172,10 +169,18 @@ if (!self.window) (function() { memmax: exports.memory.buffer.byteLength, malloc: exports.mem_get, free: exports.mem_clr, + set_debug: exports.set_debug + }; + wasm.shared = wasm.malloc(1024 * 1024 * 10), + wasm.fn = { diff: exports.poly_diff, union: exports.poly_union, - offset: exports.poly_offset, - set_debug: exports.set_debug + offset: exports.poly_offset + }; + wasm.js = { + diff: polyDiff, + union: polyUnion, + offset: polyOffset }; if (debug) { wasm.set_debug(1); diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js index de6e9abb..cbee0860 100644 --- a/src/mode/fdm/slice.js +++ b/src/mode/fdm/slice.js @@ -1171,7 +1171,7 @@ // create inner clip offset from tops (unless pre-computed) if (!slice.offsets) { // POLY.expand(tops, offset, slice.z, slice.offsets = []); - slice.offsets = geo.poly.offset(tops, offset, slice.z); + slice.offsets = geo.wasm.js.offset(tops, offset, slice.z); } let traces = POLY.flatten(slice.topShells().clone(true)), diff --git a/wasm/kiri-geo.cpp b/wasm/kiri-geo.cpp index 1b9d412d..f47dc2c3 100644 --- a/wasm/kiri-geo.cpp +++ b/wasm/kiri-geo.cpp @@ -135,7 +135,7 @@ Uint32 poly_union(Uint32 memat, Uint32 polys, float offset) { } __attribute__ ((export_name("poly_diff"))) -Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, Uint8 AB, Uint8 BA) { +Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, Uint8 AB, Uint8 BA, Uint32 clean) { Paths inA(polysA); Paths inB(polysB); @@ -152,6 +152,9 @@ Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, Uint8 AB, Uint8 BA) clip.AddPaths(inA, ptSubject, true); clip.AddPaths(inB, ptClip, true); clip.Execute(ctDifference, outs, pftEvenOdd, pftEvenOdd); + if (clean > 0) { + CleanPolygons(outs, (double)clean); + } pos = writePolys(outs, pos); clip.Clear(); } @@ -162,6 +165,9 @@ Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, Uint8 AB, Uint8 BA) clip.AddPaths(inB, ptSubject, true); clip.AddPaths(inA, ptClip, true); clip.Execute(ctDifference, outs, pftEvenOdd, pftEvenOdd); + if (clean > 0) { + CleanPolygons(outs, (double)clean); + } pos = writePolys(outs, pos); clip.Clear(); } diff --git a/wasm/kiri-geo.wasm b/wasm/kiri-geo.wasm index 7c4a688c..69cbb00d 100755 Binary files a/wasm/kiri-geo.wasm and b/wasm/kiri-geo.wasm differ