Metadata-Version: 2.4
Name: forge3d
Version: 1.44.0
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: numpy>=1.21
Requires-Dist: rasterio>=1.3.0 ; extra == 'all'
Requires-Dist: pyproj>=3.4.0 ; extra == 'all'
Requires-Dist: xarray[complete]>=2023.1.0 ; extra == 'all'
Requires-Dist: rioxarray>=0.13.0 ; extra == 'all'
Requires-Dist: dask[array]>=2023.1.0 ; extra == 'all'
Requires-Dist: matplotlib>=3.5.0 ; extra == 'all'
Requires-Dist: pillow>=9.0.0 ; extra == 'all'
Requires-Dist: cartopy>=0.21.0 ; extra == 'all'
Requires-Dist: ipywidgets>=8.0 ; extra == 'all'
Requires-Dist: pooch>=1.6 ; extra == 'all'
Requires-Dist: websocket-client>=1.5 ; extra == 'browsertests'
Requires-Dist: cartopy>=0.21.0 ; extra == 'cartopy'
Requires-Dist: matplotlib>=3.5.0 ; extra == 'cartopy'
Requires-Dist: cmcrameri>=1.7 ; extra == 'colormaps'
Requires-Dist: cmocean>=3.0 ; extra == 'colormaps'
Requires-Dist: colorcet>=3.0.0 ; extra == 'colormaps'
Requires-Dist: palettable>=3.3.3 ; extra == 'colormaps'
Requires-Dist: pycpt>=0.5.0 ; extra == 'colormaps'
Requires-Dist: pooch>=1.6 ; extra == 'datasets'
Requires-Dist: ipywidgets>=8.0 ; extra == 'jupyter'
Requires-Dist: matplotlib>=3.5.0 ; extra == 'matplotlib'
Requires-Dist: rasterio>=1.3.0 ; extra == 'raster'
Requires-Dist: pyproj>=3.4.0 ; extra == 'raster'
Requires-Dist: xarray[complete]>=2023.1.0 ; extra == 'raster'
Requires-Dist: rioxarray>=0.13.0 ; extra == 'raster'
Requires-Dist: dask[array]>=2023.1.0 ; extra == 'raster'
Requires-Dist: pillow>=9.0.0 ; extra == 'tiles'
Provides-Extra: all
Provides-Extra: browsertests
Provides-Extra: cartopy
Provides-Extra: colormaps
Provides-Extra: datasets
Provides-Extra: jupyter
Provides-Extra: matplotlib
Provides-Extra: raster
Provides-Extra: tiles
License-File: LICENSE
License-File: LICENSE-APACHE
License-File: assets/astro/THIRD_PARTY_NOTICES.md
Summary: forge3d: Rust/WebGPU offline 3D maps with Rust-first GIS vector, rasterization, mask, thematic, CRS, affine, windowing, and reprojection support
Keywords: graphics,rendering,webgpu,rust,3d,terrain,visualization
Home-Page: https://forge3d.dev
Author: forge3d authors
License: Apache-2.0 OR MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Bug Tracker, https://github.com/milos-agathon/forge3d/issues
Project-URL: Documentation, https://milos-agathon.github.io/forge3d/
Project-URL: Homepage, https://github.com/milos-agathon/forge3d
Project-URL: Repository, https://github.com/milos-agathon/forge3d

<p align="center">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/logo/forge3d_dark.svg" alt="forge3d" width="300">
</p>

<p align="center">
  <strong>Path-traced terrain and cartography for Python.</strong><br>
  Rust + WebGPU underneath. Real elevation data in, print-resolution maps out.
</p>

<p align="center">
  <a href="https://pypi.org/project/forge3d/"><img src="https://img.shields.io/pypi/v/forge3d?color=EFA026&style=flat-square" alt="PyPI"></a>
  <a href="https://pypi.org/project/forge3d/"><img src="https://img.shields.io/pypi/pyversions/forge3d?color=D0C8BA&style=flat-square" alt="Python 3.10+"></a>
  <a href="https://github.com/milos-agathon/forge3d/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0%20%2F%20MIT-blue?style=flat-square" alt="License"></a>
  <a href="https://milos-agathon.github.io/forge3d/"><img src="https://img.shields.io/badge/docs-online-blue?style=flat-square" alt="Docs"></a>
</p>

<p align="center">
  <a href="https://milosgis.com/">
    <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/shasta-hero.webp" alt="Mount Shasta rendered by forge3d, snow and glaciers picked out by low-angle sun against a dark sky" width="860">
  </a>
</p>

<p align="center">
  <sub><b>Mount Shasta</b>, path-traced with global illumination and terrain shadows.<br>
  <a href="https://milosgis.com/"><b>Drag to orbit it live &rsaquo;</b></a> &nbsp;·&nbsp; USGS 3DEP elevation &nbsp;·&nbsp; 23 cloud-free Sentinel-2 composites</sub>
</p>

---

## Install

```bash
pip install forge3d
```

<details>
<summary>Optional extras</summary>

```bash
pip install "forge3d[jupyter]"   # notebook widget support
pip install "forge3d[datasets]"  # on-demand sample datasets
pip install "forge3d[all]"       # everything
```

</details>

## Sixty seconds to a render

```python
import forge3d as f3d

dem_path = f3d.fetch_dem("rainier")

with f3d.open_viewer_async(terrain_path=dem_path, width=1440, height=900) as viewer:
    viewer.set_z_scale(0.1)
    viewer.set_orbit_camera(phi_deg=28, theta_deg=49, radius=5400, fov_deg=42)
    viewer.set_sun(azimuth_deg=302, elevation_deg=24)
    viewer.snapshot("rainier.png", width=1920, height=1080)
```

