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 targetTriangleCount and initializeVoxelSize at lines 18-23. Enable AUTO_REMESHER_DEBUG to view Area: and voxelSize: console output.
  • Distorted geometry: Verify adaptivity values and inspect vertexTargetLengths in the resample stage (lines 66-80). Extreme multipliers produce non-uniform edge lengths.
  • Missing sharp edges: Confirm you called setSharpEdgeDegrees before remesh(). The setter is defined at lines 80-84; the default may be too low for your geometry.
  • Faceted normals: Set smoothNormalDegrees to 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:

Summary

  • Enable debug mode with -DAUTO_REMESHER_DEBUG to 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 targetTriangleCount accordingly.
  • Check island count to detect non-manifold input that causes fragmentation.
  • Inspect edge lengths when adaptivity produces distortion.
  • Verify setters like setSharpEdgeDegrees and setSmoothNormalDegrees are called before remesh().

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →