imrishabh18/corne-keyboard

The code defines and renders two surface-mount chip components with SMT pads, silkscreen outlines, and 3D CAD models (OBJ and STEP) for PCB assembly.

Version
2.0.21
License
unset
Stars
1

scripts/refine-left.ts

import fs from 'node:fs'
import {runAllRoutingChecks,checkCopperToBoardEdgeClearance,checkPcbCopperOverKeepout,dedupePcbDrcErrors} from '@tscircuit/checks'
let circuit=JSON.parse(fs.readFileSync('../left-near-clean.circuit.json','utf8')).filter((x:any)=>!x.type.endsWith('_error')&&!x.type.endsWith('_warning'))
async function errors(c:any[]){return dedupePcbDrcErrors([...(await runAllRoutingChecks(c)),...checkCopperToBoardEdgeClearance(c),...checkPcbCopperOverKeepout(c)])}
function move(c:any[],from:any,to:any){for(const x of c){if(x.type==='pcb_via'&&Math.hypot(x.x-from.x,x.y-from.y)<1e-6){x.x=to.x;x.y=to.y}if(x.type==='pcb_trace')for(const p of x.route){if(Math.hypot(p.x-from.x,p.y-from.y)<1e-6&&!p.start_pcb_port_id&&!p.end_pcb_port_id){p.x=to.x;p.y=to.y}}}}
for(const [keepId,dropId] of [['pcb_via_16','pcb_via_210'],['pcb_via_177','pcb_via_180']]){
 const keep=circuit.find((x:any)=>x.pcb_via_id===keepId);const drop=circuit.find((x:any)=>x.pcb_via_id===dropId);move(circuit,{...drop},keep);circuit=circuit.filter((x:any)=>x.pcb_via_id!==dropId)
}
// Remove an isolated, redundant copper branch; verify all source connectivity below.
const orphan='source_net_0_mst16_1';circuit=circuit.filter((x:any)=>x.pcb_trace_id!==orphan)
let current=await errors(circuit)
console.log('After merged drill holes and orphan removal',current.length,current.map((x:any)=>x.message))
function score(es:any[]){return es.reduce((s,e)=>s+1+(e.actual_clearance!==undefined?Math.max(0,(e.minimum_clearance??0.1)-e.actual_clearance):e.message.includes('accidental')?2:0),0)}
for(const id of ['pcb_via_95','pcb_via_204']){
 const base=circuit;const original=base.find((x:any)=>x.pcb_via_id===id);let best=score(current);let chosen:any=null,chosenErrors:any=current
 for(const radius of [0.04,0.08,0.12,0.18,0.25,0.35])for(let k=0;k<16;k++){
  const angle=k*Math.PI/8;const c=structuredClone(base);const to={x:original.x+radius*Math.cos(angle),y:original.y+radius*Math.sin(angle)};move(c,original,to)
  const e=await errors(c);const value=score(e);if(value<best-1e-9){best=value;chosen=c;chosenErrors=e;console.log('candidate',id,to,e.length,value)}
 }
 if(chosen){circuit=chosen;current=chosenErrors}
}
fs.writeFileSync('../left-refined.circuit.json',JSON.stringify(circuit,null,2));fs.writeFileSync('../left-refined.errors.json',JSON.stringify(current,null,2));console.log('Remaining',current.length,current.map((x:any)=>x.message))