# -*- coding: utf-8 -*- u"""删掉 PCB 上「死网络」的铜:导线(铜层 1/2/15/16)+ 过孔。 /c/Python314/python .claude/pcb_prune_nets.py '<正则>' [--push] 判「死」的两条:① 网名匹配正则;② 网名不在任何焊盘上(孤儿网 —— 原理图删掉元件后, 它们的局部网 `$2N689` 这类还留在导线上)。空网名的导线不动(板框 / 手画铜带可能没网名)。 2026-09-06 为「74HC595 整窝挪到载板」写的:下板上 POGO*/EDL_EN*/HUB_RST/K*/KEY_*/SR_CAS* 那 900 多段铜整批作废;载板上 POGO*/EDL_EN*/HUB_RST 从排母来的旧线也要拆。 """ import json import os import re import sys HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) from eda import run # noqa: E402 JS = u""" await eda.dmt_EditorControl.openDocument('%s'); await new Promise(r => setTimeout(r, 1800)); const padNets = new Set(); for (const p of await eda.pcb_PrimitivePad.getAll()) { const n = p.getState_Net(); if (n) padNets.add(n); } const lines = [], vias = []; for (const l of await eda.pcb_PrimitiveLine.getAll()) { const lay = l.getState_Layer(); if (![1, 2, 15, 16].includes(lay)) continue; lines.push([l.getState_PrimitiveId(), l.getState_Net() || '', lay]); } for (const v of await eda.pcb_PrimitiveVia.getAll()) vias.push([v.getState_PrimitiveId(), v.getState_Net() || '']); return {padNets: [...padNets], lines, vias}; """ JS_DEL = u""" await eda.dmt_EditorControl.openDocument('%s'); await new Promise(r => setTimeout(r, 1500)); const L = %s, V = %s; for (let i = 0; i < L.length; i += 200) await eda.pcb_PrimitiveLine.delete(L.slice(i, i + 200)); for (let i = 0; i < V.length; i += 200) await eda.pcb_PrimitiveVia.delete(V.slice(i, i + 200)); await eda.pcb_Document.save(); await new Promise(r => setTimeout(r, 800)); return {l: (await eda.pcb_PrimitiveLine.getAll()).length, v: (await eda.pcb_PrimitiveVia.getAll()).length}; """ def main(): args = [a for a in sys.argv[1:] if not a.startswith('--')] pcb, pat = args[0], re.compile(args[1]) r = run(JS % pcb, timeout=300) assert r.get('success'), json.dumps(r, ensure_ascii=False)[:500] st = r['result'] have = set(st['padNets']) def dead(n): return bool(n) and (pat.match(n) is not None or n not in have) dl = [pid for pid, n, _lay in st['lines'] if dead(n)] dv = [pid for pid, n in st['vias'] if dead(n)] by = {} for pid, n, _lay in st['lines']: if dead(n): by[n] = by.get(n, 0) + 1 for pid, n in st['vias']: if dead(n): by['via:' + n] = by.get('via:' + n, 0) + 1 print(u'死网铜:导线 %d / 过孔 %d(板上共 %d / %d)' % (len(dl), len(dv), len(st['lines']), len(st['vias']))) for n in sorted(by): print(u' %-16s %d' % (n, by[n])) if '--push' not in sys.argv: print(u'(未加 --push,没有改动)') return r = run(JS_DEL % (pcb, json.dumps(dl), json.dumps(dv)), timeout=900) assert r.get('success'), json.dumps(r, ensure_ascii=False)[:500] print(u'已删并存盘;板上剩余导线 %d / 过孔 %d' % (r['result']['l'], r['result']['v'])) if __name__ == '__main__': main()