Imported from keshuaixu/illulu (
AGENTS.md). Install upstream withnpx skills add keshuaixu/illulu. Copyright stays with the author.
Illulu
Build a macOS-first desktop geometric optics playground for illumination engineers.
Use ~/ray-optics as the reference implementation for 2D geometric optics math, ray behavior, units, and general visual tone. Match its optics behavior closely, but do not copy its web architecture, scene editor complexity, or user-defined optics system.
Product Goal
Create a fast, GPU-rendered desktop tool for exploring off-the-shelf optical parts from Thorlabs and Edmund Optics. Optimize for quick library browsing, immediate ray-trace feedback, and a simpler workflow than ~/ray-optics.
The target user is an engineer evaluating catalog optics, not a student building custom optical scenes from scratch.
Stack
- Language:
C++20 - Build system:
CMake - GUI:
Dear ImGui - Windowing/input/app shell:
SDL3 - Rendering:
Metalon macOS
Design the code so alternate render backends can be added later, but do not spend v1 effort on cross-platform rendering abstraction beyond what is needed to keep the code clean.
V1 Scope
- Support
2Doptics only. - Treat the optics library as a filesystem directory tree of Zemax
.zmxand.zarfiles. - Use
./zmxas the initial prototype library root and only guarantee support for the example objects shipped there. - Focus on sequential Zemax-derived optical systems that reduce cleanly to a 2D cross-section.
- Prioritize spherical and even-aspheric catalog lenses commonly shipped by Thorlabs and Edmund Optics.
- For the initial prototype, support one light source type only: a random multi-mode fiber source.
- Do not write converted, cached, or intermediate library files back to disk.
Explicit Non-Goals
- No user-defined lens authoring.
- No arbitrary equation-defined optics.
- No 3D optics.
- No non-sequential Zemax support in v1.
- No scripting or plugin system in v1.
- No effort spent recreating the full object toolbox from
~/ray-optics. - No persistent import cache, generated library database, or saved intermediate representation of catalog parts.
- No prototype support beyond the optical parts present in
./zmx. - No light-source types other than the random multi-mode fiber source in the initial prototype.
Reference Rules
- Treat
~/ray-opticsas the math oracle for ray propagation, intersection logic, refraction/reflection behavior, sign conventions, and sequential lens interpretation. - Reuse the same underlying optics assumptions wherever practical.
- Keep a similar dark, technical display style, but build a desktop-native interaction model centered on import, inspect, place, and simulate.
- The prototype should browse the local Zemax library tree rather than depend on a custom authored part database.
- Prefer a simpler UI than
~/ray-optics, with fewer editing modes and less scene authoring overhead.
Required Architecture
Organize the implementation into distinct subsystems:
-
Importer- Read
.zmxfiles directly from the library tree. - Support
.zarby extracting supported Zemax payloads into the same normalization pipeline without saving extracted intermediate files. - Normalize imported data into internal optical models.
- Preserve warnings for unsupported or ignored metadata.
- Fail fast with clear diagnostics when the file uses unsupported Zemax features.
- For the initial prototype, only the sample files under
./zmxneed to be supported end to end.
- Read
-
Optics Core- Pure C++ library for surfaces, materials, transforms, apertures, and 2D ray tracing.
- Keep import parsing separate from ray-tracing math.
- Make the core testable without the UI.
-
Renderer and UI- Use GPU rendering for optics geometry, rays, overlays, and selection feedback.
- Use Dear ImGui for panels, inspectors, import controls, and simulation settings.
- Keep the main canvas as the primary experience, not an embedded preview inside heavy chrome.
-
Library Browser- Treat the directory tree of
.zmxand.zarfiles as the source of truth. - Index or scan the tree in memory only.
- Expose vendor metadata, source file identity, parsed surface data, and import warnings in the UI without generating persistent library artifacts.
- Treat the directory tree of
Data Model Expectations
Define clear internal types for:
ImportResult: normalized optics data, metadata, warnings, and hard errorsLensAssembly: placed optical part composed of ordered surfaces and gapsSurface: curvature, conic/asphere terms, aperture, material transition, and axial positionMaterial: refractive data derived from vendor/Zemax information or explicit fallback values
Imported source data should remain distinct from editable scene state. The app should place and inspect imported assemblies, not mutate raw imported lens definitions in place. Do not introduce a saved intermediate catalog format for the prototype.
UX Requirements
- Start from an immediate canvas-first workflow.
- Let the user browse and open optical parts from the local
./zmxtree. - Support fast pan, zoom, fit-to-part, selection, and inspection.
- Provide a library browser, scene tree, property inspector, and simulation controls.
- Show import warnings and unsupported-feature diagnostics clearly.
- Render optics outlines and traced rays in real time with a display style broadly similar to
~/ray-optics. - Provide controls for the random multi-mode fiber light source and no other source family in the initial prototype.
Verification Requirements
The implementation should prove correctness with:
- parser fixtures for the representative
.zmxsamples in./zmx - archive import fixtures for the supported
.zarsamples in./zmx - regression tests comparing ray paths against
~/ray-opticson shared optical fixtures - tests for unsupported Zemax records producing actionable errors
- tests that directory-tree discovery does not require generating intermediate library files
- tests covering the random multi-mode fiber source distribution and ray emission constraints
- rendering checks for lens outlines, ray intersections, and selection overlays
- basic interaction/performance checks showing smooth use on typical imported catalog assemblies
Success Criteria
V1 is successful when a user can browse the local ./zmx library tree, open a supported example Zemax part, place it in a 2D scene, emit rays from the random multi-mode fiber source, trace those rays with behavior consistent with ~/ray-optics, inspect the imported optical data, and interact with the scene smoothly through a clean desktop UI.