reduce memory consumption by deferring clipper point conversion and point keys until time of use
This commit is contained in:
parent
305066a69a
commit
e44ea73683
4 changed files with 72 additions and 70 deletions
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue