A powerful Python and OpenSCAD toolchain for generating 3D-printable roller coaster tracks. This tool accepts 3D coordinates (via CSV or algorithms), turns them into smooth track geometry, and intelligently slices the model into printable segments with interlocking connectors.
- Parametric Geometry: Generates realistic track profiles with rails, crossties, and a spine.
- Intelligent Slicing: Automatically partitions long tracks into segments that fit your 3D printer's build volume.
- Interlocking Connectors: Automatically generates male/female connectors (pegs and sockets) with configurable tolerance for easy assembly.
- Banking & Orientation: Calculates correct banking and frame orientation vectors (Forward, Up, Right) for every point on the track.
- CSV Support: Import your own track designs from simple CSV files.
- Automated Rendering: Renders all segments to STL files in one command.
- OpenSCAD: This tool relies on OpenSCAD for 3D generation.
- macOS: Install via
brew install --cask openscador download from openscad.org. - Windows/Linux: Install from openscad.org.
- macOS: Install via
- Python 3.11+
- uv (Recommended): A fast Python package and project manager.
-
Clone the repository:
git clone https://github.com/conceptcodes/rail-forge.git cd rail-forge -
Initialize the environment:
uv sync
The primary interface is generate.py.
If no input file is provided, the tool generates a demo helix/loop track.
uv run generate.py --renderYou can provide a CSV file containing x, y, z coordinates.
# or use one of the example tracks
uv run generate.py tracks/left_turn.csv --scale 100 --renderUse the --max-length argument to specify your printer's bed size (in mm). The tool will split the track into segments that fit.
# For a printer with a 256mm build plate
uv run generate.py tracks/helix.csv --scale 100 --max-length 250 --output-dir my_coaster --renderThis will produce files named track_segment_01_of_XX.stl inside the my_coaster/ directory.
| Argument | Description | Default |
|---|---|---|
file |
Input CSV file (optional). | Demo Helix |
--scale |
Scale factor for input points. | 1.0 |
--max-length |
Maximum length of a track segment in mm. | 250.0 |
--render |
Automatically render STL files using OpenSCAD. | False |
--openscad |
Path to OpenSCAD executable. | openscad |
--output-dir |
Directory to save generated STL files. | . |
Your CSV files should contain 3 columns (X, Y, Z). Headers are optional (the parser skips lines that aren't numeric).
0.0, 0.0, 0.0
10.0, 5.0, 2.0
20.0, 10.0, 5.0
...See the tracks/ directory for examples:
straight.csv: Basic straight trackhelix.csv: Unit-circle spiral (requires scaling)airtime_hill.csv: Parabolic hillleft_turn.csv/right_turn.csv: 90-degree turns
This project is structured as a modular Python package:
generate.py # CLI entry point
track.scad # OpenSCAD geometry definition
spline_data.scad # (generated) data file passed to OpenSCAD
tracks/ # Example CSV tracks
src/
│ └── roller_coaster/
│ ├── geometry.py # Vector math & path generation algorithms
│ ├── track.py # Slicing & partitioning logic
│ ├── io.py # File I/O (CSV reading, SCAD writing)
│ └── render.py # OpenSCAD process orchestration
└── pyproject.toml # Project configuration
You can modify track.scad to change the aesthetic of the coaster:
track_gauge: Width between rails.rail_diameter: Thickness of the rails.crosstie_spacing: Distance between ties.tolerance: Fit tolerance for connectors (default 0.2mm).