The Problem
Geospatial analysts and visual‑simulation pipelines need fast, headless 3‑D terrain rendering that can be driven from Python scripts while still exploiting GPU acceleration. Existing pure‑Python stacks are CPU‑bound; pure‑Rust engines lack the rich GIS ecosystem.
What This Does
forge3d bridges the gap by exposing a Rust‑implemented wgpu/WebGPU renderer as a Python package. The core resides in src/ (e.g., src/lib.rs, src/viewer/cmd/*.rs) and is built into compiled wheels via pyproject.toml/Cargo.toml. The Python façade lives in python/forge3d/, with the native bridge in python/forge3d/_native.py (the hub module imported by 13 other Python files). High‑level helpers (viewer.py, terrain_params.py, map_scene.py) assemble DEMs, raster/vector overlays, point‑clouds, and cartographic decorations, then invoke the native renderer for interactive or off‑screen snapshots.
How It Is Wired
- Entry point –
examples/bosnia_terrain_landcover_viewer.py(line 762) callsmain, which parses CLI args and eventually invokes_render. - Core rendering path –
_render(inpython/forge3d/map_scene.py) callssend_ipc(85 call sites) to forward a command to the Rust process. The Rust side receives the IPC message insrc/viewer/cmd/ipc_command.rs, routes it throughhandler.rs, and triggers the GPU pipeline defined insrc/terrain/renderer/. - Filesystem interaction – The shortest external‑touch path is
main → read_text(viaPath::read_textinpython/forge3d/_native.py), used to load shader source and scene JSON. Therunentry (inpython/forge3d/terrain_demo.py) also reads DEMs withrasterio.open(_load_dem). - Blast‑radius modules –
python/forge3d/_native.pyis the most connected hub (13 importers, 0 outgoing imports). Any change here can affect the entire Python surface.python/forge3d/helpers/offscreen.pyimports and is imported by three modules, showing moderate coupling.- Deep nesting – Functions such as
python/forge3d/colormaps/core.pyand Rust files likesrc/terrain/render_params/decode_vt.rsreach six indentation levels, making the control flow harder to follow.
The call graph shows ~6 000 internal edges; the most frequently invoked utilities (_require_native, read_text, send_ipc, evaluate, linspace, to_dict) are the primary glue between Python orchestration and the Rust engine.
How To Use It
# Clone the repository
git clone https://github.com/moses-y/forge3d.git
cd forge3d
# Install the Python wheel (builds the Rust extension via maturin)
pip install forge3d # pulls pre‑built wheels for supported platforms
# Optional extras for notebooks or bundled datasets
pip install "forge3d[jupyter]" # notebook widget support
pip install "forge3d[datasets]" # sample DEMs, point‑clouds
Running an example (the documented quick‑start) executes the Python entry point that ultimately calls the native renderer:
python examples/bosnia_terrain_landcover_viewer.py --help
The script creates a ViewerHandle via forge3d.open_viewer_async, configures camera/sun, and calls viewer.snapshot(...). Internally this triggers the IPC flow described above and writes a PNG to the local filesystem.
Real‑World Use
A data‑science pipeline can generate daily terrain visualisations:
import forge3d as f3d
dem = f3d.fetch_dem("rainier") # pulls a GeoTIFF from the bundled dataset
with f3d.open_viewer_async(terrain_path=dem, width=1920, height=1080) as v:
v.set_z_scale(0.2)
v.set_orbit_camera(phi_deg=30, theta_deg=45, radius=5000)
v.snapshot("rainier_day.png")
The call chain mirrors the wiring section: open_viewer_async → native session start → IPC command → Rust GPU render → PNG write.
Code Health & Issues
- High – Pin GitHub Actions to commit SHAs (
.github/workflows/*.yml). - High – Remove
continue-on-errorfrom correctness steps (.github/workflows/ci.yml). - Medium – Declare least‑privilege
GITHUB_TOKENpermissions (determinism-matrix.yml). - Medium – Enable a dependency‑update bot (Dependabot or Renovate).
- Medium – Add a dependency‑vulnerability scan to CI.
- Medium – Set
persist-credentials: falseon the checkout step (ci.yml). - Low – Define
timeout-minuteson workflow jobs (determinism-matrix.yml).
Additional observations: the repository includes a full test suite (tests/), CI via GitHub Actions, a LICENSE file, and a lockfile (Cargo.lock). No Dockerfile or container build is provided. Documentation is extensive (docs/ and online site).
The Bottom Line
forge3d delivers a performant, Python‑friendly WebGPU renderer with a well‑structured Rust core, suitable for GIS and simulation workloads that need GPU speed without abandoning Python tooling. The main risks are the tightly coupled native bridge (_native.py) and several high‑severity CI hygiene issues that should be addressed before adopting the package in a production CI pipeline. Engineers comfortable with Rust‑Python interop will find the codebase approachable; teams that need strict CI security should apply the listed fixes.