/** Copyright Stewart Allen -- All Rights Reserved */ "use strict"; // only active in workers if (!self.window) (function() { if (!self.geo) self.geo = {}; const factor = self.base.config.clipper; const geo = self.geo; geo.poly = { diff: polyDiff, union: polyUnion, offset: polyOffset }; function log() { console.log(...arguments); } function writePoly(view, poly, inner) { if (inner) { poly.setCounterClockwise(); } else { poly.setClockwise(); } let count = 1; let points = poly.points; let inners = poly.inner; view.writeU16(points.length, true); for (let i=0, il=points.length; i 0) { poly.add(view.readI32(true)/factor, view.readI32(true)/factor, z || 0); } return poly; } function polyOffset(polys, offset, 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.offset(memat, pcount, offset * 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); } 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); } function polyDiff(polysA, polysB, z) { let wasm = geo.wasm, memat = wasm.malloc(1024 * 128), writer = new DataWriter(wasm.heap, memat), pcountA = 0, pcountB = 0; polysA.forEach(poly => pcountA += writePoly(writer, poly)); polysB.forEach(poly => pcountB += writePoly(writer, poly)); let resat = wasm.diff(memat, pcountA, pcountB, (pcountA + pcountB) * 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 function polyNest(polys) { polys.sort((a,b) => { return b.bounds.minx - a.bounds.minx; }); // from smallest to largest, check for enclosing bounds and nest for (let i=0, il=polys.length; i response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes, { env: { polygon: (a,b) => { console.log('polygon',a,b) }, point: (a,b) => { console.log('point',a,b) }, abs: (a) => { console.log('abs',a); return Math.abs(a) } }, wasi_snapshot_preview1: { args_get: (count,bufsize) => { return 0 }, args_sizes_get: (count,bufsize) => { }, environ_get: (count,bufsize) => { return 0 }, environ_sizes_get: (count,bufsize) => { }, proc_exit: (code) => { return code } } })) .then(results => { let {module, instance} = results; let {exports} = instance; let heap = new DataView(exports.memory.buffer); let wasm = geo.wasm = { heap, exports, memory: exports.memory, malloc: exports.mem_get, start: exports._start, free: exports.mem_clr, diff: exports.poly_diff, union: exports.poly_union, offset: exports.poly_offset }; // wasm.start(); }); })();