R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
u"""删掉 PCB 上「死网络」的铜:导线(铜层 1/2/15/16)+ 过孔。
|
||||
|
||||
/c/Python314/python .claude/pcb_prune_nets.py <pcbUuid> '<正则>' [--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()
|
||||
在新工单中引用
屏蔽一个用户