This article provides guidance on optimizing mapping files to create homogeneous light guides using 3D Textures. It begins with the fundamentals of pattern definition and progresses to advanced strategies for fine-tuning. No programming skills are required to follow along, though a basic technical background is recommended to implement the workflow.
Prerequisites
The objective of this article is not to provide an in-depth tutorial on using 3D Textures; for that, refer to the Learning Hub: Ansys Speos 3D Texture and the technical documentation: 3D Texture. Some scripts will need to be downloaded from the Ansys GitHub – Optical. Keep in mind that two programming languages are involved: (1) IronPython, for scripts executed directly within Ansys Speos, and (2) Python, for scripts requiring the installation of external packages.
Note that this article will focus on Ansys Speos. It can be divided into two parts, one fully focused on Ansys Speos: creating an interface in Ansys Speos and another that is identical for Speos for NX and Speos for CREO.
Overview
Working with textures offers several advantages compared to prismatic elements:
- Texture patterns are typically much smaller in scale. This is an added value when aiming for a homogeneous appearance where the human eye cannot easily detect any artifacts—unlike in prismatic light guides, where artifacts, such as the prisms themselves, may become visible for the observer.
- From a design flexibility standpoint, we can define a cloud of points with texture, while with prismatic elements the position is defined by the guide curve and the optical axis.
Each time a 3D texture is computed, a mapping file is automatically generated in the Speos input folder. This file contains the position, orientation, and scale of each pattern. The central focus of this article is on how to leverage this automatically generated mapping file to adjust the density of patterns, applying targeted strategies to achieve homogeneous light guides.
The key concept is that with a constant pattern density, luminance tends to be higher at the incoupling area, leading to hot spots. The challenge, therefore, is to define gradual adjustments of parameters that enable a uniform luminance profile across the light guide.
Two different strategies will be followed:
- Strategy A: Create a 3D texture and use a script to [AP1] adjust all positions of the patterns (x, y, z) to define a polynomic surface. From this surface, it will be easy to create a new mapping file with a variable pitch.
- Strategy B: Use the mapping file (a densely populated one) to create a new mapping file by progressively removing points along the profile with the help of script.
- Final Update: The depth of the patterns can be carefully updated to minimize the probability of creating hot spots at the beginning.
Using 3D Textures
The first step is to carefully select the axis system (normally the texture is not oriented with respect to the global axis system, it might have different origin and different directions). Thus, begin by defining a global origin point for the feature, from which a new axis system will be established using the vector (X, Y, Z). To generate the parallelepiped, you need to input X and Y directions defining its volume with dimensions X size, Y size and Z size centered on the new origin.
Before computing, a mandatory step is to generate your pattern file. You need to make sure its orientation is coherent with the axis system selected in the pattern. The orientation with respect to the X and Y axes in the pattern CAD must match with the axis system defined in the 3D texture.
Do not forget to add a material to the pattern geometry in the pattern CAD, otherwise you will get an error while executing the compute.
If you have difficulties designing a pattern that is too small, design it bigger and apply a scale factor in the pattern with the parameter “Global scale”.
While working with 3D patterns it is expected that the pattern intersects the support, each operation (add in, add on same material, add on different material, remove, insert) corresponds to a different way of resolving this interference. Make sure, when you design the pattern that it is extruded along the Z direction. We will need to take this into consideration in simulation settings.
The first thing is making sure the “Geometrical Distance Tolerance” or GDT in small enough for our project. The GDT is a tolerance that Speos uses in the simulations to determine which surfaces are tangent, and a smaller GDT will help Speos correctly detect intersections. But how small? As reference, at least 10 times smaller than the “intersection depth” of the pattern.
Each time you compute a 3D texture (with any mode different than “from file”) a .OPT3Mapping file is created in the input folder. This contains the location and orientation of all points, and it can be reimported to compute quickly.
The file is composed of one first line with the total count of points and N lines, each representing one node.
The first triplet of numbers is the Position (x, y, z) of each pattern.
The second and third triplets of numbers represent how x and y directions are defined for this particular node with respect to the axis system of the texture. X orientation (1 0 0) means that the horizontal is exactly the same as the one in the texture and (0 1 0) same for the vertical.
The last triplet represents the scale of the geometry with respect to the (X, Y, Z) directions from the original pattern file. If the pattern is a cylinder, modifying one of the parameters would:
- Kx: You stretch or compress the pattern along the local Z-axis of the cylinder. The pattern becomes elongated or squashed in depth.
- Ky: You change the texture height along the local Y-axis. On a cylinder, this affects vertical elongation/compression of the pattern.
- Kz: This affects the scaling along the normal of the surface (radial direction on a cylinder).
Run and Result
- Step 1: Create the mapping file manually
Start by opening the project “GENERIC_CAR 2023R2_Start.scdocx”. From the simulation tab, edit “3D Texture.2”, set the mapping file to “rectangular” and click on “compute”.
Check that there is a new file in the “Speos input files”: TL L.3D Texture.2.OPT3DMapping. This file will be key for all future steps.
- Step 1.1 - Option A: Create the polynomic surface
Retrieve the file “A_1_Create_stl_polynomial_surface.py” from Ansys Optics - Automation GitHub and update the lines 5 and 6, where lines 140 to 150 with the path to the input mapping file, the output stl with the geometry and a json file with the parametrization of the surface. If you want to see the surface in the right position, you would need to make the necessary adjustments (translations and rotations). However, it is strongly recommended to see how you surface actually looks like. This article does not go further into that, since what matters for us now is having the coordinates with respect to the 3D Texture axis system.
- Step 1.2 - Option A: Create the mapping file from the polynomic surface
Retrieve the file “A_2_Create_a_variable_pitch_from_the_polynomial_surface.py” from Ansys Optics Automation GitHub - Application and update lines 30 to 45 with the input json file with the parametrization of the support surface, the filepath of the input and output mapping files, and the path to the polynomial surface in stl format.
Update the pitch in lines 47 to 49, where PITCH_X_START is the one measured in the reference axis system and PITCH_X_END in the last pattern. Between both, there will be a linear evolution along the light guide X dimension.
Finally, there are many parameters that we will assume constant: x orientation, y orientation, and kx, ky and kz ("1 0 0 0 1 0 1 1 1"), and you can find it in line 57. All this information is found in “mapping_suffix”, and each time a pattern is created this info is repeated.
Inside the script, the polynomial will be adjusted just like in the previous step and it obtains the coordinates y and z from there to create a new mapping file.
Thus, execute the script and import this file into the 3D Texture and compute.
Then, simply compute the simulation with the texture:
- Step 2 - Option B: Randomly remove points from the mapping file
Copy the file “2.1 3DT Random.scscript” and paste it in “%AppData% \SpaceClaim\Published Scripts” from Ansys Optics Automation GitHub - SpaceClaim tools. Then close Ansys Speos and open a new Ansys Speos session.
In Ansys Speos, compute again the rectangular 3D texture but this time with 0.5 mm of pitch in X and Y. Then go to structure tab, activate the component where the 3D texture is located. Then, from the simulation tab, select the texture and click on 3DT Random from the Tools Ribbon.
The idea of this script is to remove patterns with a random density of points, where the probability of removing a point is determined by the position where this one is in x. The script performs a linear interpolation between each two control points, this means, if we defined the probability at 0% and at 100%, all the points in the middle will assume a linear evolution. If the probability is 1 at 0% and 0 at 100%, we can expect it would be 0.5 at 50%.
The example below is done with 5 control points (0.03, 0%), (0.65, 35%), (0.85, 50%), (0.95, 90%), (0.97, 100%), thus the probability of removing points is very high close to the LEDs and decreases progressively.
Then, compute the simulation with the texture:
- Step 3:
It might not be enough adjusting progressively the density of points, as the gaps between points might be big, this effect can be magnified by higher luminance in these micro hotspots generated by the patterns. There is another technique that could be applied on top of doing a random variation: adjusting the depth of the patterns with the z coordinate, or the scale factor kz.
With the scale factor Kz: Being centered in the same position deforms the pattern to make a bigger or smaller depth respecting the X and Y dimensions. Modifying the z position would leave the pattern shape intact while translating the origin to obtain a higher or lower depth. This idea is the same as the parameter “offset” in light guides.
In this example, we will only focus on kz adaptation.
To make the following example, you would need to repeat the previous point with two control points: (probability: 0.5, x: 0%) and (probability: 0, x: 100%).
Once you have generated your new mapping file, retrieve “2.2 Update Kz variation in mapping file.py” from Ansys Optics Automation GitHub - SpaceClaim tools and update lines 8 with the path for above generated mapping file (input mapping file) and 9 (output mapping file, with kz variation). By default, output will be saved in the same location as the input mapping file. Update lines 4 and 5 with the desired Kz (Kz1 corresponds to the position x = 0 and Kz2 with the maximum length), set Kz1 = 0.5 and Kz2 = 0.1 and then run the script which will generate new mapping file. Update the 3D texture with this new mapping file.
Then, compute the simulation with the texture:
Finally, don’t forget to check the regulation (e.g. FMVSS 108 – Taillamp):
You can easily do this by creating an intensity sensor and importing the template “TailLamp_LightedSection1_WithLines_Left.xml” into it. During the installation of Speos, you can also download the “Speos Libraries” package, which contains standards used to simulate and verify the requirements defined by SAE, UN, and other regulatory bodies. By importing the template into the sensor, all regulatory checks will be displayed automatically each time you run a new simulation.
Or directly download it from: Ansys Download Center. Under Primary Packages / Optical / Speos Libraries.
Taking the model further
It is also possible to get information about the support surface directly from CAD using SpaceClaim. You only need to mesh a face and extrapolate all the nodes of the meshing. From there you could create a mapping file where each pattern is located in a node, or create a polynomial surface, as shown previously.
opt = FacetConvertOptions(); opt.Deviation = MM(0.0005); opt.MaxEdgeLength = MM(0.2)
m = FacetConvert.Create(BodySelection.Create(GetRootPart().Bodies[0]), opt).CreatedMeshes[0]
points = [(v.Position.X, v.Position.Y, v.Position.Z) for v in m.Shape.Vertices]
The challenge? You would need to transform all the positions and orientations to your reference axis system in the 3D texture as the mesh nodes would be given with respect to the global axis system.
Additional Resources
- Documentation Texture: Creating a 3D Texture
- Course Scripting: Ansys Speos Scripting - Ansys Speos Scripting
- GitHub Ansys Optis Automation: ansys/optical-automation: Optical Automation Framework
- Other related articles:
- Training ALH 3D Textures: Ansys Speos 3D Texture - Ansys Speos 3D Texture