reorganize and rename driver files for consistency and clarity
This commit is contained in:
parent
7f50bafe9e
commit
67f405fd7b
74 changed files with 283 additions and 283 deletions
143
src/kiri/mode/cam/work/slicer-topo.js
Normal file
143
src/kiri/mode/cam/work/slicer-topo.js
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
import { newPoint } from '../../../../geo/point.js';
|
||||
import {
|
||||
checkOverUnderOn,
|
||||
makeZLine,
|
||||
removeDuplicateLines,
|
||||
intersectPoints
|
||||
} from '../../../../geo/slicer.js';
|
||||
|
||||
/** Slicer used in Topo3 and Topo4 to find contour lines */
|
||||
export class Slicer {
|
||||
|
||||
constructor(index = 0) {
|
||||
this.min = Infinity;
|
||||
this.max = -Infinity;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
// position is a non-indexed 3js geometry position attribute array
|
||||
// create Point array from optionally filtered Z range
|
||||
setFromArray(position, options = {}) {
|
||||
const min = options.min || -Infinity;
|
||||
const max = options.max || Infinity;
|
||||
const len = position.length;
|
||||
const pts = this.points = [];
|
||||
for (let i = 0; i < len;) {
|
||||
const x0 = position[i++];
|
||||
const y0 = position[i++];
|
||||
const z0 = position[i++];
|
||||
const x1 = position[i++];
|
||||
const y1 = position[i++];
|
||||
const z1 = position[i++];
|
||||
const x2 = position[i++];
|
||||
const y2 = position[i++];
|
||||
const z2 = position[i++];
|
||||
const minz = Math.min(z0, z1, z2);
|
||||
const maxz = Math.max(z0, z1, z2);
|
||||
if (maxz < min || minz > max) {
|
||||
continue;
|
||||
}
|
||||
pts.push(
|
||||
newPoint(x0, y0, z0),
|
||||
newPoint(x1, y1, z1),
|
||||
newPoint(x2, y2, z2)
|
||||
);
|
||||
this.min = options.min || Math.min(this.min, minz);
|
||||
this.max = options.max || Math.max(this.max, maxz);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
setFromPoints(points, options = {}) {
|
||||
const pts = this.points = [];
|
||||
const len = points.length;
|
||||
const min = options.min || -Infinity;
|
||||
const max = options.max || Infinity;
|
||||
for (let i = 0; i < len;) {
|
||||
const p0 = points[i++];
|
||||
const p1 = points[i++];
|
||||
const p2 = points[i++];
|
||||
const minz = Math.min(p0.z, p1.z, p2.z);
|
||||
const maxz = Math.max(p0.z, p1.z, p2.z);
|
||||
if (maxz < min || minz > max) {
|
||||
continue;
|
||||
}
|
||||
pts.push(p0, p1, p2);
|
||||
this.min = options.min || Math.min(this.min, minz);
|
||||
this.max = options.max || Math.max(this.max, maxz);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
slice(interval = 1) {
|
||||
const ret = [];
|
||||
for (let z = this.min; z < this.max; z += interval) {
|
||||
ret.push({ z, index: this.index++, lines: this.sliceZ(z) });
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
sliceZ(z, options = {}) {
|
||||
const points = this.points;
|
||||
const zMin = this.min;
|
||||
const zMax = this.max;
|
||||
const phash = {};
|
||||
const lines = [];
|
||||
|
||||
let { under, over, both } = options;
|
||||
let p1, p2, p3;
|
||||
|
||||
// default to 'over' selection with 2 points on a line
|
||||
if (!under && !both) over = true;
|
||||
|
||||
// iterate over matching buckets for this z offset
|
||||
for (let i = 0; i < points.length;) {
|
||||
p1 = points[i++];
|
||||
p2 = points[i++];
|
||||
p3 = points[i++];
|
||||
let where = { under: [], over: [], on: [] };
|
||||
checkOverUnderOn(p1, z, where);
|
||||
checkOverUnderOn(p2, z, where);
|
||||
checkOverUnderOn(p3, z, where);
|
||||
if (where.under.length === 3 || where.over.length === 3) {
|
||||
// does not intersect (all 3 above or below)
|
||||
} else if (where.on.length === 2) {
|
||||
// one side of triangle is on the Z plane and 3rd is below
|
||||
// drop lines with 3rd above because that leads to ambiguities
|
||||
// with complex nested polygons on flat surface
|
||||
let add2 = both ||
|
||||
(over && (where.over.length === 1 || z === zMax)) ||
|
||||
(under && (where.under.length === 1 || z === zMin));
|
||||
if (add2) {
|
||||
lines.push(makeZLine(phash, where.on[0], where.on[1], false, true));
|
||||
}
|
||||
} else if (where.on.length === 3) {
|
||||
// triangle is coplanar with Z
|
||||
// we drop these because this face is attached to 3 others
|
||||
// that will satisfy the if above (line) with 2 points
|
||||
} else if (where.under.length === 0 || where.over.length === 0) {
|
||||
// does not intersect but one point is on the slice Z plane
|
||||
} else {
|
||||
// compute two point intersections and construct line
|
||||
let line = intersectPoints(where.over, where.under, z);
|
||||
if (line.length < 2 && where.on.length === 1) {
|
||||
line.push(where.on[0]);
|
||||
}
|
||||
if (line.length === 2) {
|
||||
lines.push(makeZLine(phash, line[0], line[1]));
|
||||
} else {
|
||||
console.log({ msg: "invalid ips", line: line, where: where });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.length == 0 && options.noEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
return removeDuplicateLines(lines);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue