seveibar/pd-dual-stepper-controller

Bottom-side PCB silkscreen artwork consisting of embedded mirrored TS Circuit SVG logos, with via-clearance-aware lower-board placement.

Version
0.1.0
License
unset
Stars
0

scripts/resume-freerouting.py

"""Add the routed session to the authoritative DSN as editable copper for another routing pass."""
from freerouting_geometry import *
text=Path(sys.argv[1] if len(sys.argv)>1 else 'work/freerouting/routed.ses').read_text().replace('(string_quote ")','(string_quote DQUOTE)')
tokens=re.findall(r'"(?:[^"\\]|\\.)*"|[()]|[^\s()]+',text);stack=[];tree=None
for token in tokens:
 if token=='(':
  obj=[]
  if stack:stack[-1].append(obj)
  stack.append(obj)
 elif token==')':tree=stack.pop()
 else:stack[-1].append(token.strip('"'))
def entries(a,k):return [x for x in a if isinstance(x,list) and x and x[0]==k]
def one(a,k):return next(iter(entries(a,k)),None)
routes=one(tree,'routes');res=one(routes,'resolution');scale={'um':.001,'mm':1}[res[1]]/float(res[2]);copper=[]
fixed=[e for e in j if e['type']=='pcb_via']
for net in entries(one(routes,'network_out'),'net'):
 for wire in entries(net,'wire'):
  path=one(wire,'path');copper.append('(wire (path '+path[1]+' '+' '.join(u(float(v)*scale) for v in path[2:])+f') (net {net[1]}) (type normal))')
 for via in entries(net,'via'):
  x,y=float(via[2])*scale,float(via[3])*scale
  if any(math.hypot(x-e['x'],y-e['y'])<.0002 for e in fixed):continue
  copper.append(f'(via VIA {xy(x,y)} (net {net[1]}) (type normal))')
fresh=Path(sys.argv[2] if len(sys.argv)>2 else 'work/freerouting/board.dsn').read_text();assert fresh.endswith(')\n)\n')
Path(sys.argv[3] if len(sys.argv)>3 else 'work/freerouting/resume-clean.dsn').write_text(fresh[:-4]+'\n'+'\n'.join(copper)+'\n)\n)\n')
print('Preserved',len(copper),'editable wire/via objects')