BeamletOpticsGUI.jl
BeamletOpticsGUI is the interactive GUI of BeamletOptics.jl (BMO), a package for non-sequential 3D ray and Gaussian beamlet tracing. It opens a window in which a BMO system and its beams are drawn, the components are moved and rotated with the mouse and keyboard, and the beams and the detector views on the cards of the detectors are updated after each change:
using BeamletOptics, BeamletOpticsGUI, GLMakie
gui = live_view(system, beam)
display(gui)BeamletOpticsGUI sits on BeamletOptics and visualizes its systems. All optics is computed by BeamletOptics; the GUI draws the components and beams with the render! and live_render! functions of BeamletOptics (through their render handle protocol) and adds the interaction.
Installation
BeamletOpticsGUI needs BeamletOptics 0.14 and a Makie backend with a window (GLMakie). It is installed from the General registry:
using Pkg
Pkg.add("BeamletOpticsGUI")
Pkg.add("GLMakie")On a headless Linux machine, run scripts under a virtual display, e.g. xvfb-run -a julia --project=. script.jl.
Order of loading
The order of the packages in using makes a difference. Load GLMakie last:
using BeamletOptics, BeamletOpticsGUI, GLMakieThe window works in any order; the difference is the lag of the first hover, click or drag. BeamletOpticsGUI is precompiled for GLMakie with sessions of mouse and key actions, such that these actions compile little when they are used for the first time. Julia checks precompiled code against the packages that are already loaded, and that code is built with GLMakie loaded after BeamletOpticsGUI. In a session that loads GLMakie first, Julia rejects a part of it and compiles it again at the first use: about twice as much as with GLMakie loaded last (over a whole session of either layout, about 1.5 s instead of 0.8 s of compilation). The same holds for separate using lines and for a startup file that loads GLMakie.
What is in the package
| Page | Content |
|---|---|
| Live view | live_view: the complete window with cards, panels, clip planes, tracing and export |
| Kinematic controls | kinematic_controls!: moving components with the mouse and keyboard |
| View cube | view_cube!: the CAD-style cube for the standard views |
| Cards and widgets | recipes for cards of own component types, own widgets and controls |
| Interactive Michelson interferometer | a complete example |
| API | the exported names |
Design principles
The GUI is developed against four principles. The table states what is met today and what is not. Features in the column "Gap" are planned and are not available.
| # | Principle | State today | Gap |
|---|---|---|---|
| P1 | The GUI sits on BeamletOptics systems and visualizes them. All physics is computed by BeamletOptics. Components can be added and removed in the GUI. One view holds several systems with several beams each. | Met: live_view(sys1 => b1, sys1 => b2, sys2 => b3), solving via solve_system! (each system on its own), components of a System and sources are added from a catalog and removed at runtime, systems are added and removed in the window (add_system!, remove_system!), an object belongs to any number of systems or to none and is drawn once, a source to at most one, see Adding and removing components and Several systems. Adding, removing and changing are part of the undo history. | The objects of a StaticSystem can not be changed. Only components and sources from the catalog can be changed afterwards (page "Edit"); export_script writes their constructors and those of the objects added with code. The glasses of the catalog are data of the GUI until BeamletOptics has a glass catalog. |
| P2 | The layout is built from widgets, one per BeamletOptics type. Widgets without a type are generic windows. | Met for cards (card_rows per type: objects, lenses, beamsplitters, polarizers, detectors, sources, Gaussians, systems) and for generic windows (add_panel!, add_controls!, add_tool!). | The detector view on the card is hard-wired to Detector. The icon per type in the object tree is internal. |
| P3 | Any layout can be assembled from the widgets and presented to the user. | Not met: there are two fixed layouts, chosen by layout = :compact or layout = :app. | Public widget blocks (tree, inspector, dock, toolbar) and a public layout interface. |
| P4 | An extensible API lets users with own BeamletOptics types define widgets that the GUI loads. | Met for cards: card_rows, card_actions, CardWidget, card_input, card_show!, from a package extension on BeamletOpticsGUI, see Cards and widgets. | No own result view per type (see P2). No public icon per type. |
The split of the GUI from BeamletOptics changed no behavior. The gaps are closed one after the other in the order P3, P2 and P4, P1, each with its own plan.
Relation to BeamletOptics
| BeamletOptics | BeamletOpticsGUI | |
|---|---|---|
| Optics, systems, beams, detectors | yes | uses them |
render!, live_render!, update_render!, remove_render!, pick_object, look and camera helpers | yes | uses them |
live_view, kinematic_controls!, view_cube!, cards, panels | no | yes |
The names that moved from BeamletOptics to BeamletOpticsGUI keep their names and signatures. They were never part of a BeamletOptics release, so there is nothing to migrate.
AI assistants
The package ships an agent skill for the GUI, which builds on the skill of BeamletOptics for the optics. Install the version that matches the installed package with
using BeamletOpticsGUI
BeamletOpticsGUI.install_agent_skill() # -> ./.claude/skills/beamletopticsgui