# How the text-to-CAD Model Works: Inside the Decorator-Driven Pipeline

> Discover how the text-to-CAD model converts Python functions into CAD files using decorator-driven pipelines. Learn about the registration, execution, and export process for seamless CAD generation.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: internals
- Published: 2026-09-13

---

**The text-to-CAD model transforms Python functions into CAD files using decorators like `@step()` that register geometry definitions in a global registry, later executed via a thread-local build context and exported through a generation engine.**

The earthtojake/text-to-cad library provides a declarative workflow for converting Python scripts into industry-standard CAD formats such as STEP and DXF. By leveraging lightweight decorators and a thread-local build context, the pipeline enables incremental compilation, caching, and live preview capabilities without boilerplate configuration.

## Core Architecture of the text-to-CAD Pipeline

The library operates on a decorator-driven registration pattern that separates model declaration from execution. This architecture allows functions to be defined as CAD models while deferring geometry construction until the build phase.

### Model Declaration via Decorators

Decorators such as `@step()`, `@dxf()`, `@stl()`, `@glb()`, and `@threemf()` mark Python functions as CAD model definitions. These decorators do not execute geometry code immediately; instead, they register the function for later invocation. In [`packages/cadgen/src/cadgen/authoring.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/authoring.py), lines 4-13 illustrate this registration pattern where the decorator captures the callable without building geometry.

When applied, these decorators create a **ModelDef** instance that stores:
- The target output format (STEP, DXF, etc.)
- The callable geometry function
- Output path resolution logic
- Mesh tolerance settings and kinematic metadata

### The ModelDef Registry

Registered models are stored as immutable **ModelDef** objects in a global registry keyed by the model's *script::function* reference. According to the source code in [`packages/cadgen/src/cadgen/authoring.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/authoring.py) (lines 70-78), this registry maintains the mapping between function references and their execution parameters, enabling the CLI to resolve and dispatch the correct pipeline for any given model.

## The Build Execution Flow

When you run `python model.py`, the text-to-CAD pipeline activates through several coordinated stages that handle parsing, context management, and file generation.

### CLI Entry Point and Argument Parsing

The entry point `run_model_argv` in [`packages/cadgen/src/cadgen/cli/_run_model.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/cli/_run_model.py) (lines 44-66) parses command-line arguments, resolves the script-function pair into a model reference, and dispatches to the appropriate generation function. This module handles flags such as `--verbose`, `--force`, and mesh tolerance overrides before invoking the build process.

### The Thread-Local Building Context

Actual geometry construction occurs within a `building()` context manager that creates a thread-local **BuildFrame**. As implemented in [`packages/cadgen/src/cadgen/authoring.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/authoring.py) (lines 81-90), this context tracks:
- Invoked child models and their resulting tree hashes
- A unique root identifier for event streaming
- Build state isolation for incremental updates

This design enables snapshot isolation and incremental builds, where only modified geometry triggers recompilation.

### Generation Engine and Export

The generation logic resides in [`packages/cadgen/src/cadgen/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/generation.py), which re-exports `generate_step_targets` and `generate_dxf_targets`. These functions drive the full pipeline including:
- Freshness gate checking for cache validation
- Incremental package compilation
- OCP kernel integration for geometry operations
- Final export to STEP, DXF, STL, GLB, or 3MF formats

The internal implementation in [`packages/cadgen/src/cadgen/_internal/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/_internal/generation.py) handles the heavy lifting of compiling models and writing output files next to the source script (or to user-specified paths as defined by `ModelDef.output_path` at lines 86-90 in [`authoring.py`](https://github.com/earthtojake/text-to-cad/blob/main/authoring.py)).

## Optional Warm Daemon for Parallel Execution

When the environment variable `CADGEN_EVENTS=1` is set, the pipeline supports a warm daemon process managed through [`packages/cadgen/src/cadgen/daemon/executors.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/daemon/executors.py). As shown in [`packages/cadgen/src/cadgen/cli/_run_model.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadgen/src/cadgen/cli/_run_model.py) (lines 63-65), this daemon receives build events over a line-sink, enabling parallel builds and live-preview updates in the CAD Viewer without cold-start penalties.

## Practical text-to-CAD Examples

A minimal model declares geometry using the build123d API and the `@step()` decorator:

```python

# demo_bracket.py

from cadgen import build123d as bd
from cadgen import step

@step()
def bracket():
    """A simple rectangular bracket."""
    return bd.Box(40, 10, 10)

```

Running the model creates `demo_bracket.step` beside the script:

```bash
python demo_bracket.py

```

Explicit CLI usage with flags:

```bash
python demo_bracket.py --verbose --force --mesh-tolerance 0.01

```

For 2D DXF output instead of 3D STEP:

```python
from cadgen import dxf

@dxf()
def my_drawing():
    # 2D geometry construction

    pass

```

```bash
python my_drawing.py  # Produces my_drawing.dxf

```

## Summary

- **Decorator registration**: Functions become CAD models via `@step()`, `@dxf()`, and similar decorators that store definitions in a global registry without immediate execution.
- **Lazy evaluation**: Geometry building is deferred until script execution, managed by a thread-local `BuildFrame` context that tracks dependencies and enables incremental compilation.
- **CLI dispatch**: The `run_model_argv` function in [`_run_model.py`](https://github.com/earthtojake/text-to-cad/blob/main/_run_model.py) parses arguments and routes to `generate_step_targets` or `generate_dxf_targets` based on the model type.
- **Multi-format export**: The generation engine exports to STEP, DXF, STL, GLB, and 3MF formats with configurable mesh tolerances.
- **Optional daemon**: Setting `CADGEN_EVENTS=1` enables a warm daemon for parallel builds and live preview capabilities.

## Frequently Asked Questions

### What file formats does the text-to-CAD model support?

The text-to-CAD pipeline supports STEP and DXF as primary CAD formats, plus STL, GLB, and 3MF for mesh-based exports. You specify the output format by choosing the appropriate decorator: `@step()` for STEP files, `@dxf()` for 2D drawings, and `@stl()`, `@glb()`, or `@threemf()` for mesh formats.

### How does the warm daemon improve text-to-CAD performance?

When `CADGEN_EVENTS=1` is set, the warm daemon process receives build events over a line-sink and maintains a hot OCP kernel instance. This eliminates cold-start latency for subsequent builds and enables parallel execution for batch processing, significantly reducing build times for complex model trees.

### Can I customize mesh export tolerances in text-to-CAD?

Yes. The `ModelDef` class stores mesh tolerance parameters that you can override via CLI flags. Pass `--mesh-tolerance` and `--mesh-angular-tolerance` to `python model.py` to control tessellation quality for STL, GLB, and 3MF exports without modifying the source code.

### What is the difference between @step() and @dxf() decorators?

Both decorators register functions as CAD models, but `@step()` configures the pipeline to generate 3D STEP files (CAD industry standard for solids), while `@dxf()` targets 2D DXF drawings. The decorator determines which generation function the CLI invokes—`generate_step_targets` or `generate_dxf_targets`—and sets the appropriate file extension and export logic in the `ModelDef` registry.