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

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, 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).

  • 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).

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

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:

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:

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), 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 (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.

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 →