R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-10-04 19:24:45 +08:00
共同撰写人 Claude Opus 5.5
父节点 cd01640c40
当前提交 cf7cc9cf90
共修改 759 个文件,包含 76962 行新增和 5299 行删除
+174
查看文件
@@ -0,0 +1,174 @@
# -*- coding: utf-8 -*-
u"""南侧板 v4 —— 跟着 15 mm 分风腔加长(2026-09-13)。
与 v3 的差别只有两处,都是「端板外移 11」的下游:
· 长度 x −27.4~125.4(152.8)⇒ **−38.4~136.4(175.0)**
· A 组螺丝孔 x −13.70/111.70 ⇒ **−31/129**(端板角柱中心),z 2.0/60.0 ⇒ **10/60**
⛔ 旧的 x=−13.70 打在端板的**空气**里:端板在 z=72 那层只有 2.4 厚的板本体,
L 脚在底部 z 0~2.4,中间是空的。v10 加的角柱(x −36~−26 / 124~134,截面 8×10、
通高 z 0~72)才是这 8 颗螺丝真正能拧进去的肉。
· B 组 3 个孔(x 30/49/68, z −5)保留 —— B 组已取消,孔留着无害(PROGRESS 已记)。
其余(USB-C 开口位置 13×9、板厚、z 范围)与 v3 逐字相同:开口对准的是底板上的座子,
座子没动 ⇒ 开口不能动。
⛔ 竖板、法线沿 y ⇒ 画在**上视基准面**:草图 (u,v) → 模型 (x, −z),拉伸法线 +y。
⛔ 画草图前必须 `sm.AddToDB = True`。
⛔ 判据:矩形开口用不了圆柱面计数 ⇒ 用面数(6 + 每个通口 4)+ Ø3.4 圆柱面计数。
"""
import io
import os
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', write_through=True)
import pythoncom
import win32com.client as wc
DST = u'D:\\DCDC\\新建文件夹\\5blades\\SouthPanel_v4.SLDPRT'
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
X0, X1 = -38.4, 136.4
Z0, Z1 = -10.0, 72.0
PANEL_T = 2.4
_J1_CX, _J23_CX, _OP_CZ = 12.50, 84.00, -1.20
OP_W, OP_H = 13.0, 9.0
OPENINGS = [(_J1_CX - OP_W / 2, _J1_CX + OP_W / 2),
(_J23_CX - OP_W / 2, _J23_CX + OP_W / 2)]
OP_Z0, OP_Z1 = _OP_CZ - OP_H / 2, _OP_CZ + OP_H / 2
SCREW_D = 3.4
POST_CX_W, POST_CX_E = -31.0, 129.0 # 端板角柱中心(西 x −36~−26 / 东 124~134)
SCREW_HOLES = [(POST_CX_W, 10.0), (POST_CX_W, 60.0),
(POST_CX_E, 10.0), (POST_CX_E, 60.0),
(30.0, -5.0), (49.0, -5.0), (68.0, -5.0)]
def prop(o, n):
v = getattr(o, n)
return v() if type(v).__name__ in ('method', 'function', 'builtin_function_or_method') else v
def D(x):
return x if hasattr(x, '_oleobj_') else wc.Dispatch(x)
def P(*a):
print(*a)
def M(v):
return v / 1000.0
def UZ(z):
u"""上视基准面:草图纵坐标 v → 模型 −z"""
return M(-z)
app = wc.GetActiveObject('SldWorks.Application')
for d in list(app.GetDocuments or []):
try:
t = prop(d, 'GetTitle') or ''
if 'SOUTHPANEL_V4' in t.upper():
app.CloseDoc(t)
P(u'关掉旧文档 %s' % t)
except Exception:
pass
tmpl = app.GetUserPreferenceStringValue(8)
app.NewDocument(tmpl, 0, 0.0, 0.0)
part = app.ActiveDoc
P(u'新建零件 %s' % prop(part, 'GetTitle'))
sm, fm = part.SketchManager, part.FeatureManager
def sk_name():
nm, f = None, prop(part, 'FirstFeature')
while f:
if prop(f, 'GetTypeName2') == 'ProfileFeature':
nm = prop(f, 'Name')
f = prop(f, 'GetNextFeature')
return nm
def pick(name, typ):
part.ClearSelection2(True)
part.Extension.SelectByID2(name, typ, 0, 0, 0, False, 0, EMPTY, 0)
return part.SelectionManager.GetSelectedObjectCount2(-1)
def bodies():
return part.GetBodies2(0, True) or []
def bbox():
b = bodies()
if not b:
return None
xs = [[round(v * 1000, 3) for v in prop(D(x), 'GetBodyBox')] for x in b]
return [min(v[0] for v in xs), min(v[1] for v in xs), min(v[2] for v in xs),
max(v[3] for v in xs), max(v[4] for v in xs), max(v[5] for v in xs)]
P(u'\n[1] 板本体 %.1f(x) × %.1f(z) × %.1f,含 2 个 USB-C 开口 + %d 个 Ø%.1f 螺丝孔'
% (X1 - X0, Z1 - Z0, PANEL_T, len(SCREW_HOLES), SCREW_D))
pick(u'上视基准面', 'PLANE')
sm.InsertSketch(True)
sm.AddToDB = True
sm.CreateCornerRectangle(M(X0), UZ(Z0), 0.0, M(X1), UZ(Z1), 0.0)
for ox0, ox1 in OPENINGS:
sm.CreateCornerRectangle(M(ox0), UZ(OP_Z0), 0.0, M(ox1), UZ(OP_Z1), 0.0)
for sx, sz in SCREW_HOLES:
sm.CreateCircleByRadius(M(sx), UZ(sz), 0.0, M(SCREW_D / 2))
sm.AddToDB = False
_segs = prop(D(prop(sm, 'ActiveSketch')), 'GetSketchSegments')
want_segs = 4 * (1 + len(OPENINGS)) + len(SCREW_HOLES)
P(u' 草图 segment = %d(期望 %d)' % (len(_segs) if _segs else 0, want_segs))
# 回读每个圆:只数条数查不出自动捕捉的静默篡改
for _s in (_segs or []):
_ss = D(_s)
if prop(_ss, 'GetType') != 1:
continue
_c = D(prop(_ss, 'GetCenterPoint2'))
P(u' 圆 r=%.3f 圆心=(%.3f, %.3f)'
% (prop(_ss, 'GetRadius') * 1000, prop(_c, 'X') * 1000, prop(_c, 'Y') * 1000))
sm.InsertSketch(True)
if pick(sk_name(), 'SKETCH') != 1:
P(u'⛔ 草图没选中'); sys.exit(2)
feat = fm.FeatureExtrusion3(True, False, False, 0, 0, M(PANEL_T), 0.0,
False, False, False, False, 0.0, 0.0,
False, False, False, False, True, True, True, 0, 0.0, False)
P(u' 拉伸 → %r' % (prop(feat, 'Name') if feat else feat))
b = bbox()
P(u' box %s(期望 x %.1f~%.1f, y 0~%.1f, z %.1f~%.1f)' % (b, X0, X1, PANEL_T, Z0, Z1))
if not b:
P(u'⛔ 没出实体(多半开口越界或轮廓自相交),停手'); sys.exit(3)
bd = D(bodies()[0])
nf = len(prop(bd, 'GetFaces'))
want_faces = 6 + 4 * len(OPENINGS)
P(u' 面数 = %d(期望 ≥ %d = 6 + 每个通口 4)%s'
% (nf, want_faces, u'✅' if nf >= want_faces else u'⛔ 开口没成形'))
hist = {}
for f in prop(bd, 'GetFaces'):
s = prop(D(f), 'GetSurface')
if prop(s, 'IsCylinder'):
r = round(list(prop(s, 'CylinderParams'))[6] * 1000, 2)
hist[r] = hist.get(r, 0) + 1
P(u' 圆柱面直方图 %s' % dict(sorted(hist.items())))
n34 = hist.get(round(SCREW_D / 2, 2), 0)
P(u' Ø%.1f 螺丝孔 = %d 个(期望 %d)%s'
% (SCREW_D, n34, len(SCREW_HOLES), u'✅' if n34 >= len(SCREW_HOLES) else u'⛔ 没打全'))
if n34 < len(SCREW_HOLES):
P(u'⛔ 停手:包围盒与面数都看不出漏孔,靠的就是这个计数'); sys.exit(4)
e1 = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
w1 = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
part.Extension.SaveAs3(DST, 0, 1, EMPTY, EMPTY, e1, w1)
P(u'\n另存 err=%s 存在=%s %.0f KB'
% (e1.value, os.path.exists(DST), os.path.getsize(DST) / 1024.0 if os.path.exists(DST) else 0))
if not os.path.exists(DST):
P(u'⛔ 没落盘,停手'); sys.exit(5)
P(u'⚠ 零件保持打开')