用户自定义(User Defined)
用户自义定表面(UDS)是一种强大、灵活、快速的面型定义方法,用于定义OpticStudio中没有的表面。UDS的形状可以是任意的,可以表示折射、反射、衍射,可以任意改变光束的相位,后面可以是均匀介质或是任意形态的渐变折射率介质。此外,UDS也可以任意切趾光束或衰减光束,或使用UDS定义用于偏振分析的任一电场或膜层数据。后者能使光束按照任意公式/光学系统中任一表面用户自定义表格实现部分透射。
该功能非常灵活的原因是,表面所有的性质都是用户在一个单独的C或C++程序中定义的,该程序通过Windows的动态连接库(DLL)功能实现与OpticStudio动态链接。DLL必须包含返回OpticStudio所需全部数据的函数,OpticStudio用这些数据进行绘图、光线追迹、计算折射角以及通过折射率和表面介质位置之间的函数确定渐变折射率介质的折射率。
DLL是汇编代码,由于OpticStudio传递给DLL一个指针,指向需要被计算的数据,因此UDS的速度非常快,几乎与OpticStudio本身的代码速度一样快(函数调用只会导致计算机少量负担)。
UDS功能强大,对UDS的使用有合理的代价。对UDS的使用要求用户配备适当的、能够产生兼 容的32位Windows DLL(或64位,如果使用OpticStudio的64位版本)的程序编译器或开发工具。此外,假定用户会编写所需要的代码,更重要的是,要确保代码是可靠的并且没有bug。为了使速度最快,OpticStudio几乎不核对DLL返回的数据,因此调试UDS DLL很容易导致OpticStudio崩溃。
正因如此,OpticStudio技术支持所提供的支持服务仅限于确保UDS范例文件能够被正确执行。
UDS DLL
学习如何创建UDS DLL的最佳方法是,首先将示例DLL的源代码文件(以.C结尾的文件)复制到一个新的文件名中,编辑这个示例文件来满足您的需要,然后重新进行汇编产生一个新的DLL。DLL源代码中提供了一段很好的"boiler plate",它是所有DLL共有的。
定义一个UDS DLL需要两个文件:一个诸如MY_SURF.C的C(或C++)源代码文件,一个名为USERSURF.H的头文件。只有C文件需要进行修改。C文件中定义了两个函数:第一个是"DLLMain",用于(可选的)初始化DLL数据。另一个函数是"UserDefinedSurface5",它一般 对每个表面类型都要修改。早期版本的OpticStudio用户界面使用的函数名是"UserDefinedSurface、UserDefinedSurface2、UserDefined Surface3和UserDefinedSurface4",这些名字仍然支持但已经被废弃了。新的DLL文件名应该使用"UserDefinedSurface5"。
OpticStudio传递给函数两个结构,这些结构在USERSURF.H文件中定义。这些结构是:
- "USER_DATA"
- "FIXED_DATA5"
USER_DATA
该数据结构包含:
- 光线x、y、z在平面上与曲面顶点相切。DLL必须迭代到真实的表面(或分析计算截距),并返回更新后的光线位置。
- I、m、n在光线截距处的方向余弦
- In、mn、nn在要计算和返回的光线截距处的表面法线
- 其他数据如渐变折射率面的折射率、透射、光程
DLL必须在与表面交互后计算所有新的光线数据。
FIXED_DATA5
该数据结构主要包含DLL无法改变的数据,如编辑器中的所有表面数据、光线波长、偏振态等。光线偏振态和参数比率是DLL唯一可以修改的数据
此外,FIXED_DATA5还包含"类型(Type)"和"数(Numb)"参数,表示OpticStudio希望从指定的DLL调用中得到的数据。在UserDefinedSurface5函数中,这些参数是一个C"Switch-case"结构。"类型"是一个介于0-10之间的数(包含0和10)。
下面的表格中描述了"类型"码:
类型 | Zemax需要DLL计算的数据 |
0 | 表面名称、径向对称状态以及渐变折射状态 |
1 | 参数栏的名称 |
2 | 附加数据栏的名称 |
3 | 表面矢高和其他矢高 |
4 | 近轴光线追迹至该表面并折射穿过该表面 |
5 | 实际光线追迹至该表面并折射穿过该表面,也包括透射和偏振数据(如果有的话) |
6 | 渐变折射率传播过程中的折射率和一阶导数 |
7 | 用户初次选择表面类型时默认的数据 |
8 |
在需要时初始化DLL。包括分配DLL所需的静态内存,加载数据文件,或其它即时计算或初始化。每次加载DLL时都会调用此类型码。但是Zemax可以多次载入相同的DLL。例如,Zemax中每个分析窗口都会得到自己的镜头数据副本,在分析窗口每次更新时,每个副本将会载入并初始化DLL。Zemax可以同时(并行执行)更新多个分析窗口,因而多个DLL可以同时运行。因此,当Zemax多次加载DLL时,使用固定的文件名多次写入存储。 相同的文件在Zemax多次导入DLL时可以多次创建或写入。 |
9 |
在需要时终止DLL。包括释放已分配的内存或关闭数据文件。只有从表面中删除DLL或镜头被关闭时才调用此类型值。参阅上述类型码8的注释,了解Zemax00如何载入、初始化并立刻终止多个DLL。 DLL只有在终止前必须释放内存或进行其它的"清除"操作时才处理此类型码。 |
10 | DLL中所使用的参数缩放比例和附加数据。比例因子储存在参考路径下的用户数据库(USER_DATA)中。 |
在DLL示例源代码文件中提供了大量的注释。可以在<data>\DLL\Surfaces文件夹中找到DLL文件,同时 新的DLL文件也必须放在这个文件夹中。
折射和反射UDS DLL(Refractive and reflective UDS DLLs)
对于折射或反射,而非渐变或衍射的常规均匀表面,以文件US_STAND.C开始。它是US_STAND.DLL的源代码文件,而US_STAND.DLL是OpticStudio内置表面标准面的复刻。它的代码并不完全相同,而且运行速度比OpticStudio使用的方程稍慢,但在功能上是等价的。US_STAND.C包含一个一般的Snell法则的折射函数,也可用于反射。该DLL与所有的UDS DLL一样,提供矢高、光线交点方程、表面法线、光程和近轴折射功能。
渐变折射率UDS DLL(Gradient index UDS DLLs)
渐变折射率表面应该用US_CRIN 1.C作为初始点。除了返回标记表示该表面是渐变折射率类型,以及执行数据类型"6"用于返回给定的X、Y、Z的折射率和所有参数及附加数据以外,编码类似于US_STAND.C。还必须提供X、Y、Z方向的折射率的一阶导数。
对于渐变折射率UDS DLL,只要玻璃一栏是空白的,用于近轴光线追迹的折射率即为表面的前顶点(坐标(0, 0, 0)处的折射率。如果DLL的材料一栏中(在LDE的常规材料一栏)被指定 了某种玻璃材料,那么近轴参考折射率就是根据玻璃库中的材料数据计算的。当使用渐变折射率DLL时,一般不需要甚至不建议指定玻璃的名称。只有当DLL基于玻璃库数据计算折射率偏移时,才需要指定玻璃的名称。
衍射UDS DLL(Diffractive UDS DLLs)
衍射光学元件与标准光学元件非常相似,除了通过相位导数(关于X、 Y)使得光线进一步偏移外,还需要修改光程来包含相位的变化。
一般,衍射光学元件的"折射"定义为:
这里,l和m都是方向余弦,计算Z方向余弦n,使得方向向量的大小归一,φ是以弧度表示的相位。
DLL例子:US_GRATE.DLL,通过复刻OpticStudio内建光栅面来说明衍射计算。
使用DLL的透镜阵列(Lenslet arrays using DLLs)
使用用户自定义表面可以很容易对透镜阵列进行建模。基本上,光线追迹可确定光线打到了阵列透镜的哪一部分,然后用该部分透镜的曲率来确定光线折射。示例源代码和DLL分别参考US_ARRAY.C和US_ARRAY.DLL。
使用DLL自定义表面切趾
DLL的实际光线追迹部分,类型码5,允许定义表面透过率。表面透过率必须是介于0.0到1.0之间的数字,并表示光线穿过该表面透射的相对强度。在本章中,透射意味着"光线继续",因此对于反射表面,透射部分通常表示反射到下一个表面。
表面透过率可用于定义任意表面切趾。透射函数可以是任何一种基于光线坐标、方向余弦、表面参数或其它数据的公式;或者,该函数可以从查找表中或可在DLL中执行的任意其它方法获得。
不需要定义表面透过率。如果DLL没有定义透过率,OpticStudio假设它是1.0。无论表面透过率是多少,OpticStudio都将修改光线强度以考虑菲涅尔表面、膜层,以及进行偏振光线追迹时通常要考虑的体吸收效应。
如果OpticStudio不进行偏振光追迹,那么DLL定义的透过率只起衰减作用。与光瞳切趾不同,使用UDS定义的表面切趾可以放在光学系统任何地方的任何表面上。注意,对于是光线位置函数的切趾(大部分都是),不同视场会观察到不同的有效切趾。注意,该技巧可用来模拟任意中性密度过滤器或是透过率与波长有关的过滤器。
使用DLL定义偏振及膜层数据(Polarization and coating data using DLLs)
DLL的实际光线追迹部分,类型码5,允许直接定义透射及反射电场,或定义s及p方向的复反射及透射系数,基于DLL中可用的任何视场或膜层数据,包含光线余弦(Ray cosines)、法向向量(normal vectors)、折射率(index)或其它用户自定义数据,或者可以在DLL中实现任何方法。视场和膜层数据不是必须定义的,如果DLL没有对这些数据进行定义的话,OpticStudio会使用表面默认算法。有关如何定义电场或膜层数据的源代码示例,请参见范例DLL US_OLARIZATION。
错误处理与UDS(Error handling and UDS)
如果DLL计算了一个有意义的结果,并且没有出现错误,则OpticStudio按内部约定返回0值。否则,DLL将返回-1。光线追迹时无论是近轴光线还是实际光线,例外情况是:如果光线与表面无交点,将返回表面序号;如果光线内全反射(TIR),那么返回的是表面序号的负数。OpticStudio使用这些错误代码为用户和各种OpticStudio功能提供有意义的诊断。
DLL示例(Sample DLLs)
我们提供了许多UDS DLL示例,它们可作为使用DLL之前的准备,也可以作为用于研究和修改的C语言源代码。编写DLL最简单的办法是寻找你所需要的DLL或用途最接近的DLL,然后按照需求复制和编辑C语言源代码文件。下面的表格列出了可用的DLL以及每个DLL的简述。注意,尽管示例DLL已经测试过,且通常认为是可靠的,但仍然"按现状(as is)"提供。
"在下面的所有DLL描述中,c为曲率,k为圆锥系数,z为矢高坐标,r为径向坐标,ρ为归一化为表面半直径后的径向坐标,D为透射函数的对数(即D = -Log10(T),其中T为透过率)。必要时,应在相应的描述中指定其它参数。"
UDS DLL例子


DLL名称 | 描述 |
US_ARRAYEVEN | 模拟了nxm透镜阵列,每个透镜的维度为HxW;要指定4个参数。透镜具有矩形轮廓和"偶次非球面"面型,即平面、球面、二次非球面和径向多项式非球面。在每个方向上透镜的数目必须是奇数。 |
US_CYLAR | 对垂直排列的n个柱透镜建模,每个透镜的高度均为H。这些透镜在YZ平面上是圆柱形或二次非球面。 |
US_DGCYL | 对柱面上的衍射光栅建模,光栅刻线是沿表面的弧线(而不是沿切平面y坐标)的等距间隔。光栅刻线平行于圆柱的坐标轴。 |
US_DATASURFACE | 此表面使用FIXED_DATA4结构,并且可以传递来自上一个数据表面的值。第一次加载此表面时,会读取上一个数据表面的附加数据值,说明在"数值"参数栏中读取了多少数据值,并且将这些值复制到EDE。它不会动态更新,仅用于说明对DLL中这些值的访问。 |
US_EAPERIODIC | 此表面类似于偶次非球面,不过它含有一个附加项,描述矢高按正弦变化。这类变体非常适用于对不规则表面进行建模。表面的完整矢高表达式由以下公式给出: 这里,参数c、k与 |
US_FILT1 |
此表面定义了一个切趾函数 |
US_FILT2 | 此表面定义了一个切趾函数,光学密度Dmax是从0到归一化径向坐标p1的距离,在p2处D线性变化为D=0,随后变成D=0。 |
US_FILT3 | 此表面定义了一个切趾函数 |
US_FILT4 |
此表面定义了一个切趾函数: 这里,r是径向坐标,R是孔径半径, |
US_FILT5 |
此表面定义了一个切趾函数: 这里,na是入射光线的数值孔径,NA是用户自定义参数, |
US_FILT6 |
此表面定义了一个切趾函数: 其中, |
US_FILT7 | 此表面对表面透过率进行切趾,通过附加数据编辑器中值的线性插值计算,附加数据编辑器中的值可以是表面径向坐标的函数,也可以是发生折射的表面局部Z轴与光线间夹角的函数。 |
US_FILT8 | 此表面可对软边缘的矩形孔径建模,"MaxX"及"MaxY"参数为矩形孔径的X及Y的半宽。透过率会在变化距离中平稳地从1变为0(变化距离是"DelX"和"DelY"到孔径边界距离的两倍)。该函数会产生一个便利的"软边缘"孔径,适用于优化通过矩形孔径的透过率。 |
US_GCYL | 模拟带有渐变折射率介质的圆柱型表面,该渐变折射率(GRIN)介质在同心圆柱薄壳层中具有一常数折射率,以多项式表达的GRIN分布其中心在曲面的曲率中心,此DLL用于模拟光线沿着垂直于光纤轴向方向横穿光纤。 |
US_GRATE | 模拟含有平行于X轴的光栅刻线的标准面,这些光栅刻线在切平面上沿Y方向等距间隔。它相当于Zemax"衍射光栅"表面的复刻;有不同的方法可用来测量光程,且通常不会造成光线追踪问题。目的是说明在Zemax UDS DLL中如何对衍射表面进行模拟 |
US_GRIN1 | 模拟二次GRIN介质。它相当于Zemax"渐变1"表面的复刻。该示例文件为了说明在Zemas UDS DLL中如何对GRIN表面进行模拟。 |
US_HOLOGRAM_KOGELNIK | 该DLL建模了一个体全息图,也称为体布拉格光栅(Volume Bragg Grating),以下列论文为理论基础 - Kogelnik, H.(1969) Coupled Wave Theory for Thick Hologram Gratings。Bell System Technical Journal, 48, 2909-2947。它构建系统的定义方式类似于表面类型全息图1和全息图2。全息图的平均折射率、调制折射率和厚度等更多参数,被用来计算衍射效率。诸如收缩率和折射率变化在内的公差参数包括在可制造性分析中。了解有关如何使用此DLL的更多详情,请参阅知识库文章使用Kogelnik的方法模拟体全息光栅的衍射效率(Simulating diffraction efficiency of a volume holographic grating using Kogelnik’s method)。 |
US_IGRIN | 带有色散的GRIN示例。 |
US_ITERA |
此DLL是Zemax"标准"表面的复刻。除了它使用"dumb"迭 代查找交点(而非解析解来寻找交点)。此示例为了说明如何在只知道矢高表达式的前提下找到表面交点。绝大部分多项式非球面都需要此类型的迭 代,因为不能用解析解来确定光线与表面交点。 注意:这个示例DLL中的迭代非常简单,可能无法处理入射角非常大的光线。在广角系统中使用时,DLL可能会出现以下错误消息:错误2(Error 2)。在这些情况下,应使用更稳健的算法,比如US_STAND.DLL中给出的算法。 |
US_LUNE |
模拟一个伦伯透镜,这是一个球透镜,材料是一个渐变折射率线性变化作为距离曲率中心的函数, ![]() 其中n为折射率,r为到球透镜曲率中心的距离,R为球透镜的半径。 |
US_MEMS |
对微型机电系统(MEMS)(如数字反射镜装置(DMD))进行建模。MEMS由小矩形反射镜的2D阵列构成。反射镜可以有三个不同的倾斜角,绕着轴旋转使反射镜指向任意方向。这些反射镜的状态有三种情况,可以用寻址行、列来设置,或者对个别反射镜进行设置模拟想要的MEMS某一种状态。尽管这个模型是严格的几何模型,它仍然可以有效模拟由特定设备(针对个别反射镜的任意设置)反射的光线。该模型的参数有: Nx:X方向反射镜的数目 NY:Y方向反射镜的数目 Wx:X方向的总宽度,以镜头单位表示 Wy:Y方向的总宽度,以镜头单位表示 参数5、6和7(角度0、角度1和角度2):状态为0、1或2时对应的反射镜角度 参数8(旋转角(Rot Angle)):反射镜绕z轴倾斜的旋转角 参数13(P标记):如果是0,反射镜按行寻址;如果是1,按列;如果是2,按单个反射镜。 参数14(行1-15或列1-15或像素1-15):行/列/反射镜1-15的状态 参数15(行1-15或列1-15或像素1-15):行/列/反射镜16-30的状态 参数12+N:行/列/反射镜1+15*(N-2)-15*(N-1)的状态 旋转角绕局部Z轴有效旋转反射镜的倾斜面;初始倾斜面绕着局部X轴旋转。旋转角从+y轴顺时针方向测量。反射镜的角度沿旋转倾斜方向倾斜。 在参数中用3个基本的整数值来定义行/列/反射镜的状态。如果要确定用于任何一种MEMS逻辑状态的值,可以创建一个类似于下面的表格,它显示用于3行或3列或3个反射镜的值: 注意,参数的值由以下形式给出: 这里,M1是第一行/列/反射镜的逻辑状态(0、1或2),M2是第二行/列/反 射镜的逻辑状态,以此类推。每个参数最多可定义15个行/列/反射镜的值。 |
US_MULTI_ZONE_ ASPHERE |
该表面模拟了一系列环状偶次非球面区域。每个区域都有半径、圆锥系数、至12阶的偶次非球面系数以及那个区域的最大的径向孔径。可以支持共20个同心区域。每个区域都被偏移,这样在区域边界处面是连续的。 |
US_OFFST | 偏移面。此表面模拟隐藏在表面内部的一段附加距离的光线传播。该传播距离对每一种波长都是独立的。它可以对每一种颜色通道具有独立聚焦性质的 系统进行建模,例如数字投影仪。 |
US_OGIVE |
尖顶部(Ogive)面型。Ogive面与标准面一样,除了表面沿轴旋转有一 定量的偏移以外。表面矢高的形式为: 其中, |
US_POLARIZATION | 这2个DLL显示如何定义电场或膜层。不同之处在于US_POLARIZATION基于数据结构FIXED_DATA2,而电场数据则通过成员double dbreserved[]进行交换。US_POLARIZATION2基于数据结构FIXED_DATA5,电场数据通过成员双Exr、Exi、Eyr、Eyi、Ezr、Ezi进行交换。 |
US_POLARIZATION2 | |
US_STAND | 此DLL是Zemax"标准"面类型的复刻。它是最简单的DLL表面,并且是学习UDS DLL的一个很好的开始案例。 |
US_STAND2 | 此DLL是Zemax"标准"面类型的复刻,使用"UserDefinedSurface2"函数和结构定义。 |
US_ZERNIKE+MSF |
模拟Zernike Standard矢高(Zernike Standard Sag)表面并描述额外的波纹术语。矢高图的偶次非球面部分定义为 ![]() a2、a4 ...... a16的长度单位是-1、-3...-15。A的单位是长度。ω0的单位是长度的倒数。φ0在输入时的单位是度数,但在上面的表达式中转换为弧度进行计算。 了解有关如何使用此DLL的更多详情,请参阅知识库文章构造评估和公差操作的中空间频率加工误差(Constructing mid-spatial frequency tooling errors for evaluation and tolerancing)。 |
Lumerical-metalens-xxxxxx | 这个DLL可对超透镜元件建模。要使用此DLL,用户必须首先从Lumerical模拟并生成超透镜数据,然后将数据读入此DLL。输入文件可以是一对扩展名为.pmap和.aph的文件,也可以是一个扩展名为.h5的文件。输入文件应位于\Document\Zemax\DLL\Surfaces\文件夹中。要加载输入文件,我们只需在用户自定义表面的注释中键入文件名即可。如果输入的是一对文件(.pmap和.aph),则只需在注释栏中键入文件名即可。有关超透镜工作流程的更多指导,请参阅应用库文章大规模超透镜 - 光线传播(Large-Scale Metalens – Ray Propagation)。 |
r/c/m: | 3 | 2 | 1 | 参数 |
0 | 0 | 0 | 0 | |
0 | 0 | 1 | 1 | |
0 | 0 | 2 | 2 | |
0 | 1 | 0 | 3 | |
0 | 1 | 1 | 4 | |
0 | 1 | 2 | 5 | |
0 | 2 | 0 | 6 | |
... |
编译示例
要为用户自定义的代码编译DLL,请参阅知识库文章如何编译用户自定义的DLL(How to compile a User-Defined DLL)。此外,还有一个基于Visual Studio C++的示例项目,位于{Zemax}\DLL\Surfaces\Solution\AllProjects\。
下一部分: