_updateIndices()

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));
  }