文件

102 行
4.5 KiB
Python

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# -*- coding: utf-8 -*-
u"""下板 PCB1 板框 + 定位孔(2026-09-06 两板对齐版)。
/c/Python314/python .claude/pcb1_outline.py --push
板框 220 × 135、左下角 (−30,−5)(下板坐标原点不动,= 载板坐标 − (30,5));
定位孔取 `pcb1_place.MH`(= 载板 `pcb2_place.MH` 减 (30,5),四角 + 两侧中点)。
原来 `pcb_place.py --outline` 干这件事,但那个单板时代的脚本在 import 时就要找 J2 之类早就删掉的位号,
跑不起来了;这里把它的 `outline_poly` / `push_outline` 抠出来独立跑(同样的多段线 + MULTI 层自由焊盘写法,
注意事项见 pcb_place.push_outline 的 docstring)。
"""
import json
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
from eda import run # noqa: E402
from pcb1_place import MH, PCB, MIL, MH_HOLE, MH_PAD # noqa: E402
# ⚠️ 不能 `from pcb_place import ...`:那个单板时代的脚本在 import 时就跑 put() 表,找不到 J2 直接 assert。
# 板框常量在这里独立维护(和 pcb_place.py 里的 OX/OY/OW/OH 同值)。
OX, OY, OW, OH = -30.0, -5.0, 220.0, 135.0
CORNER_R = 5.0
def outline_poly():
u"""板框多边形 -> TPCB_PolygonSourceArray(mil),逆时针、四角 R5、末段圆弧回到起点(抄自 pcb_place.outline_poly)。"""
R = CORNER_R
X0, Y0, X1, Y1 = OX, OY, OX + OW, OY + OH
pts = []
L = lambda x, y: pts.append(('L', x, y))
A = lambda x, y: pts.append(('ARC', 90.0, x, y))
start = (X0 + R, Y0)
L(X1 - R, Y0); A(X1, Y0 + R)
L(X1, Y1 - R); A(X1 - R, Y1)
L(X0 + R, Y1); A(X0, Y1 - R)
L(X0, Y0 + R); A(X0 + R, Y0)
src, mode = [start[0] * MIL, start[1] * MIL], None
for q in pts:
if q[0] == 'L':
if mode != 'L':
src.append('L'); mode = 'L'
src += [q[1] * MIL, q[2] * MIL]
else:
src.append('ARC'); mode = 'ARC'
src += [q[1], q[2] * MIL, q[3] * MIL]
return [round(v, 4) if isinstance(v, float) else v for v in src]
OPEN = ("await eda.dmt_EditorControl.openDocument('%s');"
"await new Promise(r=>setTimeout(r,1500));" % PCB)
def call(body, timeout=240):
r = run(OPEN + body, timeout=timeout)
if not r.get('success'):
sys.exit(u'下发失败: ' + json.dumps(r, ensure_ascii=False)[:500])
return r['result']
def main():
if '--push' not in sys.argv:
print(u'板框 %.0f×%.0f 左下角 (%.0f,%.0f);定位孔 %s(加 --push 下发)' % (OW, OH, OX, OY, MH))
return
n = call("""
let del = 0;
for (const l of await eda.pcb_PrimitiveLine.getAll())
if (l.getState_Layer() === 11) { await eda.pcb_PrimitiveLine.delete(l.getState_PrimitiveId()); del++; }
for (const p of await eda.pcb_PrimitivePolyline.getAll())
if (p.getState_Layer() === 11) { await eda.pcb_PrimitivePolyline.delete(p.getState_PrimitiveId()); del++; }
const poly = await eda.pcb_MathPolygon.createPolygon(%s);
const r = await eda.pcb_PrimitivePolyline.create('', 11, poly, 5);
const left = (await eda.pcb_PrimitivePolyline.getAll()).filter(p => p.layer === 11).length;
return {del, made: r ? r.primitiveId : null, left};
""" % json.dumps(outline_poly()))
if n['left'] != 1:
sys.exit(u'!! layer 11 上有 %d 条多段线,应为 1' % n['left'])
print(u'板框: %.0f × %.0f,左下角 (%.0f,%.0f),R%.0f;删旧 %d' % (OW, OH, OX, OY, CORNER_R, n['del']))
k = call("""
const MH = %s;
let del = 0;
for (const p of await eda.pcb_PrimitivePad.getAll()) {
const num = p.getState_PadNumber();
let parent = null; try { parent = p.getState_ParentPrimitiveId ? p.getState_ParentPrimitiveId() : null; } catch (e) {}
if (typeof num === 'string' && num.indexOf('MH') === 0 && !parent) { await eda.pcb_PrimitivePad.delete(p.getState_PrimitiveId()); del++; }
}
let k = 0;
for (let i = 0; i < MH.length; i++) {
await eda.pcb_PrimitivePad.create(12, 'MH' + (i + 1), MH[i][0], MH[i][1], 0,
['ELLIPSE', %.2f, %.2f], 'GND', ['ROUND', %.4f], 0, 0, 0, true);
k++;
}
await eda.pcb_Document.save();
return {del, k};
""" % (json.dumps([[round(x * MIL, 2), round(y * MIL, 2)] for x, y in MH]),
MH_PAD * MIL, MH_PAD * MIL, MH_HOLE * MIL))
print(u'定位孔: 删旧 %d / 新建 %d(Φ%.1f / 焊盘 Φ%.1f / 接 GND)' % (k['del'], k['k'], MH_HOLE, MH_PAD))
if __name__ == '__main__':
main()