Skip to main content

ZOS-API interface 2024 R2 SP02

PythonStandalone_09_NSC_CAD

Last update: 17.07.2025
1import clr, os, winreg
2from itertools import islice
3
4class PythonStandaloneApplication(object):
5 class LicenseException(Exception):
6 pass
7 class ConnectionException(Exception):
8 pass
9 class InitializationException(Exception):
10 pass
11 class SystemNotPresentException(Exception):
12 pass
13
14 def __init__(self, path=None):
15 # determine location of ZOSAPI_NetHelper.dll & add as reference
16 aKey = winreg.OpenKey(winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER), r"Software\Zemax", 0, winreg.KEY_READ)
17 zemaxData = winreg.QueryValueEx(aKey, 'ZemaxRoot')
18 NetHelper = os.path.join(os.sep, zemaxData[0], r'ZOS-API\Libraries\ZOSAPI_NetHelper.dll')
19 winreg.CloseKey(aKey)
20 clr.AddReference(NetHelper)
21 import ZOSAPI_NetHelper
22
23 # Find the installed version of OpticStudio
24 if path is None:
25 isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize()
26 else:
27 # Note -- uncomment the following line to use a custom initialization path
28 isInitialized = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize(path)
29
30 # determine the ZOS root directory
31 if isInitialized:
32 dir = ZOSAPI_NetHelper.ZOSAPI_Initializer.GetZemaxDirectory()
33 else:
34 raise PythonStandaloneApplication.InitializationException("Unable to locate Zemax OpticStudio. Try using a hard-coded path.")
35
36 # add ZOS-API referencecs
37 clr.AddReference(os.path.join(os.sep, dir, "ZOSAPI.dll"))
38 clr.AddReference(os.path.join(os.sep, dir, "ZOSAPI_Interfaces.dll"))
39 import ZOSAPI
40
41 # create a reference to the API namespace
42 self.ZOSAPI = ZOSAPI
43
44 # create a reference to the API namespace
45 self.ZOSAPI = ZOSAPI
46
47 # Create the initial connection class
48 self.TheConnection = ZOSAPI.ZOSAPI_Connection()
49
50 if self.TheConnection is None:
51 raise PythonStandaloneApplication.ConnectionException("Unable to initialize .NET connection to ZOSAPI")
52
53 self.TheApplication = self.TheConnection.CreateNewApplication()
54 if self.TheApplication is None:
55 raise PythonStandaloneApplication.InitializationException("Unable to acquire ZOSAPI application")
56
57 if self.TheApplication.IsValidLicenseForAPI == False:
58 raise PythonStandaloneApplication.LicenseException("License is not valid for ZOSAPI use")
59
60 self.TheSystem = self.TheApplication.PrimarySystem
61 if self.TheSystem is None:
62 raise PythonStandaloneApplication.SystemNotPresentException("Unable to acquire Primary system")
63
64 def __del__(self):
65 if self.TheApplication is not None:
66 self.TheApplication.CloseApplication()
67 self.TheApplication = None
68
69 self.TheConnection = None
70
71 def OpenFile(self, filepath, saveIfNeeded):
72 if self.TheSystem is None:
73 raise PythonStandaloneApplication.SystemNotPresentException("Unable to acquire Primary system")
74 self.TheSystem.LoadFile(filepath, saveIfNeeded)
75
76 def CloseFile(self, save):
77 if self.TheSystem is None:
78 raise PythonStandaloneApplication.SystemNotPresentException("Unable to acquire Primary system")
79 self.TheSystem.Close(save)
80
81 def SamplesDir(self):
82 if self.TheApplication is None:
83 raise PythonStandaloneApplication.InitializationException("Unable to acquire ZOSAPI application")
84
85 return self.TheApplication.SamplesDir
86
87 def ExampleConstants(self):
88 if self.TheApplication.LicenseStatus == self.ZOSAPI.LicenseStatusType.PremiumEdition:
89 return "Premium"
90 elif self.TheApplication.LicenseStatus == self.ZOSAPI.LicenseStatusTypeProfessionalEdition:
91 return "Professional"
92 elif self.TheApplication.LicenseStatus == self.ZOSAPI.LicenseStatusTypeStandardEdition:
93 return "Standard"
94 else:
95 return "Invalid"
96
97 def reshape(self, data, x, y, transpose = False):
98 """Converts a System.Double[,] to a 2D list for plotting or post processing
99
100 Parameters
101 ----------
102 data : System.Double[,] data directly from ZOS-API
103 x : x width of new 2D list [use var.GetLength(0) for dimension]
104 y : y width of new 2D list [use var.GetLength(1) for dimension]
105 transpose : transposes data; needed for some multi-dimensional line series data
106
107 Returns
108 -------
109 res : 2D list; can be directly used with Matplotlib or converted to
110 a numpy array using numpy.asarray(res)
111 """
112 if type(data) is not list:
113 data = list(data)
114 var_lst = [y] * x;
115 it = iter(data)
116 res = [list(islice(it, i)) for i in var_lst]
117 if transpose:
118 return self.transpose(res);
119 return res
120
121 def transpose(self, data):
122 """Transposes a 2D list (Python3.x or greater).
123
124 Useful for converting mutli-dimensional line series (i.e. FFT PSF)
125
126 Parameters
127 ----------
128 data : Python native list (if using System.Data[,] object reshape first)
129
130 Returns
131 -------
132 res : transposed 2D list
133 """
134 if type(data) is not list:
135 data = list(data)
136 return list(map(list, zip(*data)))
137
138if __name__ == '__main__':
139 zos = PythonStandaloneApplication()
140
141 # load local variables
142 ZOSAPI = zos.ZOSAPI
143 TheApplication = zos.TheApplication
144 TheSystem = zos.TheSystem
145
146 if not os.path.exists(TheApplication.SamplesDir + "\\API\\Python"):
147 os.makedirs(TheApplication.SamplesDir + "\\API\\Python")
148
149
150 #! [e09s01_py]
151 # Open new Non-Sequential system and save
152 TheSystem = TheApplication.CreateNewSystem(ZOSAPI.SystemType.NonSequential) # Create New NSC File
153 filename = TheApplication.SamplesDir + "\\API\\Python\\e09_NSC_CAD.zos" # Define file path and name
154 TheSystem.SaveAs(filename) # Save New NSC File
155 #! [e09s01_py]
156
157 #! [e09s02_py]
158 # Insert CAD object
159 NSCE = TheSystem.NCE
160 Obj1 = NSCE.GetObjectAt(1)
161 Obj1.ZPosition = -5
162 Obj1_Type = Obj1.GetObjectTypeSettings(ZOSAPI.Editors.NCE.ObjectType.CADPartSTEPIGESSAT) # create CAD object type
163 # Set object 1 as ExtPoly.stp if it exists in proper directory. The directory is defined under OpticStudio Preferences...Folders...Objects
164 if os.path.isfile(TheApplication.ObjectsDir + "\\CAD Files\\ExtPoly.stp"): # Check if the CAD part exists in correct directory
165 Obj1_Type.FileName1 = 'ExtPoly.stp' # set CAD file to be used (file must be in valid directory)
166 Obj1.ChangeType(Obj1_Type) # Set Object 1 as the previously specified CAD file
167 else:
168 raise ImportError("CAD file not found")
169 #! [e09s02_py]
170
171 #! [e09s03_py]
172 # Access the CAD settings for object 1
173 Obj1_CAD = Obj1.CADData
174
175 # Determine if the surface-to-face mapping is available for this object. If yes, update the mapping
176 if Obj1_CAD.HasFaceData:
177 if Obj1_CAD.NumberOfSurfaces > 1:
178 # Assign the last face to surface 0. Now, the first and last surfaces will be defined with the same scatter and coating properties.
179 Obj1_CAD.SetSurfaceFace(0, Obj1_CAD.NumberOfSurfaces-1)
180 #! [e09s03_py]
181
182 #! [e09s04_py]
183 POBfile = open(TheApplication.ObjectsDir + "\\Polygon Objects\\API_cube_demo.POB", "w") # Open new POB file
184 # Append new POB file with polygon definitions (see help files for syntax information)
185 POBfile.write("! A cube" '\n')
186 POBfile.write("! front face vertices" '\n' "V 1 -1 -1 0" '\n' "V 2 1 -1 0" '\n' "V 3 1 1 0" '\n' "V 4 -1 1 0" '\n')
187 POBfile.write("! back face vertices" '\n' "V 5 -1 -1 2" '\n' "V 6 1 -1 2" '\n' "V 7 1 1 2" '\n' "V 8 -1 1 2" '\n')
188 POBfile.write("! Front" '\n' "R 1 2 3 4 0 0" '\n' "! Back" '\n' "R 5 6 7 8 0 0" '\n')
189 POBfile.write("! Top" '\n' "R 4 3 7 8 0 0" '\n' "! Bottom" '\n' "R 1 2 6 5 0 0" '\n')
190 POBfile.write("! Left Side" '\n' "R 1 4 8 5 0 0" '\n' "! Right Side" '\n' "R 2 3 7 6 0 0")
191 POBfile.close()
192 Obj2 = NSCE.InsertNewObjectAt(2) # Add new line to NSCE
193 Obj2_Type = Obj2.GetObjectTypeSettings(ZOSAPI.Editors.NCE.ObjectType.PolygonObject)
194 Obj2_Type.FileName1 = "API_cube_demo.POB"
195 Obj2.ChangeType(Obj2_Type)
196 #! [e09s04_py]
197
198 TheSystem.Analyses.New_Analysis(ZOSAPI.Analysis.AnalysisIDM.NSC3DLayout)
199 TheSystem.Save() # Save NSC File
200
201
202 # This will clean up the connection to OpticStudio.
203 # Note that it closes down the server instance of OpticStudio, so you for maximum performance do not do
204 # this until you need to.
205 del zos
206 zos = None
Definition: ZemaxService.cs:198

Connect with Ansys