Converting 3D STEP Geometry to 2D Cut Layouts for Laser, Plasma, and Waterjet Cutting

The text-to-cad repository provides a modular pipeline that converts 3D STEP files into production-ready DXF cut layouts through separate CAD and DXF skills, using build123d for solid modeling and ezdxf for validated 2D projection.

This open-source toolkit from earthtojake/text-to-cad automates the entire workflow from design intent to manufacturing files. Its layered architecture ensures that 3D geometry and 2D cut layouts stay synchronized, eliminating manual redrawing and reducing errors for CNC cutting processes.

How the Conversion Pipeline Works

The repository organizes functionality into three orthogonal layers that enforce clean separation between geometry creation, format conversion, and visualization.

Layer Purpose Location
Skills Reusable agent workflows (CAD, DXF, G-code slicing) skills/
Packages Shared runtime utilities (viewer, rendering, geometry) packages/
Applications End-user tools (CLI, web viewer, benchmarks) viewer/, scripts/, benchmarks/

The CAD Skill: Creating Validated STEP Geometry

Located at skills/cad/, this skill generates STEP-first geometry using build123d Python sources. Running python scripts/step <source.py> produces:

  • A validated .step (or .stp) artifact
  • Optional secondary meshes (STL, 3MF, GLB)

The skill enforces unit consistency, origin placement, and assembly structure through conventions documented in skills/cad/SKILL.md. Every CAD generator must implement gen_step() as its entry point.

The DXF Skill: Projecting to 2D Cut Layouts

The skills/dxf/ skill consumes Python sources defining gen_dxf() — or automatically projects from existing gen_step() definitions. Key capabilities:

  • Automatic face projection from STEP topology when working with CAD-backed sources
  • Validation via ezdxf for layer names, closed polylines, and required holes
  • Default units and material-aware offsets for kerf compensation

This ensures your laser, plasma, or waterjet cut layout matches the true 3D geometry without manual tracing.

Step-by-Step: From STEP to DXF

Follow this command sequence to generate a validated cut layout:


# 1. Generate STEP from build123d source

python scripts/step src/bracket.py -o models/bracket.step

# 2. Project to 2D DXF automatically

python scripts/dxf src/bracket.py -o models/bracket.dxf

# 3. Launch viewer for visual confirmation

cad-viewer launch --dir "$(pwd)/models"

The DXF skill validates outputs before handoff, checking that all cutting contours are closed polylines and hole layers are properly named for post-processors.

Key Technical Implementation Details

Generator Function Signatures

Both skills expect specific Python function signatures in source files:

import build123d as bd

def gen_step():
    """Return a build123d Compound, Solid, or Assembly.
    Called by scripts/step to produce STEP output."""
    plate = bd.Box(120, 60, 5)
    # ... feature operations ...

    return plate

def gen_dxf():
    """Return an ezdxf document.
    Called by scripts/dxf for 2D cut layout generation."""
    import ezdxf
    doc = ezdxf.new(setup=True)
    msp = doc.modelspace()
    # ... projection logic ...

    return doc

Handoff Policy to CAD Viewer

Every skill must hand artifacts to $cad-viewer per SKILL.md specifications. This launches the web-based viewer at viewer/vite.config.mjs entry points, returning a shareable URL for stakeholder review. The policy is enforced across all skills — CAD, DXF, and future formats like G-code.

Shared Package Architecture

Runtime code in packages/ prevents cross-skill imports (enforced by tests):

  • packages/cadjs/ — JavaScript viewer utilities for scene scaling, edge display, and screenshot capture
  • packages/implicitjs/ — Experimental GLSL-based implicit CAD engine for browser-native rendering

Both are bundled via scripts/bundle/bundle.sh before release.

Validating Output for Manufacturing

The pipeline includes deterministic checks that downstream CAM systems can trust:

Validation Tool Location
STEP geometry inspection scripts/inspect skills/cad/
DXF closed polyline check ezdxf query skills/dxf/
Layer naming conventions ezdxf layer API skills/dxf/

For laser/plasma/waterjet cutting, the DXF skill specifically verifies that outer contours and inner holes are on separate layers with consistent color codes — a requirement for many nesting software packages.

Complete Working Example

This end-to-end example creates a plate with mounting holes, exports STEP, and generates a matching DXF cut layout:


