A hardware-aware image-to-plotter pipeline optimized for the UUNA TEK iDraw 2.0 A4 / AxiDraw ecosystems. This system stylizes raw photos into technical blueprints, normalizes them for machine readiness, and automates SVG vectorization.
One source photo rendered by nine of the pipelines — AI lineart, drafted entourage, dusk notan value plate, multi-region compose, burin engrave, weighted-Voronoi stipple, hatch value study, and two art-theory style lenses. Every panel is a plot-ready SVG; the whole grid above is token-free / model-optional.
Tracked in the repo:
- /packages/cli → The Python engine,
penoperator wrapper, hardware profiles. - /docs → Full documentation (workflow, pipeline catalog, calibration, research library).
- /scripts → Batch/maintenance helpers.
- /print-files/prompts → Stylistic prompt definitions (Presets 0–7).
- /print-files/calibration → Calibration records + learned media parameters.
- /print-files/pass-plans → Multi-pen / multi-pass plot plans.
Created at runtime (not tracked — see .gitignore):
- /print-files/originals → Your raw input photos (HEIC/JPG/PNG).
- /workspace → Candidate SVGs/previews/montages, per-image variation reviewers, album/timeline HTML.
- /models → Downloaded neural-model weights (optional; see Requirements §4).
- /jobs, /.cache, /logs → Run archive + pipeline caches + logs.
- Hardware-Aware Profiles: Optimized specifically for UUNA TEK iDraw 2.0 A4 (bed size, pen width, GRBL acceleration).
- Hybrid Stylization: Uses Structural Anchors (Contour & Centerline) to lock subject identity, proportions, and topology during AI stylization.
- Deterministic Reduction: Optional non-AI mode for pure geometric edge detection (Canny-based).
- Vision-Integrated Naming: Generates descriptive 3-word slugs for every image.
- Eight Technical Presets (0-7): From Architectural Precision to Focal Isolation.
- Audit-Ready Providence: Every plot in
/historycontains its full lineage of artifacts.
Developed and tested on macOS (Apple Silicon / arm64), Python 3.14. The image → SVG pipeline is portable (should run on Linux/Intel with the same Python deps); the plotting side (serial dispatch + the Inkscape iDraw extension) is Mac-oriented. Board-firmware flashing is Windows-only, so on Mac the pipeline relies on software resilience (see the Z-compensate/lockup notes below).
You can generate plot-ready SVGs with no plotter attached — the hardware is only needed to actually draw.
The pipeline uses two virtualenvs because vpype pins an older shapely
that conflicts with the main stack.
Main environment — rendering, vectorization, the pen CLI:
python3.14 -m venv venv
venv/bin/pip install -r requirements.txtPackage (pinned in requirements.txt) |
Used for |
|---|---|
numpy, scipy |
array + geometry math |
opencv-python-headless |
image processing, edge/FDoG, face + segmentation |
Pillow, pillow-heif |
image IO incl. HEIC/HEIF |
scikit-image |
skeletonization / centerline tracing |
svgwrite, shapely |
SVG emission + geometry ops |
torch, torchvision, controlnet-aux |
optional neural line/edge + SAM models |
PyYAML, python-dotenv, requests, pypdf |
config, .env.local, HTTP, PDF |
openai, google-generativeai |
optional remote AI providers |
vpype environment — path optimization (linemerge / linesort / occult):
python3 -m venv venv-vpype
venv-vpype/bin/pip install "vpype==1.9.0" "setuptools<81"
setuptools<81keepspkg_resourcesavailable for vpype 1.9 on Python 3.14.
| Tool | Needed for | Source |
|---|---|---|
| Inkscape 1.x | headless plot dispatch — the iDraw extension runs under Inkscape's Python (lxml in the main venv supports this) |
inkscape.org |
| iDraw / AxiDraw extension | the plotter control script the dispatcher shells out to | vendor (UUNA TEK / Evil Mad Scientist) |
| DrawingBot V3 (optional) | a few stylization presets | drawingbotv3.com |
UUNA TEK iDraw 2.0 A4 (or AxiDraw) over USB serial — GRBL controller,
board firmware 2.22. Bed size, pen width, and acceleration live in
packages/cli/plotter_profiles/. Not required for anything upstream of the plot.
The AI line pipelines download weights into models/ (git-ignored):
- lineart — Informative Drawings
sk_model.pth(~16 MB) →models/lineart/. - SAM (whole-scene segmentation) and other edge models similarly.
If a weight is absent the pipeline skips it or falls back to a classical CV equivalent — the deterministic fleet needs none of them.
Only the AI-styled variants call a remote provider. Copy the template and fill in whichever you have:
cp .env.example .env.local # git-ignored; never committedImage-gen tries providers in a fallback chain (xai → openai → gemini) and, on a
credit/quota error, transparently moves to the next. All optional.
venv/bin/python -m unittest discover packages/cli/tests # geometry regression tests
packages/cli/pen setup # probe plotter port + iDraw extension + Inkscape (plotter optional)
packages/cli/pen plot --simulate # zero-motion rehearsal of the picked jobThe entire classical / faithful fleet — scene line (drafted entourage), dusk (notan value plate), compose plate, portrait/group line & engrave, hatch, stipple, and every style-lens in its faithful CV mode — needs neither an API key nor a model weight. AI features are strictly additive and degrade gracefully when unavailable.
The daily loop is three commands and one number (full reference: docs/hands-free-workflow.md §11):
packages/cli/pen make photo.heic # process + render preview montage
packages/cli/pen pick 3 # select candidate 3, prepare dispatch files
# power-cycle plotter → carriage against BOTH top-right corner stops →
# paper's TOP-RIGHT corner nested into the plotted jig (pen ON the paper)
packages/cli/pen plot --simulate # zero-ink rehearsal (optional)
packages/cli/pen plot # digest preflight + confirm once + plot
packages/cli/pen photo <img> # feedback loop: photograph the result
packages/cli/pen review # ratings → learned line widthsOne-shot prep (image → print-ready SVG + the exact plot command, no make/pick loop). Locks every print parameter FIRST — and asks/lists options for any you omit (pen, paper, orientation, fit, correction) — then orients, crops-to-fill, vectorizes, fits to paper, validates with a z-compensate simulate, and prints the ready-to-run plot + resume commands. Never auto-plots:
packages/cli/pen prep photo.jpg --pen pilot_g2_07 --paper strathmore-half \
--fit fill --correction uuna_tek_writing_robot_t_a4_ant_2026-06
# add --vector fdog for a PHOTO (centerline is for clean line-art);
# --orient auto|cw|ccw, --fit fill|whole, --yes to take defaults for omitted inputs
# --detail auto|full|high|medium|low : linework density (faithful — selects from
# real edges, never invents). 'auto' derives it from the pen×paper budget;
# lower keeps only the longer/stronger contours and drops fine texture.
# --sweep : render ALL detail levels into one labeled contact sheet
# (detail_sweep.png, with pen-down length per level) to choose visually.
# Input EXIF orientation is honored, so a correctly-shared upright photo loads
# upright; --orient only optimizes fill (auto rotates 90° to best fill the sheet).Machine geometry (measured, do not re-derive from intuition): the plot path rotates 90° — drawings extend LEFT and DOWN from the pen start; dispatch counter-rotates so output reads upright. Every dispatch runs a digest preflight showing exact travel before any motion.
Occasional:
packages/cli/pen setup # probe hardware + calibration guidance
packages/cli/pen plot-file <file.svg> # direct dispatch (tool auto-detected from pass filenames)
packages/cli/pen plot-file <file.svg> --z-compensate # apply the bed-warp correction (tiles by depth level)
packages/cli/pen plot-file <file.svg> --z-compensate --z-start-index K # RESUME at level K (earlier levels already drawn — no double-ink)
packages/cli/pen load-pen [--offset N] # Z-fidelity pen loading (guided; engagement in mm)
packages/cli/pen calibrate [--compact] # generate calibration test sheet
packages/cli/pen record-calibration --gap 3 --speed 4
packages/cli/pen learn # aggregate reviews into findingsBed-warp compensation & the controller lockup. --z-compensate plots in
depth-banded passes (one dispatch per level) to offset the non-flat platform —
see docs/z-warp-calibration.md. Between passes the iDraw can transiently refuse
the reconnect; this is handled in software: --z-retries N (default 2)
auto-retries a lockup, and on a hard lockup the run prints the exact
--z-start-index K resume command (power-cycle, return the pen to (18,0), resume
— nothing already drawn is re-inked). The board firmware is 2.22 (query via
the iDraw control script's --mode manual --manual_cmd fw_version); UUNA TEK's
"3.9.x" is the PC app, not board firmware, and firmware flashing is
Windows-only, so Mac relies on this software resilience.
Multi-pass (proven 2026-06-12 — see hands-free-workflow.md for the swap sequence
and per-pen offset calibration): plot pass 1 → motors-on → load-pen swap →
plot pass 2. Per-pen barrel offsets live in tool_registry.py and are
compensated automatically.
Generates all styles using structural anchors to preserve subject identity.
venv/bin/python packages/cli/main.py process-all-presets --mode hybridPure mathematical trace (No AI/No API calls).
venv/bin/python packages/cli/main.py process-all --mode deterministicConverts everything in outputs/ into SVGs optimized for the iDraw.
venv/bin/python packages/cli/main.py vectorize-allUUNA TEK iDraw 2.0 A4 — Plotter Pipeline — 2026
