in packages/miew/src/gfx/VolumeMesh.js [273:351]
_updateIndices() {
// Algorithm:
// 1. Get plane vertices (from 3 to 6 vertices)
// 2. Get "right" vector in plane
// 3. Sort vertices using Graham-like method
// 4. Create indices
let i;
let faceIdx;
let face;
const vert = this.vertices;
const { size } = this;
this._collectVertices(this.faces[0], (vertex) => vertex.z === -size.z);
this._collectVertices(this.faces[1], (vertex) => vertex.z === size.z);
this._collectVertices(this.faces[2], (vertex) => vertex.y === -size.y);
this._collectVertices(this.faces[3], (vertex) => vertex.y === size.y);
this._collectVertices(this.faces[4], (vertex) => vertex.x === -size.x);
this._collectVertices(this.faces[5], (vertex) => vertex.x === size.x);
const vCenter = new THREE.Vector3();
const vRight = new THREE.Vector3();
const vDir = new THREE.Vector3();
for (faceIdx = 0; faceIdx < this.faces.length; ++faceIdx) {
face = this.faces[faceIdx];
if (face.indices.length === 0) continue;
vCenter.set(0, 0, 0);
for (i = 0; i < face.indices.length; ++i) {
vCenter.add(vert[face.indices[i]]);
}
vCenter.multiplyScalar(1.0 / face.indices.length);
vRight.subVectors(vert[face.indices[0]], vCenter);
vRight.normalize();
const rightProj = [];
for (i = 0; i < face.indices.length; ++i) {
vDir.subVectors(vert[face.indices[i]], vCenter);
rightProj[i] = vDir.dot(vRight);
}
for (i = 1; i < face.indices.length; ++i) {
if (rightProj[i] < rightProj[0]) {
// swap
let t = rightProj[0];
rightProj[0] = rightProj[i];
rightProj[i] = t;
[t] = face.indices;
face.indices[0] = face.indices[i];
face.indices[i] = t;
}
}
this._sortIndices(face, vRight);
}
let numIndices = 0;
for (faceIdx = 0; faceIdx < this.faces.length; ++faceIdx) {
face = this.faces[faceIdx];
if (face.indices.length >= 3) {
numIndices += 3 * (face.indices.length - 2);
}
}
let offset = 0;
const indices = new Uint16Array(numIndices);
for (faceIdx = 0; faceIdx < this.faces.length; ++faceIdx) {
face = this.faces[faceIdx];
for (i = 0; i < face.indices.length - 2; ++i) {
indices[offset] = face.indices[0]; // eslint-disable-line prefer-destructuring
indices[offset + 1] = face.indices[i + 1];
indices[offset + 2] = face.indices[i + 2];
offset += 3;
}
}
this.geometry.setIndex(new THREE.BufferAttribute(indices, 1));
}