How the Python cadpy Library Generates GLB Meshes from STEP Files
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 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 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 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_keyto 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 namedSTEP_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) 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:
- A 12-byte header with magic number and version
- A JSON chunk containing the glTF scene description
- 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 viewingexport_assembly_glb_from_scene: Exports full assemblies with per-occurrence color mapping via theoccurrence_colorsparameterexport_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 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
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
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_sceneincadpy/step_scene.py, which parses STEP files into aLoadedStepScenehierarchy usingbuild123d. - Mesh generation occurs in
scene_glb_mesh_payloadfromcadpy/glb_mesh_payload.py, computing vertex positions, normals, barycentrics, and edge-class attributes. - The
_HierarchicalGlbWriterclass incadpy/glb.pymanages material assignment, mesh caching by payload key, and optional STEP topology embedding viaSTEP_TOPOLOGY_EXTENSION. - Final serialization uses
_GlbBuilderto 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 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, enabling accurate wireframe rendering and edge selection in compatible viewers.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →