文件格式与互转:Zemax .zmx / .zda 与 Code V .seq / .len 文件的导入导出

做光学设计迁移,第一个要面对的硬骨头就是文件格式。Zemax 和 Code V 各自有一套自己的文件体系,互不兼容。我刚开始从 Zemax 切到 Code V 时,就吃过这个亏——拿着 .zmx 文件直接往 Code V 里拖,结果软件根本不认。嗯,今天我们就来彻底搞清楚这些格式的区别,以及怎么安全地互转。

格式概览:四种文件,两种哲学

先看一张总览图,帮你快速建立整体认知:

Zemax 与 Code V 文件格式互转体系 Zemax 文件格式 .zmx(文本) .zda(二进制) Code V 文件格式 .seq(序列) .len(镜头) 互转 核心差异:数据结构与信息完整性 Zemax 特点 • 面型数据与求解类型耦合紧密 • 玻璃库路径为绝对路径 • 非序列组件描述方式独特 Code V 特点 • 面型数据独立于求解约束 • 玻璃库路径为相对路径 • 非序列需用宏或外部文件 推荐互转流程 Zemax 导出 .zmx 手动检查 Code V 导入 .seq

Zemax 文件格式详解

.zmx 文本格式

.zmx 是 Zemax 的默认保存格式,本质上是纯文本文件。你可以用记事本打开它,直接看到镜头数据。我个人习惯在迁移前先用文本编辑器打开 .zmx 文件看一眼,确认里面有没有特殊字符或乱码。

小技巧: .zmx 文件的第一行通常是版本号,比如 "ZEMAX 20.1"。如果版本号太低(比如 13 以下),Code V 导入时可能会丢失某些新功能参数。

.zmx 文件的结构大致如下:

VERS 20.1
UNIT MM
MODE SEQ
SURF 0  STANDARD
  STOP
  RADIUS INFINITY
  THICKNESS 0
SURF 1  STANDARD
  RADIUS 50
  THICKNESS 10
  GLASS "BK7"
SURF 2  STANDARD
  RADIUS -100
  THICKNESS 5
  GLASS "SF5"
SURF 3  STANDARD
  RADIUS INFINITY
  THICKNESS 0
  IMAGE

看到没?每个面(SURF)后面跟着面型类型,然后是半径、厚度、玻璃等参数。这种结构很直观,但有个坑——Zemax 的求解类型(比如边缘光线高度求解、曲率求解)是直接写在面数据里的,而 Code V 的求解是独立定义的。这个差异会导致互转时求解丢失。

.zda 二进制格式

.zda 是 Zemax 的二进制存档格式。它比 .zmx 更紧凑,加载速度更快,但人类无法直接阅读。我建议:迁移时优先用 .zmx 格式,因为 .zda 转 .seq 时,Code V 的转换器经常报错。

注意: .zda 文件在不同版本的 Zemax 之间也可能不兼容。如果你用 Zemax 20.1 保存的 .zda,用 Zemax 19.4 可能打不开。所以跨版本迁移时,务必用 .zmx 格式。

Code V 文件格式详解

.seq 序列文件

.seq 是 Code V 的标准序列文件格式。它也是文本文件,但语法和 Zemax 完全不同。Code V 使用关键字驱动的语法,比如:

! 镜头标题:双胶合透镜
RDM  1  50.000  10.000  BK7
RDM  2  -100.000  5.000  SF5
RDM  3  INFINITY  0.000
END

这里 RDM 是 "Radius, Diameter, Material" 的缩写。Code V 的语法更简洁,但参数顺序和 Zemax 不一样。我记得第一次手动转换时,把半径和厚度搞反了,结果优化了半天才发现。

.len 镜头文件

.len 是 Code V 的二进制镜头文件。它包含完整的镜头数据、优化变量、约束条件等。.len 文件比 .seq 更强大,但跨版本兼容性也差一些。我个人习惯:用 .seq 做数据交换,用 .len 做本地工作。

