# How to Create Parametric CAD Models from Natural Language Descriptions Using build123d

> Learn to generate parametric CAD models from natural language using build123d and the text-to-CAD repository. Convert descriptions into STEP files with this Python-powered pipeline.

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

---

**The text-to-CAD repository converts plain English specifications into validated STEP files by generating build123d Python scripts through a multi-stage pipeline of brief extraction, source generation, export, and validation.**

The **text-to-CAD** skill in the `earthtojake/text-to-cad` repository demonstrates a complete workflow for parametric CAD generation. Rather than generating geometry directly, the system produces reproducible Python source code using **build123d**, a high-level geometry-centric library that serves as the computational foundation for all solid modeling operations. This approach ensures version control, auditability, and precise parameter adjustment.

## The build123d Pipeline: From Text to STEP

The repository implements a strict five-stage pipeline that treats the STEP file as the single source of truth. Understanding each stage allows you to integrate or extend the system for custom manufacturing workflows.

### Stage 1: Natural Language to CAD Brief

The process begins with parsing user requests into a structured **CAD brief**. This intermediate representation captures dimensions, features, materials, and relationships without committing to implementation details.

For example, the input "a 100 × 60 × 20 mm block with four 8 mm through-holes and a 2 mm chamfer on the top edge" becomes a specification document stored at [`references/cad-brief.md`](https://github.com/earthtojake/text-to-cad/blob/main/references/cad-brief.md). The brief format enforces completeness—every dimension must be specified or explicitly left parametric.

### Stage 2: Brief to build123d Source Generation

From the brief, the skill generates a Python module implementing a mandatory `gen_step()` function. This function returns a `build123d.Shape` or `Assembly` object that fully defines the geometry.

The generation follows conventions documented in [`skills/cad/references/build123d-modeling.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/references/build123d-modeling.md), including:

- **Explicit labeling** of all `Solid` and `Compound` objects via the `label` parameter
- **Selector-based feature access** (`.faces()`, `.edges()`, `.vertices()`) rather than index-based access
- **Absolute positioning** with `Location` objects for reproducibility

### Stage 3: STEP Export via cadpy

The CLI command `python scripts/step <source>.py` triggers the export machinery in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py). This module:

1. Imports and executes the user script to obtain the `gen_step()` return value
2. Calls `build_build123d_step_scene()` to construct a `STEPControl_Writer` scene
3. Invokes `export_build123d_step_scene()` to write the `.step` file

The implementation in [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py) handles OCP (Open CASCADE Python) bindings, ensuring valid AP214/AP242 STEP output suitable for downstream CAM and PDM systems.

### Stage 4: Validation and Inspection

After export, `scripts/inspect` validates geometric integrity:

```bash
python scripts/inspect refs block.step --facts --planes

```

This command extracts **selectors** (named topological entities), **dimensions** (measured extents), and **planes** (datum references) from the STEP file, comparing them against the original brief. The validation logic is documented in [`skills/cad/references/inspection-and-validation.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/references/inspection-and-validation.md).

### Stage 5: Viewer Handoff

Finally, the system invokes the CAD Viewer skill (`$cad-viewer`) to present the model. As specified in `skills/cad/SKILL.md#non-negotiables`, every CAD skill must hand off to the viewer—no direct display of geometry is permitted. This separation of concerns enables remote collaboration and persistent share links.

## Practical build123d Implementation Patterns

### Basic Solid with Features

The minimal script structure demonstrates core build123d patterns used throughout the repository:

```python

# block.py

from build123d import *

def gen_step():
    # Base solid: width, depth, height

    block = SolidBox(100, 60, 20)

    # Feature pattern: four through-holes on grid

    hole_positions = [(20, 15), (80, 15), (20, 45), (80, 45)]
    for x, y in hole_positions:
        hole = Cylinder(radius=8, height=30, align=Align.CENTER)
        positioned_hole = Transform(
            location=Location(x, y, 0),
            shape=hole
        )
        block = block.cut(positioned_hole)

    # Edge treatment: chamfer on top edges

    block = block.fillet(radius=2, edges=block.top_edges())

    return block

```

Execute with:

```bash
python scripts/step block.py

```

This produces `block.step` alongside the source file, maintaining the provenance link.

### Assembly Construction with Joints

For multi-part designs, the repository provides `AssemblyHelper` in `cadpy.assembly`:

```python
from cadpy.assembly import AssemblyHelper
from build123d import *

def gen_step():
    # Define components with labels

    base = SolidBox(50, 50, 10, label="Base_Plate")
    cover = SolidBox(30, 30, 5, label="Top_Cover")

    # Assemble with explicit relationships

    helper = AssemblyHelper()
    helper.add(base)
    helper.add(cover, location=Location(x=0, y=0, z=10))
    
    # Constrain degrees of freedom

    helper.rigid_joint(
        parent_label="Base_Plate",
        child_label="Top_Cover",
        axis=Axis.Z
    )
    
    return helper.assemble()

```

The `rigid_joint` method records the assembly mate in the STEP structure, preserving design intent for downstream applications.

## Complete CLI Workflow Example

The following sequence demonstrates the full pipeline from natural language to viewable model:

```bash

# Generate build123d source from description

python -m skills.cad.scripts.generate_source \
    --brief "Create a 100x60x20 mm block with four 8 mm vertical holes and a 2 mm top chamfer."

# Build STEP geometry

python scripts/step block.py

# Validate against specification

python scripts/inspect refs block.step --facts --planes

# Generate preview image

python scripts/snapshot block.step --output block_preview.png

# Open in CAD Viewer

cad-viewer open block.step

```

Each command produces auditable artifacts: source code, STEP geometry, validation report, and visual snapshot.

## Key Source Files and Their Roles

| Path | Purpose |
|------|---------|
| [`skills/cad/SKILL.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/SKILL.md) | Skill contract, workflow definition, non-negotiable requirements |
| [`skills/cad/references/build123d-modeling.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/references/build123d-modeling.md) | build123d coding standards and anti-patterns |
| [`skills/cad/references/step-generation.md`](https://github.com/earthtojake/text-to-cad/blob/main/skills/cad/references/step-generation.md) | Export process documentation |
| [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py) | OCP-based STEP writer implementation |
| [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) | Source execution and export orchestration |
| `skills/cad/scripts/step` | User-facing build command |
| `skills/cad/scripts/inspect` | Geometric validation and fact extraction |
| `skills/cad/scripts/snapshot` | PNG/GIF preview generation |

## Summary

- **build123d** provides the geometric kernel for all solid modeling in the text-to-CAD pipeline
- The **five-stage workflow** (brief → source → STEP → validation → viewer) ensures reproducibility and quality
- **`gen_step()`** is the required function signature for all generated scripts
- **STEP files** are the ground truth, with secondary formats derived automatically
- **AssemblyHelper** extends the pattern to multi-part designs with preserved joints
- Validation through `scripts/inspect` catches dimensional and topological deviations before handoff

## Frequently Asked Questions

### What makes build123d suitable for AI-generated CAD code?

build123d provides a **fluent, type-hinted Python API** that maps cleanly to natural language concepts—`SolidBox`, `Cylinder`, `fillet`, `cut`. Unlike lower-level CAD kernels, it requires no boilerplate for common operations, reducing token count and error rates in LLM outputs. The explicit `Location` and `Align` systems eliminate ambiguity that plagues coordinate-based approaches.

### How does the system ensure generated dimensions match the request?

The **`scripts/inspect`** tool performs **fact extraction** on the exported STEP file, measuring actual geometric extents and comparing them against the CAD brief. Discrepancies trigger validation failures before viewer handoff. This closed-loop verification catches rounding errors, unit mismatches, and missing features.

### Can I modify parameters after the STEP file is generated?

Yes—this is the primary advantage of the **source-first architecture**. Edit the generated Python script (dimension values, feature counts, positions), re-run `python scripts/step <file>.py`, and obtain an updated STEP file with full traceability. The brief-to-source relationship supports parametric variation studies without regenerating from natural language.

### What STEP schema versions does the exporter support?

According to [`packages/cadpy/src/cadpy/step_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/step_export.py), the implementation uses **OCP (Open CASCADE Python)** bindings targeting **AP214** and **AP242** schemas. These are the dominant standards for mechanical CAD interoperability, supported by SolidWorks, Fusion 360, CATIA, and NX.