From d976461ed46cb15b6faed75599a985b94b30a880 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Mon, 22 Sep 2025 21:38:02 -0400 Subject: [PATCH] code formatting --- src/kiri/mode/cam/cl-helical.js | 104 +++++++++++++-------------- src/kiri/mode/cam/slice.js | 124 ++++++++++++++++---------------- src/mesh/tool.js | 57 +++++++-------- 3 files changed, 142 insertions(+), 143 deletions(-) diff --git a/src/kiri/mode/cam/cl-helical.js b/src/kiri/mode/cam/cl-helical.js index 6894f0a6..f8102e94 100644 --- a/src/kiri/mode/cam/cl-helical.js +++ b/src/kiri/mode/cam/cl-helical.js @@ -5,59 +5,59 @@ import { clearPops, env } from "./client.js"; let alert, lastWidget; export let helicalOn = false; export function selectHelical() { - if (helicalOn) { - return helicalDone(); - } - clearPops(); - alert = api.show.alert("analyzing surfaces...", 1000); - let cylinders = env.poppedRec.cylinders; + if (helicalOn) { + return helicalDone(); + } + clearPops(); + alert = api.show.alert("analyzing surfaces...", 1000); + let cylinders = env.poppedRec.cylinders; - CAM.surface_prep(false, () => { - api.hide.alert(alert); - alert = api.show.alert("[esc] cancels surface selection"); - for (let [wid, arr] of Object.entries(cylinders)) { - let widget = api.widgets.forid(wid); - if ( widget && arr?.length ) - for (let faceid of arr) { - CAM.cylinderToggle(widget, faceid, (faceids) => { - // cylinders[widget.id] = faceids; - }); + CAM.surface_prep(false, () => { + api.hide.alert(alert); + alert = api.show.alert("[esc] cancels surface selection"); + for (let [wid, arr] of Object.entries(cylinders)) { + let widget = api.widgets.forid(wid); + if (widget && arr?.length) + for (let faceid of arr) { + CAM.cylinderToggle(widget, faceid, (faceids) => { + // cylinders[widget.id] = faceids; + }); + } + } + }); + helicalOn = env.hoveredOp; + helicalOn.classList.add("editing"); + api.feature.on_mouse_up = (obj, ev) => { + let { face } = obj; + let min = Math.min(face.a, face.b, face.c); + let faceid = min / 3; + let widget = (lastWidget = obj.object.widget); + CAM.cylinderToggle(widget, faceid, ({ faces, error }) => { + if (error) { + api.show.alert(error, 3000); + console.log(error); + return; + } + cylinders[widget.id] = faces; + }); + }; +}; + +export function helicalDone() { + if (!(helicalOn && env.poppedRec && env.poppedRec.cylinders)) { + return; + } + let { cylinders } = env.poppedRec; + for (let wid of Object.keys(cylinders)) { + let widget = api.widgets.forid(wid); + if (widget) { + CAM.cylinderClear(widget); + } else { + delete cylinders[wid]; } } - }); - helicalOn = env.hoveredOp; - helicalOn.classList.add("editing"); - api.feature.on_mouse_up = (obj, ev) => { - let { face } = obj; - let min = Math.min(face.a, face.b, face.c); - let faceid = min / 3; - let widget = (lastWidget = obj.object.widget); - CAM.cylinderToggle(widget, faceid, ({ faces, error }) => { - if ( error ) { - api.show.alert(error, 3000); - console.log( error ); - return; - } - cylinders[widget.id] = faces; - }); - }; -}; - -export function helicalDone(){ - if (!( helicalOn && env.poppedRec && env.poppedRec.cylinders )) { - return; - } - let { cylinders } = env.poppedRec; - for (let wid of Object.keys(cylinders)) { - let widget = api.widgets.forid(wid); - if (widget) { - CAM.cylinderClear(widget); - } else { - delete cylinders[wid]; - } - } - api.hide.alert(alert); - api.feature.on_mouse_up = undefined; - helicalOn.classList.remove("editing"); - helicalOn = false; + api.hide.alert(alert); + api.feature.on_mouse_up = undefined; + helicalOn.classList.remove("editing"); + helicalOn = false; }; diff --git a/src/kiri/mode/cam/slice.js b/src/kiri/mode/cam/slice.js index cf77b042..0d8f884d 100644 --- a/src/kiri/mode/cam/slice.js +++ b/src/kiri/mode/cam/slice.js @@ -510,8 +510,7 @@ export async function traces(settings, widget) { widget.traces = polylines; return true; -}; - +} /** * Returns an array of arrays of perpindicular triangles in the mesh. @@ -523,110 +522,109 @@ export async function traces(settings, widget) { * @param {object} opts - options object * @return {array} - array of arrays of triangle data */ -export async function cylinders(settings, widget, opts){ - - let {} = opts ?? {} - - let {array:verts} = widget.mesh.geometry.attributes.position - let perpTriangles = [] +export async function cylinders(settings, widget, opts) { + let { } = opts ?? {}; + let { array: verts } = widget.mesh.geometry.attributes.position; + let perpTriangles = []; //iterate over all triangles - for(let i = 0; i < verts.length; i+=9){ - let a = [verts[i], verts[i+1], verts[i+2]], - b = [verts[i+3], verts[i+4], verts[i+5]], - c = [verts[i+6], verts[i+7], verts[i+8]]; + for (let i = 0; i < verts.length; i += 9) { + let a = [verts[i], verts[i + 1], verts[i + 2]], + b = [verts[i + 3], verts[i + 4], verts[i + 5]], + c = [verts[i + 6], verts[i + 7], verts[i + 8]]; //calculate normal - let normal = new THREE.Vector3(a[0]-b[0], a[1]-b[1], a[2]-b[2]) - .cross(new THREE.Vector3(b[0]-c[0], b[1]-c[1], b[2]-c[2])) - .normalize() + let normal = new THREE.Vector3(a[0] - b[0], a[1] - b[1], a[2] - b[2]) + .cross(new THREE.Vector3(b[0] - c[0], b[1] - c[1], b[2] - c[2])) + .normalize(); // if perpindicular normal, and at least 2 Zs are the same - if(normal.z.round(5) == 0 && ! (a[2] != b[2] && b[2] != c[2])){ + if (normal.z.round(5) == 0 && !(a[2] != b[2] && b[2] != c[2])) { let minZ = Math.min(a[2], b[2], c[2]), maxZ = Math.max(a[2], b[2], c[2]); - if(minZ == maxZ){ // all Zs are the same indicated malformed geometry + if (minZ == maxZ) { // all Zs are the same indicated malformed geometry continue; } - perpTriangles.push({...[a,b,c], normal,minZ,maxZ,i:index}) + perpTriangles.push({ ...[a, b, c], normal, minZ, maxZ, i: index }); } } //map where zmax, zmin -> triangleData - let cylinderTriangles = new Map() - for(let t of perpTriangles){ - let hash = `${t.minZ.round(5)},${t.maxZ.round(5)}` - if(!cylinderTriangles.has(hash)){ - cylinderTriangles.set(hash,[]) + let cylinderTriangles = new Map(); + for (let t of perpTriangles) { + let hash = `${t.minZ.round(5)},${t.maxZ.round(5)}`; + if (!cylinderTriangles.has(hash)) { + cylinderTriangles.set(hash, []); } - cylinderTriangles.get(hash).push(t) + cylinderTriangles.get(hash).push(t); } - - return Array.from(cylinderTriangles.values()) + + return Array.from(cylinderTriangles.values()); } - - /** - * Find all triangles that are part of the same cylinder as the given triangle - * @param {Widget} widget - widget object - * @param {number} face - index of face in triangle vertex data - * @return {array} - array of all triangle data that belong to the same cylinder - * @requires surface_prep must be called first - */ +/** + * Find all triangles that are part of the same cylinder as the given triangle + * @param {Widget} widget - widget object + * @param {number} face - index of face in triangle vertex data + * @return {array} - array of all triangle data that belong to the same cylinder + * @requires surface_prep must be called first + */ export function cylinder_find (widget, face){ CAM.surface_prep(widget,false); return widget.tool.findCylinderSurface(face); } -export function cylinder_poly_find(widget, face){ +export function cylinder_poly_find(widget, face) { let faces = cylinder_find(widget, face); let vert = widget.getGeoVertices({ unroll: true, translate: true }).map(v => v.round(4)); - let slicer = new cam_slicer(widget,{}) - let opts = { - dedup:false, - edges: false, - over:true - } - let firstOffset = faces[0]*9 - let [x1,y1,z1,x2,y2,z2,x3,y3,z3]= Array.from(vert.subarray(firstOffset,firstOffset+9)) - let zs = [z1,z2,z3].map(z => z.round(5)) + let slicer = new cam_slicer(widget, {}); + let firstOffset = faces[0] * 9; + let [x1, y1, z1, x2, y2, z2, x3, y3, z3] = Array.from(vert.subarray(firstOffset, firstOffset + 9)); + let zs = [z1, z2, z3].map(z => z.round(5)); let zmin = Math.min(...zs); let zmax = Math.max(...zs); - let zmid = (zmin+zmax)/2 - let cylVerts = new Float32Array(faces.length*9) - + let zmid = (zmin + zmax) / 2; + let cylVerts = new Float32Array(faces.length * 9); + let opts = { + dedup: false, + edges: false, + over: true + }; + let i = 0 //for each cylinder face index - for(let index of faces){ - let off = index*9 + for (let index of faces) { + let off = index * 9; //copy the 9 triangle vertices floats in - for(let j = 0;j < 9;j++){ - cylVerts[i] = vert[off+j] - i++ + for (let j = 0; j < 9; j++) { + cylVerts[i] = vert[off + j]; + i++; } } + //slice the poly at the midpoint - let poly = slicer.sliceZ(zmid, cylVerts,opts)?.polys?.at(0) - if(!poly) throw "slicing returned no poly" + let poly = slicer.sliceZ(zmid, cylVerts, opts)?.polys?.at(0); + if (!poly) throw "slicing returned no poly"; + let circular = poly.circularity() > 0.98; + //throw error if not circular - if(!circular) throw "faces must be circular" - + if (!circular) throw "faces must be circular"; + //calculate circle properties let area = poly.area(), - diam = Math.sqrt(area / Math.PI)* 2, + diam = Math.sqrt(area / Math.PI) * 2, center = poly.calcCircleCenter(); - - //find direction using normal to center point + //find direction using normal to center point let point = newPoint(x1, y1, z1), delta = point.setZ(center.z).sub(center), - normal = new THREE.Vector3(x1-x2, y1-y2, z1-z2) - .cross(new THREE.Vector3(x2-x3, y2-y3, z2-z3)), + normal = new THREE.Vector3(x1 - x2, y1 - y2, z1 - z2) + .cross(new THREE.Vector3(x2 - x3, y2 - y3, z2 - z3)), dotProd = normal.dot(delta), - interior = dotProd < 0 + interior = dotProd < 0 - return {faces, zmin, zmax, poly, circular, area, diam, center,interior} + return { faces, zmin, zmax, poly, circular, area, diam, center, interior } } /** diff --git a/src/mesh/tool.js b/src/mesh/tool.js index 41db2f8b..bc80aa6a 100644 --- a/src/mesh/tool.js +++ b/src/mesh/tool.js @@ -241,13 +241,12 @@ class MeshTool { }; } -/** - * Retrieves the adjacent faces for a given face index. - * - * @param {number} face - The index of the face for which adjacent faces are to be found. - * @returns {number[]} An array of face indices that are adjacent to the given face. - */ - + /** + * Retrieves the adjacent faces for a given face index. + * + * @param {number} face - The index of the face for which adjacent faces are to be found. + * @returns {number[]} An array of face indices that are adjacent to the given face. + */ getAdjacentFaces(face) { const { faces, sides } = this.getIndex(); const foff = face * 6; @@ -319,31 +318,31 @@ class MeshTool { * 3. Filtering faces with normals perpendicular to Z axis * 4. Recursively adding adjacent faces with the same Z values and normal perpendicular to Z axis */ - findCylinderSurface(face){ - face = Number(face) - - const radianTolerance = 8 * (Math.PI/180); + findCylinderSurface(face) { + face = Number(face); + const radianTolerance = 8 * (Math.PI / 180); const vertexTolerance = 1e-4; - //helper function - const dissimilar = (a,b,c) => Math.abs(a-b) > vertexTolerance && - Math.abs(b-c) > vertexTolerance && - Math.abs(a-c) > vertexTolerance; + + // helper function + const dissimilar = (a, b, c) => Math.abs(a - b) > vertexTolerance && + Math.abs(b - c) > vertexTolerance && + Math.abs(a - c) > vertexTolerance; let found = {}, out = [face], - {vertices} = this, - {faces} = this.getIndex(), - faceOffset = face*9, - zs = [2,5,8].map(i => vertices[faceOffset+i].round(5)), //get zs from face vertices + { vertices } = this, + { faces } = this.getIndex(), + faceOffset = face * 9, + zs = [2, 5, 8].map(i => vertices[faceOffset + i].round(5)), //get zs from face vertices lowZ = Math.min(zs), highZ = Math.max(zs), checked = {}, check = [face]; - - //check for errors, and throw if found - if(dissimilar(...zs)){ + + // check for errors, and throw if found + if (dissimilar(...zs)) { throw `face must have only 2 Z values. found: ${zs.join(", ")}` - }else if(Math.abs( faces[face * 6 + 2] > 1e-6 )){ + } else if (Math.abs(faces[face * 6 + 2] > 1e-6)) { throw "face's normal must be perpendicular to Z axis" } @@ -352,11 +351,12 @@ class MeshTool { const face = check.shift(); const froot = face * 6; const vroot = face * 9 - + // filter faces to those perpendicular to +z axis - if ( Math.abs( faces[froot + 2] > 1e-6 )) continue; - //filter faces with verts don't share the z values of the first face - if( + if (Math.abs(faces[froot + 2] > 1e-6)) continue; + + // filter faces with verts don't share the z values of the first face + if ( !(vertices[vroot + 2] !== lowZ || vertices[vroot + 2] !== highZ) && !(vertices[vroot + 5] !== lowZ || vertices[vroot + 5] !== highZ) && !(vertices[vroot + 8] !== lowZ || vertices[vroot + 8] !== highZ) @@ -369,7 +369,7 @@ class MeshTool { } const aroot = f * 6; let sum = 0; - for (let i=0; i<3; i++) { + for (let i = 0; i < 3; i++) { sum += Math.pow(faces[froot + i] - faces[aroot + i], 2); } const fn = Math.sqrt(sum); @@ -381,6 +381,7 @@ class MeshTool { } } } + return out; }