Skip to content

Toolpath

File Format (.crs)

Toolpath files define the laser scanning pattern. Each line is a waypoint:

time        x           y           z           laser_flag
0.00000000  0.00050000  0.00200000  0.00069750  0
0.00600000  0.00350000  0.00200000  0.00069750  1
0.00700000  0.00400000  0.00200000  0.00069750  0
Column Unit Description
time s Absolute time of this waypoint
x m Beam x-position
y m Beam y-position
z m Beam z-position (typically top of powder layer)
laser_flag - 0 = laser off (repositioning), 1 = laser on (scanning)

The solver interpolates linearly between waypoints to determine beam position and scan velocity at each time step.

Conventions:

  • First line is always 0 0 0 0 0 (initial state)
  • Second line moves the beam to the scan start position (laser off)
  • Subsequent lines alternate between laser-on (scanning) and laser-off (repositioning) segments
  • Scan speed is computed automatically from position change / time change between waypoints

Toolpath Generator

A Python script generates rectangular scan patterns:

cd code_base/ToolFiles

python3 toolpath_generator_rectangle.py \
  --center_x 0.001 --center_y 0.001 --center_z 0.0006975 \
  --size_x 0.001 --size_y 0.001 \
  --scan_axis x --bidirectional \
  --hatch_spacing 0.0001 --scan_speed 1.2 \
  --turnaround_time 0.0005 \
  --geo_rotation 0 --scan_rotation 30 \
  --output center_geo0_scan30.crs

Geometry placement

Argument Unit Description
--start_x/y/z m Starting (lower-left) corner of scan region
--center_x/y/z m Rectangle center; overrides --start_x/y/z
--size_x/y m Scan region dimensions

Scan strategy

Argument Unit Description
--scan_axis - Base scan direction (x or y)
--bidirectional - Alternate scan direction each track (default)
--unidirectional - Same scan direction each track
--hatch_spacing m Nominal distance between adjacent tracks; auto-rounded so the first and last tracks touch the rectangle edges
--scan_speed m/s Laser scan speed
--turnaround_time s Delay between tracks (laser off)

Rotations (independent)

Argument Unit Description
--geo_rotation deg CCW rotation of the rectangle outline about its center. Scan tracks do not follow this rotation — they remain aligned with the scan-frame defined by --scan_axis + --scan_rotation.
--scan_rotation deg CCW rotation of the scan-track direction in the global frame, applied on top of --scan_axis. 0 = tracks along the chosen base axis (legacy behaviour).
--rotation_angle deg DEPRECATED alias for --geo_rotation (kept for backward compatibility; emits a one-line note).

The two rotations combine like this:

geo_rotation scan_rotation Effect
0 0 Axis-aligned rectangle, axis-aligned tracks (default).
θ 0 Tilted rectangle, axis-aligned tracks (legacy --rotation_angle θ).
0 θ Axis-aligned rectangle, tracks tilted by θ in the global frame.
θ θ Rigid rotation: rectangle and tracks rotate together.
α β (α ≠ β) Rectangle at α, tracks at β — fully independent.

Realistic LPBF strategies often rotate the scan direction between layers (e.g. 67° per layer) on a fixed part outline — that's the --geo_rotation 0 --scan_rotation 67·k pattern.

Plot bounds + simulation domain

Argument Unit Description
--input_param path PHOENIX input_param.txt to read X/Y zone-length block from. Defaults to ../inputfile/input_param.txt relative to the script.
--domain_x/y m Override the auto-read X/Y domain extent for the PNG axis limits.
--output - Output .crs filename (.png is <output>.png).

When --input_param resolves to an existing file, the generator reads the X-zone and Y-zone length sums and (a) sets the PNG axis limits to the full simulation domain and (b) outlines the domain as a dashed grey rectangle so the scan footprint is visible inside the simulation volume. Pass --input_param '' (empty) to fall back to autoscale.

Output: .crs file + .png visualization. Stdout reports the parsed domain, the actual hatch (after the round-to-fit adjustment), and the number of tracks.

Note

The .png visualization is only generated when using toolpath_generator_rectangle.py. Manually created .crs files do not have a .png.

Reference toolpaths in code_base/ToolFiles/

File Geometry Rotations Notes
center_rot0.crs 1×1 mm centered, hatch 0.1 mm 0 / 0 Baseline.
center_rot45.crs 1×1 mm centered, hatch 0.1 mm 45° / 0 Tilted rectangle, axis-aligned tracks.
center_rot0_hatch50.crs 1×1 mm centered, hatch 0.05 mm 0 / 0 Half hatch → 21 tracks, ~28 ms total.
center_geo0_scan30.crs 1×1 mm centered, hatch 0.1 mm 0 / 30° Axis-aligned rect, tracks tilted 30°.
center_geo30_scan30.crs 1×1 mm centered, hatch 0.1 mm 30° / 30° Rigid 30° rotation.

Manual Toolpath Creation

For simple patterns (single track, custom shapes), create the .crs file directly:

Example: Single track at 0.5 m/s along x at y=2mm

      0.00000000      0.00000000      0.00000000      0.00000000 0
      0.00000000      0.00050000      0.00200000      0.00069750 0
      0.00600000      0.00350000      0.00200000      0.00069750 1
      0.00700000      0.00400000      0.00200000      0.00069750 0
  • Line 1: Initial state (origin)
  • Line 2: Move to start (x=0.5mm, y=2mm, z=0.6975mm), laser off
  • Line 3: Scan to x=3.5mm in 6ms (speed = 3mm/6ms = 0.5 m/s), laser on
  • Line 4: Overshoot/cool-down, laser off

Set toolpath_file in input_param.txt:

&output_control ... toolpath_file='./ToolFiles/species_test.crs' /