improve efficiency of wasm poly diff

This commit is contained in:
Stewart Allen 2021-06-23 11:13:45 -04:00
commit 14ee94311d
5 changed files with 60 additions and 54 deletions

View file

@ -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));
}
}

View file

@ -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);

View file

@ -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)),

View file

@ -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();
}

Binary file not shown.