complete body separation code

This commit is contained in:
Stewart Allen 2022-04-05 09:40:25 -07:00
commit 406cacc453
5 changed files with 72 additions and 9 deletions

View file

@ -101,7 +101,7 @@ mesh.tool = class MeshTool {
}
generateFaceMap(vertices) {
this.checkVertices(vertices, 3);
this.vertices = this.checkVertices(vertices, 3);
const normals = this.normals = [];
const sides = this.sides = [];
const _va = new THREE.Vector3();
@ -158,12 +158,13 @@ mesh.tool = class MeshTool {
return sides.map(side => this.side2face[side].filter(v => v != face)).flat();
}
findConnectedSurface(faces, radians, filterZ) {
const found = {};
// depends on generateFaceMap() being run first
findConnectedSurface(faces, radians, filterZ, found = {}) {
const norms = this.normals;
if (filterZ) {
faces = faces.filter(f => norms[f][2] >= filterZ);
}
const checked = {};
const check = faces.slice();
for (let face of faces) {
found[face] = 1;
@ -173,11 +174,17 @@ mesh.tool = class MeshTool {
while (check.length) {
const face = check.shift();
const norm = norms[face];
// if (!norm || norm.length < 3) {
// throw `invalid face ${face}`;
// }
if (filterZ !== undefined && norm[2] < filterZ) {
continue;
}
const fadj = this.getAdjacentFaces(face).filter(f => !found[f]);
const fadj = this.getAdjacentFaces(face);
for (let f of fadj) {
if (found[f] || checked[f]) {
continue;
}
// #1 most accurate
// const nf = this.normals[f];
// _v1.set(nf[0], nf[1], nf[2]);
@ -195,6 +202,7 @@ mesh.tool = class MeshTool {
if (fn <= radians) {
faces.push(f);
check.push(f)
checked[f] = 1;
found[f] = 1;
}
}
@ -202,6 +210,29 @@ mesh.tool = class MeshTool {
return faces;
}
// depends on generateFaceMap() being run first
isolateBodies() {
const verts = this.checkVertices(this.vertices);
const bodies = [];
const used = {};
for (let i=0, l=this.normals.length-1; i<l; i++) {
if (used[i]) {
continue;
}
const body = this.findConnectedSurface([i], Infinity, undefined, used);
if (body.length) {
// todo: pre-allocate known length
// then copy array regions from verts to bverts
const bverts = [];
for (let f of body) {
bverts.push(...verts.slice(f*9, f*9+9));
}
bodies.push(bverts);
}
}
return bodies;
}
/**
* finds edge lines which are line segments on a single face.
* construct ordered line maps with array of connected edges.