from __future__ import annotations
import os
import numpy as np
from skZemax.skZemaxClass import skZemaxClass
skZemax = skZemaxClass()
# Open file
skZemax.Utilities_OpenZemaxFile(
skZemax.SamplesDir() + os.sep + r"Sequential\Objectives\Cooke 40 degree field.zmx",
False,
)
# Lockdown the sample sheet to do new things with it...
skZemax.System_Lockdown(usePrecisionRounding=True, decimalPrecision=2)
# recreate the functionality of the tilt/decenter elements tool
# apply coordinate breaks around the 2nd lens element (surf 3/4)
skZemax.LDE_ChangeSurfaceType(skZemax.LDE_InsertNewSurface(3), "CoordinateBreak")
skZemax.LDE_ChangeSurfaceType(skZemax.LDE_InsertNewSurface(6), "CoordinateBreak")
skZemax.LDE_GetSurface(3).Comment = "CB1"
skZemax.LDE_GetSurface(6).Comment = "CB2"
# insert a dummy surface after 2nd CB
skZemax.LDE_InsertNewSurface(7).Thickness = skZemax.LDE_GetSurface(
5
).Thickness # the dummy carries the original thickness
skZemax.LDE_GetSurface(7).Comment = "Dummy"
# we're going to play with the STOP surface position, so let's put STOP on surf 1
skZemax.LDE_SetSurfaceAsStop(1)
# create position solve
skZemax.Solver_LDESurfaceProperty_ForValue(
in_surface=5,
property="thickness",
solve_type="position",
params={"FromSurface": 3, "Length": 0},
)
# create pickup solve
skZemax.Solver_LDESurfaceProperty_ForValue(
in_surface=6,
property="thickness",
solve_type="surfacepickup",
params={
"Surface": 5,
"ScaleFactor": -1,
"Offset": 0,
"Column": skZemax.LDE_GetSurfaceColumnEnum("Thickness"),
},
)
# set pickup solves for coordinate break tilt/decenter parameter cells
# these parameters are columns 12-16 in the Lens Data Editor (parameters 1-5)
#
# Note, I convert names into parameter index with skZemax.LDE_GetSurfaceColumnEnum().
surf6 = skZemax.LDE_GetSurface(6)
surf3 = skZemax.LDE_GetSurface(3)
for prop in [
"Decenter X",
"Decenter Y",
"Par3",
"Par4",
"Par5",
]: # Switching to Par# notation for example, but can be "Tilt About X/Y/Z" instead.
skZemax.Solver_LDESurfaceProperty_ForValue(
in_surface=surf6,
property=prop,
solve_type="surfacepickup",
params={
"Surface": 3,
"ScaleFactor": -1,
"Offset": 0,
"Column": skZemax.LDE_GetSurfaceColumnEnum(prop, surf3),
},
) # Don't need surf3 input for 'Par#' names
# assign random tilt/decenter values (the pickups above should undo the tilt/decenter)
for par in ["Par1", "Par2", "Par3", "Par4", "Par5"]:
surf3.GetCellAt(
int(skZemax.LDE_GetSurfaceColumnEnum(par))
).DoubleValue = np.random.uniform(-0.1, 0.01)
# also, set the 'order' flag for CB#2
surf6.GetCellAt(int(skZemax.LDE_GetSurfaceColumnEnum("Order", surf6))).IntegerValue = 1
# We now get the global rotation matrix at surface 5.
_, R = skZemax.LDE_GetObjectRotationAndPositionMatrices(5)
skZemax.Visualization_SEQ_ShadedModel(
save_image=True,
saved_image_location=skZemax.Utilities_skZemaxExampleDir()
+ os.sep
+ r"e07_TiltDecenterAndMFOperand_Shaded.png",
)
skZemax.Utilities_SaveZemaxFileAs(
skZemax.Utilities_skZemaxExampleDir() + os.sep + r"e07_TiltDecenterAndMFOperand.zmx"
)
del skZemax
skZemax = None