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

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, while the CLI entry point at 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.

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 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 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:

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:

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, and executes the script. The engine creates a hidden GLB topology artifact through step_scene.py for visualization, then exports the STEP file.

Command-Line Interface Usage

Generate STEP files directly from natural language using piped input:

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:

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

Generate mesh side-cars alongside the STEP file:

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 carries these paths through the pipeline, ensuring shared mesh calculations across formats.

Python API Integration

Embed the generation engine directly in Python tooling:

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 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.

Summary

  • Natural language processing: The CAD skill uses LLM prompting configured in skills/cad/agents/openai.yaml to generate build123d Python scripts defining gen_step() functions.
  • CLI entry: 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 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. 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 at line 338, which wraps Open CASCADE's STEPCAFControl_Writer. The orchestration logic resides in packages/cadpy/src/cadpy/generation.py at line 1823.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →