216 lines
12 KiB
VB.net
216 lines
12 KiB
VB.net
' =============================================================================
|
|
' NX Journal: 参数化母模 + 参数表 → 批量导出 STEP (欧霓博目录软件专用)
|
|
'
|
|
' ▍这个脚本干什么
|
|
' 逐行读取 CSV 参数表 (每行 = 一个型号: 型号编码 + bore/stroke/magnet/mount... + step_file),
|
|
' 对每个型号: 修改母模表达式 → 更新模型 → 导出 STEP214 文件。
|
|
' ★ 已按 step_file 去重: 多个型号行共用同一文件时只导出一次 (52,154 行型号
|
|
' 只会导出唯一几何文件, 例如 KC 系列 2,772 个)。断点续跑: 输出目录已存在的文件会跳过。
|
|
'
|
|
' ▍使用前置 (母模要求, 详见《NX母模建模操作说明书.md》)
|
|
' 1) 母模中所有"会变"尺寸必须用表达式驱动, 表达式名与 CSV 列名一字不差
|
|
' 2) 磁石槽/安装形式/双轴等"有无"特征 → 按表达式抑制 (Suppression by Expression)
|
|
' 3) 建模验收: 手动改 bore/stroke/magOn/mountIdx 各验证过重建无误
|
|
'
|
|
' ▍运行方法
|
|
' NX 打开母模 → 菜单 工具 → 日记 → 播放 → 选本文件
|
|
' (注意: Ctrl+U 只认 .dll, 本 .vb 必须走"日记→播放")
|
|
'
|
|
' ▍CONFIG 区修改清单 (建模工程师每次只改这里)
|
|
' [1] csvPath / outDir 两个路径
|
|
' [2] exprMap — 尺寸映射: NX 表达式名 → CSV 列名 (新增独立尺寸表达式就加一行)
|
|
' [3] switchRules — 枚举开关: {CSV列名, 列值, NX表达式名, 表达式值}
|
|
' 例: 磁石列 "M" → magOn=1; 固定形式 "FA" → mountIdx=1 (取值按母模约定)
|
|
' [4] exportStl / stlOutDir — 同步导出 STL 网格 (桌面目录软件窗口内 3D 预览用, 开源 Helix 渲染)
|
|
' STL 文件名与 STEP 同名 (.stl), 放在 catalog\mesh\ 目录; 不需要窗口内预览就 exportStl = False
|
|
'
|
|
' ▍注意
|
|
' - DexBuilder 导出接口 NX 10 ~ NX 2506 兼容; 若你的 NX 版本 API 有差异,
|
|
' 用【工具→日记→录制】录一次 文件→导出→STEP214, 替换 ExportStep 函数体。
|
|
' - 中文注释需 UTF-8 带 BOM (改完跑 fix-bom.ps1), 否则 NX 读乱。
|
|
' - 导出失败的行不会中断整体, 最后汇总统计写进 NX 信息窗口 (ListingWindow)。
|
|
' =============================================================================
|
|
Option Strict Off
|
|
Imports System
|
|
Imports System.IO
|
|
Imports NXOpen
|
|
Imports NXOpen.UF
|
|
|
|
Module BatchStepExport
|
|
|
|
Dim theSession As Session = Session.GetSession()
|
|
Dim workPart As Part = theSession.Parts.Work
|
|
Dim lw As ListingWindow = theSession.ListingWindow
|
|
|
|
Sub Main()
|
|
|
|
' ╔════════════════════════════ CONFIG 区 (只改这里) ═══════════════════════════════╗
|
|
' ║ [1] 两个路径 ║
|
|
' ╚═════════════════════════════════════════════════════════════════════════════════╝
|
|
Dim csvPath As String = "D:\catalog\params.csv" ' 参数表路径 → 改为 catalog\csv\<系列>.csv
|
|
Dim outDir As String = "D:\catalog\step_out\" ' STEP 输出目录 → 改为 catalog\step\
|
|
' (目录不存在会自动创建)
|
|
|
|
' ╔═════════════════════════════════════════════════════════════════════════════════╗
|
|
' ║ [4] STL 网格同步导出 (窗口内 3D 预览用; 不开就设 False) ║
|
|
' ╚═════════════════════════════════════════════════════════════════════════════════╝
|
|
Dim exportStl As Boolean = True ' True = STEP 导出时同步导出同名 STL
|
|
Dim stlOutDir As String = "D:\catalog\mesh\" ' STL 输出目录 → 改为 catalog\mesh\
|
|
|
|
' ╔═════════════════════════════════════════════════════════════════════════════════╗
|
|
' ║ [2] 尺寸映射 exprMap: "NX母模表达式名" → "CSV列名" ║
|
|
' ║ 母模里每个独立尺寸表达式加一行; 联动尺寸(公式)不用写 ║
|
|
' ╚═════════════════════════════════════════════════════════════════════════════════╝
|
|
Dim exprMap As New System.Collections.Generic.Dictionary(Of String, String)()
|
|
exprMap.Add("bore", "bore") ' 缸径: 母模表达式 "bore" ← CSV 列 "bore"
|
|
exprMap.Add("stroke", "stroke") ' 行程: 母模表达式 "stroke" ← CSV 列 "stroke"
|
|
' 示例(按需取消注释):
|
|
' exprMap.Add("magPos", "magpos") ' 磁石位置是独立规格时: CSV 要有 magpos 列
|
|
|
|
' ╔═════════════════════════════════════════════════════════════════════════════════╗
|
|
' ║ [3] 枚举开关映射 switchRules: 每行 = {CSV列名, 列值, NX表达式名, 表达式值} ║
|
|
' ║ 作用: 该型号在这一列的值 = 列值 时, 把 NX 表达式设为 表达式值 ║
|
|
' ║ (驱动母模里"按表达式抑制"的开关, 空串列值写作 "") ║
|
|
' ╚═════════════════════════════════════════════════════════════════════════════════╝
|
|
Dim switchRules As New System.Collections.Generic.List(Of String())()
|
|
switchRules.Add({"magnet", "", "magOn", "0"})
|
|
switchRules.Add({"magnet", "M", "magOn", "1"})
|
|
switchRules.Add({"mount", "", "mountIdx", "0"})
|
|
switchRules.Add({"mount", "FA", "mountIdx", "1"})
|
|
switchRules.Add({"mount", "FB", "mountIdx", "2"})
|
|
switchRules.Add({"mount", "CA", "mountIdx", "3"})
|
|
switchRules.Add({"mount", "CB", "mountIdx", "4"})
|
|
switchRules.Add({"mount", "LB", "mountIdx", "5"})
|
|
switchRules.Add({"mount", "YB", "mountIdx", "6"})
|
|
' ================================================================
|
|
|
|
lw.Open()
|
|
lw.WriteLine("批量导出开始: " & csvPath)
|
|
Directory.CreateDirectory(outDir)
|
|
If exportStl Then
|
|
Directory.CreateDirectory(stlOutDir)
|
|
lw.WriteLine("同步导出 STL 网格: " & stlOutDir)
|
|
End If
|
|
|
|
Dim lines() As String = File.ReadAllLines(csvPath)
|
|
If lines.Length < 2 Then
|
|
lw.WriteLine("参数表为空!")
|
|
Return
|
|
End If
|
|
|
|
Dim header() As String = lines(0).Split(","c)
|
|
Dim colStep As Integer = Array.IndexOf(header, "step_file")
|
|
If colStep < 0 Then
|
|
lw.WriteLine("参数表缺少 step_file 列!")
|
|
Return
|
|
End If
|
|
' 预解析列号
|
|
Dim colOf As New System.Collections.Generic.Dictionary(Of String, Integer)()
|
|
For Each kv As KeyValuePair(Of String, String) In exprMap
|
|
colOf(kv.Key) = Array.IndexOf(header, kv.Value)
|
|
If colOf(kv.Key) < 0 Then
|
|
lw.WriteLine("参数表缺少列: " & kv.Value)
|
|
Return
|
|
End If
|
|
Next
|
|
|
|
Dim okCount As Integer = 0
|
|
Dim failCount As Integer = 0
|
|
Dim skipCount As Integer = 0
|
|
' 去重: 多个型号行共用同一 step_file, 每个文件只导出一次 (本批内)
|
|
Dim exported As New System.Collections.Generic.HashSet(Of String)()
|
|
|
|
For i As Integer = 1 To lines.Length - 1
|
|
If lines(i).Trim().Length = 0 Then Continue For
|
|
Dim c() As String = lines(i).Split(","c)
|
|
Dim model As String = c(0).Trim()
|
|
Dim stepFile As String = c(colStep).Trim()
|
|
If exported.Contains(stepFile) Then
|
|
skipCount += 1
|
|
Continue For
|
|
End If
|
|
' 断点续跑: 输出目录已存在同名文件 → 跳过 (想强制重导, 先删该文件再跑)
|
|
If File.Exists(Path.Combine(outDir, stepFile)) Then
|
|
exported.Add(stepFile)
|
|
skipCount += 1
|
|
Continue For
|
|
End If
|
|
lw.Write("[" & i & "/" & (lines.Length - 1) & "] " & stepFile & " ... ")
|
|
|
|
Try
|
|
' ---- 1) 设置表达式 (尺寸) ----
|
|
For Each kv As KeyValuePair(Of String, String) In exprMap
|
|
workPart.Expressions.Edit(kv.Key, c(colOf(kv.Key)).Trim())
|
|
Next
|
|
|
|
' ---- 1.5) 设置枚举开关 (抑制/特征组切换) ----
|
|
For Each rule As String() In switchRules
|
|
Dim colIdx As Integer = Array.IndexOf(header, rule(0))
|
|
If colIdx >= 0 AndAlso c(colIdx).Trim() = rule(1) Then
|
|
workPart.Expressions.Edit(rule(2), rule(3))
|
|
End If
|
|
Next
|
|
|
|
' ---- 2) 更新模型 ----
|
|
Dim update As NXOpen.Update = theSession.CreateUpdate()
|
|
Dim nErrs As Integer = 0
|
|
update.InterpartDelay = False
|
|
update.ModelingInterpartUpdate = True
|
|
update.DoUpdate(nErrs)
|
|
update.Dispose()
|
|
If nErrs > 0 Then
|
|
lw.WriteLine("警告: 更新有 " & nErrs & " 个错误")
|
|
End If
|
|
|
|
' ---- 3) 导出 STEP ----
|
|
ExportStep(Path.Combine(outDir, stepFile))
|
|
|
|
' ---- 3.5) 同步导出 STL 网格 (窗口内 3D 预览; 同名 .stl) ----
|
|
If exportStl Then
|
|
Dim stlFile As String = Path.ChangeExtension(stepFile, ".stl")
|
|
If Not File.Exists(Path.Combine(stlOutDir, stlFile)) Then
|
|
ExportStl(Path.Combine(stlOutDir, stlFile))
|
|
End If
|
|
End If
|
|
|
|
exported.Add(stepFile)
|
|
okCount += 1
|
|
lw.WriteLine("OK")
|
|
|
|
Catch ex As Exception
|
|
failCount += 1
|
|
lw.WriteLine("FAIL: " & ex.Message)
|
|
End Try
|
|
Next
|
|
|
|
lw.WriteLine("")
|
|
lw.WriteLine("完成: " & okCount & " 个文件导出成功, " & failCount & " 失败, " & skipCount & " 行共用文件已跳过 (共扫描 " & (lines.Length - 1) & " 行型号), 输出目录: " & outDir)
|
|
End Sub
|
|
|
|
' STEP214 导出 (NX 10+ DexBuilder; 旧版本请用录制日记替换此函数)
|
|
Sub ExportStep(fileName As String)
|
|
Dim dexBuilder As NXOpen.DexBuilder = workPart.DexManager.CreateBuilder()
|
|
dexBuilder.PartType = NXOpen.DexBuilder.PartTypeOption.Part
|
|
dexBuilder.OutputFile = fileName
|
|
dexBuilder.Translator = NXOpen.DexBuilder.TranslatorType.Step214
|
|
dexBuilder.ColorAndLayers = True
|
|
dexBuilder.Commit()
|
|
dexBuilder.Destroy()
|
|
End Sub
|
|
|
|
' STL 网格导出 (窗口内 3D 预览用, 二进制格式体积小; 若 NX 版本 API 有差异,
|
|
' 用【工具→日记→录制】录一次 文件→导出→STL 替换本函数体)
|
|
Sub ExportStl(fileName As String)
|
|
Dim stlBuilder As NXOpen.StlBuilder = workPart.StlManager.CreateStlBuilder()
|
|
stlBuilder.OutputFile = fileName
|
|
stlBuilder.BinaryFormat = True ' 二进制 STL
|
|
stlBuilder.TriangleTolerance = 0.5 ' 三角网格公差 (mm), 越小越精细文件越大 (0.5 屏幕预览足够)
|
|
stlBuilder.AdjacentTolerance = 0.1
|
|
stlBuilder.AutoNormalGen = True
|
|
stlBuilder.NormalDirection = 1 ' 1 = 朝外
|
|
stlBuilder.Commit()
|
|
stlBuilder.Destroy()
|
|
End Sub
|
|
|
|
End Module
|