From aeb8d9512a6d8b97afb56c8fff3bbd8997c3952e Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sat, 10 Jul 2021 21:19:56 -0400 Subject: [PATCH] change fingerprinting algorithm --- src/geo/bounds.js | 11 +++++++++++ src/geo/polygon.js | 27 ++++++++++++++++++++++---- src/geo/polygons.js | 45 +++++++++++++++++++++++++++++++++---------- src/kiri/codec.js | 7 +++---- src/kiri/layers.js | 3 +++ src/mode/fdm/slice.js | 6 ++++-- 6 files changed, 79 insertions(+), 20 deletions(-) diff --git a/src/geo/bounds.js b/src/geo/bounds.js index f4f06ad8..5cde101a 100644 --- a/src/geo/bounds.js +++ b/src/geo/bounds.js @@ -58,6 +58,17 @@ UTIL.isCloseTo(this.maxy, bounds.maxy, margin); }; + /** + * @returns {Number} absolute delta in x,y coordinate space + */ + PRO.delta = function(bounds) { + return + Math.abs(this.minx - bounds.minx) + + Math.abs(this.miny - bounds.miny) + + Math.abs(this.maxx - bounds.maxx) + + Math.abs(this.maxy - bounds.maxy); + }; + /** * @param {Bounds} b */ diff --git a/src/geo/polygon.js b/src/geo/polygon.js index dfc626b9..25ad5bd8 100644 --- a/src/geo/polygon.js +++ b/src/geo/polygon.js @@ -476,7 +476,7 @@ const pa = this.points, pln = pa.length, open = this.open, - newp = newPolygon(), + newp = newPolygon().copyZ(this.z), min = dist || BASE.config.precision_merge; let lo; newp.push(lo = pa[0]); @@ -519,7 +519,7 @@ redo |= ang[0] > 90; } if (redo) { - const newp = newPolygon(); + const newp = newPolygon().copyZ(this.z); // newp.debug = this.debug = true; newp.open = open; for (let i=0; i p.cloneZ(z, true)); + } + return p; + }; + + PRO.copyZ = function(z) { + if (z !== undefined) { + this.z = z; + } + return this; + }; + /** * set all points' z value * @@ -839,7 +858,7 @@ * @returns {number} z value of first point */ PRO.getZ = function(i) { - return this.points[i || 0].z; + return this.z !== undefined ? this.z : this.points[i || 0].z; }; /** diff --git a/src/geo/polygons.js b/src/geo/polygons.js index f2a09485..59c1dc82 100644 --- a/src/geo/polygons.js +++ b/src/geo/polygons.js @@ -871,37 +871,62 @@ flatten(polys).sort((a,b) => { return a.area() > b.area(); }).forEach(p => { - finger.push(p.area()); - finger.push(p.perimeter()); - finger.push(p.bounds); + // finger.push(p.area()); + // finger.push(p.perimeter()); + // finger.push(p.bounds); + finger.push({ + c: p.circularityDeep(), + p: p.perimeterDeep(), + b: p.bounds + }); }); return finger; } + // compare fingerprint arrays function fingerprintCompare(a, b) { + // true if array is the same object if (a === b) { return true; } + // fail on missing array if (!a || !b) { return false; } + // require identical length arrays if (a.length !== b.length) { return false; } - for (let i=0; i 0.001) { + for (let i=0; i 0.001) { return false; } - if (Math.abs(a[i+1] - b[i+1]) > 0.0001) { + // test perimeter + if (Math.abs(ra.p - rb.p) > 0.001) { return false; } - if (Math.abs(a[i+2].centerx() - b[i+2].centerx()) > 0.0001) { - return false; - } - if (Math.abs(a[i+2].centery() - b[i+2].centery()) > 0.0001) { + // test bounds + if (ra.b.delta(rb.b) > 0.001) { return false; } } + // for (let i=0; i 0.001) { + // return false; + // } + // if (Math.abs(a[i+1] - b[i+1]) > 0.0001) { + // return false; + // } + // if (Math.abs(a[i+2].centerx() - b[i+2].centerx()) > 0.0001) { + // return false; + // } + // if (Math.abs(a[i+2].centery() - b[i+2].centery()) > 0.0001) { + // return false; + // } + // } return true; } diff --git a/src/kiri/codec.js b/src/kiri/codec.js index 06f8ddd8..c5b88f74 100644 --- a/src/kiri/codec.js +++ b/src/kiri/codec.js @@ -257,7 +257,7 @@ return top; }); - function encodePointArray(points, state) { + function encodePointArray(points, state, z) { if (!points) return null; let array = codec.allocFloat32Array(points.length * 3), @@ -280,7 +280,7 @@ } array[pos++] = point.x; array[pos++] = point.y; - array[pos++] = point.z; + array[pos++] = z !== undefined ? z : point.z; }); if (zeroOut && state.zeros) { @@ -314,11 +314,10 @@ } state.poly[this.id] = this; - return { type: 'poly', id: this.id, - array: encodePointArray(this.points, state), + array: encodePointArray(this.points, state, this.z), inner: encode(this.inner, state), parent: encode(this.parent, state), depth: this.depth, diff --git a/src/kiri/layers.js b/src/kiri/layers.js index a9c45c4e..0d9c713f 100644 --- a/src/kiri/layers.js +++ b/src/kiri/layers.js @@ -85,6 +85,9 @@ } addPolys(polys, options) { + if (polys.length === 0) { + return this; + } if (options && options.clean) { polys = polys.map(p => p.clean(true)); } diff --git a/src/mode/fdm/slice.js b/src/mode/fdm/slice.js index bcb29cbf..ccdcb49a 100644 --- a/src/mode/fdm/slice.js +++ b/src/mode/fdm/slice.js @@ -600,7 +600,7 @@ output .setLayer("sparse fill", COLOR.infill) - .addPolys(top.fill_sparse || [], vopt({ offset, height, outline: true })) + .addPolys(top.fill_sparse || [], vopt({ offset, height, outline: true, trace:true })) if (top.thin_fill) output .setLayer("thin fill", COLOR.fill) @@ -866,7 +866,7 @@ cache = !(options.cache === false), type = options.type || 'hex'; - if (slice.tops.length === 0 || density === 0.0 || slice.isSolidLayer) { + if (slice.tops.length === 0 || density === 0.0 || slice.isSolidLayer || slice.index < 0) { slice.isSparseFill = false; return; } @@ -943,9 +943,11 @@ if (skippable && slice.fingerprintSame(down)) { // the fill fingerprint can slightly different because of solid projections if (down._fill_finger && POLY.fingerprintCompare(slice._fill_finger, down._fill_finger)) { + // console.log({fill_clone: down.index}); for (let i=0; i p.cloneZ(slice.z)); tops[i].fill_sparse = down.tops[i].fill_sparse.map(poly => { return poly.clone().setZ(slice.z); });