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,
CONF = BASE.config,
KEYS = BASE.key,
ROUND = UTIL.round,
PRO = Point.prototype;
ROUND = UTIL.round;
BASE.Point = Point;
BASE.newPoint = newPoint;
/**
*
* @param {number} x
* @param {number} y
* @param {number} z
* @param {String} [key]
* @constructor
*/
function Point(x,y,z,key,CP) {
class Point {
constructor(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;
console.trace({x,y,z,key,CP});
throw "invalid point constructor"
} 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._key = key;
}
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
}
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.newPoint = newPoint;
BASE.pointFromClipper = function(cp, z) {
return newPoint(cp.X / CONF.clipper, cp.Y / CONF.clipper, z);
};
/** ******************************************************************
* Point Prototype Functions
******************************************************************* */
PRO.toClipper = function() {
return {
X: this.x * CONF.clipper,
Y: this.y * CONF.clipper
};
}
PRO.setZ = function(z) {
this.z = z;
return this;
@ -85,7 +89,8 @@
};
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() {
@ -96,7 +101,7 @@
* @returns {Point}
*/
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) {
let poly = newPolygon(), i = 0, l = path.length;
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;
};
@ -1455,28 +1456,14 @@
return poly;
};
PRO.toClipper = function(inout,debug) {
PRO.toClipper = function(inout) {
let poly = this,
cur = [],
out = inout || [];
if (debug) {
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);
}
out.push(poly.points.map(p => p.toClipper()));
if (poly.inner) {
poly.inner.forEach(function(p) {
p.toClipper(out, debug);
p.toClipper(out);
});
}
return out;

View file

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

View file

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