Metadata-Version: 2.4
Name: llmcad
Version: 0.3.0
Summary: A minimal, LLM-friendly CAD library in Python
Project-URL: Homepage, https://github.com/llmcad/llmcad
Project-URL: Documentation, https://llmcad.org
Project-URL: Repository, https://github.com/llmcad/llmcad
Project-URL: Issues, https://github.com/llmcad/llmcad/issues
Author-email: BuildCAD AI <hello@buildcad.ai>
License-Expression: MIT
License-File: LICENSE
Keywords: 3d,ai,cad,llm,modeling,opencascade
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: cadquery-ocp<7.10,>=7.8
Requires-Dist: numpy
Requires-Dist: pillow
Requires-Dist: vtk
Provides-Extra: docs
Requires-Dist: mkdocs-material; extra == 'docs'
Description-Content-Type: text/markdown

<p align="center">
  <a href="https://llmcad.org"><img src="https://llmcad.org/img/logo.png" alt="llmcad" width="400"></a>
</p>
<p align="center">
  <em>A minimal, LLM-friendly CAD library in Python.</em>
</p>
<p align="center">
<a href="https://pypi.org/project/llmcad" target="_blank">
    <img src="https://img.shields.io/pypi/v/llmcad?color=blue&label=PyPI" alt="PyPI version">
</a>
<a href="https://pypi.org/project/llmcad" target="_blank">
    <img src="https://img.shields.io/pypi/pyversions/llmcad" alt="Python versions">
</a>
<a href="https://github.com/llmcad/llmcad/blob/main/LICENSE" target="_blank">
    <img src="https://img.shields.io/github/license/llmcad/llmcad" alt="License">
</a>
</p>

---

**Documentation**: <a href="https://llmcad.org" target="_blank">https://llmcad.org</a>

**Source Code**: <a href="https://github.com/llmcad/llmcad" target="_blank">https://github.com/llmcad/llmcad</a>

---

llmcad is a Python CAD library designed from the ground up to be **LLM-friendly**. It wraps OpenCASCADE (via <a href="https://github.com/CadQuery/OCP" target="_blank">OCP</a>) with a minimal, explicit API that makes 3D modeling predictable and debuggable — whether you're writing code yourself or letting an AI agent do it.

<p>
  <a href="https://buildcad.ai" target="_blank"><img src="https://buildcad.ai/img/logo.png" alt="BuildCAD AI" width="20" valign="middle"></a>
  &nbsp;Developed by and powering <a href="https://buildcad.ai" target="_blank"><b>BuildCAD AI</b></a> — the #1 Text-to-CAD tool.
</p>

## Why llmcad?

LLMs struggle with 3D spatial reasoning. Traditional CAD APIs make this worse with large surface areas, implicit state, and global coordinate math.

llmcad fixes this with three design principles:

- **Named geometry**: Every face and edge has a semantic name (`top`, `front`, `left_edge`). No guessing indices or filtering by coordinates.
- **Face-local coordinates**: Position things relative to faces using intuitive local offsets (`offset`, `inset`). No global coordinate math.
- **Minimal API**: ~28 core concepts. If an LLM can't hold the entire API in context, the API is too big.

## Key Features

- **Shapes** — `Box`, `Cylinder`, `Sphere` centered at origin with named faces
- **Sketches** — `Rect`, `Circle`, `Ellipse`, `Polygon`, `Text`, and turtle-style `Sketch` builder
- **Operations** — `extrude`, `revolve`, `loft`, `sweep`, `fillet`, `chamfer`, `shell`, `split`, `mirror`
- **Assembly** — `place` parts on faces, `Assembly` for multi-part models
- **Booleans** — `+` (union), `-` (cut), `&` (intersect) — operator syntax, no method chains
- **Visual debugging** — Multi-view `snapshot()` renders for LLM feedback loops
- **Export** — `export_step`, `export_stl`, `export_glb` for CAD interchange, 3D printing, and web viewers
- **Immutable** — Boolean ops return new bodies. No hidden mutation.

## Installation

```bash
pip install llmcad
```

Requires Python 3.10+. Dependencies (`cadquery-ocp`, `numpy`, `Pillow`, `vtk`) are installed automatically.

## Quick Example

A mounting plate with a boss, through-hole, filleted edges, and corner mounting holes — in 15 lines:

```python
from llmcad import Box, Rect, Circle, extrude, fillet

# Base plate
plate = Box(100, 60, 10, color="steel")

# Raised boss on top
boss = extrude(Rect(30, 30).place_on(plate.top), amount=20)
plate = plate + boss

# Through-hole in boss
hole = extrude(Circle(12).place_on(plate.top), through=True)
plate = plate - hole

# Fillet top edges
plate = fillet(plate.top.edges, radius=3)

# Corner mounting holes
for corner in plate.bottom.corners:
    pos = corner.inset(dx=8, dy=8)
    h = extrude(Circle(5).place_on(plate.bottom, at=pos), through=True)
    plate = plate - h
```

<p align="center">
  <img src="docs/img/examples/ex15_mounting_plate.png" alt="Mounting plate example" width="500">
</p>

## How It Works

### Named Faces

