Devesh36/pocket-audio-player

A portable, rechargeable microSD audio player built around an RP2040, SPI flash, USB‑C charging/power management, LCD/button controls, PCM5102A I²S DAC, and TPA6132A headphone amplifier in a 3D‑printed enclosure.

Version
1.0.12
License
unset
Stars
0

scripts/check-enclosure-mesh.ts

const results=[]
for(const name of ['case-base','case-lid','button-plunger','ring-button']){
 const raw=await Bun.file(`dist/enclosure/${name}.stl`).text()
 const vertices=raw.split('\n').filter(l=>l.startsWith('vertex ')).map(l=>l.slice(7).trim().split(/\s+/).map(Number).map(v=>Math.round(v*1e5)/1e5).join(','))
 const edges=new Map<string,number>(),directed=new Map<string,number>(),owners=new Map<string,number[]>()
 for(let i=0;i<vertices.length;i+=3){
  for(const [a,b] of [[vertices[i],vertices[i+1]],[vertices[i+1],vertices[i+2]],[vertices[i+2],vertices[i]]]){
   const e=[a,b].sort().join('|'),d=[a,b].join('|')
   edges.set(e,(edges.get(e)??0)+1);directed.set(d,(directed.get(d)??0)+1);owners.set(e,[...(owners.get(e)??[]),i/3])
  }
 }
 const nonManifoldEdges=[...edges.values()].filter(n=>n!==2).length
 const inconsistentWindingEdges=[...edges.keys()].filter(e=>{const [a,b]=e.split('|');return directed.get([a,b].join('|'))!==directed.get([b,a].join('|'))}).length
 const adjacent=new Map<number,Set<number>>()
 for(const faces of owners.values())for(const face of faces){if(!adjacent.has(face))adjacent.set(face,new Set());for(const next of faces)adjacent.get(face)!.add(next)}
 const unseen=new Set(Array.from({length:vertices.length/3},(_,i)=>i));let surfaceComponents=0
 while(unseen.size){surfaceComponents++;const first=unseen.values().next().value!;unseen.delete(first);const pending=[first];while(pending.length){for(const next of adjacent.get(pending.pop()!)??[]){if(unseen.delete(next))pending.push(next)}}}
 if(surfaceComponents!==1)throw new Error(`${name}: disconnected printable geometry`)
 if(nonManifoldEdges||inconsistentWindingEdges)throw new Error(`${name}: STL boundary/winding check failed`)
 results.push({file:`${name}.stl`,triangles:vertices.length/3,nonManifoldEdges,inconsistentWindingEdges,surfaceComponents})
}
await Bun.write('dist/enclosure/mesh-check.json',JSON.stringify(results,null,2))
console.log(JSON.stringify(results,null,2))