# How the DXF Skill Converts CAD Geometry to 2D Drawings in text-to-cad

> Learn how the DXF skill converts CAD geometry to 2D drawings using a standardized pipeline. Understand CLI parsing, module loading, and file I/O with text-to-cad.

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

---

**The DXF skill converts CAD geometry to 2D drawings by wrapping a Python generator that produces an `ezdxf` document, handling CLI parsing, module loading, payload validation, and file I/O through a standardized pipeline.**

The DXF skill in the `earthtojake/text-to-cad` repository provides a clean abstraction for transforming programmatically defined geometry into industry-standard DXF files. Rather than implementing drawing logic itself, the skill orchestrates a pipeline that loads user-defined Python scripts, validates their output, and manages the technical details of file serialization. This architecture allows developers to focus on describing geometry using the `ezdxf` library while the skill handles the surrounding infrastructure.

## The DXF Generation Pipeline

The conversion process follows a strict six-step workflow defined in the `cadpy` package. Each stage enforces specific contracts to ensure that arbitrary Python generators can reliably produce valid 2D CAD drawings.

### CLI Entry Point and Argument Parsing

The process begins in [`skills/dxf/scripts/dxf/cli.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/dxf/scripts/dxf/cli.py), which constructs an argument parser accepting either a plain Python source file or a `SOURCE.py=OUTPUT.dxf` pair. When a user executes the `dxf` command, the CLI forwards the request to `cadpy.generation.generate_dxf_targets` for processing.

This separation of concerns keeps command-line interface logic distinct from the core generation engine, allowing the same underlying routines to be invoked programmatically or via different frontends.

### Dynamic Script Loading

The `cadpy.generation.run_script_generator` function handles the dynamic import of user-provided scripts. It temporarily adjusts `sys.path` to ensure the script can import the repository's `cadpy` package, then loads the module using a temporary import name prefixed with `_cad_tool_` to avoid namespace collisions.

This approach isolates user code while maintaining access to necessary dependencies, enabling the generator to execute arbitrary Python files without permanent modification to the environment.

### The gen_dxf Contract

Once the module loads successfully, the generator searches for a callable named `gen_dxf`. This function serves as the primary interface between user code and the DXF skill. The skill invokes `gen_dxf` with no arguments and captures its return value, expecting the user to implement all geometry construction logic using libraries like `ezdxf` within this single entry point.

### Payload Normalization

The raw return value from `gen_dxf` undergoes strict validation via `_normalize_dxf_payload`. This function enforces that the payload is a dictionary containing exactly one key: `document`. The associated value must be an `ezdxf` `Drawing` object or a compatible interface providing a `saveas` method.

Any deviation from this contract—missing keys, extra fields, or incorrect object types—triggers a clear error message before file writing begins, preventing malformed output.

### File Writing and Metadata Storage

The `_write_dxf_payload` function extracts the validated document object, creates the output directory if necessary, and calls `document.saveas(str(output_path))` to persist the 2D geometry to disk. Immediately after writing, the skill records provenance metadata through `write_dxf_text_to_cad_metadata`, creating a JSON sidecar file that accompanies the DXF output.

If the expected output file does not exist after the `saveas` call completes, the system raises a `RuntimeError`, alerting the user to potential issues with missing `saveas` invocations or misconfigured output paths.

## Practical Implementation Example

To convert CAD geometry to 2D drawings using the DXF skill, implement a Python file with a `gen_dxf` function that constructs geometry using `ezdxf`:

```python

# my_part.py – generator for the DXF skill

from ezdxf import new

def gen_dxf():
    """Return a ready-to-save DXF document."""
    doc = new(dxfversion="R2010")          # create empty DXF drawing

    msp = doc.modelspace()
    msp.add_line((0, 0), (100, 0))         # draw horizontal line

    msp.add_circle((50, 50), radius=25)    # draw circle

    return {"document": doc}               # required payload format

```

Execute the conversion via the command line:

```bash

# Generate DXF from the script

dxf my_part.py -o output/part.dxf

```

This command loads [`my_part.py`](https://github.com/earthtojake/text-to-cad/blob/main/my_part.py), invokes `gen_dxf`, validates the returned dictionary, writes `output/part.dxf`, and stores provenance metadata alongside the file.

## Error Handling and Validation

The DXF skill implements defensive programming at multiple layers to ensure robust conversion. During the generation phase in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py), the system validates that the user-provided script actually produces a DXF file at the specified location, raising descriptive errors when files are missing. The payload normalization step catches type mismatches early, preventing cryptic errors during file serialization by verifying the `document` object provides the expected `saveas` interface before attempting to write.

## Summary

- The DXF skill acts as a thin wrapper around Python generators using the `ezdxf` library, not a geometry engine itself.
- User scripts must expose a `gen_dxf()` function returning `{"document": drawing_object}` to satisfy the payload contract.
- The pipeline in `cadpy.generation` handles dynamic module loading, validation, directory creation, file writing, and metadata tracking.
- Strict validation via `_normalize_dxf_payload` ensures only properly formatted `ezdxf` Drawing objects reach the file system.
- Provenance metadata is automatically recorded in JSON sidecar files via `write_dxf_text_to_cad_metadata`.

## Frequently Asked Questions

### What Python library does the DXF skill use for creating drawings?

The DXF skill is built around `ezdxf`, a Python library for creating and modifying DXF files. User generators typically import `ezdxf` to construct `Drawing` objects, modelspaces, and geometric entities like lines and circles, which the skill then validates and persists to disk.

### What happens if my gen_dxf function returns the wrong data type?

The `_normalize_dxf_payload` function in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) validates the return value and raises a clear error if the payload is not a dictionary containing exactly one `document` key with an `ezdxf` Drawing object. This prevents invalid data from reaching the file writing stage.

### Can I use other CAD libraries besides ezdxf with the DXF skill?

Technically yes, provided your chosen library produces an object compatible with the `ezdxf` Drawing interface—specifically, it must provide a `saveas` method that accepts a file path string. However, the skill is explicitly designed and tested around `ezdxf`, making it the recommended and most reliable choice for geometry generation.

### Where does the DXF skill store metadata about generated files?

After writing the DXF file via `_write_dxf_payload`, the skill calls `write_dxf_text_to_cad_metadata` to create a JSON sidecar file adjacent to the output. This metadata file contains provenance information documenting the generation parameters and source script used to create the 2D drawing.