This C++ application is designed to generate 3D models from heightmap images through triangulation, optionally adding solid bases and applying various modifications to the heightmap before processing. It also supports generating normal and hillshade maps based on the input heightmap. Below is a detailed usage guide, including implementation and algorithm details.
To use this application, you need to compile the provided source files (base.cpp
, blur.cpp
, heightmap.cpp
, main.cpp
, stl.cpp
, triangulator.cpp
, along with their headers) into an executable. The program requires specifying an input heightmap file and various optional parameters to control the output model’s characteristics.
./heightmap_to_stl [options] infile [outfile.stl]
infile
: The path to the input heightmap image. The program supports common image formats like PNG, JPG, etc.outfile.stl
: (Optional) The path to the output STL file. If not provided, the program can still generate normal maps or hillshade images if specified.-z, --zscale <value>
: Z scale relative to x & y (mandatory).-x, --zexagg <value>
: Z exaggeration factor. Default is 1
.-e, --error <value>
: Maximum triangulation error allowed. Default is 0.001
.-t, --triangles <value>
: Maximum number of triangles. Optional.-p, --points <value>
: Maximum number of vertices. Optional.-b, --base <value>
: Height of the solid base to add under the terrain. Default is 0
(no base).--level
: Auto-level input heightmap to use the full grayscale range.--invert
: Invert the heightmap.--blur <value>
: Apply Gaussian blur with the specified sigma. Default is 0
(no blur).--gamma <value>
: Apply a gamma curve with the specified exponent. Default is 0
(no gamma correction).--border-size <value>
: Add a border of the specified size in pixels around the heightmap. Default is 0
.--border-height <value>
: Z height of the border. Default is 1
.--normal-map <path>
: Path to write the normal map PNG.--shade-path <path>
: Path to write the hillshade PNG.--shade-alt <value>
: Hillshade light altitude angle. Default is 45
.--shade-az <value>
: Hillshade light azimuth angle. Default is 0
.-q, --quiet
: Suppress console output.The application consists of several key components:
The core of the application is the triangulation process, which converts the heightmap into a 3D mesh. The triangulator dynamically adds points based on error metrics, aiming to use the fewest points necessary to represent the terrain accurately within the specified error tolerance. It implements a variation of the Delaunay triangulation algorithm optimized for heightmaps, with a focus on generating a mesh that accurately represents the terrain’s features while controlling the number of triangles.
Optionally, a solid base can be added under the terrain model. This is useful for creating models that can stand on their own or for adding thickness for 3D printing purposes.
Gaussian Blur: Implemented following Ivan Kutskir’s method for a fast Gaussian blur, which uses three box blurs to approximate a Gaussian kernel. This method significantly reduces the computational cost compared to a direct Gaussian blur implementation.
Triangulation: The application first establishes a basic triangulation covering the entire heightmap and then iteratively refines the mesh. It inserts new points at locations where the current triangulation deviates from the heightmap by more than the specified error tolerance. This
process involves checking candidate points for each triangle and determining if adding a point reduces the error. It uses a priority queue to manage triangles based on their maximum error, ensuring the algorithm always works on the most erroneous triangle.
Legalization: After inserting a point and creating new triangles, the application checks if the Delaunay criterion is violated (i.e., if there’s a point inside the circumcircle of any triangle) and performs edge flips to restore the Delaunay property. This step is crucial for maintaining a mesh that accurately represents the underlying terrain.
This application is suitable for GIS professionals, game developers, or anyone interested in converting heightmaps into 3D models, whether for visualization, analysis, or 3D printing.