A curious feature was seeing the possibility to both generate and visualise the exposure points generated in along scan vectors. This also includes generating a pseudo ‘heatmap’ or exposure map of the energy deposited by the laser scanning across the surface. Variations of this idea, I have seen across a variety of commercial software – in particular Renishaw’s QuantAM, which is perhaps the source of inspiration for coming up with an approach.
Usually, there is not much indication as the relative exposure of energy from the laser into a layer based both the chosen laser parameters applied to the scan vectors of a specific LayerGeometry group and also the overall spatial distribution of scan vectors in a region. For instance, overlaps between scan vectors will in theory deposit more energy across time into a localised region . Ideally, the exposure of energy from the laser is very uniform across the regions.
It is debatable whether there is particular usefulness of visualising the exposure map of the laser – but in practice can be used to differentiate laser scan parameters used on models in parametric studies. With further thought, a cheap numerical simulation could potentially capture the transient heat distribution generated by the sequential deposition of these exposure points.
A Light Background on Laser Exposure:
Hopefully someone can further comment on of this and perhaps correct me…
SLM systems are built using fiber laser systems offering a very fine, high quality controlled laser beam. Two types of laser operation exist: continuous wave (CW) and pulsed.
In practice, with pulsed lasers used in AM platforms, the scan vector is decomposed across a number of exposure points at a set ‘pointDistance’ from each other along the scan vector. Each exposure irradiates energy into the powder-bed surface at a fixed energy (inferred from the average laserPower) for a set time period referred as a ‘pointExposureTime‘. After exposure, the galvo-mirrors instantaneously move to direct the beam to the next exposure point. The relative speed this occurs optically gives the illusion that the laser is continuously moving. Continuous wave, as the name describes, emits continuous irradiation whilst the beam traverses the surface. The laser speed parameter is used here.
Different systems use either pulsed, continuous, or even both modes of operation, offering different benefits. This in principle is the reason for BuildStyle class containing the following parameters to cover both situations:
- Point Exposure Time
- Point Distance
- Laser Speed
- Laser Power – used across both modes
Ultimately, this does not matter, but the proposed method obviously requires the user to set at minimum the pointDistance
parameter in order for the following methodology to work.
Proposed Methodology
Taking an existing Layer containing LayerGeometry
, the exposure points are generated individually for each scan vector. Given the potential number of scan vectors within a layer, it would be beneficial to perform this efficiently.
The basic process to do this is based on the following. The scan vector \textbf{v}
has a particular length. Based on the point exposure distance, we can equally divide along this a number of points. Using both v_o
and its direction ,we can then project a given number of exposure points along this line.
An attempt to do this more efficiently and exploit vectorisation built into numpy was achieved by the following procedure. The following properties of each scan vector (\textbf{v}
) is obtained:
- start point (
v_o
) - normalised scan vector direction (
\hat{\textbf{v}}
) - scan vector length
\lVert \textbf{v} \rVert
For each LayerGeometry
object, these are obtained across each scan vector as follows assuming that it is a HatchGeometry
object:
# Calculate the length of the hatch vector and the direction
coords = layerGeom.coords.reshape(-1, 2, 2)
delta = np.diff(coords, axis=1).reshape(-1, 2)
lineDist = np.hypot(delta[:, 0], delta[:, 1]).reshape(-1, 1)
# Take the first coordinate
v0 = coords[:, 1, :].reshape(-1, 2)
# Normalise each scan vector direction
vhat = -1.0 * delta / lineDist
The number of point exposure across each vector is calculated by simple division. Unfortunately there is rounding, so the exposure may be missing at the end of the scan vector.
# Calculate the number of exposure points across the hatch vector based on its length
numPoints = np.ceil(lineDist / pointDistance).astype(np.int)
The total number of exposure points is calculated and is used to pre-populate some arrays, where the terms are used to extrapolate the exposure point distance (Line 16) are generated. Line 10 is key here and idxArray
stores a range to account for each exposure point along the scan vector
Unfortunately, there isn’t a convenient way vectorise this so it is performed across each scan vector. Finally, the exposure points are generated by extrapolating them from v_o
along \hat{\textbf{v}}
.
# Pre-populate some arrays to extrapolate the exposure points from
totalPoints = int(np.sum(numPoints))
idxArray = np.zeros([totalPoints, 1])
pntsArray = np.zeros([totalPoints, 2])
dirArray = np.zeros([totalPoints, 2])
idx = 0
for i in range(len(numPoints)):
j = int(numPoints[i])
idxArray[idx:idx + j, 0] = np.arange(0, j)
pntsArray[idx:idx + j] = p0[i]
dirArray[idx:idx + j] = vhat[i]
idx += j
# Calculate the hatch exposure points
hatchExposurePoints = pntsArray + pointDistance * idxArray * dirArray
This generates a set of exposure points, which can be seen in the figure below:
Once the exposure points are generated, the deposited energy (laserPower x pointExposureTime) is added to each point and stored as a third column for later use.
Exposure Map Generation
Generating the exposure map is trivial. For a selected resolution chosen by the user, the bitmap slice is used currently to get the image to process with. The exposure coordinates are simply mapped, given an offset and resolution onto the image. The deposited energy is then summed accordingly across each pixel. The energy per area (latex]Q[/latex]
), is calculated by diving by the aerial coverage of a single pixel.
The resolution is arbitrarily selected. The above figure is generated with a resolution of 0.2 mm. It can be seen in this example that the there is a greater energy deposition across the the overlap regions between the islands. There are some ‘aliasing’ effects due to discretion onto a finer grid which is dependent on the resolution chosen.
Conclusions
The above exposure map generation might have little scientific utility by itself. Rather it can offer a method to potentially visualise the energy deposition across a layer.
However, many thermo-mechanical AM build simulation that incorporate thermal effects in addition to the inherent strain approach could potentially incorporate a reference exposure map across the layer rather than assuming a single aerial heat-flux applied to the layer. This could actually be carried out across a ‘packet’ or number of layers to better correspond with the geometry and scan strategies employed.
Documented Example
The code for this can be found in examples/example_heatmap.py on the github repository.