diff --git a/src/mesh/api.js b/src/mesh/api.js index f591436c..bf67a9dc 100644 --- a/src/mesh/api.js +++ b/src/mesh/api.js @@ -1235,6 +1235,7 @@ const tool = { id: m.id, opt }).then(data => { data?.vertices && m.reload(data.vertices); + return data; }); promises.push(p); } @@ -1255,14 +1256,24 @@ const tool = { clean(models) { models = fallback(models); tool.heal(models, { + round: 3, + precision: 3, merge: false, - precision: 2, dedup: true, clean: true - }).then(() => { + }).then((data) => { + for (let od of data) { + let { vertices, zlist } = od; + console.log({ zlist }); + log(`${vertices.length/3} vertices, ${zlist.length} unique Z`); + } log('cleaning complete').unpin(); util.defer(selection.update); }); + }, + + flatten(models) { + fallback(models, false).map(model => model.selectionFlatten()); } }; diff --git a/src/mesh/build.js b/src/mesh/build.js index 3b225bcd..7be0ae46 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -506,6 +506,7 @@ function ui_build() { menu_item('Triangulate', tool.triangulate, ['bi-shift','T']), menu_item('To Sketch', tool.toSketch), menu_item('Analyze', tool.analyze), + menu_item('Flatten', tool.flatten), menu_item('Clean', tool.clean), ]) ]), diff --git a/src/mesh/model.js b/src/mesh/model.js index 40352e68..536a3253 100644 --- a/src/mesh/model.js +++ b/src/mesh/model.js @@ -682,6 +682,19 @@ mesh.model = class MeshModel extends mesh.object { } } + selectionFlatten() { + let faces = this.sel.faces; + if (faces.length) { + worker.model_flatten({ id: this.id, faces }).then(data => { + if (data.vertices) { + this.reload(data.vertices); + this.sel.faces = []; + this.updateSelections(); + } + }); + } + } + triangulateSelections() { let { polys, quaternion } = this.selectionToRotationPolys(); if (polys) { diff --git a/src/mesh/tool.js b/src/mesh/tool.js index d1b45246..851058bd 100644 --- a/src/mesh/tool.js +++ b/src/mesh/tool.js @@ -39,6 +39,41 @@ mesh.tool = class MeshTool { return this.indexed; } + listZ() { + let verts = this.checkVertices(this.uvert).group(3); + let zs = new Set(); + for (let vert of verts) { + zs.add(vert[2]); + } + return Array.from(zs).sort((a,b) => a - b); + } + + flattenZ(faceIdxs) { + let { uvert, faces } = this; + let zsum = 0; + let zunq = []; + for (let faceIdx of faceIdxs) { + let fv1 = faces[faceIdx * 3 + 0]; + let fv2 = faces[faceIdx * 3 + 1]; + let fv3 = faces[faceIdx * 3 + 2]; + let z1 = uvert[fv1 + 2]; + let z2 = uvert[fv2 + 2]; + let z3 = uvert[fv3 + 2]; + zunq.push(z1,z2,z3); + zsum = zsum + z1 + z2 + z3; + } + let zavg = ((( zsum / (faceIdxs.length * 3) ) * 10000 ) | 0) / 10000; + for (let faceIdx of faceIdxs) { + let fv1 = faces[faceIdx * 3 + 0]; + let fv2 = faces[faceIdx * 3 + 1]; + let fv3 = faces[faceIdx * 3 + 2]; + uvert[fv1 + 2] = zavg; + uvert[fv2 + 2] = zavg; + uvert[fv3 + 2] = zavg; + } + return { unique: zunq.sort().uniq(), average: zavg }; + } + /** * @param {number[]} vertices non-indexed */ @@ -46,6 +81,7 @@ mesh.tool = class MeshTool { this.checkVertices(vertices, 3); let doClean = opt.clean !== false; let doDedup = opt.dedup !== false; + let round = Math.pow(10, opt.round || 0); let faces = []; let fcac = {}; // seen face hash let fnew = []; // accumulate vertex triplets @@ -54,6 +90,11 @@ mesh.tool = class MeshTool { let prec = this.precision; let dups = 0; let cull = 0; + if (round > 1) { + for (let i=0, l=vertices.length; i