Building a Reliable CAD/STEP and GLB to USDZ Conversion Pipeline for Apple Vision Pro

A practical, production-grade guide to building a robust backend conversion pipeline that reliably transforms CAD/STEP and GLB files into high-quality USDZ for Apple Vision Pro, iOS, and industrial spatial computing workflows.

Building a Reliable CAD/STEP and GLB to USDZ Conversion Pipeline for Apple Vision Pro

Building a Reliable CAD/STEP and GLB to USDZ Conversion Pipeline for Apple Vision Pro

Delivering high-quality 3D models to Apple Vision Pro presents a significant technical challenge: most engineering teams work with STEP (or other CAD) files, while Apple platforms expect optimized USDZ files for RealityKit.

Direct conversion inside a single HTTP request works for simple demos but fails quickly with real industrial assets. Large assemblies, complex NURBS geometry, heavy textures, and strict server resource limits often cause timeouts, missing textures, lost part names, and incorrect scaling.

In this article, we share our production-grade pipeline that reliably converts both STEP and GLB files into high-quality USDZ files suitable for Apple Vision Pro applications.

1. Why a Dedicated Conversion Pipeline Is Necessary

STEP files contain precise engineering data (NURBS surfaces, metadata, assemblies with thousands of parts). Converting them requires heavy tessellation and careful handling. GLB files, while mesh-based, still need material normalization, texture processing, and USDZ-specific optimizations.

Our final architecture separates concerns for stability and scalability:

User uploads STEP or GLB file
  ↓
API validates file and creates async job
  ↓
Worker picks up job from queue
  ↓
STEP → GLB conversion (dedicated service)
  ↓
GLB → USDZ conversion with scene normalization
  ↓
Post-processing (mesh names, scale, materials)
  ↓
USDZ uploaded to CDN
  ↓
Client receives job status and download URL

2. Core Conversion Technologies

  • STEP → GLB: Powered by cascadio (Python library v0.0.17) built on top of OCCT (Open CASCADE Technology). This combination provides robust STEP parsing, tessellation, and GLB export while preserving hierarchy and part names.
  • GLB → USDZ: Uses Three.js with the official USDZExporter, running entirely on Node.js with extensive polyfills and post-processing.

3. API Design – Fully Asynchronous

All heavy conversions are processed asynchronously to prevent API timeouts.

Endpoint Method Purpose
POST /model-converter/jobs POST Upload STEP or GLB file and create a new conversion job. Returns job ID immediately.
GET /model-converter/jobs/:jobId GET Check the current status of a conversion job (queued, processing, completed, or failed).
GET /model-converter/jobs/:jobId/download GET Download the final USDZ file after successful conversion.

4. STEP to GLB Conversion

We run a dedicated NestJS service for STEP processing because tessellation is CPU and memory intensive.

async convertStepToGlb(fileBuffer: Buffer, originalName: string): Promise<Buffer> {
  const formData = new FormData();
  formData.append('file', fileBuffer, originalName);

  const response = await firstValueFrom(
    this.httpService.post(`${this.occtServiceUrl}/convert/step-to-glb`, formData, {
      headers: formData.getHeaders(),
      responseType: 'arraybuffer',
      timeout: 300_000,
    })
  );
  return Buffer.from(response.data);
}

5. GLB to USDZ Conversion

This step requires significant Node.js polyfilling because Three.js and USDZExporter were originally designed for browser environments.

async convertGlbToUsdz(glbBuffer: Buffer, originalName?: string): Promise<Buffer> {
  ensureNodeRuntime();           // Blob, fetch, canvas, Image polyfills
  await ensureImageLoaderPatch();

  const scene = new THREE.Scene();
  const loader = new GLTFLoader();
  // Parse GLB ...

  await prepareScene(scene);     // Material normalization + texture baking
  const rawUsdz = await new USDZExporter().parse(scene, { 
    quickLookCompatible: true 
  });

  // Preserve original mesh/part names
  return postProcessUsdz(Buffer.from(rawUsdz), meshNames, rootDisplayName);
}

6. Critical Scene Preparation & Normalization

Many conversions fail silently due to unsupported materials or incorrect scaling. We apply the following steps:

  • Convert all materials to MeshStandardMaterial
  • Fix ORM textures (Occlusion/Roughness/Metalness)
  • Bake textures using canvas when necessary
  • Normalize model scale based on bounding box
  • Collect and restore original mesh names via USDA post-processing

7. Common Production Issues and Solutions

Issue Cause Solution
Missing textures Server lacks canvas / image decoding @napi-rs/canvas + custom ImageLoader patch
Parts disappear in USDZ Unsupported materials Force MeshStandardMaterial + proper side setting
Wrong scale in Vision Pro CAD units vary wildly Automatic bounding box normalization
Lost part names USDZExporter renames objects Name collection + USDA post-processing
Frequent timeouts Synchronous conversion Async jobs + dedicated STEP service

Conclusion

A reliable STEP and GLB to USDZ conversion pipeline is far more than just calling an exporter. It requires:

  • Clear separation between API layer and heavy processing
  • Dedicated service for CAD tessellation using cascadio + OCCT
  • Robust Node.js environment with comprehensive polyfills for Three.js
  • Thoughtful scene normalization and post-processing
  • Proper error handling, timeouts, and monitoring

This pipeline has proven stable under production load and forms the foundation for our 3D workflow serving engineering visualization and AR training use cases.