Metadata-Version: 2.5
Name: bevel-cad
Version: 0.1.0
Summary: Render, export, and configure CadQuery parts: layered YAML config, timestamped render bundles, previews, web viewer, CLI and MCP server.
Project-URL: Homepage, https://github.com/jimcortez/bevel-cad
Project-URL: Repository, https://github.com/jimcortez/bevel-cad
Project-URL: Issues, https://github.com/jimcortez/bevel-cad/issues
Project-URL: Changelog, https://github.com/jimcortez/bevel-cad/blob/main/CHANGELOG.md
Author-email: Jim Cortez <jim@jimcortez.com>
License: MIT
License-File: LICENSE
Keywords: 3d-printing,cad,cadquery,mcp,step,stl
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Manufacturing
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
Requires-Python: <3.13,>=3.11
Requires-Dist: cadquery>=2.8
Requires-Dist: httpx<1,>=0.28
Requires-Dist: numpy>=1.26
Requires-Dist: omegaconf>=2.3
Requires-Dist: pillow>=10
Requires-Dist: pyrender>=0.1.45
Requires-Dist: pyyaml>=6
Requires-Dist: trimesh>=4.0
Provides-Extra: dev
Requires-Dist: mcp[cli]<3,>=2; extra == 'dev'
Requires-Dist: pyright>=1.1.409; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.15; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: mcp<3,>=2; extra == 'mcp'
Description-Content-Type: text/markdown

# bevel-cad

[![PyPI](https://img.shields.io/pypi/v/bevel-cad.svg)](https://pypi.org/project/bevel-cad/)
[![Python](https://img.shields.io/pypi/pyversions/bevel-cad.svg)](https://pypi.org/project/bevel-cad/)
[![License](https://img.shields.io/pypi/l/bevel-cad.svg)](LICENSE)
[![CI](https://github.com/jimcortez/bevel-cad/actions/workflows/ci.yml/badge.svg)](https://github.com/jimcortez/bevel-cad/actions/workflows/ci.yml)

*WARNING: project under active development and not stable at all*

Render, export, and configure [CadQuery](https://cadquery.readthedocs.io/) parts.

`bevel` turns a `build(cfg)` function into a **render bundle** — a timestamped folder with
STL / STEP / 3MF / GLB / GLTF / OBJ exports, a preview PNG, the exact config that produced
it, timings, and a log — and can push the geometry to
[cadquery-web-viewer](https://github.com/jimcortez/cadquery-web-viewer). Configuration is
layered YAML (OmegaConf) with `key.path=value` overrides; a project is a `bevel.yaml` plus
`configs/` and `src/` folders; everything is available as a CLI, a Python API, and an MCP
server so AI assistants can drive it.

```bash
pip install "bevel-cad[mcp]"               # or: uv add "bevel-cad[mcp]"

bevel create my_block --template basic     # scaffold a project (interactive if args omitted)
cd my_block
bevel render my_block                      # -> renders/my_block_<YYYYMMDD-HHMMSS>/
bevel render my_block my_block.cylinder_depth=null --skip preview   # override + faster loop
bevel inspect renders/*/my_block_*.stl     # watertight? components? open edges?
bevel render my_block --viewer             # push to a running cadquery-web-viewer
bevel mcp                                  # expose all of the above to an AI agent
```

## A part

```python
import cadquery as cq
import bevel_cad

@bevel_cad.part(defaults={"widget": {"width": 40.0, "hole_d": 6.0}})
def build(cfg) -> cq.Workplane:
    p = cfg.widget
    return cq.Workplane("XY").box(p.width, p.width, 5).faces(">Z").workplane().hole(p.hole_d)
```

Return an `Assembly` with named children to get one STL per body (and per-body colours in
the viewer). Anything with `.wrapped` (build123d) or a `trimesh.Trimesh` works too.

## Python API

```python
from bevel_cad import load_config, render_part

cfg = load_config(files=["configs/widget.yaml"], dotlist=["widget.hole_d=8"])
result = render_part(build(cfg), cfg, name="widget-8mm")
print(result.bundle_dir, result.path_for("stl"), result.extra_paths)
```

## Project layout

```
bevel.yaml            project config: how to render (formats, tolerances, viewer)
bevel.local.yaml      personal overrides (git-ignored)
configs/<part>.yaml   per-part config: `part:` + the part's block
src/<part>.py         build(cfg) -> geometry
renders/<slug>_<ts>/  bundles
```

Config layers, low to high: built-in defaults → `~/.config/bevel/config.yaml` →
`bevel.yaml` → `bevel.local.yaml` → part `defaults=` → `-c FILE …` → `KEY=VALUE`.
The `project`, `rendering`, and `viewer` blocks are typed and validated; everything else is
free-form. Missing keys raise (no silent `None`); use `cfg.get("key", default)` for optional ones.

## Commands

| command | |
|---|---|
| `bevel render [TARGET] [-c FILE]… [KEY=VALUE]… [--name N] [--out DIR] [--only F] [--skip F] [--viewer]` | build + bundle |
| `bevel config [TARGET] …` | print the merged config |
| `bevel list` / `bevel describe NAME` | discoverable parts and their defaults |
| `bevel renders` / `bevel show BUNDLE` | previous bundles; files, snapshot, stats, log |
| `bevel inspect MESH…` | watertight, components, boundary/non-manifold edges, volume |
| `bevel upload BUNDLE` | re-push a bundle to the viewer |
| `bevel create` / `bevel add` / `bevel templates` | scaffolding (`basic`, `label`) |
| `bevel skills list\|install` | agent skills for building/verifying parts |
| `bevel mcp [--transport stdio\|streamable-http]` | MCP server |

Every command takes `--root DIR` and `--json`. `TARGET` is a `.py`/`.yaml` path, a project part
name, `pkg.module[:fn]`, or a registered name (`bevel_cad.parts` / `bevel_cad.providers` entry points).
A ready-made project lives in [examples/](examples/).

## Docs

[docs/config.md](docs/config.md) · [docs/cli.md](docs/cli.md) · [docs/parts.md](docs/parts.md) ·
[docs/project-layout.md](docs/project-layout.md) · [docs/viewer.md](docs/viewer.md) ·
[docs/mcp.md](docs/mcp.md) · [docs/skills.md](docs/skills.md) ·
[docs/releasing.md](docs/releasing.md)

## Extending

Other packages register parts via entry points and can add typed config blocks / CLI flags:

```toml
[project.entry-points."bevel_cad.parts"]
clamp = "mypkg.parts.clamp"
[project.entry-points."bevel_cad.providers"]
mypkg = "mypkg.registry:bevel_parts"      # -> {name: "module.path", ...}
```

```python
from bevel_cad.cli import CliHooks, main
main(hooks=CliHooks(schema=MySchema, add_render_flags=add_my_flags, prepare_config=wrap_cfg))
```

MIT licensed. Python 3.11–3.12 (cadquery 2.8 needs 3.11; the viewer pins `<3.13`).
See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev loop and [docs/releasing.md](docs/releasing.md) for releases.
