Understanding the Voxel Size Calculation in AutoRemesher
AutoRemesher calculates voxel size by deriving the target edge length from the input mesh's total surface area divided by the user-specified target triangle count, then uses this value as the uniform target edge length to control mesh density during the remeshing process.
AutoRemesher is an open-source automatic remeshing library that converts arbitrary triangle meshes into high-quality, isotropic triangle meshes suitable for simulation or rendering. The voxel size calculation serves as the fundamental length scale that determines how finely the resulting mesh subdivides the original geometry, directly impacting the balance between geometric fidelity and polygon count.
The Geometric Formula Behind Voxel Size
The core calculation occurs in AutoRemesher::initializeVoxelSize() within [src/AutoRemesher/autoremesher.cpp](https://github.com/huxingyi/autoremesher/blob/master/src/AutoRemesher/autoremesher.cpp) (lines 122-124):
double area = calculateMeshArea(m_vertices, m_triangles);
double triangleArea = area / m_targetTriangleCount;
m_voxelSize = std::sqrt(triangleArea / (0.86602540378 * 0.5));
This formula computes the ideal edge length for equilateral triangles that would uniformly tile the mesh surface while achieving the desired polygon budget.
Step-by-Step Implementation
-
Surface Area Summation –
calculateMeshArea()iterates over all input triangles to compute the total mesh surface area. -
Average Triangle Area – Dividing the total
areabym_targetTriangleCountyields the mean area each triangle should occupy in the remeshed result. -
Edge Length Extraction – The constant
0.86602540378 * 0.5equals √3⁄4 (approximately 0.4330127019), which is the area formula constant for equilateral triangles (Area = e² × √3⁄4). Dividing by this factor converts the target area into squared edge length. -
Final Voxel Size – Taking the square root yields the target edge length
e, stored inm_voxelSizeas the uniform target length for the isotropic remesher.
How Voxel Size Affects Remeshing Results
According to the huxingyi/autoremesher source code, the computed m_voxelSize propagates through the remeshing pipeline as the target edge length parameter:
-
Uniform remeshing – At lines 288-289 in
autoremesher.cpp, the code passesm_voxelSizetosetTargetEdgeLength(voxelSize)for each mesh island, establishing the baseline edge length for the isotropic remeshing algorithm. -
Density control – A smaller voxel size produces shorter target edges and a denser mesh with more triangles, capturing finer geometric details. A larger voxel size generates longer edges and a coarser mesh with fewer triangles, improving performance at the cost of fidelity.
-
Adaptive scaling – When curvature-based adaptivity is enabled, the base voxel size serves as the fundamental scale for local refinement. The source code scales the voxel size per-vertex using curvature multipliers:
vertexTargetLengths[v] = voxelSize * multiplier. This preserves the overall density goal while concentrating triangles in high-curvature regions.
Implementation Across the Codebase
The voxel size calculation bridges high-level user parameters with low-level remeshing operations through these key components:
src/AutoRemesher/autoremesher.h
- Declares the public API methods
setTargetTriangleCount()andsetAdaptivity()that influence the voxel size computation.
src/AutoRemesher/autoremesher.cpp
- Implements
initializeVoxelSize()to perform the geometric calculation. - Orchestrates the remeshing pipeline by passing computed voxel sizes to the isotropic remesher instances.
src/AutoRemesher/isotropicremesher.h and isotropicremesher.cpp
- Receive the voxel size via
setTargetEdgeLength()and execute the actual remeshing algorithm to generate triangles approaching the specified uniform edge length.
Practical Usage Example
To control remeshing density, set the target triangle count before executing the remesh operation:
#include <AutoRemesher/AutoRemesher>
#include <vector>
// Load mesh data
std::vector<Vector3> vertices = /* ... */;
std::vector<std::vector<size_t>> triangles = /* ... */;
AutoRemesher remesher;
remesher.setVertices(vertices);
remesher.setTriangles(triangles);
// Set target polygon count (influences voxel size calculation)
remesher.setTargetTriangleCount(5000);
// Optional: enable curvature-based adaptivity (scales voxel size locally)
remesher.setAdaptivity(0.2);
if (remesher.remesh()) {
const auto& newVertices = remesher.remeshedVertices();
const auto& newTriangles = remesher.remeshedTriangles();
// Process the uniformly remeshed result
}
In this workflow, setTargetTriangleCount(5000) triggers the voxel size formula to compute an edge length that yields approximately 5,000 triangles, while setAdaptivity(0.2) permits local deviation from this target based on surface curvature.
Summary
- Voxel size derives from geometry – The calculation uses the mesh surface area and target triangle count to solve for the equilateral triangle edge length that achieves uniform coverage.
- Constants encode geometry – The value
0.86602540378 * 0.5represents √3⁄4, converting between triangle area and edge length for equilateral geometry. - Controls remeshing density – The computed size becomes the
targetEdgeLengthparameter for the isotropic remesher, directly determining output mesh density. - Supports adaptive refinement – When adaptivity is enabled, the voxel size acts as a base scale factor multiplied by curvature-based per-vertex multipliers.
Frequently Asked Questions
How does the target triangle count parameter translate to actual mesh density?
The target triangle count inversely determines the voxel size through the area-to-edge-length formula. Setting a higher count reduces the calculated triangleArea, which shrinks the voxel size and forces the isotropic remesher to produce smaller triangles. Conversely, a lower count increases the voxel size and produces coarser geometry.
Why does the voxel size formula use the constant 0.86602540378?
This constant represents √3⁄2, and when multiplied by 0.5 it yields √3⁄4 (approximately 0.4330127019). This is the area formula constant for equilateral triangles (Area = e² × √3⁄4). The code divides the target triangle area by this constant to isolate the squared edge length before taking the square root.
How does the adaptivity parameter interact with the base voxel size?
The adaptivity parameter enables curvature-aware scaling where the base voxel size serves as a reference scale. The algorithm computes per-vertex multipliers based on local curvature, then calculates final target lengths as voxelSize * multiplier. This allows high-detail regions to receive smaller triangles while maintaining the global triangle budget approximately.
What happens if I request a target triangle count larger than the original mesh contains?
The formula will compute a voxel size smaller than the original mesh's average edge length. According to the implementation in autoremesher.cpp, this triggers finer subdivision during the isotropic remeshing phase, potentially increasing vertex count and computational cost but preserving the requested density in the output.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →