change fingerprinting algorithm
This commit is contained in:
parent
c3eb7ce810
commit
aeb8d9512a
6 changed files with 79 additions and 20 deletions
|
|
@ -58,6 +58,17 @@
|
||||||
UTIL.isCloseTo(this.maxy, bounds.maxy, margin);
|
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
|
* @param {Bounds} b
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -476,7 +476,7 @@
|
||||||
const pa = this.points,
|
const pa = this.points,
|
||||||
pln = pa.length,
|
pln = pa.length,
|
||||||
open = this.open,
|
open = this.open,
|
||||||
newp = newPolygon(),
|
newp = newPolygon().copyZ(this.z),
|
||||||
min = dist || BASE.config.precision_merge;
|
min = dist || BASE.config.precision_merge;
|
||||||
let lo;
|
let lo;
|
||||||
newp.push(lo = pa[0]);
|
newp.push(lo = pa[0]);
|
||||||
|
|
@ -519,7 +519,7 @@
|
||||||
redo |= ang[0] > 90;
|
redo |= ang[0] > 90;
|
||||||
}
|
}
|
||||||
if (redo) {
|
if (redo) {
|
||||||
const newp = newPolygon();
|
const newp = newPolygon().copyZ(this.z);
|
||||||
// newp.debug = this.debug = true;
|
// newp.debug = this.debug = true;
|
||||||
newp.open = open;
|
newp.open = open;
|
||||||
for (let i=0; i<pln; i++) {
|
for (let i=0; i<pln; i++) {
|
||||||
|
|
@ -803,7 +803,7 @@
|
||||||
* @returns {Polygon}
|
* @returns {Polygon}
|
||||||
*/
|
*/
|
||||||
PRO.clone = function(deep) {
|
PRO.clone = function(deep) {
|
||||||
let np = newPolygon(),
|
let np = newPolygon().copyZ(this.z),
|
||||||
ln = this.length,
|
ln = this.length,
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
|
|
@ -820,6 +820,25 @@
|
||||||
return np;
|
return np;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// special shallow for-render-or-read-only cloning
|
||||||
|
PRO.cloneZ = function(z, stop) {
|
||||||
|
let p = newPolygon();
|
||||||
|
p.z = z;
|
||||||
|
p.open = this.open;
|
||||||
|
p.points = this.points;
|
||||||
|
if (this.inner) {
|
||||||
|
p.inner = this.inner.map(p => p.cloneZ(z, true));
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
PRO.copyZ = function(z) {
|
||||||
|
if (z !== undefined) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set all points' z value
|
* set all points' z value
|
||||||
*
|
*
|
||||||
|
|
@ -839,7 +858,7 @@
|
||||||
* @returns {number} z value of first point
|
* @returns {number} z value of first point
|
||||||
*/
|
*/
|
||||||
PRO.getZ = function(i) {
|
PRO.getZ = function(i) {
|
||||||
return this.points[i || 0].z;
|
return this.z !== undefined ? this.z : this.points[i || 0].z;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -871,37 +871,62 @@
|
||||||
flatten(polys).sort((a,b) => {
|
flatten(polys).sort((a,b) => {
|
||||||
return a.area() > b.area();
|
return a.area() > b.area();
|
||||||
}).forEach(p => {
|
}).forEach(p => {
|
||||||
finger.push(p.area());
|
// finger.push(p.area());
|
||||||
finger.push(p.perimeter());
|
// finger.push(p.perimeter());
|
||||||
finger.push(p.bounds);
|
// finger.push(p.bounds);
|
||||||
|
finger.push({
|
||||||
|
c: p.circularityDeep(),
|
||||||
|
p: p.perimeterDeep(),
|
||||||
|
b: p.bounds
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return finger;
|
return finger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compare fingerprint arrays
|
||||||
function fingerprintCompare(a, b) {
|
function fingerprintCompare(a, b) {
|
||||||
|
// true if array is the same object
|
||||||
if (a === b) {
|
if (a === b) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// fail on missing array
|
||||||
if (!a || !b) {
|
if (!a || !b) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// require identical length arrays
|
||||||
if (a.length !== b.length) {
|
if (a.length !== b.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (let i=0; i<a.length; i += 3) {
|
for (let i=0; i<a.length; i++) {
|
||||||
if (Math.abs(a[i] - b[i]) > 0.001) {
|
let ra = a[i];
|
||||||
|
let rb = b[i];
|
||||||
|
// test circularity
|
||||||
|
if (Math.abs(ra.c - rb.c) > 0.001) {
|
||||||
return false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
if (Math.abs(a[i+2].centerx() - b[i+2].centerx()) > 0.0001) {
|
// test bounds
|
||||||
return false;
|
if (ra.b.delta(rb.b) > 0.001) {
|
||||||
}
|
|
||||||
if (Math.abs(a[i+2].centery() - b[i+2].centery()) > 0.0001) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// for (let i=0; i<a.length; i += 3) {
|
||||||
|
// if (Math.abs(a[i] - b[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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@
|
||||||
return top;
|
return top;
|
||||||
});
|
});
|
||||||
|
|
||||||
function encodePointArray(points, state) {
|
function encodePointArray(points, state, z) {
|
||||||
if (!points) return null;
|
if (!points) return null;
|
||||||
|
|
||||||
let array = codec.allocFloat32Array(points.length * 3),
|
let array = codec.allocFloat32Array(points.length * 3),
|
||||||
|
|
@ -280,7 +280,7 @@
|
||||||
}
|
}
|
||||||
array[pos++] = point.x;
|
array[pos++] = point.x;
|
||||||
array[pos++] = point.y;
|
array[pos++] = point.y;
|
||||||
array[pos++] = point.z;
|
array[pos++] = z !== undefined ? z : point.z;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (zeroOut && state.zeros) {
|
if (zeroOut && state.zeros) {
|
||||||
|
|
@ -314,11 +314,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
state.poly[this.id] = this;
|
state.poly[this.id] = this;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'poly',
|
type: 'poly',
|
||||||
id: this.id,
|
id: this.id,
|
||||||
array: encodePointArray(this.points, state),
|
array: encodePointArray(this.points, state, this.z),
|
||||||
inner: encode(this.inner, state),
|
inner: encode(this.inner, state),
|
||||||
parent: encode(this.parent, state),
|
parent: encode(this.parent, state),
|
||||||
depth: this.depth,
|
depth: this.depth,
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
addPolys(polys, options) {
|
addPolys(polys, options) {
|
||||||
|
if (polys.length === 0) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
if (options && options.clean) {
|
if (options && options.clean) {
|
||||||
polys = polys.map(p => p.clean(true));
|
polys = polys.map(p => p.clean(true));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -600,7 +600,7 @@
|
||||||
|
|
||||||
output
|
output
|
||||||
.setLayer("sparse fill", COLOR.infill)
|
.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
|
if (top.thin_fill) output
|
||||||
.setLayer("thin fill", COLOR.fill)
|
.setLayer("thin fill", COLOR.fill)
|
||||||
|
|
@ -866,7 +866,7 @@
|
||||||
cache = !(options.cache === false),
|
cache = !(options.cache === false),
|
||||||
type = options.type || 'hex';
|
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;
|
slice.isSparseFill = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -943,9 +943,11 @@
|
||||||
if (skippable && slice.fingerprintSame(down)) {
|
if (skippable && slice.fingerprintSame(down)) {
|
||||||
// the fill fingerprint can slightly different because of solid projections
|
// the fill fingerprint can slightly different because of solid projections
|
||||||
if (down._fill_finger && POLY.fingerprintCompare(slice._fill_finger, down._fill_finger)) {
|
if (down._fill_finger && POLY.fingerprintCompare(slice._fill_finger, down._fill_finger)) {
|
||||||
|
// console.log({fill_clone: down.index});
|
||||||
for (let i=0; i<tops.length; i++) {
|
for (let i=0; i<tops.length; i++) {
|
||||||
// the layer below may not have infill computed if it's solid
|
// the layer below may not have infill computed if it's solid
|
||||||
if (down.tops[i].fill_sparse) {
|
if (down.tops[i].fill_sparse) {
|
||||||
|
// tops[i].fill_sparse = down.tops[i].fill_sparse.map(p => p.cloneZ(slice.z));
|
||||||
tops[i].fill_sparse = down.tops[i].fill_sparse.map(poly => {
|
tops[i].fill_sparse = down.tops[i].fill_sparse.map(poly => {
|
||||||
return poly.clone().setZ(slice.z);
|
return poly.clone().setZ(slice.z);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue