101 行
4.0 KiB
Python
101 行
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
u"""导入 Orion OD6010(60×60×10)STEP → 另存 SLDPRT → 解剖:包围盒、安装孔、风道。
|
||
|
||
沿用 NOTES §32 的做法:LoadFile4 得到未保存零件(GetPathName 为空)⇒ 必须先 SaveAs3 才能 AddComponent4。
|
||
判据沿用 §32 的教训:配对安装孔前先按「关于原点对称 + 贯穿全厚」筛,别对 |x|、|y| 各取极值。
|
||
"""
|
||
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 = u'D:\\DCDC\\新建文件夹\\OD6010_m0_frame.stp'
|
||
DST = u'D:\\DCDC\\新建文件夹\\OD6010_m0_frame.SLDPRT'
|
||
EMPTY = wc.VARIANT(pythoncom.VT_DISPATCH, None)
|
||
|
||
|
||
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)
|
||
|
||
|
||
app = wc.GetActiveObject('SldWorks.Application')
|
||
for d in list(app.GetDocuments or []):
|
||
t = prop(d, 'GetTitle') or ''
|
||
if 'OD6015' in t.upper() or 'OD6010' in t.upper():
|
||
app.CloseDoc(t)
|
||
data = app.GetImportFileData(SRC)
|
||
err = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
|
||
app.LoadFile4(SRC, 'r', data, err)
|
||
P(u'LoadFile4 err=%s' % err.value)
|
||
part = app.ActiveDoc
|
||
P(u'文档 %s type=%s' % (prop(part, 'GetTitle'), prop(part, 'GetType')))
|
||
if prop(part, 'GetType') != 1:
|
||
P(u'⛔ 不是单体零件,停手'); sys.exit(2)
|
||
|
||
bodies = part.GetBodies2(0, True) or []
|
||
P(u'实体 %d 个' % len(bodies))
|
||
bx = None
|
||
for b in bodies:
|
||
bb = [round(v * 1000, 3) for v in prop(D(b), 'GetBodyBox')]
|
||
bx = bb if bx is None else [min(bx[i], bb[i]) for i in range(3)] + [max(bx[i + 3], bb[i + 3]) for i in range(3)]
|
||
P(u'包围盒 x %.3f~%.3f y %.3f~%.3f z %.3f~%.3f ⇒ %.2f × %.2f × %.2f'
|
||
% (bx[0], bx[3], bx[1], bx[4], bx[2], bx[5], bx[3] - bx[0], bx[4] - bx[1], bx[5] - bx[2]))
|
||
thick_ax = min(range(3), key=lambda i: bx[i + 3] - bx[i])
|
||
P(u'厚度方向 = %s(%.3f)' % ('xyz'[thick_ax], bx[thick_ax + 3] - bx[thick_ax]))
|
||
|
||
cands = []
|
||
big = []
|
||
for b in bodies:
|
||
for f in prop(D(b), 'GetFaces'):
|
||
fc = D(f)
|
||
s = prop(fc, 'GetSurface')
|
||
if not prop(s, 'IsCylinder'):
|
||
continue
|
||
cp = list(prop(s, 'CylinderParams'))
|
||
r = cp[6] * 1000
|
||
ax = max(range(3), key=lambda i: abs(cp[3 + i]))
|
||
fb = [v * 1000 for v in prop(fc, 'GetBox')]
|
||
c = [(fb[i] + fb[i + 3]) / 2 for i in range(3)]
|
||
if ax == thick_ax and 1.5 < r < 2.8:
|
||
cands.append((round(r, 3), c, fb[thick_ax], fb[thick_ax + 3]))
|
||
if ax == thick_ax and r > 25:
|
||
big.append((round(r, 3), fb[thick_ax], fb[thick_ax + 3]))
|
||
|
||
o = [i for i in range(3) if i != thick_ax]
|
||
full = bx[thick_ax + 3] - bx[thick_ax]
|
||
P(u'\n安装孔候选(半径 1.5~2.8、轴沿厚度方向)%d 个:' % len(cands))
|
||
for r, c, z0, z1 in cands:
|
||
P(u' R%.3f (%s=%.3f, %s=%.3f) 厚度向 %.2f~%.2f%s'
|
||
% (r, 'xyz'[o[0]], c[o[0]], 'xyz'[o[1]], c[o[1]], z0, z1,
|
||
u' ← 贯穿' if abs((z1 - z0) - full) < 0.05 else u''))
|
||
thru = [(r, c) for r, c, z0, z1 in cands if abs((z1 - z0) - full) < 0.05]
|
||
P(u'\n贯穿全厚的安装孔 %d 个:' % len(thru))
|
||
cx = (bx[o[0]] + bx[o[0] + 3]) / 2
|
||
cy = (bx[o[1]] + bx[o[1] + 3]) / 2
|
||
for r, c in thru:
|
||
P(u' R%.3f 相对中心 (%+.3f, %+.3f)' % (r, c[o[0]] - cx, c[o[1]] - cy))
|
||
if len(thru) == 4:
|
||
dxs = sorted(abs(c[o[0]] - cx) for _, c in thru)
|
||
dys = sorted(abs(c[o[1]] - cy) for _, c in thru)
|
||
P(u' ⇒ 孔距 %.3f × %.3f(标准 60 风扇应为 50.00 × 50.00)'
|
||
% (2 * sum(dxs) / 4, 2 * sum(dys) / 4))
|
||
P(u'风道圆柱(R>25):%s' % big)
|
||
|
||
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(零件保持打开,供 AddComponent4)'
|
||
% (e1.value, os.path.exists(DST), os.path.getsize(DST) / 1024.0 if os.path.exists(DST) else 0))
|