R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,180 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
u"""顶盖 v4 —— 加长 + 补上一条实测出来的缝(2026-09-13)。
|
||||
|
||||
与 v3 的三处差别:
|
||||
|
||||
1. **加长**:x −27.4~125.4(152.8)⇒ **−38.4~136.4(175.0)**,跟 15 mm 分风腔走。
|
||||
⚠ 泄压缝不用动:缝阵按盒子 x 中心 49 对称排布,而新盒子中心
|
||||
(−38.4+136.4)/2 = **49.0**,与旧值相同。
|
||||
|
||||
2. ⛔ **y 由 −4~102 改成 −4.055~106.745**。这是回读比对查出来的真缝:
|
||||
北板内表面在 y=104.345,而顶盖只到 102 ⇒ 沿全长(175)开着一条 **2.345 mm** 的口子。
|
||||
端板改 y 对称那轮,顶盖没跟着改,干涉检查也照不出来(不接触本来就不干涉)。
|
||||
新范围正好盖住南北两板的**外表面**(南 −4.055 / 北 106.745),成为真正的盖子。
|
||||
|
||||
3. **C 组 4 个螺丝过孔挪位**:(−13.70, 12.35/90.34) ⇒ **(−31, 2.345/100.345)** 与
|
||||
**(129, 2.345/100.345)** —— 端板 v10 四根角柱的中心。
|
||||
⛔ 旧位打在端板的空气里(端板 z=72 那层只有 2.4 厚板本体,L 脚在底部)。
|
||||
✅ 新位每个都落在 8(y)×10(x) 的角柱顶面上,Ø4.2 热熔螺母孔(留 GUI 打)有肉可吃。
|
||||
离 Ø60 风口中心 y=51.345 分别 49.0 / 49.0 > 30 ✅ 不碰风口。
|
||||
|
||||
⛔ 水平板、法线沿 z ⇒ **前视基准面**(草图 (u,v) → 模型 (x,y),法线 +z)。
|
||||
⛔ 画草图前 `sm.AddToDB = True`。
|
||||
⛔ 判据:缝是矩形 ⇒ 面数(6 + 每条缝 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\\TopPanel_v4.SLDPRT'
|
||||
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
||||
|
||||
X0, X1 = -38.4, 136.4
|
||||
Y0, Y1 = -4.055, 106.745 # 盖住南北板外表面
|
||||
PANEL_T = 2.4
|
||||
|
||||
SLOT_W = 1.5
|
||||
SLOT_L = 60.0
|
||||
SLOT_N = 11
|
||||
SLOT_SPAN = 106.0
|
||||
SLOT_XC = (X0 + X1) / 2.0 # = 49.0,与旧盒子中心相同
|
||||
SLOT_X0, SLOT_X1 = SLOT_XC - SLOT_SPAN / 2.0, SLOT_XC + SLOT_SPAN / 2.0
|
||||
SLOT_YC = 51.345 # 刀片堆叠中心(旧版写 49,偏 2.345)
|
||||
|
||||
SCREW_D = 3.4
|
||||
POST_CX_W, POST_CX_E = -31.0, 129.0
|
||||
POST_CY_S, POST_CY_N = 2.345, 100.345 # 角柱截面 y −1.655~6.345 / 96.345~104.345 的中心
|
||||
SCREW_HOLES = [(POST_CX_W, POST_CY_S), (POST_CX_W, POST_CY_N),
|
||||
(POST_CX_E, POST_CY_S), (POST_CX_E, POST_CY_N)]
|
||||
|
||||
|
||||
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 'TOPPANEL_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)]
|
||||
|
||||
|
||||
step = (SLOT_X1 - SLOT_X0) / (SLOT_N - 1)
|
||||
slots = [(SLOT_X0 + i * step - SLOT_W / 2.0, SLOT_X0 + i * step + SLOT_W / 2.0)
|
||||
for i in range(SLOT_N)]
|
||||
|
||||
P(u'\n[1] 顶盖 %.1f(x) × %.1f(y) × %.1f,%d 条 %.1f×%.0f 泄压缝 + 4 个 Ø%.1f 螺丝孔'
|
||||
% (X1 - X0, Y1 - Y0, PANEL_T, SLOT_N, SLOT_W, SLOT_L, SCREW_D))
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
sm.CreateCornerRectangle(M(X0), M(Y0), 0.0, M(X1), M(Y1), 0.0)
|
||||
for sx0, sx1 in slots:
|
||||
sm.CreateCornerRectangle(M(sx0), M(SLOT_YC - SLOT_L / 2), 0.0,
|
||||
M(sx1), M(SLOT_YC + SLOT_L / 2), 0.0)
|
||||
for sx, sy in SCREW_HOLES:
|
||||
sm.CreateCircleByRadius(M(sx), M(sy), 0.0, M(SCREW_D / 2))
|
||||
sm.AddToDB = False
|
||||
_segs = prop(D(prop(sm, 'ActiveSketch')), 'GetSketchSegments')
|
||||
want_segs = 4 * (1 + SLOT_N) + 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 %.3f~%.3f / z 0~%.1f)' % (b, X0, X1, Y0, Y1, PANEL_T))
|
||||
if not b:
|
||||
P(u'⛔ 没出实体,停手'); sys.exit(3)
|
||||
|
||||
bd = D(bodies()[0])
|
||||
nf = len(prop(bd, 'GetFaces'))
|
||||
want_faces = 6 + 4 * SLOT_N
|
||||
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 个(期望 4)%s' % (SCREW_D, n34, u'✅' if n34 >= 4 else u'⛔ 没打全'))
|
||||
if nf < want_faces or n34 < 4:
|
||||
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'⚠ 零件保持打开')
|
||||
在新工单中引用
屏蔽一个用户