`fetch_dem` pulls the elevation model, the viewer opens a real window you can orbit,
and `snapshot` writes the frame at whatever resolution you ask for.

## Population and thematic rasters

You can now turn a population raster into a continuous raised, shaded surface,
give each land-cover class its own colour, or show two variables together with
a **3×3 colour matrix**. For example, height can show population density while
colour shows how it has changed.

`RasterHeightSurfaceStyle`, `CategoricalRasterStyle` and `BivariateRasterStyle`
plug into `MapScene` using prepared arrays or local raster files. Missing cells
stay empty, units and class boundaries remain explicit, and the styles return
legend data with the labels and ranges needed to explain the map. You can save
and reload the styled scene through the existing scene-bundle workflow.

See the [raster styling guide](https://github.com/milos-agathon/forge3d/blob/main/docs/guides/thematic_raster_styles.md)
and the [runnable public-API example](https://github.com/milos-agathon/forge3d/blob/main/examples/mapscene_thematic_rasters.py).

---

## Made with forge3d

Every map below is rendered end to end by forge3d — titles, legends and scale bars
included. Nothing here was hand-edited or composited in another tool.

<table>
<tr>
<td align="center" width="33%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/lyon.webp" alt="Circular plan view of Lyon with every building extruded, the Rhone and Saone running through it" width="270"><br>
  <sub><b>Lyon, LOD2 buildings</b><br>CityGML extrusion over RGE ALTI terrain</sub>
</td>
<td align="center" width="33%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/egypt.webp" alt="Egypt in cold blue relief with the Nile and its delta glowing orange" width="270"><br>
  <sub><b>Egypt, population</b><br>GHSL R2023A density over shaded relief</sub>
</td>
<td align="center" width="33%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/france.webp" alt="France coloured by a two-variable temperature and precipitation scheme" width="270"><br>
  <sub><b>France, climate</b><br>TerraClimate temperature × precipitation</sub>
</td>
</tr>
</table>

<table>
<tr>
<td align="center" width="50%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/iberia.webp" alt="Iberian peninsula land cover, forest greens along the north and mountain ranges, crop yellows across the meseta" width="415"><br>
  <sub><b>Iberia, land cover 2024</b> — Sentinel-2 at 10 m classified over terrain, legend composed in-engine</sub>
</td>
<td align="center" width="50%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/germany.webp" alt="Germany in hypsometric relief with the Rhine, Elbe and Danube drainage networks traced in blue" width="415"><br>
  <sub><b>Germany, hydrology</b> — HydroSHEDS rivers and lakes over a hypsometric DEM</sub>
</td>
</tr>
</table>

<p align="center">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/turkiye.webp" alt="Turkiye seen at a low angle with population density extruded as thousands of spikes, Istanbul the tallest" width="850">
</p>

<p align="center">
  <sub><b>Türkiye, population density</b> — a million WorldPop 2020 cells extruded on a log scale, labelled and lit in a single pass</sub>
</p>

<table>
<tr>
<td width="34%">
  <img src="https://raw.githubusercontent.com/milos-agathon/forge3d/main/docs/assets/readme/california-smoke.webp" alt="Animated loop of wildfire smoke plumes drifting across California through summer 2025" width="280">
</td>
<td width="66%">

**And it moves.**

Volumetric smoke driven by HRRR forecast fields, advected across California
through the summer 2025 fire season and rendered frame by frame — same
scene graph as the stills, one camera, no compositing.

Scenes are driven from Python end to end, so a time axis is just another loop:
fetch the fields, step the clock, call `snapshot`, hand the frames to ffmpeg.

</td>
</tr>
</table>

<sub>The renders above are downsampled for this page. Full-resolution masters — up to 7200×7200 — are on the <a href="https://milos-agathon.github.io/forge3d/gallery/index.html">gallery</a>.</sub>

---

## What forge3d covers

| | |
|---|---|
| **Terrain** | Interactive viewing via `open_viewer_async()` and `ViewerHandle`; snapshots from GeoTIFF or `numpy` DEMs; clipmaps for large regions |
| **Rendering** | Path tracing, PBR materials, subsurface scattering, water and reflections, cloud and contact shadows, AOV and EXR output |
| **Data** | COG streaming, CRS helpers, LAZ/COPC/EPT point clouds, 3D Tiles, GeoJSON, CityJSON, on-demand sample datasets |
| **Cartography** | Raster and vector overlays, labels with halo and occlusion, graticules, `Legend`, `ScaleBar`, `NorthArrow`, `MapPlate` |
| **Offscreen** | `Scene`, `Session`, `TerrainRenderer` and `TerrainRenderParams` for headless and batch work |
| **Output** | PNG and PNG16, SVG and PDF vector export, scene bundles, notebook widgets |

`MapPlate` composition, vector export and the building import pipelines are Pro
features; set a key with `forge3d.set_license_key(...)` to unlock them.

## Documentation

- [**Quickstart**](https://milos-agathon.github.io/forge3d/start/quickstart.html) — install, first viewer session, first overlay, first notebook widget
- [**Feature Map**](https://milos-agathon.github.io/forge3d/guides/feature_map.html) — repo-wide overview of the supported workflows
- [**Tutorials**](https://milos-agathon.github.io/forge3d/tutorials/index.html) — guided GIS and Python tracks
- [**Gallery**](https://milos-agathon.github.io/forge3d/gallery/index.html) — finished recipes at full resolution
- [**API Reference**](https://milos-agathon.github.io/forge3d/api/api_reference.html) — the full public Python surface

## License

The open-source core is released under Apache-2.0 OR MIT. Pro-gated features
require a commercial license key.

