skill
EDA Skillpack
Public Made by Adomby adom
All skills for all EDA capabilities across the Adom ecosystem.
main
from geometry import *
from shapely.ops import nearest_points
s=json.load(open('evidence/after-routing-state.json'));plans=json.load(open('stitching.json'));zs=json.load(open('outer-pours.json'));keep=unary_union([Polygon(z['polygon']) for z in zs if z.get('type')=='keepout']);out=[]
for plan in plans:
net=plan['net'];foreign=[p['g'] for p in pads if p['net']!=net]
foreign += [LineString([(t['start']['x'],t['start']['y']),(t['end']['x'],t['end']['y'])]).buffer(t['width']/2) for t in s['segments'] if t['net_name']!=net and t['layer']=='F.Cu']
foreign += [Point(v['position']['x'],v['position']['y']).buffer(v['size']/2) for v in s['vias'] if v['net_name']!=net]
obstacles=unary_union(foreign).buffer(.451).union(keep)
paths=[]
for path in plan['paths']:
pt=Point(path[0]['x'],path[0]['y']);candidates=[]
for p in pads:
if p['net']!=net or p['name'].startswith('U6.'):continue
inner=p['g'].buffer(-.15)
if inner.is_empty:continue
a=nearest_points(inner,pt)[0]
if a.is_empty:continue
line=LineString([a,pt])
if line.length<4 and not line.intersects(obstacles):candidates.append((line.length,a))
if candidates:
a=min(candidates,key=lambda q:q[0])[1];paths.append([{'x':round(a.x,6),'y':round(a.y,6),'layer':'F.Cu'}]+path)
if paths:out.append(dict(plan,paths=paths))
print(net,len(paths))
Path('stitching-unanchored-rejected.json').write_text(json.dumps(plans,indent=2));Path('stitching.json').write_text(json.dumps(out,indent=2))