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 pointexamples/bosnia_terrain_landcover_viewer.py (line 762) calls main, which parses CLI args and eventually invokes _render.
  • Core rendering path_render (in python/forge3d/map_scene.py) calls send_ipc (85 call sites) to forward a command to the Rust process. The Rust side receives the IPC message in src/viewer/cmd/ipc_command.rs, routes it through handler.rs, and triggers the GPU pipeline defined in src/terrain/renderer/.
  • Filesystem interaction – The shortest external‑touch path is main → read_text (via Path::read_text in python/forge3d/_native.py), used to load shader source and scene JSON. The run entry (in python/forge3d/terrain_demo.py) also reads DEMs with rasterio.open (_load_dem).
  • Blast‑radius modules
  • python/forge3d/_native.py is the most connected hub (13 importers, 0 outgoing imports). Any change here can affect the entire Python surface.
  • python/forge3d/helpers/offscreen.py imports and is imported by three modules, showing moderate coupling.
  • Deep nesting – Functions such as python/forge3d/colormaps/core.py and Rust files like src/terrain/render_params/decode_vt.rs reach 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-error from correctness steps (.github/workflows/ci.yml).
  • Medium – Declare least‑privilege GITHUB_TOKEN permissions (determinism-matrix.yml).
  • Medium – Enable a dependency‑update bot (Dependabot or Renovate).
  • Medium – Add a dependency‑vulnerability scan to CI.
  • Medium – Set persist-credentials: false on the checkout step (ci.yml).
  • Low – Define timeout-minutes on 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.