# How to Debug Unexpected Results When Remeshing with AutoRemesher

> Debug unexpected AutoRemesher results by enabling debug builds with -DAUTO_REMESHER_DEBUG and attaching a progress callback to trace the voxel-size island-splitting and parameterization stages.

- Repository: [Jeremy HU/autoremesher](https://github.com/huxingyi/autoremesher)
- Tags: how-to-guide
- Published: 2026-07-11

---

**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`](https://github.com/huxingyi/autoremesher/blob/main/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:

```bash
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:

```cpp
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:

```cpp
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:

```cpp
// 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:

```cpp
#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`](https://github.com/huxingyi/autoremesher/blob/main/src/AutoRemesher/autoremesher.h)**: Public API including `setSharpEdgeDegrees`, `setSmoothNormalDegrees`, and the progress handler interface.
- **[`src/AutoRemesher/autoremesher.cpp`](https://github.com/huxingyi/autoremesher/blob/main/src/AutoRemesher/autoremesher.cpp)**: Core pipeline implementation with `initializeVoxelSize`, island management, and progress reporting (lines 44-64).
- **[`thirdparty/isotropicremesher/isotropicremesher.cpp`](https://github.com/huxingyi/autoremesher/blob/main/thirdparty/isotropicremesher/isotropicremesher.cpp)**: Low-level isotropic remeshing logic used per-island.
- **[`src/AutoRemesher/Parameterizer.cpp`](https://github.com/huxingyi/autoremesher/blob/main/src/AutoRemesher/Parameterizer.cpp)**: Frame field and UV mapping construction where most geometric failures originate.
- **[`src/AutoRemesher/QuadExtractor.cpp`](https://github.com/huxingyi/autoremesher/blob/main/src/AutoRemesher/QuadExtractor.cpp)**: Quad topology extraction from parameterized surfaces.
- **[`src/AutoRemesher/MeshSeparator.cpp`](https://github.com/huxingyi/autoremesher/blob/main/src/AutoRemesher/MeshSeparator.cpp)**: Connected-component analysis that splits inputs into islands.

## 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`](https://github.com/huxingyi/autoremesher/blob/main/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.