app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
master
import json,sys,math
from pathlib import Path
from shapely.geometry import Point,LineString
from plan_priority import Geometry,ROOT,connect
src=json.loads((ROOT/'repair-02/candidate-plan.json').read_text());m=Geometry();seeds=[]
for name,y in [(f'IC1.{i}',10.35 if i%2==0 else 9.7) for i in range(10,16)]:
p=m.pads[name];at=(p['at'][0],y);seeds.append((name,p['net'],p['at'],at))
keep=[];removed=[]
for r in src['routes']:
hit=any(math.dist(v,at)<.405 for v in r['vias'] for _,_,_,at in seeds)
for name,net,start,at in seeds:
if r['net']==net:continue
corridor=LineString([start,at]).buffer(.075+.106);disk=Point(at).buffer(.225+.106)
for p in r['parts']:
g=LineString(p['points']).buffer(p['width']/2)
if g.intersects(disk) or p['layer']==1 and g.intersects(corridor):hit=True
if any(Point(v).buffer(.225).intersects(corridor.union(disk)) for v in r['vias']):hit=True
(removed if hit else keep).append(r)
for r in keep:m.add_route(r['net'],[(p['layer'],p['points'],p['width']) for p in r['parts']],r['vias'])
for name,net,start,at in seeds:
assert m.clear([start,at],net,1,.13),(name,'trace')
assert m.via_clear(at,net),(name,'via')
m.add_route(net,[(1,[start,at],.13)],[at])
# Route further connections from the newly created physical through-via.
m.groups[net]=[{**p,'at':at,'layers':[1,2,15,16],'shape':Point(at).buffer(.225)} if p['name']==name else p for p in m.groups[net]]
out=ROOT/'repair-04';out.mkdir(exist_ok=False);(out/'removed.json').write_text(json.dumps(removed,indent=2));(out/'fanout.json').write_text(json.dumps(seeds,indent=2));print('Removed',len(removed),[r['net'] for r in removed],flush=True)
# Reuse the actual-copper component check from the prior repair tool.
s=(ROOT/'repair.py').read_text();a=s.index('def components');b=s.index('priority=',a);exec(s[a:b])
for net in sorted(m.groups,key=lambda n:({'ACDRV2':0,'!QON':1}.get(n,10),n)):
pads=m.groups[net]
if len(set(components(net)))==1:continue
pairs=sorted([(math.dist(a['at'],b['at']),i,j) for i,a in enumerate(pads) for j,b in enumerate(pads[:i])])
for _,i,j in pairs:
c=components(net)
if c[i]==c[j]:continue
r=connect(m,pads[i],pads[j],net,.15,True);print(net,pads[i]['name'],pads[j]['name'],bool(r),flush=True)
if r:m.add_route(net,*r)
(out/'candidate-plan.json').write_text(json.dumps({'routes':m.routes,'status':'native validation pending'},indent=2));m.export(out/'bq25792-astra-candidate.brd')
print('Remaining',{n:len(set(components(n))) for n in m.groups if len(set(components(n)))>1},flush=True)