首次提交: OnebotCatalog 项目代码与文档(含 NX 按需生成服务二期、后台、一键启动)
This commit is contained in:
85
onebot-data/tools/gen-mesh-preview.py
Normal file
85
onebot-data/tools/gen-mesh-preview.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
gen-mesh-preview.py —— 生成占位 STL 网格 (窗口内 3D 预览用, 开源 Helix Toolkit 渲染)
|
||||
|
||||
用途: 真实数模导出前, 为每个型号生成一个简单圆柱占位网格,
|
||||
放在 onebot-data\\catalog\\mesh\\ 下 (与 step\\ 同名, .stl 后缀)。
|
||||
桌面软件发现 mesh 侧车文件后, 直接在窗口内渲染, 不再弹浏览器。
|
||||
|
||||
真实网格来源: NX journal (nx-batch-export.vb) 导出 STEP 时同步导出 STL 到 mesh\\,
|
||||
本脚本只在"还没拿到真实网格"时充当占位。
|
||||
|
||||
用法: python gen-mesh-preview.py
|
||||
"""
|
||||
import os
|
||||
import struct
|
||||
import math
|
||||
|
||||
MESH_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'catalog', 'mesh')
|
||||
|
||||
# 型号 → (半径 mm, 高度 mm): 按型号里的规格数字粗略缩放, 仅占位用
|
||||
MODELS = [
|
||||
('UCBM25', 12.5, 60), ('UCBM32', 16, 75), ('UCBM40', 20, 90),
|
||||
('UCBM50', 25, 110), ('UCBM63', 31.5, 135), ('UCBM80', 40, 170),
|
||||
('ULP32', 16, 90), ('ULP50', 25, 120), ('ULP63', 31.5, 140),
|
||||
('USP32', 16, 90), ('USP50', 25, 120), ('USP63', 31.5, 140),
|
||||
('UGP40', 20, 100), ('UGPS32D', 16, 100),
|
||||
('LAE140', 30, 140), ('LAE225', 40, 225), ('LAE350', 55, 350),
|
||||
('UAGP080_W', 40, 80), ('UAGP080_B', 40, 80), ('UAGP120_W', 50, 120),
|
||||
('UAGP120_B', 50, 120), ('UAGP150_W', 50, 150), ('UAGP150_B', 50, 150),
|
||||
('UAGP155_W', 50, 155), ('UAGP155_B', 50, 155), ('UAGP170_W', 62.5, 170),
|
||||
('UAGP170_B', 62.5, 170), ('UAGP210_W', 62.5, 210), ('UAGP210_B', 62.5, 210),
|
||||
('UAGP215_W', 62.5, 215), ('UAGP215_B', 62.5, 215), ('UAGP300_W', 80, 300),
|
||||
('UAGP300_B', 80, 300), ('UAGP350_W', 80, 350), ('UAGP350_B', 80, 350),
|
||||
('UAGP355_W', 80, 355), ('UAGP355_B', 80, 355), ('UAGP605_W', 100, 600),
|
||||
('UAGP605_B', 100, 600),
|
||||
('KC-00-32x10', 16, 100), # KC 试点真实型号: 网格预览样例
|
||||
]
|
||||
|
||||
|
||||
def cylinder_tris(r, h, n=24):
|
||||
"""圆柱体三角网格: (法线, 顶点) 三元组列表, 轴为 Z, 底面 z=0, 顶面 z=h"""
|
||||
tris = []
|
||||
top, bot = [], []
|
||||
for i in range(n):
|
||||
a0, a1 = 2 * math.pi * i / n, 2 * math.pi * (i + 1) / n
|
||||
x0, y0 = r * math.cos(a0), r * math.sin(a0)
|
||||
x1, y1 = r * math.cos(a1), r * math.sin(a1)
|
||||
# 顶面 (z=h, 法线 +Z)
|
||||
tris.append(((0, 0, 1), ((0, 0, h), (x0, y0, h), (x1, y1, h))))
|
||||
# 底面 (z=0, 法线 -Z)
|
||||
tris.append(((0, 0, -1), ((0, 0, 0), (x1, y1, 0), (x0, y0, 0))))
|
||||
# 侧面 (两块三角, 法线径向)
|
||||
nx0, ny0 = math.cos(a0), math.sin(a0)
|
||||
nx1, ny1 = math.cos(a1), math.sin(a1)
|
||||
tris.append(((nx0, ny0, 0), ((x0, y0, 0), (x0, y0, h), (x1, y1, h))))
|
||||
tris.append(((nx1, ny1, 0), ((x0, y0, 0), (x1, y1, h), (x1, y1, 0))))
|
||||
return tris
|
||||
|
||||
|
||||
def write_stl(path, tris):
|
||||
with open(path, 'wb') as f:
|
||||
f.write(b'ONEBOT mesh preview'.ljust(80, b'\0'))
|
||||
f.write(struct.pack('<I', len(tris)))
|
||||
for (nx, ny, nz), (p0, p1, p2) in tris:
|
||||
f.write(struct.pack('<12f', nx, ny, nz,
|
||||
p0[0], p0[1], p0[2],
|
||||
p1[0], p1[1], p1[2],
|
||||
p2[0], p2[1], p2[2]))
|
||||
f.write(struct.pack('<H', 0))
|
||||
|
||||
|
||||
def main():
|
||||
if not os.path.isdir(MESH_DIR):
|
||||
os.makedirs(MESH_DIR)
|
||||
made = 0
|
||||
for name, r, h in MODELS:
|
||||
path = os.path.join(MESH_DIR, name + '.stl')
|
||||
write_stl(path, cylinder_tris(r, h))
|
||||
made += 1
|
||||
print('已生成 %d 个占位 STL → %s' % (made, MESH_DIR))
|
||||
print('提示: 真实网格由 NX journal 导出 STEP 时同步生成, 同名 .stl 覆盖本占位即可')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user