Every shape comes with semantic face names. No need to filter by normal direction or index into face lists.

```python
box = Box(60, 40, 20)

box.top      # +Z face
box.bottom   # -Z face
box.front    # -Y face
box.back     # +Y face
box.left     # -X face
box.right    # +X face
```

### Face-Local Positioning

Place sketches and holes relative to faces using local coordinates. `offset(dx, dy)` moves in the face's local frame — `dx` is always "right" and `dy` is always "up", regardless of which face you're on.

```python
# Hole offset 20mm to the right on the top face
pos = plate.top.center.offset(dx=20)
hole = extrude(Circle(5).place_on(plate.top, at=pos), through=True)

# Holes at each corner, inset 8mm from edges
for corner in plate.top.corners:
    pos = corner.inset(dx=8, dy=8)  # direction toward center is automatic
```

### Boolean Operations

Combine bodies with Python operators. Each operation returns a new body — the originals are unchanged.

```python
base = Box(80, 60, 10)
boss = extrude(Rect(30, 30).place_on(base.top), amount=20)

result = base + boss   # union
result = base - boss   # cut
result = base & boss   # intersect
```

### Visual Debugging

Render multi-view snapshots for visual verification — essential for LLM feedback loops.

```python
from llmcad import snapshot

snapshot(plate, "plate")  # saves plate.png with front, right, top, and iso views
```

## More Examples

<table>
<tr>
<td align="center"><b>Box</b><br><img src="docs/img/examples/ex01_box.png" width="200"></td>
<td align="center"><b>Cylinder</b><br><img src="docs/img/examples/ex02_cylinder.png" width="200"></td>
<td align="center"><b>Sphere</b><br><img src="docs/img/examples/ex03_sphere.png" width="200"></td>
</tr>
<tr>
<td align="center"><b>Plate with Hole</b><br><img src="docs/img/examples/ex04_plate_hole.png" width="200"></td>
<td align="center"><b>Filleted Edges</b><br><img src="docs/img/examples/ex06_fillet.png" width="200"></td>
<td align="center"><b>Chamfered Edges</b><br><img src="docs/img/examples/ex07_chamfer.png" width="200"></td>
</tr>
<tr>
<td align="center"><b>Boolean Subtraction</b><br><img src="docs/img/examples/ex08_subtract.png" width="200"></td>
<td align="center"><b>Corner Holes</b><br><img src="docs/img/examples/ex11_corner_holes.png" width="200"></td>
<td align="center"><b>Stacked Boxes</b><br><img src="docs/img/examples/ex12_stacked.png" width="200"></td>
</tr>
</table>

See the <a href="https://llmcad.org/examples/" target="_blank">full examples gallery</a> for all 18 examples with code.

## Export

Export to STEP (CAD interchange), STL (3D printing), or GLB (web viewers):

```python
from llmcad import Box, export_step, export_stl, export_glb

box = Box(50, 50, 50, color="steel")

export_step(box, "box.step")  # exact B-Rep geometry
export_stl(box, "box.stl")    # triangulated mesh
export_glb(box, "box.glb")    # binary glTF 2.0 with PBR material
```

## API at a Glance

| Category       | Symbols                                                              |
| -------------- | -------------------------------------------------------------------- |
| **Shapes**     | `Box`, `Cylinder`, `Sphere`                                          |
| **Sketches**   | `Rect`, `Circle`, `Ellipse`, `Polygon`, `Text`, `Sketch`            |
| **Operations** | `extrude`, `revolve`, `loft`, `sweep`, `fillet`, `chamfer`, `shell`, `split`, `mirror` |
| **Assembly**   | `place`, `Assembly`, `RevoluteJoint`                                 |
| **Booleans**   | `+` (union), `-` (cut), `&` (intersect)                             |
| **Debug**      | `snapshot`, `show`, `show_faces`, `show_edges`, `measure`            |
| **Export**     | `export_step`, `export_stl`, `export_glb`                            |
| **Types**      | `Body`, `FaceRef`, `EdgeRef`, `Position`                             |

Full API reference: <a href="https://llmcad.org/api-reference/" target="_blank">llmcad.org/api-reference</a>

## Dependencies

llmcad builds on:

- <a href="https://github.com/CadQuery/OCP" target="_blank">**OCP**</a> — Python bindings for OpenCASCADE, the industry-standard open-source CAD kernel
- <a href="https://numpy.org" target="_blank">**NumPy**</a> — array operations for tessellation and rendering
- <a href="https://pillow.readthedocs.io" target="_blank">**Pillow**</a> — image output for snapshots
- <a href="https://vtk.org" target="_blank">**VTK**</a> — offscreen multi-view rendering

## License

This project is licensed under the terms of the <a href="https://github.com/llmcad/llmcad/blob/main/LICENSE" target="_blank">MIT license</a>.

---

<p align="center">
  <a href="https://buildcad.ai" target="_blank"><img src="https://buildcad.ai/img/logo.png" alt="BuildCAD AI" width="40" valign="middle"></a>
  &nbsp;
  Developed by and powering <a href="https://buildcad.ai" target="_blank"><b>BuildCAD AI</b></a> — the #1 Text-to-CAD tool.
</p>
