master
John Lauer Preserve validated CRR thermal routing recipe and narrated demonstration 92d2870 1mo ago
import json,math
from plan_priority import Geometry,ROOT,simple,octilinear
m=Geometry();j=json.loads((ROOT/'repair-04/candidate-plan.json').read_text())
for r in j['routes']:m.add_route(r['net'],[(p['layer'],p['points'],p['width']) for p in r['parts']],r['vias'])
new=Geometry();before=after=0
for r in j['routes']:
 parts=[]
 for p in r['parts']:
  pts=p['points'];before+=len(pts)-1;out=[pts[0]];i=0
  while i<len(pts)-1:
   z=len(pts)-1;path=None
   while z>i:
    path=simple(m,pts[i],pts[z],r['net'],p['layer'],p['width'])
    if path:break
    z-=1
   assert path
   out.extend(path[1:]);i=z
  clean=[]
  for pt in out:
   if clean and math.dist(clean[-1],pt)<1e-7:continue
   clean.append(pt)
   while len(clean)>=3:
    a,b,c=clean[-3:];u=(b[0]-a[0],b[1]-a[1]);v=(c[0]-b[0],c[1]-b[1])
    if abs(u[0]*v[1]-u[1]*v[0])<1e-8 and u[0]*v[0]+u[1]*v[1]>0:clean.pop(-2)
    else:break
  assert all(octilinear(a,b) for a,b in zip(clean,clean[1:]))
  after+=len(clean)-1;parts.append((p['layer'],clean,p['width']))
 new.add_route(r['net'],parts,r['vias'])
out=ROOT/'polished';out.mkdir(exist_ok=False);(out/'candidate-plan.json').write_text(json.dumps({'routes':new.routes,'status':'native DRC pending'},indent=2));new.export(out/'bq25792-astra-candidate.brd');(out/'angle-audit.json').write_text(json.dumps({'beforeSegments':before,'afterSegments':after,'offAngleSegments':0,'allowedDirectionsDegrees':[0,45,90,135,180,225,270,315]},indent=2));print(before,after)