Skip to content

Geometry representation ​

In BMO, the distinction between an object and its geometric representation (shape) is a central design principle. This separation is intended to ensure flexibility and modularity in modeling optical components. Unlike the surface based representation of optical elements in other tools, they are treated as volumetric bodies in this simulation framework.

Separation of geometry and optical interactions ​

An object does not handle its geometry itself. Everything geometric, e.g. intersect3d, position or orientation, is forwarded to its shape trait, which returns the shape or shapes of the object. Moving an object works the same way: objects are BeamletOptics.Movable by default, and the movable methods of an object forward translate3d! and rotate3d! to the shape trait, which then moves every shape of the object. Solid arrows are labeled with the function or field that leads from one type to the next, dotted arrows point to subtypes. What a subtype has to implement is listed in the docstring of each type.

The geometry, represented by a concrete subtype of the BeamletOptics.AbstractShape, defines the physical boundaries of the element. Shapes can be represented in various forms, such as Meshes or Signed Distance Functions (SDFs). The main goal for this design choice is to allow for the possibility to switch out geometry representations for more advanced methods in the future, e.g. NURBS.jl.

BeamletOptics.AbstractShape Type
julia
AbstractShape{T<:Real}

A generic type for a shape that exists in 3D-space. Must have a position and orientation. Types used to describe the geometry of a shape should be subtypes of Real.

Implementation reqs.

Subtypes of AbstractShape should implement the following:

Fields:

  • pos: a 3D-vector that stores the current position of the object-specific coordinate system

  • dir: a 3x3-matrix that represents the orthonormal basis of the object and therefore, the orientation

Getters/setters

  • position / position!: gets or sets the position vector of the AbstractShape

  • orientation / orientation!: gets or sets the orientation matrix of the AbstractShape

Kinematic:

AbstractShapes are BeamletOptics.Movable with an BeamletOptics.Oriented frame, see BeamletOptics.AbstractKinematicTrait. The default primitives translate3d!(::Movable, shape, offset) and rotate3d!(::Movable, shape, R::AbstractMatrix) act on position/orientation; subtypes with additional geometry data (e.g. mesh vertices) dispatch their own.

Ray Tracing:

  • intersect3d: returns the intersection between an AbstractShape and AbstractRay, or lack thereof. See also Intersection

Rendering (with Makie):

Refer to the render! documentation.

source

On the other hand, the optical behavior — how light interacts with the element — is defined by the BeamletOptics.AbstractObject type. This decoupling allows for independent development and extension of geometry representations and optical interaction models within the Intersect-Interact-Repeat-Loop.

BeamletOptics.AbstractObject Type

A generic type for 2D/3D objects that can be used to model optical elements. The geometry of the object is represented via an AbstractShape. The optical effect that occurs between the object and an incoming ray/beam of light is modeled via its interact3d method.

Implementation reqs.

Subtypes of AbstractObject must implement the following:

Shape trait

An AbstractObject can consist of a single AbstractShape, e.g. a lens element, or a collection of functionally dependant shapes, e.g. a cube beamsplitter. In order to model this, the API implementation of an AbstractObject requires the definition of the shape trait. This trait allows the dispatch onto specialized methods to handle the kinematic interface and tracing methods for objects consisting of one or more shapes.

  • shape_trait_of: defines the shape type of the AbstractObject, refer to AbstractShapeTrait for more information

Default shape trait

Unless specified otherwise, the shape_trait_of an AbstractObject is defined as SingleShape. This requires object.shape as a dedicated field. For MultiShapes the getter function shape(object) must return a tuple of all shapes that make up the object.

Getters/setters

All kinematic functions defined for the AbstractShape can also be called for a AbstractObject. In this case, the shape trait will define how the specific movement function is dispatched.

Kinematic

AbstractObjects are BeamletOptics.Movable with an BeamletOptics.Oriented frame, see BeamletOptics.AbstractKinematicTrait. The primitives translate3d!(::Movable, object, offset) and rotate3d!(::Movable, object, R::AbstractMatrix) forward to the shape trait. A subtype can opt out of the kinematic API via BeamletOptics.kinematic_trait_of(::Foo) = BeamletOptics.Static().

Functions:

source

Single and multi-shaped objects ​

An AbstractObject can consist of multiple AbstractShapes or even multiple subsidiary AbstractObjects, facilitating the creation of composite optical elements. For example, a lens with an anti-reflective coating could be represented as the substrate and a seperate model for the coating, each with its own geometric and optical properties. In general, an object can have the SingleShape or a MultiShape trait. The BeamletOptics.AbstractShapeTrait allows the solver and kinematic API to apply different implementations of basis functions via multiple dispatch.

BeamletOptics.SingleShape Type

Represents that the AbstractObject consists of a single underlying shape.

AbstractObject implementation reqs.

If shape_trait_of(::Foo) = SingleShape() is defined, Foo must implement the following:

Fields

source
BeamletOptics.MultiShape Type

Represents that the AbstractObject consists of a two or more AbstractShapes.

AbstractObject implementation reqs.

If shape_trait_of(::Foo) = MultiShape() is defined, Foo must implement the following:

Functions

  • shape(::Foo): a getter function that returns a Tuple of all relevant shapes, e.g. (foo.front, foo.middle, foo.back)

All shapes returned by shape(::Foo) must be movable, see BeamletOptics.AbstractKinematicTrait.

Additional information

Kinematic center

Unless specified otherwise by dispatching position / position! and orientation / orientation! onto custom pos and dir data fields, the position and orientation of the first element returned by shape(object) will be used as the kinematic center for e.g. translate3d!.

source