From 36be938d2a1c5eb44ad88c7181ad82ba47694eb0 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 6 Sep 2021 18:10:34 -0400 Subject: [PATCH] add geo/mesh class to contain repair utilities --- app.js | 2 + src/geo/mesh.js | 182 +++++++++++++++++++++++++++++++++++++++++++++ src/kiri/slicer.js | 3 +- src/kiri/widget.js | 5 ++ 4 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 src/geo/mesh.js diff --git a/app.js b/app.js index 23851022..3710c608 100644 --- a/app.js +++ b/app.js @@ -240,6 +240,7 @@ const script = { "geo/polygon", "geo/polygons", // "geo/gyroid", + "geo/mesh", "moto/kv", "moto/ajax", "moto/ctrl", @@ -300,6 +301,7 @@ const script = { "geo/polygon", "geo/polygons", "geo/gyroid", + "geo/mesh", "moto/pack", "kiri/slice", "kiri/slicer", diff --git a/src/geo/mesh.js b/src/geo/mesh.js new file mode 100644 index 00000000..56b6e610 --- /dev/null +++ b/src/geo/mesh.js @@ -0,0 +1,182 @@ +/** 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 -- All Rights Reserved */ } }; + PRO.debugMesh = function(precision) { + let mesh = new base.Mesh({precision, vertices: this.getVertices().array}); + return mesh; + }; + PRO.getVertices = function() { return this.mesh.geometry.attributes.position; };