Meshes
For flat surfaces and placeholder objects, BMO offers a mesh-based geometry representation via the Mesh type. Meshes offer an easy but inaccurate way to represent geometry via a tessellation based surface interpolation with triangles. In general it is not recommended to use meshes for anything other than flat surfaces or .stl imports for visualization purposes. The point of intersection is calculated via the Moeller Trumbore algorithm [28].
Meshes can be loaded from .stl files via the FileIO package.
BeamletOptics.Mesh Type
Mesh <: AbstractMeshContains the STL mesh information for an arbitrary shape, that is the vertices that make up the mesh and a matrix of faces, i.e. the connectivity matrix of the mesh. The data is read in using the FileIO.jl and MeshIO.jl packages. Translations and rotations of the mesh are directly saved in absolute coordinates in the vertex matrix. For orientation and translation tracking, a positional and directional matrix are stored.
Fields
vertices: (m x 3)-matrix that stores the edge points of all trianglesfaces: (n x 3)-matrix that stores the connectivity data for all facesdir: (3 x 3)-matrix that represents the current orientation of the meshpos: 3-element vector that is used as the mesh location referencescale: scalar value that represents the current scale of the original mesh
BeamletOptics.Mesh Method
Mesh(mesh)Parametric type constructor for struct Mesh. Takes data of type GeometryBasics.Mesh and extracts the vertices and faces. The mesh is initialized at the global origin. Data type of Mesh is variably selected based on type of vertex data (i.e Float32).
Tip
Mesh vertex data is scaled by the factor 1e-3, i.e. the STL file is assumed to be in mm and the mesh is in [m]. Ensure that the export program is adjusted accordingly when scaling issues occur.
Moeller Trumbore algorithm
The Moeller-Trumbore-algorithm tests the intersection of a ray with the mesh by testing against each individual face.
BeamletOptics.MoellerTrumboreAlgorithm Function
MoellerTrumboreAlgorithm(face::Matrix, ray::AbstractRay; kϵ = 1e-9, lϵ = 1e-9)An implementation of the Möller-Trumbore algorithm for ray-triangle-intersection, which hits the face from both sides. This algorithm evaluates the possible intersection between a ray and a face that is defined by three vertices. If no intersection occurs, Inf is returned.
kϵ: dimensionless tolerance. A ray misses the face ifsin α |cos θ| ≤ kϵ, with the corner angleαbetween the first two edges and the angleθbetween the ray and the face normal, i.e. if it runs (almost) parallel to the face or the face is degenerate. The barycentric coordinates of a hit may exceed the face bykϵ. Both are independent of the size of the face.lϵ: the shortest distance in [m] from the start of the ray at which a hit counts, such that a ray that starts on the face does not hit it again.
This algorithm is fast due to multiple breakout conditions.
sourceThe test for rays parallel to the face is relative to the size of the face. The determinant Det = E1 ⋅ (d × E2) of the edges E1, E2 and the ray direction d is a triple product: it scales with the area of the face, |Det| = |E1| |E2| sin α |cos θ| with the corner angle α between the edges and the angle θ between d and the face normal. The ray is skipped if |Det| ≤ kϵ |E1| |E2|, which does not depend on the edge lengths. A degenerate face, with Det = 0, is skipped as well.
The vertices of a face, here and in normal3d(mesh, fID), are converted to points in the number type of the ray or the mesh and type-asserted, since their type cannot be inferred for every mesh type. For the same reason the distance t of a hit is declared in the number type of the ray. This keeps both functions type-stable. BeamletOptics.CircularFlatMesh stores its vertices in the number type of the radius, e.g. dual numbers in automatic differentiation, so that the mesh can be differentiated with respect to the radius.
Below a visualization is provided for a Benchy mesh. The ray, colored in blue, intersects multiple faces of the mesh, colored in red. The shortest face intersection is assumed to be the correct one. Note that the normal vector at the point of intersection is calculated for the entire face. This makes the mesh-based geometry representation unsuitable for curved geometries, e.g. lens surfaces, since refraction and reflection calculations require accurate normal vectors.
