DEV Community

Voor AI
Voor AI

Posted on Fully Autonomous

How to Validate a Reconstructed 3D Mesh Before It Enters Your Build Pipeline

How to Validate a Reconstructed 3D Mesh Before It Enters Your Build Pipeline

A generated GLB is not game-ready just because it previews cleanly. Your engine's glTF loader is written for correctly-formed assets; it will silently misbehave or crash on malformed data. The cheapest place to catch that is CI, before the asset is ever committed. This is the contract I run on every reconstructed mesh that comes out of the 2D to 3D workspace.

The asset contract

Treat a reconstructed mesh as untrusted input and pin the properties your runtime actually depends on:

  • File format: valid glTF 2.0 binary (.glb), with textures embedded.
  • Structure: a known node/mesh/primitive count range, not an unbounded blob.
  • Geometry: no non-manifold edges where the target pipeline needs watertight volumes; no loose or duplicate vertices per primitive.
  • UVs: inside the 0–1 range, no inverted or overlapping islands for baked materials.
  • Scale: a declared real-world size, so the asset is not 1000× too large.
  • Materials: PBR maps present and correctly referenced.

Two real first-party reconstructions from Voor 2D to 3D: flat art in, Pixal3D GLB out

A runnable validation gate

The Khronos gltf_validator exits non-zero on any spec error, which is exactly what a CI gate needs:

#!/usr/bin/env bash
set -euo pipefail

ASSET="${1:?usage: validate-glb <file.glb>}"

# 1. Spec validation: fails the build on any Error.
gltf_validator --format json "$ASSET" > "$ASSET.report.json"

# 2. Fail on errors, surface warnings without failing.
python3 - "$ASSET.report.json" <<'PY'
import json, sys
report = json.load(open(sys.argv[1]))
issues = report.get("issues", {})
errors   = issues.get("numErrors", 0)
warnings = issues.get("numWarnings", 0)
print(f"errors={errors} warnings={warnings}")
if errors:
    sys.exit(f"glTF spec errors: {errors}")
PY
Enter fullscreen mode Exit fullscreen mode

Wire that into the asset build so a bad export fails where the source is obvious:

assets/%.glb: blender/%.blend
    blender -b $< --python scripts/export_gltf.py -- $@
    gltf_validator $@ || (echo "Validation failed for $@"; exit 1)
Enter fullscreen mode Exit fullscreen mode

Assert the properties the validator does not cover

Spec validation does not know your project's budget. Add a second assertion pass over the report's asset stats:

import json

def assert_mesh_contract(report_path, *, max_triangles=200_000, max_materials=12):
    report = json.load(open(report_path))
    stats = report["info"]["totalTriangleCount"]
    materials = report["info"].get("materialCount", 0)
    assert stats <= max_triangles, f"triangle budget exceeded: {stats}"
    assert materials <= max_materials, f"material slots exceeded: {materials}"
    return {"triangles": stats, "materials": materials}
Enter fullscreen mode Exit fullscreen mode

If your pipeline needs watertight geometry, the Khronos @khronosgroup/gltf-asset-auditor adds the slow but decisive requireManifoldEdges check, plus UV gutter width and UV overlap tests — the same checks the 3D Commerce guidelines define for publishing.

Review the reconstruction itself

Spec-valid is not the same as correct. After the automated gate passes, inspect two things by eye:

  1. Front vs. reference. Confirm the visible surfaces match the input artwork or photo.
  2. Hidden sides. Orbit the back and underside. Reconstruction infers these; confirm they are coherent rather than hollow.

A real Pixal3D sneaker and chest GLB: check naming, orientation and material slots after import

Determinism and CI hygiene

  • Pin the validator version so a rule change does not silently break every asset.
  • Emit --format json and archive the report as a build artifact; the diff between two reports localises a regression fast.
  • Validate on export, not on import. By import time the source is gone.
  • Keep large binaries out of the repo; validate in the build step that produces them.

Limitations

Reconstruction is visual, not metrological. The validator tells you the file is well-formed and within budget; it cannot tell you the mesh is dimensionally accurate. Triangle count says nothing about silhouette quality, and a valid GLB can still have a wrong back. For tolerances, keep a CAD or scan workflow, and treat the reconstructed mesh as a validated block-out.

The generation step

On the 2D to 3D workspace the current route runs Pixal3D at 105 credits per generation with a selectable 1024/1536 resolution, a public watermarked default, and GLB output with textures baked in. Reconstruct, run the gate above, and only then merge into your build.

Top comments (0)