# How to Generate STEP Files from Natural Language with the CAD Skill

> Generate STEP files from natural language using the CAD skill in earthtojake/text-to-cad. Convert text prompts to CAD geometry with an LLM and cadpy engine.

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

---

**The CAD skill in earthtojake/text-to-cad converts natural language descriptions into STEP files by using an LLM to generate build123d Python scripts, which the cadpy engine renders into standardized STEP geometry with optional STL, 3MF, and GLB side-cars.**

The earthtojake/text-to-cad repository provides a CAD skill that bridges natural language and manufacturing-ready geometry. By chaining LLM-generated Python scripts with the build123d API, the system produces valid STEP files suitable for downstream CAD tools and the integrated CAD Viewer.

## The Three-Layer Pipeline Architecture

The system processes natural language through three distinct layers to generate STEP files.

### Layer 1: Natural Language to Python Script

The skill parses user prompts and emits Python modules defining a `gen_step()` or `gen_assembly()` function. These scripts utilize the high-level **build123d** API provided by the **cadpy** package. The prompt-to-script conversion logic resides in the skill's LLM configuration at [`skills/cad/agents/openai.yaml`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/agents/openai.yaml), while the CLI entry point at [`skills/cad/scripts/step/cli.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/scripts/step/cli.py) receives the generated script path.

### Layer 2: CLI to Generation Engine

The `scripts/step` CLI parses command-line arguments including target files, `--kind` specifications, and side-car options. The `cli.main` function builds an `argparse.ArgumentParser` via `_add_step_arguments`, normalizes numeric flags through `_normalize_cli_numeric`, and forwards requests to `cadpy.generation.generate_step_targets` at [source line 2183](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py#L2183).

### Layer 3: Engine to STEP File Export

The generation engine loads user scripts, executes `gen_step()`, and exports geometry using **OCP**'s STEP writer. The `cadpy.step_export.write_step` function at [source line 338](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py#L338) creates an `STEPCAFControl_Writer`, transfers the XCAF document, and writes the final file. The surrounding orchestration in `cadpy.generation._generate_step_outputs` at [source line 1823](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py#L1823) handles GLB topology generation for the CAD Viewer and optional side-car creation.

## Step-by-Step Workflow

To generate STEP files from natural language, the system executes the following sequence.

First, the LLM expands a prompt like "a rectangular block 100 mm × 50 mm × 20 mm with a 10 mm hole" into a build123d script:

```python
from build123d import *

def gen_step():
    block = Box(100, 50, 20)
    hole = Cylinder(r=5, h=50).rotate((0, 0, 90))
    return block - hole

```

Second, users invoke the CLI:

```bash
python -m scripts.step parts/block.py

```

Third, `generate_step_targets` resolves the target, computes a deterministic hash via `step_hash` in [`step_targets.py`](https://github.com/earthtojake/text-to-cad/blob/main/step_targets.py), and executes the script. The engine creates a hidden GLB topology artifact through [`step_scene.py`](https://github.com/earthtojake/text-to-cad/blob/main/step_scene.py) for visualization, then exports the STEP file.

## Command-Line Interface Usage

Generate STEP files directly from natural language using piped input:

```bash
text-to-cad "a 100 mm cylinder with a 20 mm hole through the middle" \
  | python -m scripts.step - -o cylinder.step

```

The hyphen (`-`) tells the CLI to read the generated Python script from stdin, creating a temporary file that gets imported and executed.

For explicit file targets with output mapping:

```bash
python -m scripts.step parts/gear.py=out.step --kind part

```

Generate mesh side-cars alongside the STEP file:

```bash
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

```

The `StepImportOptions` dataclass in [`step_targets.py`](https://github.com/earthtojake/text-to-cad/blob/main/step_targets.py) carries these paths through the pipeline, ensuring shared mesh calculations across formats.

## Python API Integration

Embed the generation engine directly in Python tooling:

```python
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 while enabling programmatic control in Jupyter notebooks or automation scripts.

## Caching and Reproducibility

The system computes a deterministic hash of source scripts and imports via [`source_hash.py`](https://github.com/earthtojake/text-to-cad/blob/main/source_hash.py) to guarantee identical STEP output from identical inputs. This enables incremental builds and CI verification as demonstrated in [`tests/python/skills/cad/step/test_cli.py`](https://github.com/earthtojake/text-to-cad/blob/main/tests/python/skills/cad/step/test_cli.py).

## Summary

- **Natural language processing**: The CAD skill uses LLM prompting configured in [`skills/cad/agents/openai.yaml`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/agents/openai.yaml) to generate build123d Python scripts defining `gen_step()` functions.
- **CLI entry**: [`skills/cad/scripts/step/cli.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/scripts/step/cli.py) parses arguments and delegates to `cadpy.generation.generate_step_targets`.
- **STEP export**: `cadpy.step_export.write_step` serializes geometry using OCP's `STEPCAFControl_Writer`.
- **Side-cars**: Optional STL, 3MF, and GLB outputs share mesh calculations via `StepImportOptions`.
- **Reproducibility**: Deterministic hashing in [`source_hash.py`](https://github.com/earthtojake/text-to-cad/blob/main/source_hash.py) ensures cacheable, consistent builds.

## Frequently Asked Questions

### What Python API does the generated code use?

The LLM generates scripts using the **build123d** API, a high-level CAD modeling library. These scripts define a `gen_step()` function that returns build123d geometry objects, which the cadpy engine converts to STEP format.

### Can I convert existing STEP files to other formats?

Yes. The CLI accepts existing STEP files as targets and can generate side-car meshes (STL, 3MF, GLB) without regeneration. Use the `--stl`, `--3mf`, or `--glb` flags with an existing `.step` file as input.

### How does the system handle script caching?

The engine computes a deterministic hash of the Python script source and its imports using [`source_hash.py`](https://github.com/earthtojake/text-to-cad/blob/main/source_hash.py). This hash prevents redundant regeneration when inputs haven't changed, supporting incremental builds and CI pipelines.

### Where is the STEP writing logic implemented?

The actual STEP serialization occurs in [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py) at line 338, which wraps Open CASCADE's `STEPCAFControl_Writer`. The orchestration logic resides in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) at line 1823.