R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,160 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# v3 短机版:外形 x −24.8~115.9,四角过孔跟顶盖角柱到 x −11 / 108.5
|
||||
u"""**一整块底盖** BottomPlate_v3(2026-09-13 两件式外壳)。
|
||||
|
||||
= 175.0 × 110.8 × 2.4 平板(与顶盖外形齐平)+ 底板 PCB 的 4 根 Ø8 × 10 立柱(柱顶 Ø4.2 螺母孔)
|
||||
+ 四角 4 个 Ø3.4 过孔(M3 从下往上拧进顶盖角柱底部的热熔螺母)。
|
||||
|
||||
零件本地坐标 = 装配坐标平移 z +10:板占本地 z −2.4~0,立柱 0~10;装配时 dz = −10
|
||||
⇒ 板 z −12.4~−10(顶盖墙底落在 z=−10)、柱顶 z=0 = 底板 PCB 底面。
|
||||
|
||||
与 Tray_v9 相比:外形放大到整机尺寸;取消端板锁孔(端板已并进顶盖);
|
||||
取消南边两个 USB-C 缺口 —— 那是板面还在 z −2.4~0 时代的遗留,现在板面在 −10,
|
||||
离 Type-C 插入通道底 −3.25 还有 6.75,缺口已无意义。
|
||||
|
||||
两种孔都画进拉伸草图一次成形(本机最可靠的路):
|
||||
· 四角过孔画进 [1] 平板草图 ⇒ 通孔
|
||||
· 螺母孔画进 [2] 立柱草图 ⇒ 只穿立柱那 10 mm,底下平板没有孔 ⇒ 盲孔深 10
|
||||
"""
|
||||
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\\BottomPlate_v3.SLDPRT'
|
||||
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
||||
|
||||
X0, X1, Y0, Y1 = -24.8, 115.9, -4.055, 106.745
|
||||
T = 2.4
|
||||
CORNER_HOLES = [(-11.0, 3.345), (-11.0, 99.345), (108.5, 3.345), (108.5, 99.345)] # = 顶盖角柱中心
|
||||
R_THRU = 1.7
|
||||
PCB_POSTS = [(4.0, 4.0), (94.0, 4.0), (4.0, 94.0), (94.0, 94.0)]
|
||||
POST_R, POST_H, R_INS = 4.0, 10.0, 2.1
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
app = wc.GetActiveObject('SldWorks.Application')
|
||||
for d in list(app.GetDocuments or []):
|
||||
try:
|
||||
t = prop(d, 'GetTitle') or ''
|
||||
if 'BOTTOMPLATE_V3' in t.upper():
|
||||
app.CloseDoc(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 last_sketch():
|
||||
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 boss(depth, rev):
|
||||
if pick(last_sketch(), 'SKETCH') != 1:
|
||||
raise RuntimeError(u'草图没选中')
|
||||
return fm.FeatureExtrusion3(True, False, rev, 0, 0, M(depth), 0.0,
|
||||
False, False, False, False, 0.0, 0.0,
|
||||
False, False, False, False, True, True, True, 0, 0.0, False)
|
||||
|
||||
|
||||
def bbox():
|
||||
b = part.GetBodies2(0, True) or []
|
||||
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)]
|
||||
|
||||
|
||||
def cyls():
|
||||
out = []
|
||||
b = part.GetBodies2(0, True) or []
|
||||
for f in prop(D(b[0]), 'GetFaces') if b else []:
|
||||
fc = D(f)
|
||||
s = prop(fc, 'GetSurface')
|
||||
if prop(s, 'IsCylinder'):
|
||||
fb = [v * 1000 for v in prop(fc, 'GetBox')]
|
||||
out.append((round(list(prop(s, 'CylinderParams'))[6] * 1000, 2), fb))
|
||||
return out
|
||||
|
||||
|
||||
P(u'\n[1] 平板 %.1f × %.1f × %.1f + 四角 Ø%.1f 过孔' % (X1 - X0, Y1 - Y0, T, 2 * R_THRU))
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
sm.CreateCornerRectangle(M(X0), M(Y0), 0.0, M(X1), M(Y1), 0.0)
|
||||
for hx, hy in CORNER_HOLES:
|
||||
sm.CreateCircleByRadius(M(hx), M(hy), 0.0, M(R_THRU))
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(T, True)
|
||||
b = bbox()
|
||||
P(u' box %s' % b)
|
||||
if b is None or abs(b[2] + T) > 0.02 or abs(b[5]) > 0.02:
|
||||
P(u'⛔ 停手'); sys.exit(2)
|
||||
|
||||
P(u'\n[2] 4 根 PCB 立柱 Ø%.0f × %.0f + 柱顶 Ø%.1f 螺母孔(盲孔)' % (2 * POST_R, POST_H, 2 * R_INS))
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
for hx, hy in PCB_POSTS:
|
||||
sm.CreateCircleByRadius(M(hx), M(hy), 0.0, M(POST_R))
|
||||
sm.CreateCircleByRadius(M(hx), M(hy), 0.0, M(R_INS))
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(POST_H, False)
|
||||
b = bbox()
|
||||
P(u' box %s(期望 z −2.4~10)' % b)
|
||||
|
||||
cs = cyls()
|
||||
h = {}
|
||||
for r, _ in cs:
|
||||
h[r] = h.get(r, 0) + 1
|
||||
P(u' 圆柱面直方图 %s(期望 {1.7: 4, 2.1: 4, 4.0: 4})' % dict(sorted(h.items())))
|
||||
ins = [fb for r, fb in cs if abs(r - R_INS) < 0.01]
|
||||
thru = [fb for r, fb in cs if abs(r - R_THRU) < 0.01]
|
||||
ok_ins = len(ins) == 4 and all(abs(fb[2]) < 0.05 and abs(fb[5] - POST_H) < 0.05 for fb in ins)
|
||||
ok_thru = len(thru) == 4 and all(abs(fb[2] + T) < 0.05 and abs(fb[5]) < 0.05 for fb in thru)
|
||||
P(u' 螺母孔 z 0~10(盲,底下平板无孔)%s;四角过孔 z −2.4~0(通)%s'
|
||||
% (u'✅' if ok_ins else u'⛔', u'✅' if ok_thru else u'⛔'))
|
||||
if not (ok_ins and ok_thru and b and abs(b[5] - POST_H) < 0.02):
|
||||
P(u'⛔ 不存盘'); sys.exit(3)
|
||||
|
||||
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))
|
||||
在新工单中引用
屏蔽一个用户