123 lines
4.5 KiB
Markdown
123 lines
4.5 KiB
Markdown
# WoodShop
|
||
|
||
**Voice-driven conversational 3D woodworking & furniture modeler.**
|
||
|
||
Talk to it like the Star Trek holodeck and watch furniture build itself:
|
||
|
||
> *"Place a 6 foot 2x4, sand it, then attach a 2 foot 2x4 at 90 degrees, 10 inches from the end."*
|
||
|
||
> *"Build a coffee table: a four foot by two foot frame from 2x4s, with four legs 18 inches tall standing at the corners."*
|
||
|
||
Each board is real dimensional lumber (a 2x4 is modeled at its true 1.5″ × 3.5″),
|
||
so the result is buildable — export to **STEP** (CAD/CNC) or **STL** (3D print),
|
||
and get a **cut list with board-feet and a shopping estimate**.
|
||
|
||
## How it works
|
||
|
||
WoodShop reuses the existing [CmdForge](https://gitea.brrd.tech/rob/cmdforge)
|
||
tool ecosystem for everything that isn't woodworking-specific, so no wheels are
|
||
reinvented:
|
||
|
||
```
|
||
woodshop-talk ── the conversational loop
|
||
│ dictate ............. speech → text (CmdForge tool)
|
||
│ pa-load-tools ....... wood-* → Claude schemas (CmdForge tool)
|
||
│ claude -p ........... interpret → tool calls (provider)
|
||
│ pa-execute-tool ..... dispatch each wood-* (CmdForge tool)
|
||
│ read-aloud .......... speak confirmation (CmdForge tool)
|
||
▼
|
||
scene.json ← single source of truth (parts, joints, selection, undo)
|
||
▲ │ writes
|
||
│ reads/mutates ▼
|
||
wood-* CmdForge tools woodshop-view
|
||
(place/join/stand/move/...) live pyvista 3D, watches scene.json
|
||
```
|
||
|
||
The `wood-*` tools are thin wrappers over the `woodshop` CLI, so the modeling
|
||
logic lives in one place and the tools double as the LLM's documented command
|
||
vocabulary.
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
python -m venv .venv && source .venv/bin/activate
|
||
pip install -e ".[gui,dev]" # 'gui' pulls build123d + pyvista + PySide6 + pyvistaqt
|
||
python scripts/gen_wood_tools.py # register the wood-* CmdForge tools
|
||
```
|
||
|
||
## Usage
|
||
|
||
### The studio (recommended)
|
||
|
||
```bash
|
||
woodshop # launches the unified desktop app
|
||
```
|
||
|
||
One window with the **3D viewport** (click a board to select it), a **parts
|
||
panel** (list + selected-part inspector + quick-action buttons), and a
|
||
**command bar** at the bottom where you type or push-to-talk (🎤). Mouse,
|
||
keyboard, and voice all drive the same scene and the same visible selection, so
|
||
"delete that" / the Delete button / saying "delete the front-left leg" are
|
||
interchangeable. Menus cover New/Open/Save projects, Export STL/STEP, Save
|
||
Image, Undo/Redo, camera views, and Build templates.
|
||
|
||
### Standalone tools (headless / scripting)
|
||
|
||
```bash
|
||
woodshop-view & # just the live 3D window (watches the scene)
|
||
woodshop-talk # just the voice/text loop; --voice to speak
|
||
woodshop-talk --once "build a workbench top from five 2x6 boards 6 feet long"
|
||
```
|
||
|
||
Or drive it directly from the CLI:
|
||
|
||
```bash
|
||
woodshop place 2x4 "6 ft" # place a board
|
||
woodshop stand # stand it up (a leg)
|
||
woodshop join p2 --to p1 --angle 90 --offset "10 in"
|
||
woodshop rename "front-left leg"
|
||
woodshop cutlist # bill of materials
|
||
woodshop export table.step # STEP / STL export
|
||
woodshop save "coffee table" # named projects
|
||
woodshop open "coffee table"
|
||
```
|
||
|
||
Run `woodshop --help` for the full command list (place, join, stand, lay,
|
||
rotate, move, trim, copy, rename, sand, delete, undo, clear, status, cutlist,
|
||
export, save, open, projects).
|
||
|
||
The active scene lives at `$WOODSHOP_SCENE` or
|
||
`~/.local/share/woodshop/scene.json`; named projects in
|
||
`~/.local/share/woodshop/projects/`.
|
||
|
||
## Development
|
||
|
||
```bash
|
||
pytest # 41 tests
|
||
```
|
||
|
||
Key modules:
|
||
|
||
| Module | Role |
|
||
|--------|------|
|
||
| `scene.py` | Part/Joint/Scene model, operations, undo, persistence |
|
||
| `lumber.py` | nominal → actual dimensional lumber table |
|
||
| `units.py` | parse "6 ft" / "3 ft 6 in" / "-2 ft" → inches |
|
||
| `cli.py` | the `woodshop` command |
|
||
| `geometry.py` | build123d solids + STL/STEP export |
|
||
| `cutlist.py` | cut list, board-feet, shopping estimate |
|
||
| `viewer.py` | live pyvista 3D viewport (`woodshop-view`) |
|
||
| `driver.py` | conversational loop (`woodshop-talk`) |
|
||
| `scripts/gen_wood_tools.py` | (re)generate the `wood-*` CmdForge tools |
|
||
|
||
### Known limitations
|
||
|
||
- Joins are flush butt joints: B's end sits against A's face and B aligns to
|
||
A's reference corner (tops level + one side flush), so mixed-size boards line
|
||
up. Joinery *cuts* (mortise/tenon, lap, pocket holes) aren't modeled yet.
|
||
- Command interpretation latency is ~7–13s per utterance (one `claude -p` call).
|
||
|
||
## License
|
||
|
||
MIT
|