optimize verticesToPoints when not decimating (no hash). make slice async for future minion work
This commit is contained in:
parent
755f38fb39
commit
14c4338534
4 changed files with 41 additions and 26 deletions
|
|
@ -19,6 +19,7 @@ gapp.overlay(base, {
|
||||||
* with optional decimation
|
* with optional decimation
|
||||||
*/
|
*/
|
||||||
function verticesToPoints(array, options) {
|
function verticesToPoints(array, options) {
|
||||||
|
console.time('verticesToPoints');
|
||||||
let parr = new Array(array.length / 3),
|
let parr = new Array(array.length / 3),
|
||||||
i = 0,
|
i = 0,
|
||||||
j = 0,
|
j = 0,
|
||||||
|
|
@ -30,19 +31,6 @@ function verticesToPoints(array, options) {
|
||||||
oldpoints = parr.length,
|
oldpoints = parr.length,
|
||||||
newpoints;
|
newpoints;
|
||||||
|
|
||||||
// replace point objects with their equivalents
|
|
||||||
while (i < array.length) {
|
|
||||||
let p = base.newPoint(array[i++], array[i++], array[i++]),
|
|
||||||
k = p.key,
|
|
||||||
m = hash[k];
|
|
||||||
if (!m) {
|
|
||||||
m = p;
|
|
||||||
hash[k] = p;
|
|
||||||
unique++;
|
|
||||||
}
|
|
||||||
parr[j++] = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
let {threshold, precision, maxpass} = options || {};
|
let {threshold, precision, maxpass} = options || {};
|
||||||
// threshold = point count for triggering decimation
|
// threshold = point count for triggering decimation
|
||||||
// precision = under which points are merged
|
// precision = under which points are merged
|
||||||
|
|
@ -51,6 +39,25 @@ function verticesToPoints(array, options) {
|
||||||
precision = precision >= 0 ? precision : config.precision_decimate;
|
precision = precision >= 0 ? precision : config.precision_decimate;
|
||||||
maxpass = maxpass >= 0 ? maxpass : 0;
|
maxpass = maxpass >= 0 ? maxpass : 0;
|
||||||
|
|
||||||
|
// replace point objects with their equivalents
|
||||||
|
if (maxpass) {
|
||||||
|
while (i < array.length) {
|
||||||
|
let p = base.newPoint(array[i++], array[i++], array[i++]),
|
||||||
|
k = p.key,
|
||||||
|
m = hash[k];
|
||||||
|
if (!m) {
|
||||||
|
m = p;
|
||||||
|
hash[k] = p;
|
||||||
|
unique++;
|
||||||
|
}
|
||||||
|
parr[j++] = m;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (i < array.length) {
|
||||||
|
parr[j++] = base.newPoint(array[i++], array[i++], array[i++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// decimate until all point spacing > precision
|
// decimate until all point spacing > precision
|
||||||
if (maxpass && precision > 0.0)
|
if (maxpass && precision > 0.0)
|
||||||
while (parr.length > threshold) {
|
while (parr.length > threshold) {
|
||||||
|
|
@ -115,6 +122,7 @@ function verticesToPoints(array, options) {
|
||||||
time: (Date.now() - t)
|
time: (Date.now() - t)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.timeEnd('verticesToPoints');
|
||||||
return parr;
|
return parr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ class OpRough extends CamOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('indices', ...indices, {zBottom});
|
// console.log('indices', ...indices, {zBottom});
|
||||||
slicer.slice(indices, { each: (data, index, total) => {
|
await slicer.slice(indices, { each: (data, index, total) => {
|
||||||
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
||||||
if (flats.indexOf(data.z) >= 0) {
|
if (flats.indexOf(data.z) >= 0) {
|
||||||
// exclude flats injected to complete shadow
|
// exclude flats injected to complete shadow
|
||||||
|
|
@ -517,7 +517,7 @@ class OpOutline extends CamOp {
|
||||||
slices.push(slice);
|
slices.push(slice);
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
slicer.slice(indices, { each: (data, index, total) => {
|
await slicer.slice(indices, { each: (data, index, total) => {
|
||||||
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
shadow = unsafe ? data.tops : POLY.union(shadow.slice().appendAll(data.tops), 0.01, true);
|
||||||
if (flats.indexOf(data.z) >= 0) {
|
if (flats.indexOf(data.z) >= 0) {
|
||||||
// exclude flats injected to complete shadow
|
// exclude flats injected to complete shadow
|
||||||
|
|
@ -1504,7 +1504,7 @@ class OpXRay extends CamOp {
|
||||||
slice.xray();
|
slice.xray();
|
||||||
addSlices(slice);
|
addSlices(slice);
|
||||||
}, over: false, flatoff: 0, edges: true, openok: true };
|
}, over: false, flatoff: 0, edges: true, openok: true };
|
||||||
slicer.slice(xrayind, xrayopt);
|
await slicer.slice(xrayind, xrayopt);
|
||||||
// xrayopt.over = true;
|
// xrayopt.over = true;
|
||||||
// slicer.slice(xrayind, xrayopt);
|
// slicer.slice(xrayind, xrayopt);
|
||||||
}
|
}
|
||||||
|
|
@ -1537,7 +1537,7 @@ class OpShadow extends CamOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
let lsz; // only shadow up to bottom of last shadow for progressive union
|
let lsz; // only shadow up to bottom of last shadow for progressive union
|
||||||
let terrain = slicer.slice(tzindex, { each: (data, index, total) => {
|
let terrain = await slicer.slice(tzindex, { each: (data, index, total) => {
|
||||||
let shadow = trueShadow ? shadowAt(data.z, lsz) : [];
|
let shadow = trueShadow ? shadowAt(data.z, lsz) : [];
|
||||||
tshadow = POLY.union(tshadow.slice().appendAll(data.tops).appendAll(shadow), 0.01, true);
|
tshadow = POLY.union(tshadow.slice().appendAll(data.tops).appendAll(shadow), 0.01, true);
|
||||||
tslices.push(data.slice);
|
tslices.push(data.slice);
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,7 @@ CAM.slice = async function(settings, widget, onupdate, ondone) {
|
||||||
unsafe = proc.camExpertFast,
|
unsafe = proc.camExpertFast,
|
||||||
units = settings.controller.units === 'in' ? 25.4 : 1,
|
units = settings.controller.units === 'in' ? 25.4 : 1,
|
||||||
axisRotation,
|
axisRotation,
|
||||||
axisIndex,
|
axisIndex;
|
||||||
thruHoles;
|
|
||||||
|
|
||||||
if (tabs) {
|
if (tabs) {
|
||||||
// make tab polygons
|
// make tab polygons
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,13 @@ class Slicer {
|
||||||
this.zLine = {}; // count of z coplanar lines
|
this.zLine = {}; // count of z coplanar lines
|
||||||
this.zList = {}; // count of z values for auto slicing
|
this.zList = {}; // count of z values for auto slicing
|
||||||
this.zSum = 0; // used in bucketing calculations
|
this.zSum = 0; // used in bucketing calculations
|
||||||
return this
|
console.time('set points');
|
||||||
|
this
|
||||||
.computeBounds()
|
.computeBounds()
|
||||||
.computeFeatures()
|
.computeFeatures()
|
||||||
.computeBuckets();
|
.computeBuckets();
|
||||||
|
console.timeEnd('set points');
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
computeBounds() {
|
computeBounds() {
|
||||||
|
|
@ -70,7 +73,7 @@ class Slicer {
|
||||||
computeFeatures(options) {
|
computeFeatures(options) {
|
||||||
const opt = this.setOptions(options);
|
const opt = this.setOptions(options);
|
||||||
const points = this.points;
|
const points = this.points;
|
||||||
const bounds = this.bounds;
|
// const bounds = this.bounds;
|
||||||
const zFlat = this.zFlat;
|
const zFlat = this.zFlat;
|
||||||
const zLine = this.zLine;
|
const zLine = this.zLine;
|
||||||
const zList = this.zList;
|
const zList = this.zList;
|
||||||
|
|
@ -80,6 +83,7 @@ class Slicer {
|
||||||
zList[z] = (zList[z] || 0) + 1;
|
zList[z] = (zList[z] || 0) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.time('compute features');
|
||||||
for (let i = 0, il = points.length; i < il; ) {
|
for (let i = 0, il = points.length; i < il; ) {
|
||||||
let p1 = points[i++];
|
let p1 = points[i++];
|
||||||
let p2 = points[i++];
|
let p2 = points[i++];
|
||||||
|
|
@ -122,6 +126,7 @@ class Slicer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.timeEnd('compute features');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -137,8 +142,9 @@ class Slicer {
|
||||||
let points = this.points;
|
let points = this.points;
|
||||||
let bucketCount = Math.max(1, Math.ceil(zMax / (zSum / points.length)) - 1);
|
let bucketCount = Math.max(1, Math.ceil(zMax / (zSum / points.length)) - 1);
|
||||||
let zScale = this.zScale = 1 / (zMax / bucketCount);
|
let zScale = this.zScale = 1 / (zMax / bucketCount);
|
||||||
let buckets = this.buckets = {};
|
let buckets = this.buckets = [];
|
||||||
|
|
||||||
|
console.time('compute buckets');
|
||||||
if (bucketCount > 1) {
|
if (bucketCount > 1) {
|
||||||
buckets.length = bucketCount;
|
buckets.length = bucketCount;
|
||||||
// create empty buckets
|
// create empty buckets
|
||||||
|
|
@ -163,23 +169,25 @@ class Slicer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.timeEnd('compute buckets');
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// slice through points at given Z and return polygons
|
// slice through points at given Z and return polygons
|
||||||
slice(z, options, index, total, mark) {
|
async slice(z, options, index, total, mark) {
|
||||||
const opt = this.setOptions(options);
|
const opt = this.setOptions(options);
|
||||||
|
|
||||||
// if Z is supplied as an array, iterate and collect
|
// if Z is supplied as an array, iterate and collect
|
||||||
if (Array.isArray(z)) {
|
if (Array.isArray(z)) {
|
||||||
const mark = util.time();
|
const mark = util.time();
|
||||||
const rarr = [];
|
const rarr = [];
|
||||||
z.forEach((zv,zi) => {
|
for (let zi=0; zi<z.length; zi++) {
|
||||||
const data = this.slice(zv, opt, zi, z.length, mark);
|
const data = await this.slice(z[zi], opt, zi, z.length, mark);
|
||||||
if (data) {
|
if (data) {
|
||||||
rarr.push(data);
|
rarr.push(data);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return rarr;
|
return rarr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue