add poly union to wasm geo helper
This commit is contained in:
parent
b6d91f39a5
commit
c9cf45bc40
4 changed files with 89 additions and 6 deletions
|
|
@ -1817,7 +1817,14 @@
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
} else if (debug) {
|
} else if (debug) {
|
||||||
console.log("union debug", { src, dst });
|
console.log("union debug", {
|
||||||
|
src,
|
||||||
|
dst,
|
||||||
|
d0: Math.abs(src[0].poly.area() - dst[0].poly.area()),
|
||||||
|
d1: Math.abs(src[1].poly.area() - dst[1].poly.area()),
|
||||||
|
m0: src[0].isEqual2D(dst[0]),
|
||||||
|
m1: src[1].isEqual2D(dst[1])
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@ if (!self.window) (function() {
|
||||||
const factor = self.base.config.clipper;
|
const factor = self.base.config.clipper;
|
||||||
const geo = self.geo;
|
const geo = self.geo;
|
||||||
|
|
||||||
geo.poly = { offset : polyOffset };
|
geo.poly = {
|
||||||
|
union: polyUnion,
|
||||||
|
offset: polyOffset
|
||||||
|
};
|
||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
console.log(...arguments);
|
console.log(...arguments);
|
||||||
|
|
@ -70,6 +73,27 @@ if (!self.window) (function() {
|
||||||
return polyNest(out);
|
return polyNest(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function polyUnion(polys, z) {
|
||||||
|
let wasm = geo.wasm,
|
||||||
|
memat = wasm.malloc(1024 * 128),
|
||||||
|
writer = new DataWriter(wasm.heap, memat),
|
||||||
|
pcount = 0;
|
||||||
|
polys.forEach(poly => pcount += writePoly(writer, poly));
|
||||||
|
let resat = wasm.union(memat, pcount, pcount * factor),
|
||||||
|
reader = new DataReader(wasm.heap, resat),
|
||||||
|
out = [];
|
||||||
|
for (;;) {
|
||||||
|
let poly = readPoly(reader, z);
|
||||||
|
if (poly) {
|
||||||
|
out.push(poly);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wasm.free(memat);
|
||||||
|
return polyNest(out);
|
||||||
|
}
|
||||||
|
|
||||||
// nest closed polygons without existing parent / child relationships
|
// nest closed polygons without existing parent / child relationships
|
||||||
function polyNest(polys) {
|
function polyNest(polys) {
|
||||||
polys.sort((a,b) => {
|
polys.sort((a,b) => {
|
||||||
|
|
@ -120,14 +144,16 @@ if (!self.window) (function() {
|
||||||
let heap = new DataView(exports.memory.buffer);
|
let heap = new DataView(exports.memory.buffer);
|
||||||
let wasm = geo.wasm = {
|
let wasm = geo.wasm = {
|
||||||
heap,
|
heap,
|
||||||
|
exports,
|
||||||
memory: exports.memory,
|
memory: exports.memory,
|
||||||
start: exports._start,
|
|
||||||
offset: exports.poly_offset,
|
|
||||||
malloc: exports.mem_get,
|
malloc: exports.mem_get,
|
||||||
free: exports.mem_clr
|
start: exports._start,
|
||||||
|
free: exports.mem_clr,
|
||||||
|
union: exports.poly_union,
|
||||||
|
offset: exports.poly_offset
|
||||||
};
|
};
|
||||||
|
|
||||||
wasm.start();
|
// wasm.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -92,3 +92,53 @@ Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset) {
|
||||||
|
|
||||||
return resat;
|
return resat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__ ((export_name("poly_union")))
|
||||||
|
Uint32 poly_union(Uint32 memat, Uint32 polys) {
|
||||||
|
|
||||||
|
using namespace ClipperLib;
|
||||||
|
|
||||||
|
Paths ins(polys);
|
||||||
|
Paths outs;
|
||||||
|
Uint32 pos = memat;
|
||||||
|
Uint16 poly = 0;
|
||||||
|
|
||||||
|
while (poly < polys) {
|
||||||
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
||||||
|
Uint16 points = ls->length;
|
||||||
|
pos += 2;
|
||||||
|
while (points-- > 0) {
|
||||||
|
struct point32 *ip = (struct point32 *)(mem + pos);
|
||||||
|
pos += 8;
|
||||||
|
ins[poly] << IntPoint(ip->x, ip->y);
|
||||||
|
}
|
||||||
|
poly++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Clipper clip;
|
||||||
|
clip.AddPath(ins[0], ptSubject, true);
|
||||||
|
clip.AddPath(ins[1], ptClip, true);
|
||||||
|
clip.Execute(ctUnion, outs, pftEvenOdd, pftEvenOdd);
|
||||||
|
|
||||||
|
Uint32 resat = pos;
|
||||||
|
|
||||||
|
for (Path po : outs) {
|
||||||
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
||||||
|
ls->length = po.size();
|
||||||
|
pos += 2;
|
||||||
|
for (IntPoint pt : po) {
|
||||||
|
struct point32 *ip = (struct point32 *)(mem + pos);
|
||||||
|
ip->x = (int)pt.X;
|
||||||
|
ip->y = (int)pt.Y;
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// null terminate
|
||||||
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
||||||
|
ls->length = 0;
|
||||||
|
|
||||||
|
clip.Clear();
|
||||||
|
|
||||||
|
return resat;
|
||||||
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in a new issue