reduce memory consumption by deferring clipper point conversion and point keys until time of use

This commit is contained in:
Stewart Allen 2021-06-18 16:56:41 -04:00
commit e44ea73683
4 changed files with 72 additions and 70 deletions

View file

@ -10,51 +10,55 @@
UTIL = BASE.util, UTIL = BASE.util,
CONF = BASE.config, CONF = BASE.config,
KEYS = BASE.key, KEYS = BASE.key,
ROUND = UTIL.round, ROUND = UTIL.round;
PRO = Point.prototype;
class Point {
constructor(x,y,z,key,CP) {
// todo make more efficient for cloning when all 5 params are passed
if (CP) {
console.trace({x,y,z,key,CP});
throw "invalid point constructor"
} else {
this.x = x;
this.y = y;
this.z = z || 0;
this._key = key;
}
this.poly = null; // parent polygon
this.pos = 0; // position in group
}
get key() {
if (this._key) {
return this._key;
}
return this._key = [
this.x.round(6),
this.y.round(6),
this.z.round(6)
].toString();
}
}
const PRO = Point.prototype;
BASE.Point = Point; BASE.Point = Point;
BASE.newPoint = newPoint; BASE.newPoint = newPoint;
BASE.pointFromClipper = function(cp, z) {
/** return newPoint(cp.X / CONF.clipper, cp.Y / CONF.clipper, z);
* };
* @param {number} x
* @param {number} y
* @param {number} z
* @param {String} [key]
* @constructor
*/
function Point(x,y,z,key,CP) {
// todo make more efficient for cloning when all 5 params are passed
if (CP) {
this.x = x || (CP.X / CONF.clipper) || 0;
this.y = y || (CP.Y / CONF.clipper) || 0;
this.z = z || 0;
this.X = CP.X;
this.Y = CP.Y;
this.key = null;
} else {
this.x = x;
this.y = y;
this.z = z || 0;
this.X = (x * CONF.clipper);
this.Y = (y * CONF.clipper);
this.key = key || [x, y, z].toString();
}
this.poly = null; // parent polygon
// this.dist = 0.0; // for group intersection sorting and tests
// this.p1 = null; // used in sliceIntersect(), connectLines() and intersect()
// this.p2 = null; // used in sliceIntersect(), connectLines() and intersect()
this.pos = 0; // position in group
// this.mod = 0; // group length (for modulus of pos)
// this.del = false; // for culling
// this.group = null; // for grouping in slice intersect, offset lines in trace
}
/** ****************************************************************** /** ******************************************************************
* Point Prototype Functions * Point Prototype Functions
******************************************************************* */ ******************************************************************* */
PRO.toClipper = function() {
return {
X: this.x * CONF.clipper,
Y: this.y * CONF.clipper
};
}
PRO.setZ = function(z) { PRO.setZ = function(z) {
this.z = z; this.z = z;
return this; return this;
@ -85,7 +89,8 @@
}; };
PRO.rekey = function() { PRO.rekey = function() {
this.key = [this.x,this.y,this.z].join(','); this._key = undefined;
// this.key = [this.x,this.y,this.z].join(',');
}; };
PRO.toString = function() { PRO.toString = function() {
@ -96,7 +101,7 @@
* @returns {Point} * @returns {Point}
*/ */
PRO.clone = function() { PRO.clone = function() {
return newPoint(this.x, this.y, this.z, this.key); return newPoint(this.x, this.y, this.z, this._key);
}; };
/** /**

View file

@ -1406,7 +1406,8 @@
function fromClipperPath(path, z) { function fromClipperPath(path, z) {
let poly = newPolygon(), i = 0, l = path.length; let poly = newPolygon(), i = 0, l = path.length;
while (i < l) { while (i < l) {
poly.push(newPoint(null,null,z,null,path[i++])); // poly.push(newPoint(null,null,z,null,path[i++]));
poly.push(BASE.pointFromClipper(path[i++], z));
} }
return poly; return poly;
}; };
@ -1455,28 +1456,14 @@
return poly; return poly;
}; };
PRO.toClipper = function(inout,debug) { PRO.toClipper = function(inout) {
let poly = this, let poly = this,
cur = [], cur = [],
out = inout || []; out = inout || [];
if (debug) { out.push(poly.points.map(p => p.toClipper()));
let d = [],
points = poly.points,
len = points.length,
i = 0,
p;
while (i < len) {
p = points[i++];
d.push({X:p.x, Y:p.y});
}
// poly.points.forEach(function(p) { d.push({X:p.x, Y:p.y}) });
out.push(d);
} else {
out.push(poly.points);
}
if (poly.inner) { if (poly.inner) {
poly.inner.forEach(function(p) { poly.inner.forEach(function(p) {
p.toClipper(out, debug); p.toClipper(out);
}); });
} }
return out; return out;

View file

@ -50,21 +50,25 @@
******************************************************************* */ ******************************************************************* */
function setZ(polys, z) { function setZ(polys, z) {
polys.forEach(p => p.setZ(z)); for (let poly of polys) {
poly.setZ(z);
}
return polys; return polys;
} }
function toClipper(polys,debug) { function toClipper(polys) {
let out = []; let out = [];
polys.forEach(function(poly) { poly.toClipper(out,debug) }); for (let poly of polys) {
poly.toClipper(out);
}
return out; return out;
} }
function fromClipperNode(tnode, z) { function fromClipperNode(tnode, z) {
let poly = BASE.newPolygon(); let poly = BASE.newPolygon();
tnode.m_polygon.forEach(function(p) { for (let point of tnode.m_polygon) {
poly.push(newPoint(null, null, z, null, p)); poly.push(BASE.pointFromClipper(point, z));
}); }
poly.open = tnode.IsOpen; poly.open = tnode.IsOpen;
return poly; return poly;
}; };
@ -636,10 +640,15 @@
rayint.origin = newPoint(start.x, start.y, start.z); rayint.origin = newPoint(start.x, start.y, start.z);
for (i = 0; i < steps; i++) { for (i = 0; i < steps; i++) {
let p1 = newPoint(start.x - raySlope.dx * 1000, start.y - raySlope.dy * 1000, zpos, NOKEY), lines.push([
p2 = newPoint(start.x + raySlope.dx * 1000, start.y + raySlope.dy * 1000, zpos, NOKEY); {
X: (start.x - raySlope.dx * 1000) * CONF.clipper,
lines.push([p1,p2]); Y: (start.y - raySlope.dy * 1000) * CONF.clipper
},{
X: (start.x + raySlope.dx * 1000) * CONF.clipper,
Y: (start.y + raySlope.dy * 1000) * CONF.clipper
}
]);
start.x += stepX; start.x += stepX;
start.y += stepY; start.y += stepY;
} }
@ -656,8 +665,8 @@
if (minlen && plen < minlen) return; if (minlen && plen < minlen) return;
if (maxlen && plen > maxlen) return; if (maxlen && plen > maxlen) return;
} }
let p1 = newPoint(null,null,zpos,null,poly.m_polygon[0]); let p1 = BASE.pointFromClipper(poly.m_polygon[0], zpos);
let p2 = newPoint(null,null,zpos,null,poly.m_polygon[1]); let p2 = BASE.pointFromClipper(poly.m_polygon[1], zpos);
let od = rayint.origin.distToLineNew(p1,p2) / spacing; let od = rayint.origin.distToLineNew(p1,p2) / spacing;
lines.push([p1, p2, od]); lines.push([p1, p2, od]);
}); });

View file

@ -803,7 +803,7 @@
if (isNaN(x)) { if (isNaN(x)) {
solids.push(x); solids.push(x);
} else { } else {
line.push(newPoint(x,y,slice.z)); line.push(newPoint(x, y, slice.z));
slice.isSparseFill = true; slice.isSparseFill = true;
} }
}, },
@ -904,6 +904,7 @@
return; return;
} }
lines = lines.map(a => a.map(p => p.toClipper()));
clip.AddPaths(lines, ptyp.ptSubject, false); clip.AddPaths(lines, ptyp.ptSubject, false);
clip.AddPaths(POLY.toClipper(polys), ptyp.ptClip, true); clip.AddPaths(POLY.toClipper(polys), ptyp.ptClip, true);