iso10110.elements#

ISO 10110 Lens Element Inference

Infers lens elements (singlets, cemented doublets, etc.) from an optic’s surface sequence. Optiland is purely surface-based; there is no first-class LensElement concept. This module derives elements by grouping consecutive glass-bounded surface intervals.

Bernhard Lutzer, 2026

Functions

identify_elements(optic)

Infer lens elements from optic's surface sequence.

is_air(material)

Return True if material is air or vacuum (n ≈ 1).

Classes

LensElement(surfaces, surface_indices)

A logical lens element inferred from a consecutive run of glass surfaces.

class LensElement(surfaces: list[Surface], surface_indices: list[int])[source]#

A logical lens element inferred from a consecutive run of glass surfaces.

A singlet has two bounding surfaces and one glass segment. A cemented doublet has three surfaces and two glass segments (the middle surface is the cement interface). In general an N-component cemented group has N+1 surfaces.

Variables:
  • surfaces (list[Surface]) – Ordered list of Surface objects that bound this element, including the final air-exit surface.

  • surface_indices (list[int]) – Corresponding global indices in the SurfaceGroup.

center_thickness(optic) → float[source]#

Total on-axis thickness of the element (front vertex to rear vertex).

component_thicknesses(optic) → list[float][source]#

Center thickness of each individual glass component.

property glass_materials#

List of glass materials, one per component (excludes trailing air).

property is_cemented: bool#

True if this element consists of more than one glass component.

max_semi_aperture(optic: Optic) → float[source]#

Return the maximum semi-aperture across all surfaces of this element.

property num_components: int#

Number of individual glass pieces (1 for singlet, 2 for doublet…).

radii() → list[float][source]#

Radius of curvature for every surface (including the air-exit surface).

semi_aperture(surf_local_idx: int, optic: Optic) → float[source]#

Return the semi-aperture of a surface within this element.

An explicitly configured physical aperture (e.g. RadialAperture) takes priority, since it defines the actual manufactured/clipped edge of the surface — this matters both when it is smaller than the ray bundle (vignetting: the drawing must show the true, smaller mechanical edge, not the unclipped ray height) and when it is larger (an intentionally oversized blank). Falls back to semi_aperture populated by optic.updater.update_paraxial(), and finally to a direct paraxial marginal-ray estimate when neither is available.

Parameters:
  • surf_local_idx – 0-based index within this element’s surface list.

  • optic – The parent optic (used for the paraxial fallback).

surface_indices: list[int]#
surfaces: list[Surface]#
identify_elements(optic: Optic) → list[LensElement][source]#

Infer lens elements from optic’s surface sequence.

Skips the object surface (index 0) and the image surface (index -1). Consecutive surfaces whose material_post is glass (n > 1.01) are grouped into a single LensElement. The final surface of each element is the one whose material_post transitions back to air.

This grouping is purely a glass/air-transition heuristic and does not understand reflective (mirror) surfaces or images immersed in a non-air medium — both configurations emit a UserWarning and may yield a missing or incomplete element list rather than raising, since mirror support is not implemented yet.

Returns:

List of LensElement in optical order.

is_air(material) → bool[source]#

Return True if material is air or vacuum (n ≈ 1).