ZEMAX中如何使用自定义面型(UDS)?(一)
前言:
尽管ZEMAX提供了很多种面型供使用,可是有些时候总觉得不够用。
比如:新的面型,面型参数不够,自定义不够灵活。这时候就需要自定义面型了。
针对自定义面型,ZEMAX提供了完善的接口,如果软件本身提供的面型不够用,只需要按照指定格式编写一个DLL即可。
前段时间,在ZEMAX中开发PW法的插件,利用到了自定义面型。网上也比较缺乏这方面的资料,在此写一篇教程,希望能够帮助大家加深对ZEMAX中自定义面型的理解。欢迎有兴趣的朋友与作者进行交流。
这是一个介绍自定义面型的基础教程,包含两部分:
一、ZEMAX自定义面型简介
a) 对于程序来说面型是什么?
b) 什么是自定义面型?
c) 自定义面型的DLL文件怎么工作?
d) 一个标准球面的源代码详解
二、自定义带PW参数的理想面实例。
本文为第一部分,第二部分后续推出。
ZEMAX自定义面型简介
1. 对于程序来说面型是什么?
在ZEMAX程序中,面型只不过是一个抽象概念,包含一堆数据的一个对象。常见的比如:r(曲率半径)、d(透镜直径)、n(透镜折射率),面型名称,t(厚度)等。不同的面型有不同的参数,不同的软件也有些不一样。
2. 什么是自定义面型?
ZEMAX为了拓展面型功能,允许用户自定义。就是写一个应用程序拓展(DLL),里面包含了很多函数,这些函数(也就一个)会被ZEMAX调用。自定义面型的核心算法就被放在这些函数内部。
切记:ZEMAX调用这些函数是按指定格式的。
位宽:这个要跟ZEMAX统一,操作手册上说64位的软件就用64位的DLL,32位的软件就用32位的DLL,貌似在实际操作中64位程序必须使用32位DLL。
那么到底ZEMAX会从这个DLL中调用哪些函数,或者说到底哪些东西是可以自定义的?ZEMAX规定,用户需要在DLL中自定义包含用于绘制这个面,光线追迹(包括近轴和实际),梯度折射率的数据。
REF: The DLLmust contain functions which return to ZEMAX all the data required to draw thesurface, trace rays, compute refraction angles, and for gradient index, todetermine the index as a function of position within the media following thesurface.
实际上就是ZEMAX挖了很多坑,将对应的坑填上对应的计算公式就行了。
3. 自定义面型的DLL文件怎么工作?
比如ZEMAX主程序要追迹光线,如果这个面是自定义面型,那么主程序就跳转到这个DLL(DLL函数的地址)。这个DLL包含自定义内容,那么就实现了这个面型的自定义化。
DLL就是一个封装了一些函数的文件,ZEMAX让用户把自己的算法写在这个函数里面,在使用这个面型的时候,ZEMAX会按规定格式调用这个函数。
在早期的ZEMAX,这个函数的函数名为UserDefinedSurface,UserDefinedSurface2。后面的数字是保留更新用的,ZEMAX 09可以使用UserDefinedSurface3,ZEMAX 16(Optic Studio)使用到了UserDefinedSurface4。
接下来看一下这个入口函数,找到UserDefinedSurface3的声明:
int _declspec(dllexport)APIENTRY UserDefinedSurface3(USER_DATA *UD, FIXED_DATA3 *FD);
从中可以看出zemax调用这个函数的时候会传给它两个指针。UD 和FD,UD是USER_DATA的指针类型,包含一些基本光线数据,比如入射光线的坐标、方向。
- typedef struct
- {
- double x, y, z; /* the coordinates */
- double l, m, n; /* the ray direction cosines */
- double ln, mn, nn; /* the surface normals */
- double path; /* the path change */
- double sag1, sag2; /* the sag and alternate hyperhemispheric sag */
- double index, dndx, dndy, dndz; /* for GRIN surfaces only */
- double rel_surf_tran; /* for relative surface transmission data, if any */
- double udreserved1, udreserved2, udreserved3, udreserved4; /* for future expansion */
- char string[20]; /* for returning string data */
- }USER_DATA;
复制代码
FD是FIXED_DATA3的指针类型,包含一些结构数据,比如n(入射面介质折射率)、n’(出射面介质折射率)等。
- typedef struct
- {
- int type, numb; /* the requested data type and number */
- int surf, wave; /* the surface number and wavelength number */
- double wavelength, pwavelength; /* the wavelength and primary wavelength */
- double n1, n2; /* the index before and after */
- double cv, thic, sdia, k; /* the curvature, thickness, semi-diameter, and conic */
- double param[9]; /* the parameters 1-8 */
- double fdreserved1, fdreserved2, fdreserved3, fdreserved4; /* for future expansion */
- double xdata[201]; /* the extra data 1-200 */
- char glass[21]; /* the glass name on the surface */
- }FIXED_DATA;
- typedef struct
- {
- int type, numb; /* the requested data type and number */
- int surf, wave; /* the surface number and wavelength number */
- int unit; /* the unit flag */
- double wavelength, pwavelength; /* the wavelength and primary wavelength */
- double n1, n2; /* the index before and after */
- double cv, thic, sdia, k; /* the curvature, thickness, semi-diameter, and conic */
- int ireserved[20]; /* for future expansion */
- double dbreserved[20]; /* for future expansion */
- double param[51]; /* the parameters 0-50 */
- double xdata[201]; /* the extra data 1-200 */
- char glass[21]; /* the glass name on the surface */
- }FIXED_DATA2;
复制代码
这两个结构体在USERSURF.H中声明。FIXED_DATA3也是从FIXED_DATA一路走来的,不断拓展。
FIXED_DATA中有个两个变量int type, numb,这两个变量一起控制着ZEMAX要计算的内容。
- typedef struct
- {
- int type, numb; /* the requested data type and number */
复制代码
其一为int type,是计算类型,Type与计算类型的关系:
The surface name, radial symmetry status, and grin status
The name of the parameter columns
The name of the extra data columns
The sag and alternate sag of the surface
A paraxial ray trace to and refraction through the surface
A real ray trace to and refraction through the surface, including transmittance and polarization data if any
The index and first derivatives for gradient index propagation
The default data when the user first selects the surface type
The initialization of the DLL, if required. 在这里可以初始化静态数据,申请内存,加载文件,类似于构造函数,每次加载执行一次。切记:一台机器可以同时运行多个ZEMAX,一个ZEMAX可以运行多个系统的副本(比如DDE),那么他们每一个副本都会执行这个函数。
The termination of the DLL, if required. 与上一个相反,类似于析构函数,清理战场用的。
The scaling of parameter and extra data values used by the DLL. The scale factor is stored in the USER_DATA structure in the path argument(double path;)
其二为intnumb,为辅助用,常见的用途为:
1. 当有多个计算内容的时候用它来切换。比如type=0时,如果numb= 0,ZEMAX请求返回面的名称,如果numb为1,ZEMAX请求返回该系统是否为旋转对称系统。
2. 指示栏目数,当type为1或2时,numb表示请求的栏目数
3. 干脆没用
4. 一个标准球面的源代码详解
下面是一个中文注释的源代码文件。
这个代码来自OpticStudio16自带的us_stand.c文件,us_stand.c是us_stand.dll的源代码,us_stand.dll是标准球面面型的DLL文件。
截图:
09版ZEMAX自带一个C++的工程文件,16的好像找不到了。
最后,ZEMAX自带大量计算源代码,涉及:
Refractive and reflective UDS DLLs
Lenslet arrays using DLLs
User defined surface apodization using DLLs
想要写相关的自定义面型,从这些例子开始方便多了。
文件:
版权申明:
本文首发于ZEMAX中文论坛。
任何个人或网站均可部分或全文转载,但转载必须保留本版权申明。
作者联系方式:
QQ ->260021863
ZEMAX赞助:
上海理工大学