152 行
4.6 KiB
Python
152 行
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
u"""在已开着的 EndPlate_v12(已倒角、12 个螺母孔已验)上补 **L 脚 2 个 Ø3.4 锁孔**,另存 v13。
|
|
|
|
配方与 C 组相同(已验证可行):z 常量面(脚顶面 z=2.4,朝外 +z)上建草图,uv = 模型 xy,沿 z 切。
|
|
孔位:本地 x=36.5(装配 −1.9,对托盘原锁孔)、y=21.345 / 81.345,切深 2.6(脚厚 2.4,切穿)。
|
|
|
|
判据(双向):R1.7 由 4(风扇孔)→ **6**,且新增的 2 个轴沿 z、位于 x 36.5 / y 21.345、81.345;
|
|
R2.1 仍 6、R3.0 仍 4、R30 仍 1。
|
|
"""
|
|
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
|
|
|
|
SRC_TAG = 'ENDPLATE_V12'
|
|
DST = u'D:\\DCDC\\新建文件夹\\5blades\\EndPlate_v13.SLDPRT'
|
|
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
|
FOOT_TOP = 2.4
|
|
HOLES = [(36.5, 21.345), (36.5, 81.345)]
|
|
R = 1.7
|
|
|
|
|
|
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')
|
|
part = None
|
|
for d in app.GetDocuments or []:
|
|
if SRC_TAG in (prop(d, 'GetTitle') or '').upper():
|
|
part = d
|
|
break
|
|
if part is None:
|
|
P(u'⛔ %s 没开着' % SRC_TAG); sys.exit(2)
|
|
e0 = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
|
|
app.ActivateDoc3(prop(part, 'GetTitle'), False, 0, e0)
|
|
part = app.ActiveDoc
|
|
sm, fm = part.SketchManager, part.FeatureManager
|
|
P(u'零件 %s' % prop(part, 'GetTitle'))
|
|
|
|
|
|
def faces():
|
|
b = part.GetBodies2(0, True) or []
|
|
return prop(D(b[0]), 'GetFaces') if b else []
|
|
|
|
|
|
def cyls():
|
|
out = []
|
|
for f in faces():
|
|
fc = D(f)
|
|
s = prop(fc, 'GetSurface')
|
|
if prop(s, 'IsCylinder'):
|
|
cp = list(prop(s, 'CylinderParams'))
|
|
fb = [round(v * 1000, 2) for v in prop(fc, 'GetBox')]
|
|
out.append((round(cp[6] * 1000, 2), (round(cp[3]), round(cp[4]), round(cp[5])), fb))
|
|
return out
|
|
|
|
|
|
def hist():
|
|
h = {}
|
|
for r, _, _ in cyls():
|
|
h[r] = h.get(r, 0) + 1
|
|
return dict(sorted(h.items()))
|
|
|
|
|
|
def foot_ok():
|
|
n = 0
|
|
for r, ax, fb in cyls():
|
|
if abs(r - R) > 0.01 or abs(ax[2]) != 1:
|
|
continue
|
|
cx, cy = (fb[0] + fb[3]) / 2, (fb[1] + fb[4]) / 2
|
|
if any(abs(cx - hx) < 0.05 and abs(cy - hy) < 0.05 for hx, hy in HOLES):
|
|
n += 1
|
|
return n
|
|
|
|
|
|
h0 = hist()
|
|
P(u'开始 直方图 %s' % h0)
|
|
if h0.get(2.1, 0) != 6 or h0.get(1.7, 0) != 4 or h0.get(30.0, 0) != 1:
|
|
P(u'⛔ 起点不是预期的 v12,停手'); sys.exit(3)
|
|
|
|
best, ba = None, -1.0
|
|
for f in faces():
|
|
fc = D(f)
|
|
s = prop(fc, 'GetSurface')
|
|
if not prop(s, 'IsPlane'):
|
|
continue
|
|
nz = list(prop(s, 'PlaneParams'))[2]
|
|
if prop(fc, 'FaceInSurfaceSense'): # 朝外 = −曲面法线(本机实测)
|
|
nz = -nz
|
|
if nz < 0.99:
|
|
continue
|
|
fb = [v * 1000 for v in prop(fc, 'GetBox')]
|
|
if abs(fb[2] - FOOT_TOP) > 0.02 or abs(fb[5] - FOOT_TOP) > 0.02:
|
|
continue
|
|
a = prop(fc, 'GetArea') * 1e6
|
|
if a > ba:
|
|
best, ba = fc, a
|
|
if best is None:
|
|
P(u'⛔ 找不到脚顶面'); sys.exit(4)
|
|
part.ClearSelection2(True)
|
|
best.Select4(False, EMPTY)
|
|
P(u'脚顶面 面积 %.1f mm² 选中数 %d' % (ba, part.SelectionManager.GetSelectedObjectCount2(-1)))
|
|
|
|
sm.InsertSketch(True)
|
|
sm.AddToDB = True
|
|
for hx, hy in HOLES:
|
|
sm.CreateCircleByRadius(M(hx), M(hy), M(FOOT_TOP), M(R))
|
|
sm.AddToDB = False
|
|
sm.InsertSketch(True)
|
|
|
|
nm, f = None, prop(part, 'FirstFeature')
|
|
while f:
|
|
if prop(f, 'GetTypeName2') == 'ProfileFeature':
|
|
nm = prop(f, 'Name')
|
|
f = prop(f, 'GetNextFeature')
|
|
part.ClearSelection2(True)
|
|
part.Extension.SelectByID2(nm, 'SKETCH', 0, 0, 0, False, 0, EMPTY, 0)
|
|
c = fm.FeatureCut4(True, False, False, 0, 0, M(2.6), 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)
|
|
P(u'FeatureCut4 → %r' % (prop(c, 'Name') if c else c))
|
|
|
|
h = hist()
|
|
n = foot_ok()
|
|
P(u'直方图 %s 脚锁孔正确 %d/2' % (h, n))
|
|
if n != 2 or h.get(1.7, 0) != 6 or h.get(2.1, 0) != 6 or h.get(30.0, 0) != 1 or h.get(3.0, 0) != 4:
|
|
P(u'⛔ 未达标,不存盘'); sys.exit(5)
|
|
|
|
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'另存 err=%s 存在=%s %.0f KB'
|
|
% (e1.value, os.path.exists(DST), os.path.getsize(DST) / 1024.0 if os.path.exists(DST) else 0))
|