# -*- 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))