Surface Overview#

Surfaces are core elements of Optiland’s optical system. Each surface represents an optical interface, defined by its geometry, material properties, coatings, and optional apertures. Surfaces are organized into a Surface Group to manage operations on multiple surfaces.

Surface Components#

A surface consists of several components that define its optical properties:

  • Geometry: The shape of the surface (e.g., planar, spherical, aspheric, freeform). This includes the surface’s coordinate system.

  • Materials: The material type before and after the surface, which determines the refractive index and extinction coefficient.

  • Coatings: Coatings (e.g., thin films) applied to the surface for modifying reflection, transmission, and/or polarization properties.

  • Stop Surface Flag: Indicates if the surface is the aperture stop of the system.

  • Interaction Model: Defines how a ray interacts with the surface (e.g., refraction, reflection). For more details, see the Interaction Models section.

  • Physical Aperture (optional): A physical or virtual aperture defining the area where rays can interact with the surface.

  • BSDF (optional): Bidirectional Scattering Distribution Function for modeling scattering behavior.

Paraxial Surfaces#

Optiland handles paraxial surfaces not as a distinct class, but through a ThinLensInteractionModel that can be applied to a standard Surface. This model simplifies the surface to an ideal thin lens with a given focal length. This approach allows for first-order layouts and analysis. A Surface with a ThinLensInteractionModel can be converted into a thick lens equivalent using the convert_to_thick_lens function in optiland.surfaces.converters.

Ray Interaction with Surfaces#

When a ray interacts with a surface, the following steps are typically performed:

  1. Intersection: The ray’s path is intersected with the surface’s geometry.

  2. Aperture Check: The ray’s intersection point is checked against the surface’s aperture to determine if the ray is blocked.

  3. Refraction/Reflection: The ray’s direction is updated based on Snell’s law or the law of reflection, and the ray properties may be affected by the surface’s material/coating properties.

  4. Scattering: If the surface has a BSDF, the ray may be scattered based on the scattering distribution function.

  5. Recording: During a trace, each Surface temporarily stores the ray data at the intersection point.

Surface Group#

Surfaces are combined into a Surface Group, which manages a collection of surfaces and facilitates operations like ray tracing. The Surface Group:

  • Tracks the ordered list of surfaces in the optical system.

  • Propagates rays through the system, invoking surface-specific logic at each step.

  • Aggregates ray trace history from all surfaces, providing a complete picture of the ray paths.

  • Exposes methods for adding, removing, and modifying surfaces in the system.

Tip

The Surface Group allows efficient iteration over multiple surfaces, simplifying complex ray tracing operations.

Surface Factories#

To streamline surface creation, Optiland uses a multi-factory pattern, with distinct factories for different components:

  • SurfaceFactory: The main factory that orchestrates the creation of Surface objects.

  • GeometryFactory: Creates different geometry types (e.g., StandardGeometry, ToroidalGeometry).

  • MaterialFactory: Handles the creation of materials.

  • CoatingFactory: Manages the creation of coatings.

This granular approach makes the system more modular and extensible.

Extensibility#

The surface framework is designed for extensibility:

  • Custom geometries, coatings, or aperture definitions can be added by subclassing existing components. These may be added to any surface instance.

  • The factories can be extended to handle new component types.

For more detailed information on surface geometry and coatings, see their dedicated sections in this guide.

How to Extend This#

Scenario: Add a new surface geometry type to Optiland.

Step 1: Create a new file in optiland/geometries/my_geometry.py. Step 2: Subclass BaseGeometry (closed-form intersection) or NewtonRaphsonGeometry (iterative intersection) and implement distance(rays), sag(x, y), and surface_normal(rays). Step 3: Register in optiland/geometries/__init__.py. Step 4: Add the geometry type string to optiland/surfaces/factories/geometry_factory.py for JSON serialisation support. Step 5: Add tests in tests/test_geometries/test_my_geometry.py.

For a complete worked example, see Tutorial 8a: Custom Surface Types. For step-by-step guidance, see Extension Recipes.