From ab2ff26fb06ea5173318892f820913335d53e8c7 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Tue, 22 Jun 2021 22:04:26 -0400 Subject: [PATCH] add wasm debugging options --- .gitignore | 2 +- src/geo/wasm.js | 10 ++++++---- wasm/kiri-geo.cpp | 42 +++++++++++++++++++++++++++--------------- wasm/kiri-geo.wasm | Bin 65585 -> 65743 bytes 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 0750298a..02a385d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ tmp node_modules package-lock.json logs/* -data/* \ No newline at end of file +data/* diff --git a/src/geo/wasm.js b/src/geo/wasm.js index 7081f37f..6e414790 100644 --- a/src/geo/wasm.js +++ b/src/geo/wasm.js @@ -71,9 +71,9 @@ if (!self.window) (function() { break; } } - // if (debug) { - // console.log({diff_resat: resat, memat}); - // } + if (debug) { + console.log({offset: polys, resat, memat, len: resat - memat}); + } wasm.free(memat); return polyNest(out); } @@ -193,9 +193,11 @@ if (!self.window) (function() { free: exports.mem_clr, diff: exports.poly_diff, union: exports.poly_union, - offset: exports.poly_offset + offset: exports.poly_offset, + set_debug: exports.set_debug }; if (debug) { + wasm.set_debug(1); runTests(); } }); diff --git a/wasm/kiri-geo.cpp b/wasm/kiri-geo.cpp index 5fd628ce..5b6a9812 100644 --- a/wasm/kiri-geo.cpp +++ b/wasm/kiri-geo.cpp @@ -11,7 +11,7 @@ typedef int int32; using namespace ClipperLib; Uint8 *mem = 0; -const Uint8 debug = 0; +Uint8 debug = 0; extern "C" { extern void polygon(Uint32 points, Uint32 inners); @@ -38,27 +38,35 @@ void mem_clr(Uint32 loc) { free((void *)loc); } +Uint32 readPoly(Path path, Uint32 pos) { + struct length16 *ls = (struct length16 *)(mem + pos); + Uint16 points = ls->length; + if (debug) polygon(points, 0); + pos += 2; + while (points-- > 0) { + struct point32 *ip = (struct point32 *)(mem + pos); + pos += 8; + path << IntPoint(ip->x, ip->y); + if (debug) point(ip->x, ip->y); + } + return pos; +} + Uint32 readPolys(Paths paths, Uint32 pos, Uint32 count) { Uint32 poly = 0; if (debug) abc(poly, count, pos); - while (count > 0) { - struct length16 *ls = (struct length16 *)(mem + pos); - Uint16 points = ls->length; - if (debug) polygon(points, 0); - pos += 2; - while (points-- > 0) { - struct point32 *ip = (struct point32 *)(mem + pos); - pos += 8; - paths[poly] << IntPoint(ip->x, ip->y); - if (debug) point(ip->x, ip->y); - } - poly++; - count--; + while (count-- > 0) { + pos = readPoly(paths[poly++], pos); } if (debug) abc(poly, count, pos); return pos; } +__attribute__ ((export_name("set_debug"))) +void set_debug(Uint8 value) { + debug = value; +} + __attribute__ ((export_name("poly_offset"))) Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset) { @@ -69,6 +77,10 @@ Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset) { // pos = readPolys(ins, pos, polys); + // while (polys-- > 0) { + // pos = readPoly(ins[poly++], pos); + // } + while (poly < polys) { struct length16 *ls = (struct length16 *)(mem + pos); Uint16 points = ls->length; @@ -83,7 +95,7 @@ Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset) { poly++; } - if (debug) abc(memat, pos, memat - pos); + if (debug) abc(memat, pos, pos - memat); // clean and simplify polygons // Paths cleans, simples; diff --git a/wasm/kiri-geo.wasm b/wasm/kiri-geo.wasm index 332c1ef12bf53cc58109707fffdc820642605997..93ae59f1185d3c022dcdaf969442d41cb871d5d9 100755 GIT binary patch delta 20763 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