# How the Python cadpy Library Generates GLB Meshes from STEP Files

> Learn how the Python cadpy library creates GLB meshes from STEP files. Explore its process of parsing geometry, triangulating, and serializing with glTF builder support for efficient 3D model conversion.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-08-01

---

**The Python cadpy library converts STEP files into optimized GLB meshes by parsing the STEP geometry into a hierarchical scene, triangulating occurrences with per-vertex attributes, and serializing the result through a glTF builder that supports STEP topology extensions and Y-up coordinate conversion.**

The cadpy package, maintained in the earthtojake/text-to-cad repository, provides a complete pipeline for transforming CAD STEP files into binary glTF (GLB) format suitable for web viewers and game engines. Understanding how to generate GLB meshes from STEP files using the Python cadpy library involves four distinct stages: parsing the STEP structure, creating mesh payloads with topological metadata, composing the glTF hierarchy, and writing the final binary file.

## Step 1: Parse STEP Files into Scene Graphs

The pipeline begins in [`cadpy/step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/step_scene.py) with the **`load_step_scene`** function. This utility reads a STEP file using the underlying `build123d` library and constructs a **`LoadedStepScene`** object—a hierarchical tree of **`OccurrenceNode`** instances that represent the CAD assembly structure.

Each occurrence node stores:
- **Prototype geometry** references
- **Local transforms** for positioning
- **Occurrence IDs** (`occurrence_selector_id`) for stable part identification
- **Color metadata** defined in the original STEP file

The resulting scene graph preserves the topological relationships between parts, enabling accurate assembly export later in the pipeline.

## Step 2: Generate Mesh Payloads with Topological Data

Once the scene is loaded, [`cadpy/glb_mesh_payload.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb_mesh_payload.py) exposes **`scene_glb_mesh_payload`**, which traverses the `LoadedStepScene` and converts geometric prototypes into triangulated mesh data. This function computes:

- **Vertex positions** and **normals** for surface shading
- **Barycentric coordinates** for wireframe rendering
- **Edge-class attributes** (`STEP_EDGE_CLASS_ATTRIBUTE`) that encode STEP edge visibility data
- Optional **per-face colors** when color overrides are specified

The output is a **`ShapeGlbMeshPayload`** containing all vertex buffers and indices required for glTF composition. The meshing process respects CAD-specific parameters like `linear_deflection` and `angular_deflection` to control tessellation quality.

## Step 3: Compose the GLB Hierarchy

The **`_HierarchicalGlbWriter`** class in [`cadpy/glb.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb.py) orchestrates the conversion from mesh payloads to glTF structures. This writer handles:

- **Material assignment**: Determining final colors from default materials, occurrence-specific colors, or user-supplied overrides
- **Mesh caching**: Using a **`scene_glb_mesh_payload_key`** to avoid duplicating identical geometry instances
- **Topology injection**: Optionally embedding STEP selector metadata via `add_step_topology`, which writes occurrence IDs and edge visibility into a custom glTF extension named `STEP_TOPOLOGY_EXTENSION`

The writer creates glTF nodes that mirror the original STEP hierarchy, preserving assembly relationships for interactive CAD viewers.

## Step 4: Serialize to Binary GLB Format

The **`_GlbBuilder`** class (also in [`cadpy/glb.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb.py)) handles the low-level binary serialization. It constructs the glTF JSON structure—defining scenes, nodes, meshes, materials, buffer views, and accessors—and packs vertex data into aligned binary buffers.

The builder writes a standard GLB v2 file consisting of:
1. A 12-byte header with magic number and version
2. A JSON chunk containing the glTF scene description
3. A binary chunk holding vertex and index data

This implementation ensures compatibility with standard glTF 2.0 viewers while preserving CAD-specific metadata through extensions.

## Export Variants and Coordinate Systems

The `cadpy.glb` module provides three entry points for different export scenarios:

- **`export_part_glb_from_scene`**: Exports a single-part GLB optimized for individual mesh viewing
- **`export_assembly_glb_from_scene`**: Exports full assemblies with per-occurrence color mapping via the `occurrence_colors` parameter
- **`export_native_glb_from_scene`**: Performs Y-up coordinate conversion, flipping the CAD Z-up convention to the Y-up system used by most game engines and real-time renderers

## Working with STEP Topology Extensions

