woodshop/README.md

6.1 KiB
Raw Permalink Blame History

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."

You can also attach reference(s) (📎, drag-drop, paste, or a URL) and say "build something like this": one or several photos (front/side/detail), a PDF plan, a 3D model (STL/STEP/OBJ — rendered to an image, with its bounding box measured), or a web-page guide (its text is pulled). WoodShop builds a simplified, buildable interpretation in dimensional lumber. Then click 🔄 Match photo and it renders the build from several angles, compares them to your reference, and self-corrects — repeat until it looks right. (Still an interpretation, not a measured replica.)

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 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

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

woodshop            # launches the unified desktop app

One window with the 3D viewport (click a board to select it; Ctrl+click to select several), a parts panel (list + selected-part inspector + quick-action buttons), a numberpad control panel (move/rotate the selection by clicking or with your keyboard's numpad — 2/4/6/8 move, 1/3/7/9 rotate, +/ raise/lower, 0/. front/iso, 5 fit), and a command bar where you type or push-to-talk (🎤). Mouse, keyboard, and voice all drive the same scene and the same visible selection — so "move these 4 inches", the numpad 8 key, and the move button are interchangeable, and act on every selected board at once (one undo). Menus cover New/Open/Save projects, Export STL/STEP, Save Image, Undo/Redo, camera views, and Build templates.

Standalone tools (headless / scripting)

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:

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

pytest                              # 200+ tests

Key modules:

Module Role
scene.py Part/Joint/Connection/Feature/Scene model, ops, undo, persistence
lumber.py nominal → actual dimensions, material colors/defaults
colors.py color name → hex + lightness blends for the viewer
units.py parse "6 ft" / "3 ft 6 in" / "-2 ft" → inches
cli.py the woodshop command
geometry.py build123d solids (incl. joinery booleans) + STL/STEP export
cutlist.py quick cut list / board-feet / shopping summary
cutplan.py the deterministic keystone: kerf-aware nesting, rough/final, batch, offcut reuse
prices.py editable price book (Kent NB) + material-aware cost estimate
estimate.py project quote: consumables + labor + suggested selling price
inventory.py shop-wide event-sourced stock / offcut / build ledger
instructions.py / jigs.py deterministic build steps & jig suggestions
viewer.py live pyvista 3D viewport (woodshop-view)
driver.py conversational loop (woodshop-talk)
gui/ the unified PySide6 studio (woodshop-gui), incl. the Cut List & BOM window
scripts/gen_wood_tools.py (re)generate the wood-* CmdForge tools

Known limitations

  • Joinery is parametric (tenon/mortise/dado/rabbet/hole/slot/chamfer as build123d boolean ops, with connections/assemblies); what's not modeled is joinery-fit compensation for material lost to sanding, and lap/pocket-hole presets. Boards still attach as flush butt joints unless you add features.
  • Render is flat colors per material/finish — no image textures (wood grain) yet.
  • Command interpretation latency is ~713s per utterance (one claude -p call).

License

MIT