互转方法:三种路径

互转不是一键完成的,需要一些技巧。我总结了三种路径,按推荐程度排序:

路径 工具 适用场景 信息保留度
路径一 Zemax 导出 .zmx → Code V 导入 .seq 标准镜头,无复杂求解 80-90%
路径二 Zemax 导出 .zmx → 手动编辑 → Code V 导入 有特殊求解或非序列组件 95%+
路径三 第三方工具(如 OpticStudio API) 批量转换或复杂系统 90-100%

路径一:直接导入导出

这是最常用的方法。在 Zemax 中,用 "File → Save As" 保存为 .zmx 格式。然后在 Code V 中,用 "File → Import → Zemax .zmx" 导入。Code V 会自动解析 .zmx 文件并生成 .seq 文件。

关键点: 导入后一定要检查以下几点:

  • 面型是否正确(特别是非球面、衍射面)
  • 玻璃材料是否匹配(Code V 的玻璃库名称可能不同)
  • 求解和约束是否保留
  • 波长和视场设置是否一致

路径二:手动编辑

当直接导入出现问题时,手动编辑是救命稻草。我曾经遇到一个项目,Zemax 里用了复杂的边缘光线高度求解,导入 Code V 后全部丢失。最后我只能打开 .zmx 文件,找到求解定义,手动写成 Code V 的语法。

手动编辑的步骤:

  1. 用文本编辑器打开 .zmx 文件
  2. 找到需要保留的求解定义(如 "SOLVE" 关键字)
  3. 在 Code V 的 .seq 文件中,用 "Solves" 关键字重新定义
  4. 保存 .seq 文件,在 Code V 中打开
避坑指南: 我曾经因为 .zmx 文件里的玻璃名称 "BK7" 在 Code V 的玻璃库里叫 "N-BK7" 而吃了亏。导入后玻璃显示为 "UNKNOWN",系统直接报错。解决办法:在 Code V 的玻璃库中手动匹配,或者修改 .seq 文件中的玻璃名称。

路径三:第三方工具

如果你需要批量转换几十个镜头,或者系统特别复杂,可以考虑用 Zemax 的 API(OpticStudio API)写个脚本。比如用 Python 读取 .zmx 文件,然后生成 Code V 格式的 .seq 文件。这个方法灵活度高,但需要编程能力。

常见问题与解决方案

互转过程中,我遇到过不少坑。这里列几个最常见的:

问题 原因 解决方案
玻璃材料丢失 玻璃库名称不匹配 手动匹配或修改 .seq 文件
非球面系数错误 两种软件的非球面公式不同 检查公式,手动转换系数
求解和约束丢失 求解定义方式不同 手动重新定义求解
坐标断点混乱 坐标系统定义差异 检查局部坐标和全局坐标
特别提醒: 非球面系数的转换是最大的坑。Zemax 使用偶次非球面公式,Code V 使用奇次非球面公式。虽然两者可以互相转换,但高阶项的定义不同。我建议:导入后先用 Code V 的 "Verify" 功能检查一下非球面形状,确保和 Zemax 中的一致。

我的工作流建议

经过多次项目实践,我总结了一套比较稳妥的工作流:

  1. 在 Zemax 中清理文件:删除不必要的求解、注释、临时面
  2. 导出为 .zmx 格式:确保版本不要太新(建议用 Zemax 19.4 或 20.1)
  3. 在 Code V 中导入:用 "File → Import → Zemax .zmx"
  4. 检查导入结果:重点检查面型、玻璃、求解、波长、视场
  5. 手动修复问题:根据检查结果,手动修改 .seq 文件
  6. 验证光学性能:用 Code V 的 "Spot Diagram" 和 "MTF" 对比 Zemax 结果

这套流程我用了好几年,成功率在 90% 以上。剩下的 10% 通常是因为系统太复杂(比如含有非序列组件或用户自定义面型),需要额外的手动处理。