ZEMAX Users' Knowledge Base - http://www.zemax.com/kb
How to Compile a User-Defined Surface
http://www.zemax.com/kb/articles/58/1/How-to-Compile-a-User-Defined-Surface/Page1.html
By Mark Nicholson
Published on 3 October 2005
 
This article explains:
  • What user-defined surfaces are
  • How to compile a user-defined surface using Microsoft Visual C++ version 6
  • How to use other compilers

This article is also available in Japanese.


What is a User-Defined Surface?

This article is also available in Japanese.

A surface defines the  boundaries between optical materials. Surfaces can be refractive, reflective, diffractive and gradient index. ZEMAX supports more than 65 different surface types, including very general surface shapes like Polynomial surfaces and Biconic Zernikes.

But, it is often the case that a user wants something tailored specifically to his or her own needs, and this is where the user-defined surface is extremely useful and powerful. You can always raise a feature request for us to add a new surface type for you, but ZEMAX also gives you an interface to do this yourself.

The user-defined surface is a compiled function (strictly speaking, a Windows dll) which can implement any surface shape, phase, transmission function, or gradient index, and any combination of these, that you wish. User-defined surfaces can be parametric, or be based on a datafile, or both.

This article describes the steps required to compile a user-defined surface, using the supplied samples as a starting point. It does not address the specific issues involved in coding the surface, which will be described in a separate article.

Producing such a user-defined surface is relatively easy, provided you have a clear mathematical description of how the surface shape is to be defined, and a little programming experience. We provide sample files to make getting started easy. The hard part is always in knowing what the mathematical functions needed to define the surface are!

The first step, therefore, is to define the specification. Find the surface in ZEMAX which is closest to what you want, and read the description in the manual of this surface. Then write out your specification in the same style. Write a text-based description of the surface, then give the sag equation, phase equation etc as required, and list what parameters in the Lens Data Editor and Extra Data Editor do what. Finally, think what the initial values of these parameters should be when the surface is first used. For example, when you first insert a Standard surface, the radius of curvature is infinite, the thickness is zero, and the conic constant is zero. Think what this "safe data" needs to be for your surface.

Then look in the manual again, in the section on the user-defined surface. You will see that there are many supplied example files. Find the sample file that is closest to what you want, and use this as your starting point. By using a supplied sample as your starting point, you will not need to worry about writing all the code that makes your surface talk to ZEMAX: that is already done. You can concentrate solely on programming your surface.

Once you have found the sample file that is closest to your requirements, copy the source file (the file that ends in .c) and give it a new name. In this example, we are going to say that the  sample file us_arrayeven.c is the closest to our requirements. This file is in the {zemaxroot}/dll folder. This surface defines a rectangular array of even-asphere lenslets. Make a copy of this file, and call it myarray.c


  


Compiling a User-Defined Surface with Microsoft Visual C++ Version 6

First start Microsoft Visual C++ version 6. The click File > New and select a Win32 Dynamic Link Library. Give the project a name, and choose a directory to hold the project files:

The new Project wizrad in Ms Visual C++ version 6

In this case, the project name is My_asphere, Click OK, and then choose to create an empty project:

Create an empty dll project

This means that the project is an empty container waiting for you to add files. In the Explorer tree on the left hand side, select "File View", and right-mouse-click on "Source Files", and select "Add Files from Folder":

Add Files

In the dialog that opens, navigate to {zemaxroot}/dll and select myarray.c. Remember, this is the copy of us_arrayeven.c that you made when you followed the instructions on the bottom of page 1 of this article.

Then, in the project pane above, right-mouse-click on "Header Files", choose "Add Files From Folder", and add the file usersurf.h, which is also in the {zemaxroot}/dll folder. The project pane should now look like this:

After inserting all files
The last thing we have to do before we can start editing our file is to set the code generation options in Microsoft Visual C++ 6. Click on Project>Settings:

Project Settings

Select the project itself in the tree on the left hand side, and in the C/C++ tab choose Category > Code Generation, and then choose Use Run-Time Library > Multithreaded. Then select Build > Set Active Configuration, and choose "Release":

Selecting Release Mode

That's all the configuration that is required! To test that the compiler works, we will make a simple modification. Double-click on my_array.c in the project explorer to open it:

Editing the source file

Find the line in Case 0 that says "strcpy(UD->string,"Even Array");" and change the name of the surface to "My Even Array". The line of text should now read:

strcpy(UD->string,"My Even Array");

and then choose Build > Rebuild All. The dll should compile without error:

It compiles!

Then copy the dll from your project's /release folder into the {zemaxroot}/dll folder.

Now start ZEMAX, and select a surface to be user-defined:

Selecting the surface

In the Lens Data Editor, the name we gave the surface is shown:

The surface is read in correctly
Congratulations! You have compiled a user-defined surface!


Using Other Compilers

Any other C compiler can be used, providing it can create a multi-threaded Windows dll project. There are a huge number of available compilers, and we can't provide technical support on them all. If you are using some other compiler, the question to ask that program's technical support staff is:

How do I create an empty multi-threaded Win32 DLL project?

The steps on the earlier page will be helpful in working this out.


Summary and References
This article has discussed the mechanics of compiling a user-defined surface using Microsoft Visual C++ version 6. It has not described the process of writing a specific surface. This will be discussed in a separate article.