How to Debug Unexpected Results When Remeshing with AutoRemesher
Enable debug builds with -DAUTO_REMESHER_DEBUG and attach a progress callback to trace the voxel-size, island-splitting, and parameterization stages that determine final quad-mesh quality.
AutoRemesher (huxingyi/autoremesher) is a C++ library that converts triangular meshes into quad-dominant surfaces using a multi-stage pipeline. When you encounter incorrect density, distorted geometry, or missing features, you need to trace execution through the voxel-size initialization, island separation, and per-island parameterization logic implemented in the core source files.
Understanding the Remeshing Pipeline
Debugging requires familiarity with the seven-stage execution flow defined in src/AutoRemesher/autoremesher.cpp:
| Stage | Function / Class | Source Location |
|---|---|---|
| Voxel-size computation | initializeVoxelSize |
Lines 18-23 |
| Island splitting | MeshSeparator::splitToIslands |
Lines 38-41 |
| Island-context building | IslandContext construction |
Lines 56-91 |
| Isotropic remeshing | resample |
Lines 92-99 |
| Parameterization | Parameterizer |
Lines 95-108 |
| Quad extraction | QuadExtractor |
Lines 133-140 |
| Merging | Result concatenation | Lines 68-91 |
Each stage operates on the output of the previous one. Failures in early stages (like incorrect voxel sizing) propagate to produce unexpected final meshes.
Common Sources of Unexpected Results
Symptoms map directly to specific pipeline stages:
- Incorrect quad count: Check
targetTriangleCountandinitializeVoxelSizeat lines 18-23. EnableAUTO_REMESHER_DEBUGto viewArea:andvoxelSize:console output. - Distorted geometry: Verify
adaptivityvalues and inspectvertexTargetLengthsin theresamplestage (lines 66-80). Extreme multipliers produce non-uniform edge lengths. - Missing sharp edges: Confirm you called
setSharpEdgeDegreesbeforeremesh(). The setter is defined at lines 80-84; the default may be too low for your geometry. - Faceted normals: Set
smoothNormalDegreesto a positive value (e.g., 30.0). The default of 0 produces flat shading. - Empty output: Indicates empty input or total parameterization failure. The code prints "Input mesh is empty" at lines 45-49 and catches exceptions at lines 15-27.
- Partial mesh loss: One island failed during parameterization. Look for "parameterization failed … skipping this island" in the console output.
Step-by-Step Debugging Workflow
1. Enable Debug Builds
Compile with the AUTO_REMESHER_DEBUG flag to activate qDebug statements throughout the pipeline:
qmake DEFINES+=AUTO_REMESHER_DEBUG
make -j$(nproc)
2. Attach a Progress Handler
The ReportProgress mechanism (lines 44-64) allows real-time inspection. Implement a callback to identify which island or stage is active:
void progressCallback(void* tag, float progress, const char* status) {
std::cout << "[ " << int(progress * 100) << "% ] "
<< status << std::endl;
}
// In your main code:
AutoRemesher::AutoRemesher remesher(vertices, triangles);
remesher.setProgressHandler(progressCallback);
remesher.remesh();
3. Inspect Voxel Size Initialization
After calling remesh(), the debug log prints:
Area: <value> voxelSize: <value>
If the voxel size is unexpectedly large or small, verify your calls to setTargetTriangleCount and setScaling. The calculation occurs in initializeVoxelSize (lines 18-23).
4. Verify Island Separation
The log outputs Split to islands: followed by the count. A high island count suggests non-manifold input geometry. Validate and clean your mesh in an external tool like MeshLab before processing.
5. Check Adaptive Edge Lengths
When adaptivity > 0, the code computes per-vertex target lengths (lines 66-80). Add temporary instrumentation to dump these values:
for (double len : vertexTargetLengths) {
qDebug() << "Target length:" << len;
}
Min/max values outside your expected range indicate incorrect adaptivity settings or extreme curvature misinterpretation.
6. Catch Parameterization Failures
The library wraps island processing in try-catch blocks (lines 15-27). If you see "parameterization failed … skipping this island," export the specific island geometry for external analysis:
// Access island vertices/triangles from the IslandContext
// and write to an OBJ file for inspection in Blender or MeshLab
7. Final Mesh Inspection
After merging (lines 68-91), the debug build prints execution timing and final counts at lines 102-109. Compare the remeshedQuads() array size against the number of processed islands to detect extraction failures.
Complete Debugging Example
This example demonstrates a fully instrumented remeshing session:
#include <AutoRemesher/AutoRemesher>
#include <vector>
#include <iostream>
void progress(void* /*tag*/, float p, const char* s) {
std::cout << "[ " << int(p * 100) << "% ] " << s << std::endl;
}
int main() {
std::vector<AutoRemesher::Vector3> verts = {/* ... */};
std::vector<std::vector<size_t>> faces = {/* ... */};
AutoRemesher::AutoRemesher remesher(verts, faces);
remesher.setTargetTriangleCount(50000);
remesher.setScaling(1.0);
remesher.setModelType(AutoRemesher::ModelType::Organic);
remesher.setGradientAdaptivity(1.0);
remesher.setSharpEdgeDegrees(90.0); // Retain 90° edges
remesher.setSmoothNormalDegrees(30.0); // Smooth normals up to 30°
remesher.setProgressHandler(progress);
if (!remesher.remesh()) {
std::cerr << "Remeshing failed!" << std::endl;
return 1;
}
const auto& outVerts = remesher.remeshedVertices();
const auto& outQuads = remesher.remeshedQuads();
std::cout << "Success: " << outVerts.size()
<< " vertices, " << outQuads.size()
<< " quads generated." << std::endl;
}
Compile with DEFINES+=AUTO_REMESHER_DEBUG to generate the diagnostic logs referenced above.
Key Source Files for Debugging
Prioritize these files when tracing specific behaviors:
src/AutoRemesher/autoremesher.h: Public API includingsetSharpEdgeDegrees,setSmoothNormalDegrees, and the progress handler interface.src/AutoRemesher/autoremesher.cpp: Core pipeline implementation withinitializeVoxelSize, island management, and progress reporting (lines 44-64).thirdparty/isotropicremesher/isotropicremesher.cpp: Low-level isotropic remeshing logic used per-island.src/AutoRemesher/Parameterizer.cpp: Frame field and UV mapping construction where most geometric failures originate.src/AutoRemesher/QuadExtractor.cpp: Quad topology extraction from parameterized surfaces.src/AutoRemesher/MeshSeparator.cpp: Connected-component analysis that splits inputs into islands.
Summary
- Enable debug mode with
-DAUTO_REMESHER_DEBUGto expose internal state logs. - Use the progress callback to pinpoint which island or stage is failing.
- Validate voxel size output if quad density is incorrect; adjust
targetTriangleCountaccordingly. - Check island count to detect non-manifold input that causes fragmentation.
- Inspect edge lengths when
adaptivityproduces distortion. - Verify setters like
setSharpEdgeDegreesandsetSmoothNormalDegreesare called beforeremesh().
Frequently Asked Questions
Why is my remeshed mesh empty?
An empty output indicates either an empty input mesh (checked at lines 45-49) or total failure of all islands during parameterization. Check the console for "Input mesh is empty" or "parameterization failed" messages. If islands are failing, isolate one and test it individually to identify pathological geometry.
How do I fix distorted or stretched quads?
Distortion typically stems from extreme adaptivity values or incorrect voxel sizing. Check the voxelSize: debug log immediately after initialization. If adaptivity is enabled, inspect vertexTargetLengths in resample (lines 66-80) to ensure curvature-based multipliers are within reasonable bounds (typically 0.5x to 2.0x base length).
Why are sharp edges being smoothed out?
The remesher respects feature edges only when explicitly configured. Call setSharpEdgeDegrees(90.0) (or your desired angle threshold) before remesh(). The setter is located at lines 80-84 in autoremesher.cpp. Without this call, the algorithm treats all edges as smooth regardless of dihedral angle.
How do I enable detailed logging throughout the pipeline?
Define AUTO_REMESHER_DEBUG during compilation. Use qmake DEFINES+=AUTO_REMESHER_DEBUG when building. This activates qDebug() statements that print voxel sizes, island counts, per-island timing, and parameterization errors to standard 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 →