zemax光学设计笔记[5]-ZPL或ZOS-API的简单使用
zemax的编程功能简介
An application programming interface (ZOS-API) has been developed for OpticStudio that enables connections to, and customization of, the application using the latest software technology. While ZOS-API relies on a COM interface, it is rooted in .NET libraries, and as such programming with the API can be done using either C++ (COM) or C# (.NET) – depending on the user’s comfort with either language.
可以直接使用ZPL宏(Zemax Programming Language)在ZEMAX内编程,也可以使用提供的ZOS-API在外部编程然后连接进入ZEMAX,其有如下四种方式:
- 独立应用程序模式Standalone Mode
- 自定义扩展模式User Extensions Mode
- 自定义操作数模式User Operands Mode
- 自定义分析模式User Analysis Mode
支持的语言有:ZPL,C#,C++,MATLAB,Python。
ZPL快速使用
ZPL与BASIC语言类似,表达式之前不需要声明变量.表达式结尾不需要 特殊终止符(如 C 语言中的“;”)。因此,每条 ZPL 命令必须独占一行。ZPL内置示例文件:
编程->新建宏
x=5
PRINT "Hello ZPL编程,x=",x
然后另存为到~/Zemax/Macros/hello_zpl.ZPL,编程->编辑/执行选择刚才的文件执行.
ZOS-API快速使用
本文主要关注ZOS-API与C++的协作
连接ZOS-API
有两种不同方法连接到ZOS-API
- 用户的应用程序是“独立”的,并且将在执行期间启动ZemaxOpticStudio。
- Zemax OpticStudio 已经在运行,并且将“调用”用户的(“固有”)应用程序。
固有应用程序(ZOS Inherent(ZOS uses your Application))
- 自定义扩展 User Extension
- 自定义分析 User Analyses
- 自定义操作数 User Operand
这些均被视为“固有”程序,表示 ZOS 使用已编译的应用程序。
(不用看)配置Visual Studio Code编译C++并连接到ZOS-API(其实VSCODE不能用sln解决方案文件,这个是ZEMAX傲娇了,还是需要安装Visual Studio😭)
正确的操作是, ZOSAPI.dll 和 ZOSAPI_Interfaces.dll 必须保留在 OpticStudio 安装目录中。另一方面, ZOSAPI_NetHelper.dll 应始终位于运行应用程序的目录中。这意味着,如果您在开发自定义 分析、自定义操作数或自定义扩展程序,ZOSAP I_NetHelper.dll 应该与您的插件一起复制到 合适的位置。
Visual Studio Code安装C/C++(Microsoft),C/C++ Compile Run(danielpinto8zz6),Code Runner(Jun Han)三个插件
文件->首选项->设置搜索runInTerminal,勾选C-cpp-compile-run:Run-in-external-terminal和Code-runner:Run-In Terminal
安装MinGW-w64,看到
即安装成功,然后重启VS Code
新建文件hello.cpp
#include <iostream>
int main(void){
std::cout<<"hello world";
}
信任此工作区
右键,点击Run Code
(不用看)配置Code Runner插件的编译选项,连接ZOSAPI.dll,ZOSAPI_interfaces.dll和ZOSAPI_NetHelper.dll
上面几个dll文件可以用系统搜索寻找
同目录下新建.code-workspace
{
"folders": [
{
"path": "."
}
],
"settings": {
"code-runner.executorMap": {
"cpp": "cd $dir && gcc -std=c++20 -ld D:\\Zemax OpticStudio\\ZOSAPI.dll -ld D:\\Zemax OpticStudio\\ZOSAPI_interface.dll -ld C:\\Users\\mac\\Documents\\Zemax\\ZOS-API Projects\\CppStandaloneApplication\\CppStandaloneApplication\\ZOSAPI_NetHelper.dll -o .\\bin\\$fileNameWithoutExt.exe && .\\bin\\$fileNameWithoutExt.exe"
},
"files.associations": {
"ostream": "cpp"
}
}
}
TLB文件
tlb文件是一个说明文件,通过TLB文件,用户可以得知你的DLL中的COM接口以及常量等信息。其可以单独发行,也可以作为组建DLL中的一个资源随组件一起发行。你可以在VS的Object Browser中看到该文件中包括哪些常数、接口、类,而每个类又包括什么方法和属性。微软提供的各种SDK中通常包括一个或数个TLB文件以方便编程。
安装Visual Studio 2022 Community
[https://blog.csdn.net/candy5204/article/details/124950279]
下载地址
下载下来的是一个下载器
安装过程:下载器->安装器
以下是用Visual Studio实现的
Zemax中编程->C++->独立应用程序
会自动打开一个项目目录,进入CppStandaloneApplicatioin,复制ZOSAPI_NetHelper.dll文件到代码文件夹,
同目录下已经存在zosapi.h文件
CppStandaloneApplication.cpp
// CppStandaloneApplication.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <ctime>
#include <functional>
#include <assert.h>
// Note - .tlh files will be generated from the .tlb files (above) once the project is compiled.
// Visual Studio will incorrectly continue to report IntelliSense error messages however until it is restarted.
#include "zosapi.h"
using namespace std;
using namespace ZOSAPI;
using namespace ZOSAPI_Interfaces;
void handleError(std::string msg);
void logInfo(std::string msg);
void finishStandaloneApplication(IZOSAPI_ApplicationPtr TheApplication);
int main(void) {
std::cout << "ok!\n";
}
int RunApplication()
{
CoInitialize(NULL);
// Create the initial connection class
IZOSAPI_ConnectionPtr TheConnection(__uuidof(ZOSAPI_Connection));
// Attempt to create a Standalone connection
IZOSAPI_ApplicationPtr TheApplication = TheConnection->CreateNewApplication();
if (TheApplication == nullptr)
{
handleError("An unknown error occurred!");
return -1;
}
// Check the connection status
if (!TheApplication->IsValidLicenseForAPI)
{
handleError("License check failed!");
return -1;
}
if (TheApplication->Mode != ZOSAPI_Mode::ZOSAPI_Mode_Server)
{
handleError("Standlone application was started in the incorrect mode!");
return -1;
}
IOpticalSystemPtr TheSystem = TheApplication->PrimarySystem;
// Add your custom code here...
// creates a new API directory
CreateDirectory(_bstr_t(TheApplication->SamplesDir + "\\API"), NULL);
CreateDirectory(_bstr_t(TheApplication->SamplesDir + "\\API\\CPP"), NULL);
// Set up primary optical system
_bstr_t sampleDir = TheApplication->SamplesDir;
_bstr_t testFile = sampleDir + (_bstr_t)"\\API\\CPP\\e01_new_file_and_quickfocus.zmx";
// Make new file
TheSystem->New(false);
TheSystem->SaveAs(testFile);
ISDMaterialCatalogDataPtr(TheSystem->SystemData->MaterialCatalogs)->AddCatalog("SCHOTT");
// Aperture
ISystemDataPtr TheSystemData = TheSystem->SystemData;
TheSystemData->Aperture->ApertureValue = 40;
// Fields
IFieldPtr Field_1 = TheSystemData->Fields->GetField(1);
IFieldPtr NewField_2 = TheSystemData->Fields->AddField(0, 5.0, 1.0);
// Wavelength preset
bool slPreset = TheSystemData->Wavelengths->SelectWavelengthPreset(WavelengthPreset_d_0p587);
// Lens data
ILensDataEditorPtr TheLDE = TheSystem->LDE;
TheLDE->InsertNewSurfaceAt(2);
TheLDE->InsertNewSurfaceAt(2);
ILDERowPtr Surface_1 = TheLDE->GetSurfaceAt(1);
ILDERowPtr Surface_2 = TheLDE->GetSurfaceAt(2);
ILDERowPtr Surface_3 = TheLDE->GetSurfaceAt(3);
// Changes surface cells in LDE
Surface_1->Thickness = 50.0;
Surface_1->Comment = "Stop is free to move";
Surface_2->Radius = 100.0;
Surface_2->Thickness = 10.0;
Surface_2->Comment = "front of lens";
Surface_2->Material = "N-BK7";
Surface_3->Comment = "rear of lens";
// Solver
ISolveDataPtr Solver = Surface_3->RadiusCell->CreateSolveType(SolveType_FNumber);
Solver->_S_FNumber->FNumber = 10;
Surface_3->RadiusCell->SetSolveData(Solver);
// QuickFocus
IQuickFocusPtr quickFocus = TheSystem->Tools->OpenQuickFocus();
quickFocus->Criterion = QuickFocusCriterion_SpotSizeRadial;
quickFocus->UseCentroid = true;
ISystemToolPtr baseTool = quickFocus;
baseTool->RunAndWaitForCompletion();
baseTool->Close();
// Save and close
TheSystem->Save();
// Clean up
finishStandaloneApplication(TheApplication);
return 0;
}
void handleError(std::string msg)
{
throw new exception(msg.c_str());
}
void logInfo(std::string msg)
{
printf("%s", msg.c_str());
}
void finishStandaloneApplication(IZOSAPI_ApplicationPtr TheApplication)
{
// Note - TheApplication will close automatically when this application exits, so this isn't strictly necessary in most cases
if (TheApplication != nullptr)
{
TheApplication->CloseApplication();
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
return RunApplication();
}
int _tmain(int argc, _TCHAR* argv[])
{
return RunApplication();
}
然后运行
可以设置简单的序列系统,然后使用快速聚焦工具使像面聚焦,并将系统另存为: “e01_new_file_and_quickfocus.zmx”,保存在 Documents\Zemax\Samples\API\CPP.
C++使用ZOS-API与ZEMAX交互
示例文件在:编程->ZOS-API帮助->ZOS-API语法帮助->查看更多示例
zemax新建一个简单序列系统
优化->快速聚焦
保存文件到~\Documents\Zemax\Samples\API\CPP\e01_new_file_and_quickfocus.zmx
编程->C++->独立应用程序
会自动打开VS编辑器,cpp文件中
//大概第50行
// Add your custom code here...
// creates a new API directory
CreateDirectory(_bstr_t(TheApplication->SamplesDir + "\\API"), NULL);
CreateDirectory(_bstr_t(TheApplication->SamplesDir + "\\API\\CPP"), NULL);
// Set up primary optical system
_bstr_t sampleDir = TheApplication->SamplesDir;
_bstr_t testFile = sampleDir + (_bstr_t)"\\API\\CPP\\e01_new_file_and_quickfocus.zmx";
// Make new file
TheSystem->New(false);
TheSystem->SaveAs(testFile);
ISDMaterialCatalogDataPtr(TheSystem->SystemData->MaterialCatalogs)->AddCatalog("SCHOTT");
// Aperture
ISystemDataPtr TheSystemData = TheSystem->SystemData;
TheSystemData->Aperture->ApertureValue = 40;
// Fields
IFieldPtr Field_1 = TheSystemData->Fields->GetField(1);
IFieldPtr NewField_2 = TheSystemData->Fields->AddField(0, 5.0, 1.0);
// Wavelength preset
bool slPreset = TheSystemData->Wavelengths->SelectWavelengthPreset(WavelengthPreset_d_0p587);
// Lens data
ILensDataEditorPtr TheLDE = TheSystem->LDE;
TheLDE->InsertNewSurfaceAt(2);
TheLDE->InsertNewSurfaceAt(2);
ILDERowPtr Surface_1 = TheLDE->GetSurfaceAt(1);
ILDERowPtr Surface_2 = TheLDE->GetSurfaceAt(2);
ILDERowPtr Surface_3 = TheLDE->GetSurfaceAt(3);
// Changes surface cells in LDE
Surface_1->Thickness = 50.0;
Surface_1->Comment = "Stop is free to move";
Surface_2->Radius = 100.0;
Surface_2->Thickness = 10.0;
Surface_2->Comment = "front of lens";
Surface_2->Material = "N-BK7";
Surface_3->Comment = "rear of lens";
// Solver
ISolveDataPtr Solver = Surface_3->RadiusCell->CreateSolveType(SolveType_FNumber);
Solver->_S_FNumber->FNumber = 10;
Surface_3->RadiusCell->SetSolveData(Solver);
// QuickFocus
IQuickFocusPtr quickFocus = TheSystem->Tools->OpenQuickFocus();
quickFocus->Criterion = QuickFocusCriterion_SpotSizeRadial;
quickFocus->UseCentroid = true;
ISystemToolPtr baseTool = quickFocus;
baseTool->RunAndWaitForCompletion();
baseTool->Close();
// Save and close
TheSystem->Save();
编译执行
然后查看~\Documents\Zemax\Samples\API\CPP\e01_new_file_and_quickfocus.ZDA文件,可以看到代码执行效果
😏
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库