For applications requiring CAD-level selection capabilities, [`cadpy/glb_topology.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb_topology.py) implements readers for the embedded STEP topology manifest. Functions like `read_step_topology_bundle_from_glb` and `read_step_topology_index_from_glb` extract the `STEP_TOPOLOGY_EXTENSION` data, enabling downstream tools to map rendered triangles back to original STEP faces and edges.

## Practical Implementation: Exporting STEP to GLB

### Exporting a Single Part with Default Settings

```python
from pathlib import Path
from cadpy.step_scene import load_step_scene
from cadpy.glb import export_part_glb_from_scene

# Load the STEP file into a scene graph

step_path = Path("models/bracket.step")
scene = load_step_scene(step_path)

# Generate GLB with specific tessellation quality

glb_path = export_part_glb_from_scene(
    step_path,
    scene,
    linear_deflection=0.01,      # Controls chordal deviation

    angular_deflection=0.5,      # Controls angle between facets

    color=None,                  # Use default STEP colors

    selector_bundle=None,
    include_selector_topology=True,  # Embed edge visibility data

)
print(f"GLB written to: {glb_path}")

```

### Exporting an Assembly with Custom Colors

```python
from cadpy.glb import export_assembly_glb_from_scene
from cadpy.step_scene import load_step_scene
from pathlib import Path

step_path = Path("models/assembly.step")
scene = load_step_scene(step_path)

# Map occurrence IDs to RGBA tuples

occurrence_colors = {
    "occ1": (1.0, 0.0, 0.0, 1.0),  # Red housing

    "occ2": (0.0, 0.5, 1.0, 1.0),  # Blue fastener

}

glb_path = export_assembly_glb_from_scene(
    step_path,
    scene,
    linear_deflection=0.02,
    angular_deflection=0.7,
    occurrence_colors=occurrence_colors,  # Per-part color override

)

```

## Summary

- The pipeline starts with **`load_step_scene`** in [`cadpy/step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/step_scene.py), which parses STEP files into a `LoadedStepScene` hierarchy using `build123d`.
- Mesh generation occurs in **`scene_glb_mesh_payload`** from [`cadpy/glb_mesh_payload.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb_mesh_payload.py), computing vertex positions, normals, barycentrics, and edge-class attributes.
- The **`_HierarchicalGlbWriter`** class in [`cadpy/glb.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb.py) manages material assignment, mesh caching by payload key, and optional STEP topology embedding via `STEP_TOPOLOGY_EXTENSION`.
- Final serialization uses **`_GlbBuilder`** to create GLB v2 compliant files with proper JSON and binary chunk alignment.
- Three export variants support part-level, assembly-level with occurrence colors, and native Y-up coordinate conversion for game engine compatibility.

## Frequently Asked Questions

### How does cadpy handle coordinate system conversion for game engines?

The **`export_native_glb_from_scene`** function in [`cadpy/glb.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb.py) automatically converts the CAD-native Z-up coordinate system to Y-up, which is the standard for Unity, Unreal Engine, and most webGL viewers. This transformation is applied during the hierarchical node construction phase before final GLB serialization.

### What is the purpose of occurrence IDs in the generated GLB?

Each occurrence in the STEP model receives a stable **`occurrence_selector_id`** during the `load_step_scene` parsing phase. These IDs are embedded into the GLB via the `STEP_TOPOLOGY_EXTENSION` and enable downstream CAD viewers to select individual parts, isolate components, or map rendered geometry back to the original STEP topology using functions like `read_step_topology_index_from_glb`.

### Can I embed custom colors for specific parts when exporting an assembly?

Yes. The **`export_assembly_glb_from_scene`** function accepts an `occurrence_colors` parameter that maps occurrence ID strings to RGBA float tuples. The **`_HierarchicalGlbWriter`** uses these values to override default STEP colors when generating glTF materials, allowing per-part customization without modifying the source CAD file.

### Where does cadpy store edge visibility data in the GLB file?

Edge visibility classifications from the STEP file are stored as a vertex attribute named **`STEP_EDGE_CLASS_ATTRIBUTE`** within the mesh payload. When `include_selector_topology=True` is passed to the export function, this data is preserved in the GLB and can be accessed via the topology extension readers in [`cadpy/glb_topology.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/glb_topology.py), enabling accurate wireframe rendering and edge selection in compatible viewers.