# 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": "...", "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 Ramer–Douglas–Peucker 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.