seveibar/am3352-dev-board
A 324-ball TI AM3352 ARM processor with DDR3, LCD, USB, Ethernet, storage, serial, analog, clock, reset, power, and JTAG interfaces, paired with configurable JST-GH board connectors and constrained PCB routing.
- Version
- 1.0.2
- License
- unset
- Stars
- 0
scripts/normalize-copper-junctions.py
"""Make physical pad/via and trace junctions explicit in saved routing centerlines."""
import json,runpy,math,os
from pathlib import Path
from shapely.geometry import Point,LineString
from shapely.ops import unary_union
import shapely
ctx=runpy.run_path('scripts/audit-copper.py');data=json.loads(Path('design/routed-copper.json').read_text());stubs=0
names={e['source_net_id']:e['name'] for e in ctx['c'] if e['type']=='source_net'}
selected=set(os.environ.get('NORMALIZE_NETS','').split(','))
for sid,routes in data['nets'].items():
if selected!={''} and names.get(sid,sid) not in selected:continue
net=ctx['find'](sid);vias=[p for r in routes for p in r if p['route_type']=='via'];wireRoutes=[r for r in routes if not any(p['route_type']=='via' for p in r) and len(r)>1];layers={r[0]['layer'] for r in wireRoutes};result=[r for r in routes if any(p['route_type']=='via' for p in r)]
for layer in layers:
rs=[r for r in wireRoutes if r[0]['layer']==layer];lines=[LineString([(p['x'],p['y']) for p in r]) for r in rs];added=[]
pads=[(g,ctx['ports'][m[3]]) for g,m in zip(ctx['shapes'],ctx['meta']) if m[0]==layer and m[1]==net and m[3]]
for j,(r,line) in enumerate(zip(rs,lines)):
for p in [r[0],r[-1]]:
pt=Point(p['x'],p['y']);target=None
for g,port in pads:
if g.buffer(.000001).covers(pt):target=Point(port['x'],port['y']);break
if target is None:
for v in vias:
if pt.distance(Point(v['x'],v['y']))<v.get('via_diameter',.3)/2:target=Point(v['x'],v['y']);break
if target is None:
close=[(other.distance(pt),other) for k,other in enumerate(lines) if k!=j and other.distance(pt)<.049]
if close:
other=min(close,key=lambda x:x[0])[1];target=other.interpolate(other.project(pt))
if target is not None and pt.distance(target)>1e-7:added.append(LineString([pt,target]));stubs+=1
merged=shapely.union_all([shapely.set_precision(l,.000001) for l in lines+added])
pieces=list(merged.geoms) if hasattr(merged,'geoms') else [merged]
for line in pieces:
if line.is_empty or line.length<1e-7:continue
result.append([{'route_type':'wire','x':x,'y':y,'width':.1,'layer':layer} for x,y in line.coords])
data['nets'][sid]=result
Path('design/routed-copper.json').write_text(json.dumps(data,separators=(',',':'))+'\n');print('Made',stubs,'pad/via/trace contacts explicit')