How to Generate STEP Files from Natural Language Using Text-to-CAD
Text-to-CAD converts plain English descriptions into production-ready STEP files by using an LLM to generate Python scripts that describe geometry via the build123d API, then exports the result through a specialized CLI pipeline.
The text-to-cad open-source repository provides an end-to-end pipeline to generate STEP files from natural language descriptions. By chaining a large language model (LLM) with a robust CAD generation engine, the system transforms simple prompts like "a 100 mm cylinder with a 20 mm hole" into valid, manufacturable geometry. This guide explains the three-layer architecture and demonstrates how to use the CLI and Python API to convert text into STEP format.
The Three-Layer Architecture
The pipeline operates through three distinct layers that handle the transformation from natural language to final CAD output.
Layer 1: Natural Language to Python Script
The cad skill uses an LLM (configured in skills/cad/agents/openai.yaml) to parse user prompts and emit Python modules. These generated scripts define a gen_step() function (or gen_assembly() for assemblies) that uses the build123d API provided by the cadpy package to describe geometry.
For example, the prompt "a rectangular block 100 mm × 50 mm × 20 mm with a 10 mm hole through the short side" generates a script like:
from build123d import *
def gen_step():
# rectangular block
block = Box(100, 50, 20)
# hole through the short side
hole = Cylinder(r=5, h=50).rotate((0, 0, 90))
result = block - hole
return result
The script is saved to a file (e.g., parts/block.py) and passed to the generation layer.
Layer 2: CLI to Generation Engine
The scripts/step CLI in skills/cad/scripts/step/cli.py parses command-line arguments and forwards requests to the core generation engine. The entry point cli.main builds an argparse.ArgumentParser (_add_step_arguments), normalizes numeric flags (_normalize_cli_numeric), and calls cadpy.generation.generate_step_targets at line 2183.
Users invoke the pipeline via:
python -m scripts.step parts/block.py # generates block.step
python -m scripts.step parts/block.py -o out.step --stl out.stl
Layer 3: Engine to STEP Export
The generation engine (cadpy.generation._generate_step_outputs at line 1823) loads the user script, executes gen_step(), and builds the geometry. It then:
- Creates a hidden GLB topology artifact for the CAD Viewer via
step_scene.py - Exports the geometry to a STEP file using
cadpy.step_export.write_stepat line 338, which wraps the OCP STEPCAFControl_Writer - Optionally writes side-car files (
.stl,.3mf,.glb) using shared mesh data to avoid duplicate calculations
The engine validates successful writes and raises RuntimeError if the STEP writer fails.
Generating STEP Files from the Command Line
You can generate STEP files directly from natural language using the text-to-cad CLI.
Basic One-Liner Usage
Pipe a natural language description directly into the step generator:
text-to-cad "a 100 mm cylinder with a 20 mm hole through the middle" \
| python -m scripts.step -
Behind the scenes, this writes a temporary tmp_*.py file containing the LLM-generated geometry code, which the CLI imports and passes to generate_step_targets.
Explicit Script Generation with Side-Cars
For reproducible builds, save the generated Python script and explicitly define output formats:
# parts/gear.py (generated by the LLM)
from build123d import *
def gen_step():
gear = Gear(tooth_count=20, module=2)
return gear
python -m scripts.step parts/gear.py \
--stl gear.stl \
--3mf gear.3mf \
--glb gear.glb \
--mesh-tolerance 0.05 \
--mesh-angular-tolerance 0.1
This produces:
gear.step– the canonical STEP modelgear.stl,gear.3mf,gear.glb– mesh side-cars sharing the same tolerance settings
Using the Python API Directly
Embed the generation pipeline in your own Python tooling by importing from cadpy:
from cadpy.generation import generate_step_targets
from cadpy.catalog import StepImportOptions
targets = ["parts/gear.py"]
options = StepImportOptions(
stl="gear.stl",
three_mf="gear.3mf",
glb="gear.glb",
mesh_tolerance=0.05,
mesh_angular_tolerance=0.1,
)
generate_step_targets(
targets,
direct_step_kind="part",
step_options=options,
output="gear.step",
skip_step_write=False,
force=False,
verbose=True,
)
This mirrors the CLI flow but integrates seamlessly with Jupyter notebooks or automated build systems.
Caching and Reproducibility
The system computes a deterministic hash of the source script and its imports (source_hash.py) to deduplicate work. This guarantees that rerunning the same script produces identical STEP output, enabling incremental builds and CI verification as implemented in tests/python/skills/cad/step/test_cli.py.
Summary
- Text-to-CAD bridges natural language and industrial CAD formats through an LLM-driven pipeline.
- The architecture consists of three layers: prompt-to-Python generation, CLI dispatch, and geometry export.
- Key files include
skills/cad/scripts/step/cli.pyfor argument parsing,cadpy.generation.generate_step_targetsfor orchestration, andcadpy.step_export.write_stepfor final STEP serialization. - Users can invoke the system via one-liner pipes, explicit CLI commands with side-car generation, or direct Python API calls.
- Deterministic hashing ensures reproducible builds and efficient caching across multiple runs.
Frequently Asked Questions
What CAD kernel does text-to-cad use for STEP export?
Text-to-CAD uses the OCP (Open CASCADE Python) STEPCAFControl_Writer, wrapped by cadpy.step_export.write_step at line 338 of packages/cadpy/src/cadpy/step_export.py. This industrial-grade kernel ensures compatibility with major CAD platforms like SolidWorks, CATIA, and Fusion 360.
Can I generate assembly files or just single parts?
The system supports both. Define gen_step() for single parts or gen_assembly() for multi-component assemblies. The generation engine in cadpy.generation handles both function signatures and exports them to a single STEP file containing the complete assembly structure.
How does the system handle mesh quality for exported side-cars?
The StepImportOptions dataclass in step_targets.py accepts mesh_tolerance and mesh_angular_tolerance parameters. These values control the tessellation density for STL, 3MF, and GLB outputs. The engine shares the computed mesh across all side-car formats to ensure consistency and avoid redundant calculations.
Is there a way to preview the geometry before exporting the STEP file?
Yes. The generation engine automatically creates a hidden GLB topology artifact via step_scene.py that the integrated CAD Viewer uses for visualization. This allows you to inspect the geometry mesh without parsing the STEP file directly, providing immediate visual feedback on the generated model.
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 →