From 6993a339e7d9756cb5d85ab3d47bd11e1b5c08f5 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 31 Jan 2022 13:27:09 -0500 Subject: [PATCH] convert all meshes to non-indexed --- notes.md | 1 - src/mesh/model.js | 15 ++++--- src/mesh/tool.js | 112 ++++++++++++++++++++-------------------------- src/mesh/work.js | 10 ++--- 4 files changed, 62 insertions(+), 76 deletions(-) diff --git a/notes.md b/notes.md index 1fb69bc8..15170100 100644 --- a/notes.md +++ b/notes.md @@ -125,7 +125,6 @@ * add section view. local clip. raycast skip points above plane * add isolate op = separate bodies * add decimate op = face reduction -* add union op (applied after isolate) * add flatten/crush op: for z bottoms * face selection: find regions with < delta to normal * better z snap using just vertexes from face intersected diff --git a/src/mesh/model.js b/src/mesh/model.js index d26dfee0..f6e829ab 100644 --- a/src/mesh/model.js +++ b/src/mesh/model.js @@ -182,7 +182,11 @@ mesh.model = class MeshModel extends mesh.object { load(vertices, indices, normals) { let geo = new BufferGeometry(); geo.setAttribute('position', new BufferAttribute(vertices, 3)); - if (indices) geo.setIndex(new BufferAttribute(indices, 1)); + if (indices) { + // unroll indexed geometries + geo.setIndex(new BufferAttribute(indices, 1)); + geo = geo.toNonIndexed(); + } if (!normals) geo.computeVertexNormals(); let meh = this.mesh = new Mesh(geo, [ this.mats.normal, @@ -199,24 +203,23 @@ mesh.model = class MeshModel extends mesh.object { // persist in db so it can be restored on page load mapp.db.space.put(this.id, { file: this.file, mesh: vertices }); // sync data to worker - worker.model_load({id: this.id, name: this.file, vertices, indices}); + worker.model_load({id: this.id, name: this.file, vertices}); } - reload(vertices, indices, normals) { + reload(vertices) { let was = this.wireframe(false); let geo = this.mesh.geometry; geo.setAttribute('position', new BufferAttribute(vertices, 3)); geo.setAttribute('normal', undefined); // signal util.box3expand that geometry changed geo._model_invalid = true; - if (indices) geo.setIndex(new BufferAttribute(indices, 1)); - if (!normals) geo.computeVertexNormals(); + geo.computeVertexNormals(); // allows raycasting to work geo.computeBoundingSphere(); // persist in db so it can be restored on page load mapp.db.space.put(this.id, { file: this.file, mesh: vertices }); // sync data to worker - worker.model_load({id: this.id, name: this.name, vertices, indices}); + worker.model_load({id: this.id, name: this.name, vertices}); // restore wireframe state this.wireframe(was); // fixup normals diff --git a/src/mesh/tool.js b/src/mesh/tool.js index 42d88acc..0ff3f979 100644 --- a/src/mesh/tool.js +++ b/src/mesh/tool.js @@ -24,82 +24,68 @@ mesh.tool = class MeshTool { constructor(params = {}) { this.precision = Math.pow(10, params.precision || 6); if (params.vertices) { - this.setData(params.vertices, params.faces); + this.setVertices(params.vertices); } } /** - * 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. removes invalid faces. - * - * the end result is face data mapped to an indexed set of unique vertices. - * * @param {number[]} vertices - * @param {number[]} faces */ - setData(vertices, faces) { + setVertices(vertices, opt = {}) { 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 fcac = {}; // seen face hash - let fnew = []; // accumulate vertex triplets - let nuvt = []; // new vertex list - let hash = {}; // find vertex matches - let prec = this.precision; - let dups = 0; - let cull = 0; - for (let i=0, l=vertices.length; i v*3); } + vertices = nuvt; + this.stats = {cull, dups, faces:faces.length/3}; // unique vertex array this.vertices = vertices; // unique face array. elements are offset into vertices @@ -112,7 +98,7 @@ mesh.tool = class MeshTool { * construct ordered line maps with array of connected edges. * connect lines into polys. earcut polys into new faces. */ - heal(opt = { merge: true }) { + patch(opt = { merge: true }) { let vertices = this.vertices; let faces = this.faces; let hash = {}; // key to line map diff --git a/src/mesh/work.js b/src/mesh/work.js index 01cf9719..c3986d87 100644 --- a/src/mesh/work.js +++ b/src/mesh/work.js @@ -59,25 +59,23 @@ function translate_encode(id, matrix) { } function analyze(id, opt = {}) { - log(`${id} | indexing...`); + log(`${id} | analyzing...`); let geo = cache[id].geo; let tool = new mesh.tool({ vertices: geo.attributes.position.array, - faces: geo.index ? geo.index.array : undefined, debug: false }); - log(`${id} | analyzing...`); - tool.heal(opt); + log(`${id} | patching...`); + tool.patch(opt); dbug.log(tool); return tool; } let model = { load(data) { - let { vertices, indices, name, id } = data; + let { vertices, name, id } = data; let geo = new BufferGeometry(); geo.setAttribute('position', new BufferAttribute(vertices, 3)); - if (indices) geo.setIndex(new BufferAttribute(indices, 1)); cacheUpdate(id, { name, geo, xmatrix: core_matrix.clone(), trans: undefined }); },