# Install skills library

npx skills install earthtojake/text-to-cad

# Create generator source

cat > src/mounting_plate.py <<'PY'
import build123d as bd

def gen_step():
    # 200mm x 100mm x 6mm aluminum plate

    plate = bd.Box(200, 100, 6)
    
    # Four M8 clearance holes

    hole_pattern = [
        (-80, -35), (80, -35),
        (-80, 35), (80, 35)
    ]
    for x, y in hole_pattern:
        hole = bd.Cylinder(r=4.5, h=10).translate((x, y, 0))
        plate = plate.cut(hole)
    
    return plate

def gen_dxf():
    """Generate 2D cut layout from projected faces."""
    import ezdxf
    from ezdxf import units
    
    doc = ezdxf.new(setup=True)
    doc.units = units.MM
    msp = doc.modelspace()
    
    # Cutting contour on standardized layer

    msp.add_lwpolyline(
        [(-100, -50), (100, -50), (100, 50), (-100, 50)],
        close=True,
        dxfattribs={"layer": "CUT_CONTOUR", "color": 1}
    )
    
    # Holes on separate layer

    for x, y in [(-80, -35), (80, -35), (-80, 35), (80, 35)]:
        msp.add_circle(
            (x, y),
            radius=4.5,
            dxfattribs={"layer": "CUT_HOLES", "color": 3}
        )
    
    return doc
PY

# Execute pipeline

python scripts/step src/mounting_plate.py -o models/mounting_plate.step
python scripts/dxf src/mounting_plate.py -o models/mounting_plate.dxf

# Validate DXF structure

python -c "
import ezdxf
doc = ezdxf.readfile('models/mounting_plate.dxf')
print('Units:', doc.units)
print('Layers:', list(doc.layers.names()))
print('Contours:', len(doc.modelspace().query('LWPOLYLINE')))
print('Holes:', len(doc.modelspace().query('CIRCLE')))
"

# View results

cad-viewer launch --dir "$(pwd)/models"

Why This Architecture Matters for Manufacturing

No geometry duplication — The DXF skill projects from the same STEP source rather than maintaining parallel 2D drawings. When the 3D model changes, re-running scripts/dxf guarantees the cut layout synchronizes automatically.

Format extensibility — Adding waterjet-specific lead-in geometries or plasma kerf tables only requires a new skill. The core CAD and viewer packages remain unchanged.

Deterministic validation — Each skill implements its own quality gates. The scripts/inspect tool for STEP and ezdxf-based checks for DXF ensure that SendCutSend, OMAX, or Hypertherm post-processors receive valid inputs.

Summary

  • skills/cad/ generates validated STEP geometry via gen_step() and build123d
  • skills/dxf/ projects to 2D cut layouts via gen_dxf() with ezdxf validation
  • $cad-viewer handoff policy provides immediate visual confirmation for every artifact
  • Shared packages in packages/cadjs/ and packages/implicitjs/ power the web viewer without cross-skill dependencies
  • CLI entry points at scripts/step and scripts/dxf wrap Python generators for shell and agent integration

Frequently Asked Questions

Can I convert existing STEP files without rewriting them in Python?

Yes. The DXF skill can consume any STEP file through a generator that imports external geometry. Create a minimal gen_step() that loads your existing file with build123d.import_step(), then define gen_dxf() to project the faces you need for cutting. The skill architecture treats file-based and code-based sources identically.

What kerf compensation does the DXF skill apply?

Kerf width compensation is configurable per skills/dxf/SKILL.md defaults. The skill applies material-and-process-specific offsets (typically 0.1mm for laser, 0.5–1.5mm for plasma) through ezdxf geometry transformation before layer assignment. You override defaults via generator arguments or CLI flags.

How do I ensure hole positions match between STEP and DXF?

When both gen_step() and gen_dxf() exist in the same source file, derive hole coordinates from shared constants or helper functions. The DXF skill validates against the STEP geometry when CAD-backed projection is available, flagging deviations exceeding tolerance thresholds.

Does the viewer support DXF files directly?

Yes. skills/cad-viewer renders DXF alongside STEP, STL, and GLB formats. The Vite-based viewer at viewer/vite.config.mjs handles LWPOLYLINE, CIRCLE, and ARC entities common to laser cutting workflows, with layer toggle controls for contour visualization.

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 →