160 行
5.6 KiB
Python
160 行
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
||
u"""**一整块底盖** BottomPlate_v1(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_v1.SLDPRT'
|
||
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
||
|
||
X0, X1, Y0, Y1 = -38.4, 136.4, -4.055, 106.745
|
||
T = 2.4
|
||
CORNER_HOLES = [(-31.0, 3.345), (-31.0, 99.345), (129.0, 3.345), (129.0, 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_V1' 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))
|