R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,441 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# v3 短机版:风扇 6010(孔距 50.2、Ø5.2 过孔)+ 分风腔 10;内腔 x −16~113.5、外 −18.4~115.9、导轨唇边 −24.8
|
||||
u"""**v2 = v1 + 西端插拔式滤网导轨 + 建模内倒角**(2026-09-13)。
|
||||
导轨让包围盒西界变成唇边 x −43.8,add_fillets 的「包围盒角」判据会漏掉西侧两角 ⇒ 圆角在加导轨之前做。
|
||||
|
||||
(以下为 v1 说明)**一体顶盖** TopShell_v1(2026-09-13 用户改方案:顶盖一体打印 + 底盖一整块 + 螺丝固定)。
|
||||
|
||||
= 顶板 + 南/北侧墙 + 西/东端墙 + 4 根内角立柱,底部敞开,从上往下扣在底盖上。
|
||||
外形与上一版六件式完全一致(175.0 × 110.8,顶外表面 z=74.4、墙底 z=−10),
|
||||
内腔也一致(x −36~134 / y −1.655~104.345 / 顶内表面 z=72)⇒ 15 mm 分风腔、0.66 顶隙原样保留。
|
||||
|
||||
零件本地坐标:x、y = 装配坐标;**本地 z = 装配 z − 74.4**(顶外表面在本地 z=0,全部往 −z 拉)。
|
||||
装配时纯平移 dz = +74.4,不旋转。
|
||||
|
||||
建模顺序是刻意安排的(只用本机验证过的「基准面草图 + 拉伸,孔画进同一张草图」):
|
||||
[1] 4 根角柱 10×10 + 柱内 Ø4.2 孔,前视面草图,向 −z 拉 84.4(孔此时是通的)
|
||||
[2] 四面墙:外框 + 内框的环形轮廓,向 −z 拉 84.4
|
||||
[3] 顶板 + 11 条泄压缝,向 −z 拉 2.4 —— **顺带把柱孔上端封死**,
|
||||
柱孔变成从底面进、深 82 的盲孔(热熔螺母压在底口 6 mm 内即可),顶面看不到孔
|
||||
[4] 端墙外表面:Ø60 风口 + 4 × Ø3.4 风扇孔(面上草图切)
|
||||
[5] 南墙外表面:2 个 13×9 Type-C 窗口
|
||||
[6] 北墙外表面:J33 窗口 + 风扇出线窗口
|
||||
面上草图的 uv 映射按候选逐个试,每刀之后回读「目标孔/窗口是否出现在设计位置」;
|
||||
候选都经过检查:错误映射只会把轮廓画到墙外(切不到料、返回 None)。
|
||||
若出现「切出了东西但不在目标位置」立即停手、不存盘。
|
||||
"""
|
||||
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\\TopShell_v3.SLDPRT'
|
||||
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
||||
ZOFF = 74.4 # 本地 z = 装配 z − ZOFF
|
||||
|
||||
X0, X1, Y0, Y1 = -18.4, 115.9, -4.055, 106.745 # 外形
|
||||
IX0, IX1, IY0, IY1 = -16.0, 113.5, -1.655, 104.345 # 内腔
|
||||
T = 2.4
|
||||
H = 84.4 # 顶外 74.4 → 墙底 −10
|
||||
|
||||
SLOT_W, SLOT_L, SLOT_N, SLOT_SPAN = 1.5, 60.0, 11, 106.0
|
||||
SLOT_XC, SLOT_YC = (X0 + X1) / 2.0, 51.345
|
||||
|
||||
POST = 10.0
|
||||
POST_RECTS = [(IX0, IX0 + POST, IY0, IY0 + POST), (IX0, IX0 + POST, IY1 - POST, IY1),
|
||||
(IX1 - POST, IX1, IY0, IY0 + POST), (IX1 - POST, IX1, IY1 - POST, IY1)]
|
||||
POST_HOLES = [((a + b) / 2.0, (c + d) / 2.0) for a, b, c, d in POST_RECTS]
|
||||
R_INS = 2.1
|
||||
|
||||
FAN_CY, FAN_CZ = 51.345, 37.85
|
||||
R_VENT, R_FAN = 30.0, 2.6 # 风扇孔 Ø5.2:机箱自攻螺丝要穿墙拧进风扇 Ø4.4 孔
|
||||
END_CIRCLES = [(FAN_CY, FAN_CZ, R_VENT)] + [(FAN_CY + dy, FAN_CZ + dz, R_FAN)
|
||||
for dy in (-25.1, 25.1) for dz in (-25.1, 25.1)]
|
||||
SOUTH_WINDOWS = [(6.0, 19.0, -5.7, 3.3), (77.5, 90.5, -5.7, 3.3)] # x0,x1,z0,z1(装配)
|
||||
NORTH_WINDOWS = [(72.14, 87.85, -3.0, 12.0), (0.53, 19.03, -3.0, 15.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 L(z):
|
||||
return z - ZOFF
|
||||
|
||||
|
||||
app = wc.GetActiveObject('SldWorks.Application')
|
||||
for d in list(app.GetDocuments or []):
|
||||
try:
|
||||
t = prop(d, 'GetTitle') or ''
|
||||
if 'TOPSHELL_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 bodies():
|
||||
return part.GetBodies2(0, True) or []
|
||||
|
||||
|
||||
def faces():
|
||||
b = bodies()
|
||||
return prop(D(b[0]), 'GetFaces') if b else []
|
||||
|
||||
|
||||
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)]
|
||||
|
||||
|
||||
def cyls():
|
||||
out = []
|
||||
for f in faces():
|
||||
fc = D(f)
|
||||
s = prop(fc, 'GetSurface')
|
||||
if prop(s, 'IsCylinder'):
|
||||
cp = list(prop(s, 'CylinderParams'))
|
||||
fb = [v * 1000 for v in prop(fc, 'GetBox')]
|
||||
ax = max(range(3), key=lambda i: abs(cp[3 + i]))
|
||||
out.append((round(cp[6] * 1000, 2), ax, fb))
|
||||
return out
|
||||
|
||||
|
||||
def hist():
|
||||
h = {}
|
||||
for r, _, _ in cyls():
|
||||
h[r] = h.get(r, 0) + 1
|
||||
return dict(sorted(h.items()))
|
||||
|
||||
|
||||
def planes():
|
||||
u"""[(朝外法线轴, 符号, box)] —— 朝外 = PlaneParams × (sense ? −1 : +1)(NOTES §36)"""
|
||||
out = []
|
||||
for f in faces():
|
||||
fc = D(f)
|
||||
s = prop(fc, 'GetSurface')
|
||||
if not prop(s, 'IsPlane'):
|
||||
continue
|
||||
n = list(prop(s, 'PlaneParams'))[:3]
|
||||
if prop(fc, 'FaceInSurfaceSense'):
|
||||
n = [-v for v in n]
|
||||
ax = max(range(3), key=lambda i: abs(n[i]))
|
||||
out.append((ax, 1 if n[ax] > 0 else -1, [v * 1000 for v in prop(fc, 'GetBox')],
|
||||
prop(fc, 'GetArea') * 1e6, fc))
|
||||
return out
|
||||
|
||||
|
||||
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 check(tag, want, tol=0.02):
|
||||
got = bbox()
|
||||
ok = got is not None and all(abs(got[i] - want[i]) <= tol for i in range(6))
|
||||
P(u' %s box %s %s' % (tag, got, u'✅' if ok else u'⛔ 期望 %s' % want))
|
||||
if not ok:
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
# ── [1] 角柱 + 柱孔 ───────────────────────────────────────────────────────
|
||||
P(u'\n[1] 4 根角柱 %.0f×%.0f + Ø%.1f 孔,向 −z 拉 %.1f' % (POST, POST, 2 * R_INS, H))
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
for a, b, c, d in POST_RECTS:
|
||||
sm.CreateCornerRectangle(M(a), M(c), 0.0, M(b), M(d), 0.0)
|
||||
for hx, hy in POST_HOLES:
|
||||
sm.CreateCircleByRadius(M(hx), M(hy), 0.0, M(R_INS))
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(H, True)
|
||||
check(u'角柱', [IX0, IY0, -H, IX1, IY1, 0.0])
|
||||
|
||||
# ── [2] 四面墙(环形轮廓)────────────────────────────────────────────────
|
||||
P(u'\n[2] 四面墙 环形轮廓,向 −z 拉 %.1f' % H)
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
sm.CreateCornerRectangle(M(X0), M(Y0), 0.0, M(X1), M(Y1), 0.0)
|
||||
sm.CreateCornerRectangle(M(IX0), M(IY0), 0.0, M(IX1), M(IY1), 0.0)
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(H, True)
|
||||
check(u'墙', [X0, Y0, -H, X1, Y1, 0.0])
|
||||
|
||||
# ── [3] 顶板 + 泄压缝(封住柱孔上端)──────────────────────────────────────
|
||||
P(u'\n[3] 顶板 + %d 条泄压缝,向 −z 拉 %.1f' % (SLOT_N, T))
|
||||
step = SLOT_SPAN / (SLOT_N - 1)
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
sm.CreateCornerRectangle(M(X0), M(Y0), 0.0, M(X1), M(Y1), 0.0)
|
||||
for i in range(SLOT_N):
|
||||
xc = SLOT_XC - SLOT_SPAN / 2.0 + i * step
|
||||
sm.CreateCornerRectangle(M(xc - SLOT_W / 2), M(SLOT_YC - SLOT_L / 2), 0.0,
|
||||
M(xc + SLOT_W / 2), M(SLOT_YC + SLOT_L / 2), 0.0)
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(T, True)
|
||||
check(u'顶板', [X0, Y0, -H, X1, Y1, 0.0])
|
||||
ph = [c for c in cyls() if abs(c[0] - R_INS) < 0.01 and c[1] == 2]
|
||||
P(u' 柱孔 R%.1f 沿 z:%d 个(期望 4)' % (R_INS, len(ph)))
|
||||
for r, ax, fb in ph:
|
||||
P(u' 中心 (%.2f, %.2f) z %.2f~%.2f(期望 %.1f~%.1f,上端被顶板封住)'
|
||||
% ((fb[0] + fb[3]) / 2, (fb[1] + fb[4]) / 2, fb[2], fb[5], -H, -T))
|
||||
if len(ph) != 4 or any(abs(fb[5] - (-T)) > 0.05 or abs(fb[2] + H) > 0.05 for _, _, fb in ph):
|
||||
P(u'⛔ 柱孔不对,停手'); sys.exit(3)
|
||||
slot_faces = sum(1 for ax, sg, fb, a, _ in planes()
|
||||
if ax == 0 and abs(fb[2] + T) < 0.05 and abs(fb[5]) < 0.05
|
||||
and abs(fb[4] - fb[1] - SLOT_L) < 0.05)
|
||||
P(u' 泄压缝侧面 %d 个(期望 %d = 每条 2)%s' % (slot_faces, 2 * SLOT_N,
|
||||
u'✅' if slot_faces == 2 * SLOT_N else u'⛔'))
|
||||
if slot_faces != 2 * SLOT_N:
|
||||
sys.exit(3)
|
||||
|
||||
|
||||
# ── [3b] 外轮廓 4 条竖边倒 R3(此时包围盒 = 盒体本身,导轨还没加)─────────
|
||||
P(u'\n[3b] 外轮廓竖边倒 R3')
|
||||
_bx = bbox()
|
||||
_cand = []
|
||||
for _e in prop(D(bodies()[0]), 'GetEdges'):
|
||||
_E = D(_e)
|
||||
try:
|
||||
_p0 = [v * 1000 for v in prop(D(prop(_E, 'GetStartVertex')), 'GetPoint')]
|
||||
_p1 = [v * 1000 for v in prop(D(prop(_E, 'GetEndVertex')), 'GetPoint')]
|
||||
except Exception:
|
||||
continue
|
||||
if abs(_p0[0] - _p1[0]) > 1e-6 or abs(_p0[1] - _p1[1]) > 1e-6 or abs(_p0[2] - _p1[2]) < 1e-6:
|
||||
continue
|
||||
if all(min(abs(_p[i] - _bx[i]), abs(_p[i] - _bx[i + 3])) < 0.01 for _p in (_p0, _p1) for i in (0, 1)):
|
||||
_cand.append(_E)
|
||||
_done = 0
|
||||
for _E in _cand:
|
||||
for _r in (3.0, 2.0, 1.5):
|
||||
part.ClearSelection2(True)
|
||||
_E.Select4(False, EMPTY)
|
||||
try:
|
||||
_f = fm.FeatureFillet3(195, M(_r), 0, 0, 0, 0, 0, None, None, None, None, None, None, None)
|
||||
except Exception:
|
||||
_f = None
|
||||
if _f:
|
||||
_done += 1
|
||||
break
|
||||
P(u' 候选 %d 条,成功 %d 条;直方图 %s' % (len(_cand), _done, hist()))
|
||||
if _done != 4 or hist().get(3.0, 0) != 4:
|
||||
P(u'⛔ 圆角没做全,停手'); sys.exit(8)
|
||||
|
||||
|
||||
# ── 面上草图切除(带候选映射)────────────────────────────────────────────
|
||||
def pick_face(ax, sign, coord):
|
||||
best, ba = None, -1.0
|
||||
for a_, s_, fb, area, fc in planes():
|
||||
if a_ != ax or s_ != sign:
|
||||
continue
|
||||
if abs(fb[ax] - coord) > 0.02 or abs(fb[ax + 3] - coord) > 0.02:
|
||||
continue
|
||||
if area > ba:
|
||||
best, ba = fc, area
|
||||
if best is None:
|
||||
return False
|
||||
part.ClearSelection2(True)
|
||||
best.Select4(False, EMPTY)
|
||||
return part.SelectionManager.GetSelectedObjectCount2(-1) == 1
|
||||
|
||||
|
||||
def do_cut(depth):
|
||||
if pick(last_sketch(), 'SKETCH') != 1:
|
||||
return None
|
||||
return fm.FeatureCut4(True, False, False, 0, 0, M(depth), 0.0,
|
||||
False, False, False, False, 0.0, 0.0,
|
||||
False, False, False, False, False,
|
||||
True, True, False, False, False, 0, 0.0, False, False)
|
||||
|
||||
|
||||
def sketch_xform():
|
||||
sk = prop(sm, 'ActiveSketch')
|
||||
if not sk:
|
||||
return None
|
||||
arr = list(prop(D(sk), 'ModelToSketchTransform').ArrayData)
|
||||
Mx = [[arr[3 * c + r] for c in range(3)] for r in range(3)] # 列主序
|
||||
return Mx, arr[9:12]
|
||||
|
||||
|
||||
def to_sketch(X, p):
|
||||
u"""模型点 p(mm)→ 草图坐标(米)"""
|
||||
Mx, t = X
|
||||
q = [v / 1000.0 for v in p]
|
||||
return [sum(Mx[r][c] * q[c] for c in range(3)) + t[r] for r in range(3)]
|
||||
|
||||
|
||||
def open_face_sketch(face, tag):
|
||||
ax, sign, coord = face
|
||||
for attempt in range(1, 4):
|
||||
if not pick_face(*face):
|
||||
P(u' ⛔ %s 选不到面' % tag); sys.exit(4)
|
||||
sm.InsertSketch(True)
|
||||
X = sketch_xform()
|
||||
ok, nax, sz = False, -1, 99.0
|
||||
if X:
|
||||
nax = max(range(3), key=lambda i: abs(X[0][2][i]))
|
||||
probe = [0.0, 0.0, 0.0]
|
||||
probe[ax] = coord
|
||||
sz = to_sketch(X, probe)[2] * 1000.0
|
||||
ok = nax == ax and abs(sz) < 0.01
|
||||
P(u' %s 进草图 第 %d 次:法线轴 %s(目标 %s)、墙面点草图 z = %.4f mm %s'
|
||||
% (tag, attempt, 'xyz'[nax] if nax >= 0 else '?', 'xyz'[ax], sz, u'✅' if ok else u'✗ 平面不对,退出重进'))
|
||||
if ok:
|
||||
return X
|
||||
sm.InsertSketch(True)
|
||||
P(u' ⛔ %s 三次都没进到目标面,停手' % tag); sys.exit(4)
|
||||
|
||||
|
||||
def cut_shapes(tag, face, circles, rects, verify):
|
||||
nbefore = len(faces())
|
||||
X = open_face_sketch(face, tag)
|
||||
sm.AddToDB = True
|
||||
for p, r in circles:
|
||||
q = to_sketch(X, p)
|
||||
sm.CreateCircleByRadius(q[0], q[1], 0.0, M(r))
|
||||
for p0, p1 in rects:
|
||||
q0, q1 = to_sketch(X, p0), to_sketch(X, p1)
|
||||
sm.CreateCornerRectangle(q0[0], q0[1], 0.0, q1[0], q1[1], 0.0)
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
c = do_cut(T + 0.2)
|
||||
ok = verify()
|
||||
P(u' %s 切除 → %-12r 面数 %d→%d 目标 %s'
|
||||
% (tag, prop(c, 'Name') if c else c, nbefore, len(faces()), u'✅' if ok else u'⛔'))
|
||||
if not ok:
|
||||
P(u' ⛔⛔ 目标没出现在设计位置 —— 停手、不存盘'); sys.exit(5)
|
||||
|
||||
|
||||
def end_verify(xwall):
|
||||
def v():
|
||||
cs = cyls()
|
||||
for cy, cz, r in END_CIRCLES:
|
||||
hit = any(abs(rr - r) < 0.01 and ax_ == 0 and
|
||||
abs((fb[1] + fb[4]) / 2 - cy) < 0.05 and abs((fb[2] + fb[5]) / 2 - L(cz)) < 0.05 and
|
||||
min(abs(fb[0] - xwall), abs(fb[3] - xwall)) < 0.05
|
||||
for rr, ax_, fb in cs)
|
||||
if not hit:
|
||||
return False
|
||||
return True
|
||||
return v
|
||||
|
||||
|
||||
def rect_verify(wins, ywall0, ywall1):
|
||||
def v():
|
||||
ps = planes()
|
||||
for x0, x1, z0, z1 in wins:
|
||||
for xe in (x0, x1):
|
||||
hit = any(ax_ == 0 and abs(fb[0] - xe) < 0.05 and abs(fb[3] - xe) < 0.05 and
|
||||
abs(fb[2] - L(z0)) < 0.05 and abs(fb[5] - L(z1)) < 0.05 and
|
||||
fb[1] >= ywall0 - 0.05 and fb[4] <= ywall1 + 0.05
|
||||
for ax_, sg, fb, a_, _ in ps)
|
||||
if not hit:
|
||||
return False
|
||||
return True
|
||||
return v
|
||||
|
||||
|
||||
P(u'\n[4] 端墙:Ø60 风口 + 4 × Ø%.1f 风扇孔(孔距 %.1f)' % (2 * R_FAN, 2 * abs(END_CIRCLES[1][0] - FAN_CY)))
|
||||
cut_shapes(u'西端墙', (0, -1, X0), [((X0, cy, L(cz)), r) for cy, cz, r in END_CIRCLES], [], end_verify(X0))
|
||||
cut_shapes(u'东端墙', (0, +1, X1), [((X1, cy, L(cz)), r) for cy, cz, r in END_CIRCLES], [], end_verify(X1))
|
||||
|
||||
P(u'\n[5] 南墙:2 个 13×9 Type-C 窗口')
|
||||
cut_shapes(u'南墙', (1, -1, Y0), [],
|
||||
[((x0, Y0, L(z0)), (x1, Y0, L(z1))) for x0, x1, z0, z1 in SOUTH_WINDOWS],
|
||||
rect_verify(SOUTH_WINDOWS, Y0, IY0))
|
||||
P(u'\n[6] 北墙:J33 窗口 + 风扇出线窗口')
|
||||
cut_shapes(u'北墙', (1, +1, Y1), [],
|
||||
[((x0, Y1, L(z0)), (x1, Y1, L(z1))) for x0, x1, z0, z1 in NORTH_WINDOWS],
|
||||
rect_verify(NORTH_WINDOWS, IY1, Y1))
|
||||
|
||||
|
||||
# ── [6b] 西端插拔式滤网导轨(前视面草图 L 形轮廓,向 −z 拉满高)───────────
|
||||
FW, CLR, SLOT_T, LIP_T, SPACER, LIP = 70.0, 0.3, 4.4, 2.0, 4.0, 3.0
|
||||
XO = X0 - SLOT_T - LIP_T # 唇边外表面 −43.8
|
||||
YS0, YS1 = FAN_CY - FW / 2 - CLR, FAN_CY + FW / 2 + CLR # 滑槽 y 16.045 ~ 86.645
|
||||
P(u'\n[6b] 滤网导轨:滑槽 x %.1f~%.1f(厚 %.1f)、y %.3f~%.3f;唇边 x %.1f~%.1f 压边 %.1f'
|
||||
% (X0 - SLOT_T, X0, SLOT_T, YS0, YS1, XO, X0 - SLOT_T, LIP))
|
||||
rails = [
|
||||
[(X0, YS0 - SPACER), (XO, YS0 - SPACER), (XO, YS0 + LIP), (X0 - SLOT_T, YS0 + LIP),
|
||||
(X0 - SLOT_T, YS0), (X0, YS0)],
|
||||
[(X0, YS1 + SPACER), (XO, YS1 + SPACER), (XO, YS1 - LIP), (X0 - SLOT_T, YS1 - LIP),
|
||||
(X0 - SLOT_T, YS1), (X0, YS1)],
|
||||
]
|
||||
pick(u'前视基准面', 'PLANE')
|
||||
sm.InsertSketch(True)
|
||||
sm.AddToDB = True
|
||||
for poly in rails:
|
||||
for i in range(len(poly)):
|
||||
a, b = poly[i], poly[(i + 1) % len(poly)]
|
||||
sm.CreateLine(M(a[0]), M(a[1]), 0.0, M(b[0]), M(b[1]), 0.0)
|
||||
sm.AddToDB = False
|
||||
sm.InsertSketch(True)
|
||||
boss(H, True)
|
||||
lips = [(fb[1], fb[4]) for ax, sg, fb, a, _ in planes()
|
||||
if ax == 0 and sg == -1 and abs(fb[0] - XO) < 0.02 and abs(fb[3] - XO) < 0.02]
|
||||
P(u' 唇边外表面 %d 个(期望 2):%s' % (len(lips), [(round(a, 3), round(b, 3)) for a, b in sorted(lips)]))
|
||||
want_l = [(YS0 - SPACER, YS0 + LIP), (YS1 - LIP, YS1 + SPACER)]
|
||||
if len(lips) != 2 or any(abs(a - c) > 0.02 or abs(b - d) > 0.02 for (a, b), (c, d) in zip(sorted(lips), want_l)):
|
||||
P(u'⛔ 导轨不对,停手'); sys.exit(9)
|
||||
|
||||
|
||||
# ── 验收 ──────────────────────────────────────────────────────────────────
|
||||
P(u'\n[7] 验收')
|
||||
check(u'最终', [XO, Y0, -H, X1, Y1, 0.0])
|
||||
h = hist()
|
||||
P(u' 圆柱面直方图 %s(期望 {2.1: 4, 2.6: 8, 3.0: 4, 30.0: 2})' % h)
|
||||
if h.get(2.6, 0) != 8 or h.get(2.1, 0) != 4 or h.get(30.0, 0) != 2:
|
||||
P(u'⛔ 孔数不对,不存盘'); sys.exit(7)
|
||||
|
||||
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))
|
||||
在新工单中引用
屏蔽一个用户