Given a terrain example, our method analyses different metrics related to its peaks and saddles graph (the Divide Tree), and then automatically synthesizes a heightfield conforming to these statistics.
This repository contains our implementation of the paper, needed data, and examples on executing the code.
Directory | Description |
---|---|
analysis | Python package with functions related to analysis of peak orometrics. |
data | Peak data and statistics. Check the README.md inside this directory for important setup instructions. |
img | Teaser image and other beautiful pictures of our synthetic terrains rendered using VUE. |
input | Example user input maps as used for some of the figures in the article. |
results | Some of our resulting terrains shown in the article, including their orometrics and divide trees. |
synthesis | Python package with functions related to Divide Tree synthesis and terrain generation. |
utils | Python package with auxiliary and common functions to either section. |
The directories/packages analysis
, synthesis
contain the code regarding their respective parts of the article. Inside utils
there are auxiliary and common functions to both parts.
We provide several jupyter notebooks that will serve as a guide on using the code.
Analysis.ipynb: given a set of input shapefiles for the desired regions, computes the list of peaks inside each region and computes the sampled disk statistics. You need to run this script before Classifier or Synthesis, since they rely on some of the outputs produced by it.
Classifier.ipynb: the first part demonstrates how to compute the classification matrix for a set of terrains as shown in the article. The second part contains the utility to classify an arbitrary list of peaks (e.g. a synthetic terrain) into these region classes. It corresponds to sections 4.2 and 7.1 in the paper.
Synthesis.ipynb: divide tree synthesis demo, using a user input coarse elevation map and peak density map. Most of the code here is input, configuration and visualization. The parameters for the synthesis are passed in a dictionary, check the comments for details. This is section 5 in the article.
TerrainFromDivtree.ipynb: code to transform a divide tree into a TIN or DEM. Again, most of the code here is input or debug visualitzations, check the comments for info about the parameters of the reconstruction function. This is section 6 in the article.
PlotHistograms.ipynb: reads a peaks file CSV and computes the disk statistics for a given (latitude,longitude) pair, then plots the histograms as shown in the paper.
PlotDivtrees.ipynb: reads png DEM files and their Divide Tree in txt format, then plots the peaks, saddles and edges of the tree on top of the DEM for visualization, as shown in the paper and supplementary material.
In order to run our code, you will need the following packages:
numpy, pandas, scipy, scikit-learn, # numerical and data libraries
pyshp, shapely, # to process the region shapefiles and have geometric test functions
noise, pot, triangle, # additional utilities: noise, optimal transport and constrained Delaunay
pillow, scikit-image, opencv, # image libraries (we could probably do everything with only scikit or opencv?)
matplotlib, jupyter # if you want to use the sample notebooks
We tested the provided code on a new Python 3.7 environment using Miniconda. All packages were installed using conda install
except triangle
, which we had to install with pip
.
Regarding the analysis of a DEM in order to extract its Divide Tree, we edited the source code of Andrew Kirmse's prominence program to read DEM of various dimensions and cell sizes instead of the SRTM definitions, as well as adding an export function of the divide tree as a TXT, later used by our code.
You can check out this release from my fork of Andrew Kirmse's code, which replicates the necessary modifications that we did during the paper. Note that it is not the exact code we used during our experiments, so there might be some differences.
The input requires as ASCII Grid file. Note that this version of the code already produces a unified output with the prominence and isolation of all the peaks, i.e. no need to merge the two lists later. This functionality has been added recently.
The code we provide here is a cleaned version of our research code and is provided as is. It would be nice to have a Divide Tree class encapsulating peaks, saddles and connectivity, as well as the reading/writing functions. Or to provide a library/package to compute the metrics.
The erosion post-process on the terrain is not included either, since we used a C++ code that heavily depends on some internal libraries of our team. However, good aesthetic results can also be achieved with the erosion tools in other software (e.g. we experimented with Houdini). However, note that these implementations will not apply the compensating uplift that avoids eroding peaks, saddles and ridges to preserve the orometrics.
The article is published in ACM Transactions on Graphics, and can also be read here.
Check also the supplementary material here.
If you use this code for your research, please cite our paper:
@article{Argudo2019orometry,
title = {Orometry-based Terrain Analysis and Synthesis},
author = {Argudo,Oscar and Galin,Eric and Peytavie,Adrien and Paris,Axel and Gain,James and Gu\'{e}rin,Eric},
journal = {ACM Transactions on Graphics (SIGGRAPH Asia 2019)},
year = {2019},
volume = {38},
number = {6}
}
-
Christian Hill for the Poisson Disc sampling code, which I copied into utils.poisson.
-
Andrew Kirmse for sharing his result datasets of world prominences and isolations, as well as the to compute these metrics. Check out his repository.