ZEMAX | 如何编写用户自定义表面

概念



这篇文章介绍了:

■ 什么是用户自定义表面 (User-Defined Surfaces)
■ 如何使用Microsoft Visual Studio 2017 (VS2017) 编写用户自定义表面
■ 如何使用其他编译器
您可以前往以下链接查看并下载VS2017


链接: https://visualstudio.microsoft.com/zh-hans/vs/community/


用户自定义表面



表面用来定义不同光学介质之间的界面。表面可以定义为透射、反射或是衍射的。OpticStudio 18.9版本支持78种表面类型,其中包括非常通用的表面类型,例如多项式表面 (Polynomial surface) 和双锥Zernike (Biconic Zernikes) 表面等。

但有些时候,用户会需要满足特定要求的表面类型,这也是用户自定义表面类型发挥作用的时候。您可以随时将您对新表面的需求发送给support@zemax.com,但OpticStudio也为您提供了自己实现新表面设置的途径。

用户自定义表面是一个编译好的函数(严格意义上是Windows的DLL),它可以根据您的需要实现任意表面形状、相位、透过率函数、梯度折射率或这几种类型的组合。在定义用户自定义表面时,您可以自行输入表面参数,或根据已有的数据库进行定义。

本文以OpticStudio中自带的示例文件为基础,介绍了编译用户自定义表面的基本步骤。本文不涉及构建特定表面的方法,这将在其他文章中介绍。

如果您已经拥有基础的编程经验并且对想要构建的表面已经有了清晰的数学描述规范,那么定义用户自定义表面是非常容易的。通过示例文件,本文将带您快速了解如何定义用户自定义表面,但是确定所需要的数学函数往往是最难的部分。

我们要做的第一步就是确定表面的定义规范。首先,在OpticStudio已经提供的表面中寻找一个最贴近您需求的表面,阅读用户手册中关于该表面的描述。然后以该描述为基础,写出一份符合您需求的定义规范。用文本描述的方式对您要定义的表面进行描述,给出所需的表面矢高表达式及相位表达式等,给出透镜数据编辑器中额外参数的用途。最后,我们要确定初次调用该表面时额外参数的初始值。例如,当您第一次在透镜数据编辑器中插入一个标准面 (Standard surface) 时,曲率半径的初始值为无穷大,厚度的初始值为零,圆锥系数的初始值为零。您需要确定什么初始参数是最“安全”的。

回到手册中查看关于用户自定义表面的描述。您将看到我们提供的多个示例。找到和您的需求最贴近的示例文件,并将其作为构建用户自定义表面的起点。在示例文件的基础上进行修改的好处在于,您不需要编写所有的代码来使文件与OpticStudio进行通信,我们在示例文件中已经替您完成了这部分工作。您只需要专注于编写表面即可。

当您在示例文件中找到了和您的需求最贴近的示例文件时,将源文件(扩展名为xxx.c的文件)复制并重命名。在本文中,我们将使用示例中的us_arrayeven.c文件进行演示,该文件位于Zemax根目录/DLL/Surfaces文件夹中。该文件定义了一个矩形的非球面阵列表面。我们将把这一文件重命名为myarray.c。


使用VS2017编译表面




OpticStudio是64位的软件,因此为了正常工作,DLL必须编译为64位。您需要进行如下两项设置来编译64位的代码:

■ 点击生成 (Build) - 配置管理器 (Configuration Manager),选择活动解决方案配置 (Active solution configuration) 为:Release

■ 选择活动解决方案平台 (Active solution platform) 为:x64



现在,该项目的状态为一个空项目,等待我们在其中填充文件。在左侧的解决方案资源管理器 (Solution Explorer) 中,您将看到项目包含的所有文件。右键点击资源文件 (Source Files) 选择添加 (Add) – 现有项 (Existing Items):



选择前文中我们复制并重命名过的my_array.c文件,该文件是示例文件us_arrayeven.c文件的副本。在您编写自己的表面时只需要基于该文件进行修改即可。

然后,右键点击头文件 (Header Files),选择添加 (Add) – 现有项 (Existing Items),添加usersurf.h文件,该文件同样位于Zemax根目录/DLL/Surfaces文件夹中。现在,解决方案资源管理器如下图所示:



在开始编译我们自己的表面前,您必须做的最后一件事是设置VS2017的代码生成格式。右键点击“My_asphere”选择属性 (Properties):



我们要做的第一个改变是在常规 (General) 选项卡下将配置类型 (Configuration Type) 更改为动态库(.dll) (Dynamic Library (.dll)),并将字符集 (Character Set) 更改为使用Unicode字符集 (Use Unicode Character Set):



们建议您将C/C++选项卡下代码生成 (Code Generation) 一栏中的运行库 (Runtime Library) 更改为多线程(/MT) (Multi-threaded(/MT)),这项设置可以确保用户在没有C语言库函数的电脑上运行DLL。

多线程(/MT) 与 多线程DLL(/MD) 的区别:

对于多线程(/MT)和多线程DLL(/MD)的选择有时是很复杂的,这主要取决于对使用的兼容性或易用性的选择。如果您编写的DLL不需要与其他库函数交互,使用多线程(/MT)意味着您不需要担心其他使用DLL的计算机是否安装了C语言运行库。如果在您编写的DLL中使用了其他库函数,则您需要使用与其他库函数相同的运行库,大多数情况下都是多线程DLL(/MD)。

对于大多数不需要使用其他库函数的简单的DLL来说,选择多线程(/MT)通常是最好的选择。

<

以上就是您需要设置的全部内容!

您可以点击生成 (Build) – 重新生成解决方案 (Rebuild Solution) 来进行测试。此时DLL编译结果应该显示没有错误:



将您指定的项目路径中My_asphere/x64/Release文件夹中的My_asphere.dll文件拷贝到Zemax根目录/DLL/Surfaces文件夹中。



重新启动OpticStudio,在序列模式下选择表面类型为用户自定义表面,并选择数据文件(Data File)为My_asphere.dll:



祝贺!您已经成功编译完成了一个用户自定义表面!


使用其他编译器



您也可以使用其他任意可以生成多线程DLL项目的64位编译器。符合要求的编译器有非常多种,我们无法做到为全部编译器提供技术支持。如果您在使用其他编译器时遇到问题,您可以按如下格式询问编译器软件的技术支持工作人员:如何创建一个多线程的Win32 DLL空项目。前文中所述的步骤也为您创建DLL提供了帮助信息。


小结



这篇文章介绍了如何使用Microsoft Visual Studio 2017编译用户自定义表面。有关VS2017的使用信息,请参考以下内容:


链接: https://visualstudio.microsoft.com/zh-hans/vs/community/