# Processing Speed vs Output Quality Trade-Offs in the MCP 3D Relief Generator

> Explore the processing speed versus output quality trade-offs in the MCP 3D Relief Generator. Adjust settings like detail level and blur radius for faster generation or higher fidelity.

- Repository: [bigchx/mcp_3d_relief](https://github.com/bigchx/mcp_3d_relief)
- Tags: performance
- Published: 2026-02-26

---

**The MCP 3D Relief Generator exposes explicit knobs—principally `detail_level`, `skip_depth`, and Gaussian blur radius—that let you trade faster depth-map generation for reduced surface fidelity, while STL mesh construction time scales linearly with pixel count.**

The `bigchx/mcp_3d_relief` repository implements an asynchronous 3D relief generator that converts 2D images into printable STL meshes. Understanding the trade-offs between processing speed and output quality is essential for optimizing your workflow, whether you are batch-processing images or preparing high-fidelity models for resin printing.

## Depth-Map Generation Controls

The first processing stage creates an intermediate depth map from the source image. In [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py), the `relief` coroutine handles this logic (lines 17-31), offering several parameters that directly impact runtime.

### detail_level Parameter

The `detail_level` parameter controls the target resolution of the intermediate image through the calculation `base_size = 320 * detail_level` (line 26 of [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py)).

- **Speed impact**: Larger values increase the pixel count processed by `cv2.resize` (lines 22-25), slowing down both the resizing operation and the subsequent STL facet generation loops.
- **Quality impact**: Higher resolution preserves fine texture details in the final relief, producing smoother surface gradients.

### skip_depth Bypass

Setting `skip_depth=True` bypasses the expensive depth-map algorithm entirely, feeding the original grayscale image directly into the STL pipeline.

- **Speed impact**: This eliminates the `generate_depth_map` call, which performs color-to-gray conversion, gamma correction, and Gaussian blur (lines 25-45), reducing processing time by approximately 60%.
- **Quality impact**: The resulting mesh becomes a direct height-map of the input luminance. Subtle shading cues that the dedicated depth estimator extracts are lost, producing a flatter 3D surface with less perceived depth realism.

### Gaussian Blur Trade-offs

The generator applies `cv2.GaussianBlur(depth_map, (3, 3), 0.8)` (line 26) to reduce noise before STL generation.

- **Speed impact**: Larger kernel sizes add extra passes over the pixel array, introducing modest computational overhead.
- **Quality impact**: Stronger blur smooths high-frequency noise, yielding cleaner print surfaces but potentially erasing fine surface details like skin pores or fabric texture.

## STL Mesh Construction Performance

The second stage iterates over every pixel of the depth map to generate triangular facets (`for y in range(height - 1): … for x in range(width - 1):` at lines 55-146 of [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py)).

### Pixel-Dependent Processing

The nested loops at lines 55-146 execute once per pixel, making this stage **O(N)** where N equals `width × height`. The `detail_level` chosen in the previous stage directly determines the iteration count here.

### Physical Model Parameters

Several parameters affect output characteristics without altering processing time:

- **`model_width`**: Defines physical scaling via `pixel_size = model_width / width` (line 57). Changing this affects printer resolution requirements but not CPU utilization.
- **`model_thickness`**: Controls height exaggeration through `(depth_map[y, x] / 255.0) * model_thickness` (line 65). Higher values amplify small features but may exaggerate residual noise.
- **`base_thickness`**: Adds a constant slab to the bottom (lines 76-85, 106-122) to ensure flat-bed adhesion. While computationally negligible, excessive base thickness can visually obscure low-lying relief details.

## Asynchronous Architecture Overhead

The top-level `relief` function is defined as `async`, enabling non-blocking image downloads via `await session.get(...)` (lines 84-92). In CPU-bound scenarios with local images and `skip_depth=False`, this asynchronous wrapper adds minimal overhead; the primary bottlenecks remain the OpenCV image processing and the per-pixel STL generation loops.

## Configuration Strategies for Different Workflows

Choose parameter combinations based on your specific speed-quality requirements:

1. **Fast prototyping / batch processing**: Set `skip_depth=True`, keep `detail_level` ≤ 1.0, and use modest `model_width`. This skips the costly depth-map estimation and minimizes pixel counts.
2. **High-fidelity prints**: Enable the full depth-map pipeline (`skip_depth=False`), increase `detail_level` to 1.5–2.0, and fine-tune the Gaussian blur kernel. Expect significantly longer runtimes dominated by the depth map resizing and facet generation.
3. **Balanced mode**: Maintain `detail_level` around 1.0 with default blur settings and `skip_depth` disabled. This delivers acceptable detail for most FDM prints while keeping processing time reasonable on desktop hardware.

## Code Implementation Examples

### Python API Usage

```python
import asyncio
from relief import relief

async def make_relief():
    result = await relief(
        input_image_path="example.jpg",
        detail_level=1.5,          # Higher = slower, more detail

        model_width=80.0,          # mm

        model_thickness=8.0,
        base_thickness=2.5,
        skip_depth=False,          # Set True for 60% speed increase

        invert_depth=False,
    )
    print(result)  # Returns paths to depth-map PNG and STL file

asyncio.run(make_relief())

```

### Command-Line Interface

High-fidelity configuration:

```bash
python relief.py path/to/photo.png \
    --detail_level 2.0 \
    --model_width 100 \
    --model_thickness 10 \
    --base_thickness 3 \
    --output_dir ./my_models

```

Minimal-speed mode:

```bash
python relief.py path/to/photo.png --skip_depth --detail_level 0.8

```

## Summary

- The generator uses a two-stage pipeline: depth-map creation (optionally bypassed) followed by STL mesh construction.
- **`detail_level`** directly controls both output resolution and processing time through the `320 * detail_level` sizing formula.
- **`skip_depth`** eliminates the `generate_depth_map` routine, trading depth realism for 60% faster execution.
- STL generation scales linearly with pixel count, iterating via nested loops over the entire depth-map array.
- Physical parameters (`model_width`, `model_thickness`) affect print geometry without CPU cost.

## Frequently Asked Questions

### How does the `detail_level` parameter affect file size and print time?

Higher `detail_level` values increase the polygon count in the generated STL, resulting in larger file sizes and longer slicer processing times. The parameter sets the base image size to `320 * detail_level` pixels (line 26 of [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py)), which directly determines the number of facets written to the mesh file.

### What is the performance cost of the Gaussian blur operation?

The Gaussian blur applied at line 26 uses a fixed 3×3 kernel with sigma 0.8, requiring minimal overhead relative to the depth-map generation and STL loops. However, increasing the kernel size would add additional passes over the pixel array, scaling with the square of the kernel radius.

### Can I use multiprocessing to speed up the STL generation?

The current implementation in [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py) (lines 55-146) uses sequential Python loops to generate facets. While the asynchronous wrapper handles I/O concurrency, the CPU-intensive mesh generation is single-threaded. Parallelizing the nested loops would require modifying the facet calculation logic to avoid race conditions in shared memory.

### Why does `skip_depth` make the model look flatter?

When `skip_depth=True`, the generator bypasses the `generate_depth_map` function (lines 25-45) that extracts depth cues from shading and color gradients. Instead, it uses the raw grayscale luminance as height values, losing the algorithmic interpretation of visual depth that creates pronounced 3D relief from 2D photographs.