kerf-engine/README.md
2026-03-26 06:46:20 +00:00

253 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kerf
Modular raster-to-vector conversion engine paired with a 2D sign and patch design canvas. Upload a raster image (PNG, JPEG, BMP), trace it into clean vector paths using Potrace or VTracer, and export as SVG or DXF — ready for CNC routers, vinyl cutters, laser engravers, and embroidery machines.
## Quick Start
```bash
docker compose up -d
```
Once both services are healthy:
- **Web App** → [http://localhost:3000](http://localhost:3000)
- **Engine API** → [http://localhost:8000/engine/health](http://localhost:8000/engine/health)
- **Interactive API Docs** → [http://localhost:8000/docs](http://localhost:8000/docs)
Check service health:
```bash
docker compose ps
```
Tear down:
```bash
docker compose down
```
## Repository Structure
```
engine/ Kerf Engine — standalone Python/FastAPI vectorization API
api/ API route definitions
pipeline/ Preprocessing, vectorization, and post-processing stages
output/ SVG, DXF, and JSON output generators
presets/ Built-in preset configurations (JSON)
tests/ Engine test suite (pytest)
app/ Kerf App — React/TypeScript design canvas (Vite + Konva)
src/ Application source code
public/ Static assets including bundled fonts
docker/ Dockerfiles and nginx configuration
Dockerfile.engine Multi-stage build for the engine (Python 3.11)
Dockerfile.app Multi-stage build for the app (Node 22 → nginx 1.27)
nginx.conf SPA routing + /engine reverse-proxy
docker-compose.yml Full-stack orchestration with healthchecks
```
## Engine API Reference
The engine exposes four endpoints under the `/engine` prefix. All endpoints accept and return JSON unless otherwise noted.
### `GET /engine/health`
Healthcheck endpoint for container orchestration.
**Response:**
```json
{ "status": "ok" }
```
### `GET /engine/presets`
List all available presets and their parameter values.
**Response:**
```json
{
"presets": {
"sign": { "name": "sign", "description": "Metal signage, bold text cutouts", "..." : "..." },
"patch": { "name": "patch", "description": "Embroidered patches, fabric cutting", "..." : "..." }
}
}
```
### `POST /engine/trace`
Convert a raster image to vector output through the full preprocessing → vectorization → post-processing pipeline.
**Content-Type:** `multipart/form-data`
| Field | Type | Default | Description |
|-----------------|--------|------------|-------------|
| `file` | file | (required) | Raster image (PNG, JPEG, BMP) |
| `mode` | string | from preset | Vectorization engine: `potrace` or `vtracer` |
| `output_format` | string | `svg` | Output format: `svg`, `dxf`, or `json` |
| `preset` | string | `sign` | Preset name (see [Presets](#presets)) |
| `params` | string | `{}` | JSON string of parameter overrides |
**Example — trace with the sign preset:**
```bash
curl -X POST http://localhost:8000/engine/trace \
-F file=@logo.png \
-F preset=sign \
-F output_format=svg
```
**Example — trace with custom parameters:**
```bash
curl -X POST http://localhost:8000/engine/trace \
-F file=@photo.jpg \
-F preset=detailed \
-F mode=vtracer \
-F 'params={"filter_speckle": 4, "epsilon": 0.3}'
```
**Response (SVG/JSON formats):**
```json
{
"output": "<svg ...>...</svg>",
"format": "svg",
"metadata": {
"format": "svg",
"path_count": 12,
"node_count_total": 483,
"open_paths": 0,
"island_count": 2,
"warnings": [],
"processing_ms": 142.57
}
}
```
**Response (DXF format):** Raw DXF bytes with `Content-Type: application/dxf` and metadata in the `X-Kerf-Metadata` response header.
### `POST /engine/simplify`
Simplify an existing SVG using RamerDouglasPeucker path simplification. Optionally export to DXF with unit and scale control.
**Content-Type:** `multipart/form-data`
| Field | Type | Default | Description |
|-----------------|--------|------------|-------------|
| `file` | file | (required) | SVG file to simplify |
| `epsilon` | float | `1.0` | RDP simplification tolerance (higher = fewer points) |
| `output_format` | string | `svg` | Output format: `svg`, `dxf`, or `json` |
| `units` | string | none | DXF unit metadata: `inches` or `mm` |
| `scale_factor` | float | `1.0` | DXF coordinate scale factor |
**Example — simplify and export to DXF in millimeters:**
```bash
curl -X POST http://localhost:8000/engine/simplify \
-F file=@drawing.svg \
-F epsilon=2.0 \
-F output_format=dxf \
-F units=mm \
-F scale_factor=25.4
```
## Presets
Presets bundle tuned parameter sets for each pipeline stage — preprocessing, vectorization, and post-processing — optimized for specific use cases.
| Preset | Description | Mode | Epsilon | Notes |
|------------|------------------------------------|----------|---------|-------|
| `sign` | Metal signage, bold text cutouts | potrace | 2.5 | Aggressive denoising, auto-close enabled |
| `patch` | Embroidered patches, fabric cutting| potrace | 1.0 | Moderate smoothing, fine detail retention |
| `stencil` | Physical stencil cutting | potrace | 3.0 | Heavy simplification, fixed threshold at 128 |
| `detailed` | High-fidelity illustration work | potrace | 0.5 | Minimal smoothing, preserves fine curves |
| `custom` | All params exposed, no defaults | potrace | — | Pass all parameters explicitly via `params` |
Use the `params` field on `/engine/trace` to override any preset value. For example, to use the `sign` preset but switch to VTracer mode:
```bash
curl -X POST http://localhost:8000/engine/trace \
-F file=@image.png \
-F preset=sign \
-F 'params={"mode": "vtracer"}'
```
## Font System
The web app bundles three fonts for text-to-path conversion, enabling text elements to be converted to SVG outlines for cutting/engraving:
| Font | File |
|------------|-------------------------|
| Roboto | `Roboto-Regular.ttf` |
| Open Sans | `OpenSans-Regular.ttf` |
| Lato | `Lato-Regular.ttf` |
Fonts are parsed client-side using [opentype.js](https://opentype.js.org/) and converted to SVG path data with configurable font size and letter spacing. The conversion handles glyph positioning, coordinate system flipping, and path assembly — no server round-trip required.
## Engine Standalone Usage
The engine runs independently of the web app. Use it as a standalone API service or build just the engine Docker image:
**Docker (standalone):**
```bash
docker build -f docker/Dockerfile.engine -t kerf-engine .
docker run -p 8000:8000 kerf-engine
```
**Local development (Python):**
```bash
cd engine
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```
API docs are available at [http://localhost:8000/docs](http://localhost:8000/docs) (Swagger UI) and [http://localhost:8000/redoc](http://localhost:8000/redoc) (ReDoc).
## Development
### Engine (Python)
```bash
cd engine
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Run the API server with auto-reload
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# Run tests
pytest
```
System dependencies for pypotrace: `libpotrace-dev`, `libpotrace0`, `libagg-dev` (Debian/Ubuntu).
### App (React/TypeScript)
```bash
npm install
npm run dev --workspace=app
```
The Vite dev server proxies `/engine/*` requests to `http://localhost:8000` — start the engine first for full functionality.
### Full Stack (Docker Compose)
```bash
docker compose up --build
```
The app is served on port 3000 with nginx reverse-proxying `/engine/*` to the engine container.
## Known Limitations
- **Single-image processing** — the engine processes one image per request; batch endpoints are not yet available.
- **Binary vectorization only** — both Potrace and VTracer operate in binary (black/white) mode; color/multi-layer tracing is not supported.
- **No authentication** — the API is open; add a reverse proxy with auth for production deployments.
- **Font selection** — the app ships with three bundled fonts; custom font upload is not yet supported.
- **DXF fidelity** — DXF export covers basic polyline geometry; advanced CAD features (layers, blocks, hatches) are not included.