/** Copyright Stewart Allen -- All Rights Reserved */ "use strict"; (function() { const BASE = self.base = self.base || {}; if (BASE.Mesh) { return; } BASE.Mesh = class Mesh { constructor(params = {}) { this.precision = params.precision || 6; if (params.vertices) { this.setData(params.vertices, params.faces); } } /** * set vertices and faces of the mesh. if only vertices are provided * then the data is assumed to be un-indexed and will be indexed into * faces. if faces are provided, they are assumed to be index references * into the vertex data. * * the end result is face data mapped to an indexed set of unique vertices. * * @param {number[]} vertices * @param {number[]} faces */ setData(vertices, faces) { if (!vertices) { throw "missing vertices"; } if (vertices.length % 3 !== 0) { throw "invalid vertices"; } // when face/index data is missing, vertices need to be normalized if (!faces) { faces = []; let nuvt = []; // new vertex list let hash = {}; // find vertex matches let prec = this.precision; for (let i=0, l=vertices.length; i l.faces.length === 1); console.log({edges}); let loops = []; // connect edge lines into closed loops for (let i=0, l=edges.length; i l !== line && !l.used && l.faces.length === 1); if (adjacent.length === 0) { break; } if (adjacent.length > 2) { console.log('error adjacent', adjacent); break; } line = adjacent[0]; loop.push(line); line.used = true; } console.log({loop}); // drop co-linear points because they can't be connected into valid faces // fixup remaining line by dropping common point and using dropped line's point for (let j=0, jl=loop.length; j