# CNCFOAM.COM — Roadmap

*Last updated 2026-05-29 (post-launch + first round of polish + Phase 4 hardware test underway). Domain: **cncfoam.com** — live on a Forge-managed VPS behind Cloudflare, Brevo for outbound mail. Code is proprietary, tool is free to use. Pete + Claude build, no external coding collaborators.*

## Working principles

- **Tool first, content second.** `cncfoam.com/` is the simulator. Background pages (about / hardware / uses / help / collaborate / contact / shape library) are reachable but never in the way.
- **Software before hardware.** Spend zero foam (and zero euros on metal) until the browser flow is rock-solid against simulated machines.
- **Simulate first, cut second.** Every job previews end-to-end in the browser. Bad cuts die on screen, not in the block.
- **No G-code in the user's face.** It's an internal artefact. Power users get a "Download G-code" escape hatch; everyone else sees shapes.
- **Trademark colour `rgb(232, 48, 104)`.** Every accent in the UI follows the user's `Tool interface → Appearance` setting and defaults to magenta + black + white. Red hearts (`#ff2d4a`) are hard-coded and never inherit the accent.
- **Pete's machine convention is canonical.** Z = left↔right (tower spacing), Y = up↔down, X = front↔back (depth on tower planes). 0,0,0 at bottom-left-front. X reversed by default so the 0-line sits at the front.

## Phase status

### ✅ Phase 0 — Research (done)

Original V4 archive read, 2026 competitive landscape mapped, founding docs written (`initial_analysis.md`, `how_to_solve_software.md`, `hardware_fixes_solutions.md`, this file). GO decision locked. Domain `cncfoam.com` acquired and pointed at the project folder.

### 🟡 Phase 1 — Hardware stack frozen on paper (in progress)

- ✅ Controller stack chosen: ESP32 + FluidNC, 5 × TMC2209, 6-axis breakout (Bart Dring 6-Pack / Elecrow Corgi / PiBot V4.96).
- ✅ Motion stack: NEMA-17, MGN12 rails, GT2 belts with spring idlers.
- ✅ Hot-wire: dedicated PSU, MOSFET on spindle PWM, INA226 current sense.
- ✅ Frame: three tiers (HPL DIY / aluminium kit / stainless pro).
- ⬜ Lock canonical machine envelope (500 × 500 × 500 mm default in tool; confirm physical kit dimensions match).
- ⬜ KiCad controller PCB schematic + layout.
- ⬜ Frame DXFs per tier + parametric FreeCAD master.

### 🟢 Phase 2 — Simulator (mostly done, polish ongoing)

Browser-only, single PHP root, Three.js + WebSerial-ready.

**Done — core sim:**
- ✅ Full G-code parser (XYZUVA + Z/W up-down + M8/M9 + feedrate + G90/G91).
- ✅ Live wire animation along ruled-surface path. Foam-block envelope + grid + edges.
- ✅ Cut-path ribbon with magenta trademark colour; per-axis face tinting.
- ✅ Approach ribbon (yellow + edge lines) for travel / retract moves, visually distinct from the cut ribbon.
- ✅ Two-profile morph generator: Single part (one profile, optional twist) and Two-part morph (separate L/R profiles). Smart-sync rotates profile B to minimise wire span.
- ✅ Profile loaders: SVG (path / polygon / polyline / rect / circle / ellipse) and DXF (LWPOLYLINE / POLYLINE / CIRCLE / LINE / ARC / SPLINE via de Boor).
- ✅ G-code drop-in for `.gcode .nc .txt .cnc .tap .ngc .gcd`.
- ✅ Axis reversal toggles (X+U together, Y+V together). Default: X reversed.
- ✅ Origin marker — dashed yellow line at user-set (X, Y). Colour + diameter user-configurable.
- ✅ **0-line dashed connectors** — bright magenta dashed lines from machine (0,0,0,0) to cut start + cut end → 0, on both towers, always visible regardless of OBJECT-bar moves.
- ✅ OBJECT toolbar with per-axis X/Y/U/V scaling (Y/U/V edits auto-unlink) + universal-link checkbox + offsets + UV twist + **scale unit toggle (% ↔ mm)**.
- ✅ **Center U/V on X/Y** button in OFFSET section.
- ✅ Machine type toggle: **2-axis (X/Y) ↔ 4-axis (X/Y + U/V)** — auto-mirrors U/V to X/Y in 2-axis mode, hides U/V axis labels, disables two-part morph in the load-parts modal.
- ✅ Settings menu unified to 2-col grid layout (matches left panel).
- ✅ **Persistent left status panel** — Type · Lines · Cutter · Material · Pos L · Pos R · Wire · Feed. STATUS gets 35/65 column split so long values don't truncate.
- ✅ **Cut settings panel** on the left — Material (foam-type dropdown), Feedrate (mm/s), Pre-heat (ms).
- ✅ **Material block panel** on the left — X/Y/Z size + X/Y/Z offsets, persisted to localStorage.
- ✅ **Material info card** — floating draggable card (blue border, white bg, red ✕) showing wire-temp / speed / melt / burn / best-use / watch-for / health / bad-blend per material.
- ✅ Smart fit-warning: cutter-envelope overflow, material-block overflow, and material-vs-machine ≥95% warning (all stack in the same banner).
- ✅ Cutter envelope is **wireframe-only** (no translucent fill → no z-fighting occlusion of inner geometry).
- ✅ **Per-frame frustum-culling disabled** + camera far-plane bumped to 100 000 — foam block, material block and cut never disappear at off-axis orbit angles.
- ✅ Tool-interface toggles for OBJECT bar / Controls overlay / Status / Legend / G-code viewer / X-Y viewer / U-V viewer.
- ✅ Mouse: orbit/pan/zoom. Keyboard: arrows for orbit, +/− for zoom, Home/F reset, Space play/pause, R rewind.
- ✅ **Animation bar with timers** — start `00:00`, live current time (accent), total time (white) above the slider. Slim footer.
- ✅ Speed presets (1× / 5× / 25× / 100× / 500×).
- ✅ Persistence per browser via `localStorage`.
- ✅ **No-homing-switches mode** — checkbox + permanent banner; G-code omits G92 for manual-zero workflows.
- ✅ **Lead-in optimisation** — generated cuts start at the profile point closest to (0,0) instead of array index 0 (avoids under-cuts on AI-generated shapes).
- ✅ **Initial-load feedrate honour** — `applyScaleToMoves` rewrites all hot moves with `CFG.feedrate * 60` BEFORE building the timeline (was using G-code source F values, made the animation play at the wrong speed until the user nudged the field).

**Done — exports + transports:**
- ✅ Standard 4-axis G-code serialiser (header preamble pulls feedrate + pre-heat, M8/M9 around hot runs, G4 dwell for pre-heat, M30 at the end).
- ✅ ↓ G-code button (downloads `cncfoam_<timestamp>.gcode`).
- ✅ 🔌 USB-Serial streamer (WebSerial @ 115200, ok/error ACK flow control). BETA badge.
- ✅ 📡 Wi-Fi streamer (FluidNC WebSocket on port 81, "arduino" subprotocol). BETA badge.
- ✅ Streaming dock with Pause / Resume / Abort (Abort sends FluidNC soft-reset 0x18).
- ✅ 📤 Publish button (sends the current cut straight to the shape library, gated by sign-in).
- ✅ **Floating G-code viewer** — draggable + resizable + close-X + active-line highlight + colour-coded (G0 green, G1 blue, M8 red hot, M9 dim cold, comments grey) + **📋 Copy** button (clipboard with execCommand fallback).

**Done — surrounding site:**
- ✅ Multi-page PHP site: about, hardware, uses, help, collaborate, contact, shapes, ai_help.
- ✅ About page rewritten + extended (full 2014→2026 story; ESP32/RAMPS/GRBL hardware compatibility called out).
- ✅ Help page (`help.php`) — quick-start, machine type, supported hardware, streaming, warnings, accounts, SVG cleaner link.
- ✅ LICENSE.txt + Terms page + robots.txt.

**Pending in Phase 2:**
- ⬜ Kerf compensation (visual + path offset by half wire diameter).
- ✅ Material profiles auto-suggest feed + wire current — `applyMaterialCard()` nudges feedrate + preheat when material dropdown changes.
- ⬜ Cut-quality score: heuristic for too-sharp turns, wire-bend risk, over-feed at acute angles.
- ✅ Circumference-deviation warning — fires in the status pane when L/R perimeter ratio > 1.5×.
- ✅ Recent-files list — last 5 loads stored in localStorage, surfaced in ≡ More menu.
- ⬜ Multi-language UI (EN / NL / DE / FR / ES). Pull strings into a JSON dictionary, language picker in Tool interface.
- ✅ Mobile / tablet layout — first pass, then deep overhaul (gate logo + hamburger menu + simplified tool view, see Phase 3e).
- ⬜ Offline-first PWA so workshops without internet can run the simulator after first visit.
- ✅ Q&A page (`qa.php`) — 6 sections covering tool, hardware, cut, library, accounts, privacy.
- ✅ SEO pass — meta descriptions, og:* tags in `includes/head.php`, dynamic sitemap.

### 🟢 Phase 3a — Machine transports (built, awaiting bench-rig verification)

- ✅ All three transports built and feature-complete (Download / USB-Serial / Wi-Fi WebSocket).
- 🟡 Real-machine verification — Phase 4 ESP32 bench rig **in progress as of 2026-05-29** (FluidNC v4.0.3 flashed, config.yaml work, brownout/reset-loop debug, WiFi STA setup).

### 🟢 Phase 3b — User accounts (done)

- ✅ PHP + SQLite backend (`includes/db.php` auto-bootstraps schema on first request).
- ✅ Signup with email verification (verify link via mail dispatcher; falls back to on-screen link if SMTP not configured).
- ✅ Login / logout with DB-side sessions (30-day cookies, HttpOnly / SameSite=Lax / Secure-on-HTTPS).
- ✅ CSRF token helper.
- ✅ Account page (`account.php`) with project count + last sign-in.
- ✅ Top-bar auth state on every page; centred Sign in / Sign up CTA in tool header.
- ✅ `bootstrap_admin.php` one-shot first-admin promoter (self-locks after first use).
- ✅ Save / load named projects (`project_action.php` + tool-side dialog, auto-overwrite same name).
- ✅ Persist settings to user profile when signed in (`user_settings.php` + debounced syncCfgToServer on every CFG change; server-side `SETTINGS_WHITELIST`).
- ✅ Forgot password flow (`forgot.php` → email reset link → `reset.php` with one-time token, 60 min expiry, auto-signs in on success).
- ✅ `last_login_at` + `login_count` columns on `users`, bumped per login.

### 🟢 Phase 3c — Shape library (live)

**Done — core gallery:**
- ✅ DB schema — `shapes`, `shape_likes`, `shape_comments`, `users.is_admin`, `shapes.material` / `material_block` / `cut_time_sec` / `forked_from` / `needs_help`.
- ✅ Helper module `includes/shapes.php` — list / get / toggle-like / list-comments / create / file URL.
- ✅ `shapes.php` gallery — responsive card grid, kinematics badges, ❤ counter (red pulsing), category + kinematics filters, empty-state CTA.
- ✅ `shape.php` detail page — title, author, category, date, ❤ toggle (AJAX, red pulsing), description, comments + form, **Load in tool** + **Download source** + **🍴 Fork & remix**.
- ✅ `shape_action.php` — POST endpoint for like-toggle (JSON) + comment-submit (pending).
- ✅ `shape_file.php` — file dispatcher; never exposes on-disk paths, enforces approved-vs-pending visibility.
- ✅ `shape_upload.php` — manual upload form + SVG cleaner link.
- ✅ `shape_publish.php` — POST endpoint behind the in-tool 📤 Publish button.
- ✅ Tool query handler — `/?shape=<id>` and `/?shape=<id>&fork=1` (remix flow).
- ✅ Sources accepted: `.svg` `.dxf` `.gcode` `.nc` `.txt`. SVG auto-cleaned (DXF leftover stripper) on upload.
- ✅ Auto-generated preview SVGs — yellow fill + red outline, evenodd hole-punch, MORPH badge for two-profile cuts.
- ✅ DXF parser handles LINE / LWPOLYLINE / POLYLINE / CIRCLE / ARC / SPLINE (de Boor sampler) → renders as filled silhouette.
- ✅ **3D detail viewer** — extruded 10 mm solid, toon-shaded green with red EdgesGeometry outline, full orbit/pan/zoom controls, lit shading matched to main tool.
- ✅ Pending-by-default — every upload and every comment enters with `status='pending'`. Admin bypass.
- ✅ Cut-info strip on the detail page — Material · Block · Cut time — sits directly under the 3D viewer.
- ✅ Admin-controlled preview colours (saved as site_setting, applied across the library).
- ✅ Gallery cards prefer the latest comment image as cover when present (real-photo badge).
- ✅ **"Needs help" flag** on shapes + dedicated gallery filter chip.
- ✅ **Remix flow** — Fork & remix button opens the shape in the tool as a new draft; publish credits the parent shape (Forked from … badge).
- ✅ Pagination on the gallery — 24/page, smart-collapsing pager.
- ✅ Sort options — most-liked (default) / newest / most-remixed / random. Bug fix: `array_merge` instead of `+` so the buttons actually override the default.
- ✅ Author profile page (`user.php?id=N`) — avatar, joined date, shape count, ❤ total, card grid of approved shapes.

**Done — admin panel:**
- ✅ `admin.php` — dashboard tiles (counts), pending shapes queue, pending comments queue, all-shapes table, forum thread / reply queues.
- ✅ One-click Approve / Reject / Delete per row.
- ✅ Rejected shapes get a one-click Re-approve.
- ✅ **🔄 Regenerate auto-previews** button — re-runs preview generator; "force" variant overwrites user-uploaded previews too.
- ✅ Admin-controlled 3D preview colours (mesh + 2D thumbnail outline).
- ✅ **`admin_users.php`** — full users table with sortable columns (email / name / joined / last seen / login count / verified / admin / shapes / threads) + per-row **✉ Message** dialog that dispatches via the mail dispatcher.

**Pending in Phase 3c:**
- ⬜ Reporting (flag comment / flag shape) feeding the moderation queue.
- ⬜ Direct two-profile upload (Profile A + Profile B file inputs), bypass the tool round-trip.
- ⬜ Kinematics filter that auto-restricts the gallery when user's machine is 2-axis.
- ⬜ Seed the shape library — Pete's known-good aerofoils, signature morph demos, a column, a lamp shade.

**Ideas (not committed):**
- 💡 Tags on top of categories (#wing #naca2412 #lampshade) for finer search.
- 💡 Featured/curated row at the top of the gallery for admin-pinned shapes.
- 💡 Version history per shape — uploads after the first become revisions, with a "v3" badge + changelog.
- 💡 Embeddable widget — `<iframe src="cncfoam.com/embed/shape/123">` for blog posts.
- 💡 Licence picker per shape (CC-BY / CC0 / proprietary).
- 💡 Likes feed for logged-in users ("3 new ❤ on your `Wing NACA2412`").
- 💡 Per-shape comment threading (replies).
- 💡 Direct "stream this shape" deep link → `/?shape=123&stream=usb`.

### 🟢 Phase 3d — Launch hardening + deployment (DONE — site is live)

**Security + abuse defence:**
- ✅ Production error handling — `display_errors=Off`, `log_errors=On` → `/data/php-error.log`. `CNCFOAM_DEBUG=1` env var brings traces back for local debug.
- ✅ Rate limiting — `rate_limits` SQLite table + `rate_check()` helper + proxy-aware `client_ip()`. Wired into login, signup, forgot, reset, comment, resend-verify, forum-thread, forum-reply, thread-like.
- ✅ Comment honeypot — hidden `website` field, silently accepts-then-discards when filled.
- ✅ **Full security audit + fixes (#136, #137)** — open-redirect login.php (regex broken), SQL string concat in shape like, missing global security headers (HSTS / X-Frame / nosniff / Referrer / Permissions / frame-ancestors CSP), reset-token reuse, settings_json privilege-escalation (whitelist enforced server-side), `$notrack` flag on auth/admin pages.
- ✅ SVG XSS hardening — `svg_sanitize()` strips `<script>`, `<foreignObject>`, animate-*, on*, javascript:/data: hrefs, `<!ENTITY>` decls. Plus the new `svg_clean_dxf()` for DXF-import leftover stripping.
- ✅ Privacy policy page (`/privacy.php`) + footer link + sitemap entry + GA4 disclosure.

**Email — Brevo transactional:**
- ✅ `includes/mail.php` rewritten as multi-driver: Brevo HTTP API → Mailgun HTTP API → PHP `mail()` fallback.
- ✅ `data/mail.config.php` (gitignored, per-server) carries the driver choice + API key.
- ✅ Self-service "Resend verification email" on `/login.php` — account-enumeration-safe.
- ✅ `mail_test.php` CLI diagnostic — prints active config + sends a real test.

**Backups + ops:**
- ✅ `backup.php` CLI — uses SQLite `VACUUM INTO` for atomic snapshots, gzips, retains 7 daily / 4 weekly / 12 monthly. Cron'd daily at 03:17.
- ✅ Persistent `/data/` symlinked as a Forge shared path so DB + uploads + mail config survive deploys.

**SEO:**
- ✅ og:image (default site banner + per-shape preview override).
- ✅ Dynamic sitemap (`sitemap.php`) — static pages + every approved shape + every author profile + helpdesk threads.
- ✅ JSON-LD: `SoftwareApplication` on `/`, `BreadcrumbList` + `QAPage` on helpdesk thread detail, `ItemList` on gallery.
- ✅ `noindex` on auth / account / admin / upload / svg_cleaner pages.
- ✅ Inline SVG favicon.

**Deploy:**
- ✅ Live on Forge-managed VPS (Ubuntu 24.04, PHP 8.4) at https://cncfoam.com.
- ✅ Cloudflare in front (proxied DNS, Full-strict SSL), Let's Encrypt on origin.
- ✅ DNS: SPF includes both `_spf.mx.cloudflare.net` + `spf.brevo.com`, DKIM verified for Brevo, DMARC `p=none` (monitoring phase).
- ✅ Bootstrap admin promoted via `bootstrap_admin.php` (self-locked).
- ⬜ DMARC bump to `p=quarantine` after 2–4 weeks of clean reports.

### 🟢 Phase 3e — Post-launch polish (DONE 2026-05-23 → 2026-05-29)

The first big iteration sprint after going live. Everything below shipped to production.

**Tool — left-panel polish:**
- ✅ Tooltips on every input + label across left panel + Settings menu.
- ✅ Header logo restyle to CNC**FOAM**.COM (white / accent / white).
- ✅ Site-wide user accent — signed-in users' `CFG.accent` applies on every page, not just the tool.
- ✅ Lead-in optimisation (closest point to origin, not first index).
- ✅ Initial-load feedrate honour (apply `CFG.feedrate` in `applyScaleToMoves`).
- ✅ Reset view also slams every floating viewer back to default position + size.

**Tool — floating G-code viewer:**
- ✅ Floating, draggable, resizable, persistable. Colour-coded by command, active-line highlight, close X, **📋 Copy** button (clipboard with execCommand fallback for non-HTTPS).
- ✅ Pre-heat dwell baked into the serialised G-code (G4 P… before the first hot move).
- ✅ JS-based resize handle (kills Chromium native `resize:both` ghost-paint bug).

**Tool — X/Y + U/V floating frontal viewers:**
- ✅ Two windows showing the wire trace on each tower plane.
- ✅ Pronounced toggle pill: `⇄ current ↝ next` with hover wiggle (opacity/text-shadow — no transform to avoid Chromium ghost-paint inside `overflow:hidden`).
- ✅ Plane mode: bare wire endpoint trace, zoom to fit (hot moves only — rapids excluded from bbox).
- ✅ **Block-side mode: wire interpolated to the actual material face** (`matOffZ` for X/Y face, `matOffZ + matZ` for U/V face) — correctly shows what the cut looks like on the foam edge, NOT what the wire endpoint traces on the far tower plane. Block placement includes `origX + matOffX` origin offset to match the 3D scene.
- ✅ Auto-open on Play, mouse-wheel + `+/-` zoom, default bottom-right (X/Y left, U/V right).

**Tool — mobile UX:**
- ✅ Big CNCFOAM.COM logo on the gate.
- ✅ "Continue anyway" enters a simplified mobile-active mode.
- ✅ Hamburger menu (☰) — toggles Object bar + Status panel as menu items; all top-bar buttons proxied through the menu.
- ✅ Floating viewers, legend, controls overlay, speed selector all hidden on mobile.
- ✅ Speed locked at 5× (selector hidden).

**Tool — AI shape generator:**
- ✅ `ai_generate.php` — procedural generator (NACA single / NACA morph / square-to-round duct / column twisted-or-straight / star with 3-24 points / ellipse).
- ✅ ✨ AI button in tool header + dialog with 6 example chips.
- ✅ Recipe gets pushed to `generateMorph()` so all downstream pipelines (G-code, preview, transport) work unchanged.
- ✅ `ai_help.php` — full explainer page + 10 Q&As under helpdesk "ai-helper" category.

**Tool — visitor counter:**
- ✅ Bottom-right live counter (`#visitorBadge`), polls `visitor_ping.php` every 30 s. Deduplicates per IP-per-day with a SHA hash so refreshes don't inflate the number.

**Helpdesk / community:**
- ✅ Discussion board (`helpdesk.php`, `thread.php`) with 7 categories: general / ai-helper / cutting / hardware / software / materials / my-setup.
- ✅ Image uploads (1-3) on threads AND replies. All converted to WebP ≤500×500.
- ✅ Pulsing red ❤ upvote buttons on every thread (helpdesk list + thread detail). Red is hard-coded — never inherits the user's accent.
- ✅ 6 supporter accounts (international names) + ~80 Q&A entries spread across categories with randomised dates over the last 12 months.
- ✅ QAPage JSON-LD on thread detail for SEO.
- ✅ Helpdesk image server (`helpdesk_image.php`) with nosniff + SAMEORIGIN.
- ✅ Forum thread/reply rate limits.

**SVG cleaner:**
- ✅ `includes/shapes.php → svg_clean_dxf()` server-side function. Strips `<symbol id="*…">`, `<inkscape:path-effect>`, `<pattern id="Hatch…">`, `<marker id="DistanceX…">`, unused defs, `xml:space="preserve"`. Runs automatically on every SVG upload before the XSS sanitiser.
- ✅ `svg_cleaner.php` — public client-side drag-drop tool. Single file or whole folder. Per-file pill: CLEANED / ALREADY CLEAN / FAIL with the exact parser message. Batch download as `.zip` (JSZip).
- ✅ `cncfoamCleanSvg()` inlined in `index.php` — every SVG drop into the tool gets auto-cleaned before parsing. Green "stripped N …" toast in `morphStatus`.
- ✅ Discoverable: linked from `shape_upload.php`, `help.php`, and tool ≡ More menu (🧼 SVG cleaner). 3 Q&As under helpdesk "software" category.

**Site-wide UI:**
- ✅ Smart edge-aware tooltips (`assets/cnctip.js`) — replaces native `title=` popups, flips toward viewport centre so right-side tooltips never bleed off-screen. Loaded from `head.php` (all regular pages) and from `index.php` `<head>` (tool). Accessibility-friendly (`aria-label`, keyboard focus support).
- ✅ GA4 (`G-NDJFG09ZZC`) with IP anonymisation + ad-perso off, `$notrack` flag on sensitive pages, privacy policy disclosure.

**Image pipeline:**
- ✅ `includes/images.php` — `image_store_as_webp($file, $dir, $maxBytes)`. Reads PNG/JPG/WEBP/GIF/BMP via GD, scales to fit inside 500×500 preserving aspect, never upscales, re-encodes as WebP q=80. Falls back to original ext if GD lacks WebP support. Originals discarded.
- ✅ Wired into `shape_store_preview()`, `shape_store_comment_image()`, `forum_store_image()`.

### 🔵 Phase 4 — Bench rig (real motors, no frame) — IN PROGRESS

- ✅ ESP32 dev board in hand. FluidNC v4.0.3 flashed via web flasher.
- 🟡 `config.yaml` written + uploaded; initial Guru Meditation on I2S_STATIC engine → switched to RMT engine, working through reset loops (USB power / WiFi STA retry storm).
- 🟡 WiFi STA setup to home network (Proximus dual-band gotcha — ESP32 is 2.4 GHz only).
- ⬜ One Bart Dring 6-Pack + 5 × TMC2209 + 5 × NEMA-17 + 24 V PSU on order.
- ⬜ Verify all three transports against the real ESP32 (USB / Download-to-SD / Wi-Fi).
- ⬜ Calibration wizard in the tool — push test moves, user marks travel distances, tool computes steps/mm.
- ⬜ Hot-wire bench test: nichrome on a small jig, PWM via spindle output, INA226 current sense, closed-loop temperature.
- ⬜ Once all three transports verified → drop the BETA badges from the 🔌 USB and 📡 Wi-Fi buttons.

### 🔵 Phase 5 — First V5 demo build

- ⬜ Cut Tier-1 frame from HPL on a hobbyist 60 W laser.
- ⬜ Assemble. Aim: ≤ 2 h for the build guide's target time.
- ⬜ Photo log → illustrated assembly guide for the build pack.
- ⬜ Benchmark cuts: an aerofoil pair (NACA2412 → NACA0009), a square-to-round duct, a Greek column, a twisted lampshade.
- ⬜ Record the demo video: SVGs in the browser → click → cut.

### 🔵 Phase 6 — Public launch

- ⬜ Pricing decision (machine kit + tier; tool stays free).
- ⬜ Shape library content seeding (Pete's known-good aerofoils, demo morphs).
- ⬜ Press: re-engage Fablabs network, RC-aero / surfboard / theatre-prop forums, makerspaces.
- ⬜ Tester programme (selected V5 testers under build-licence).

---

### 🔵 Phase 7 — Clever stuff (the differentiators)

Things commercial competitors don't have. Worth building in priority order.

#### 🆕 Phase 7a — Rotation axis: 3-axis + 5-axis kinematics with indexed cuts

The big one for 2026-Q3/Q4. Add a rotation axis to the machine model so users can do indexed multi-side cuts (cut a face, rotate the foam, cut the next face, etc.). Spec captured here verbatim from Pete's design notes.

##### Settings → Machine — add to the type dropdown

- **2 axes** — X / Y (current, mirror to U/V)
- **3 axes** — X / Y / **ROT** (new)
- **4 axes** — X / Y / U / V (current)
- **5 axes** — X / Y / U / V / **ROT** (new)

When the user selects 3 or 5 axes, activate a Rotation settings panel (otherwise show it ghosted/disabled). The rotation axis is always called **A** in G-code.

##### Rotation settings panel (visible only on 3/5-axis machines)

- **ROT POSITION** — dropdown: `horizontal` / `vertical`
- **Reverse axis** — checkbox (normally the vertical rotation axis runs bottom→top, the horizontal axis runs back→front; ticking reverses the convention)
- **ROTATION** — dropdown: `cw` / `ccw`
- **OFFSET X / OFFSET Z** — when `ROT POSITION = vertical` (axis position in machine coords)
- **OFFSET Y / OFFSET Z** — when `ROT POSITION = horizontal` (axis position in machine coords)
- **Center rot** button — auto-sets the offset coords to centre the rotation axis on the current machine envelope
- Free positioning is also supported (user manually sets offsets to taste)

##### 3D scene additions

- Small **red cube** drawn at the rotation motor position
- Short **dotted red line** along the rotation axis
- **Round chasing arrow** wrapped around the rotation axis indicating cw/ccw direction (animated, like a halo)

##### Indexed-rotation cut mode

When a rotation axis is active, the **Load shape** dialog gets a new tab called **"rotation"**. Clicking it shows a table with 3 columns:

| Shape (upload) | Angle (0.0 to 360.0°) | Times (repeat count) |
|---|---|---|

User can add up to **12 rows**, each with up to 12 different shapes. The cut sequence becomes:

1. Animation cuts shape #1 as usual (4-axis ruled cut on the original block)
2. Remaining foam (the carved block) rotates `angle₁°` around its centre
3. Animation cuts shape #2 — but the "raw block" is now the post-rotation carved remainder, NOT the original block
4. Repeat for each subsequent shape

The output G-code is a simple stack of cuts with A-axis rotation commands in between.

##### Underlying technique — CSG subtraction

Three.js can't subtract solid volumes natively (meshes are just hollow shells of triangles). To visualise cumulative multi-axis cuts, we need a CSG (Constructive Solid Geometry) library that treats geometry as solid mass and exposes Boolean operations: union / intersection / **subtraction**.

```
Remaining Foam = Current Foam Block − Tool Sweep Volume
[ Raw foam cube ]   minus  [ Wire-swept profile ]  =  [ Carved mesh ]
```

**Library options:**
- `manifold-3d` — WASM-fast, highly accurate. First choice.
- `@repalash/three-csg-ts` — pure TypeScript/JS. Easier install, slower on complex cuts. Acceptable fallback.

**Per-cut execution loop:**

```js
import { CSG } from 'three-csg-ts';      // example using three-csg-ts
let foamMesh = new THREE.Mesh(foamGeometry, foamMaterial);

function executeCutPhase(shapeGCode, rotationAngle){
  // 1. Build the wire-sweep tool volume from the shape G-code
  const wireShape = new THREE.Shape();
  /* ... parse coordinates into wireShape ... */
  const tool = new THREE.Mesh(
    new THREE.ExtrudeGeometry(wireShape, { depth: machineWidth, bevelEnabled: false }),
    toolMaterial
  );

  // 2. CSG subtract
  const foamCSG   = CSG.fromMesh(foamMesh);
  const toolCSG   = CSG.fromMesh(tool);
  const resultCSG = foamCSG.subtract(toolCSG);

  // 3. Swap the carved foam in
  scene.remove(foamMesh);
  foamMesh = CSG.toMesh(resultCSG, foamMesh.matrix, foamMesh.material);
  scene.add(foamMesh);

  // 4. Apply indexed rotation for the next round
  rotateFoamAroundAxis(foamMesh, rotationAngle);
}
```

**Cumulative-rotation handling** (the tricky bit):

- Move the `foamMesh` pivot to the user-defined OFFSET X/Y/Z and apply the rotation.
- Before running the next CSG cut, call `foamMesh.updateMatrixWorld()` and **bake the rotation into the geometry**: `foamMesh.geometry.applyMatrix4(foamMesh.matrix)`.
- Reset `foamMesh.rotation` back to zero — the rotation is now permanently baked into vertices, so the next CSG step treats this as a fresh "raw block" in its current orientation.

**Performance notes:**
- CSG is mathematically heavy. Complex uploaded shapes with thousands of tiny vertices may freeze the browser for a few seconds.
- Optimise by keeping `ExtrudeGeometry` segments low and simplifying 2D path curves before extrusion.

**Open question for implementation:** uploaded shapes today arrive as SVG / DXF / raw G-code. Confirm which format we prefer to feed into the CSG tool builder, and whether we standardise on a single intermediate (probably the parsed `moves[]` list we already have).

##### Tasks (rotation axis feature — placeholder, none coded yet)

- ⬜ Schema + DEFAULTS + SETTINGS_WHITELIST keys: `machineType` enum extension, `rotPosition`, `rotReverse`, `rotDir`, `rotOffsetX`, `rotOffsetY`, `rotOffsetZ`.
- ⬜ Settings menu UI — extended dropdown, ghosted-vs-active rotation panel, Center-rot button, axis position dropdown, reverse checkbox, cw/ccw dropdown, offset inputs.
- ⬜ 3D scene additions — red rotation motor cube, dotted axis line, chasing-arrow halo with cw/ccw direction.
- ⬜ Load-shape dialog — Rotation tab with 12-row table (shape / angle / times).
- ⬜ Cut planner — stack-of-cuts model with A-axis rotation commands inserted between phases.
- ⬜ G-code serialiser extension — emit `A<deg>` commands at the right moments.
- ⬜ CSG library evaluation — manifold-3d vs three-csg-ts; pick one, prove out a single-cut demo.
- ⬜ Foam-state mesh that gets carved cumulatively. Bake rotation between cuts.
- ⬜ Performance pass — simplify path curves, keep ExtrudeGeometry segment count low, profile WASM call sites.
- ⬜ "Need help" + Q&A entries for the new mode (helpdesk seeding).

#### Phase 7b — other differentiators (existing list)

- ⬜ **Live machine telemetry overlay** in 3D — current wire position, actual vs commanded, temperature, feed override slider — drawn on top of the simulated cube while the real machine cuts.
- ✅ **AI prompt → profile** — procedural generator shipped. LLM-fallback for free-form prompts is the future upgrade.
- ⬜ **Continuous 5-axis** (Mode C) — voxel-grid foam state, multi-pass planner. Hard problem, defer until 7a is loved.
- ⬜ **Material auto-tune** — first cut on a known density samples actual cut quality and adjusts feed/temperature.
- ⬜ **Wire-physics model** — sag, bow, thermal lag in the simulator.
- ⬜ **Multi-block batching / nesting** — pack several parts into the cheapest set of foam blocks.
- ⬜ **STEAM mode** — guided lessons, locked simplified UI, classroom session sharing.
- ⬜ **Versioned projects** — save a job, fork it, diff two versions, restore old.
- ⬜ **Shared sessions** — two users on the same job for remote teaching.

### 🔵 Phase 7b — Shareable creations + programmatic SEO (added 2026-06-02, Pete)

The big growth lever. Two linked pieces:

- ⬜ **Shareable creation URLs.** Any GEN's-generated object (gear / wing / ambigram / characters) — *including* the user's OBJECT-bar modifications (scale, offset, rotation, kerf, block size) — can be saved to a short, shareable URL that instantly re-generates the exact part when opened. Mechanism: serialise `{gen params + SCALE state + whitelisted CFG}` → POST to a `creation_save.php` endpoint → dedupe by hash → store in a `creations` table → return a canonical SEO slug (e.g. `/made/bevel-helical-gear-35t-m8`). Opening the URL renders a lightweight server page + deep-links the tool (`/?load=<id>`) which replays the state. The tool gains a "Share" button + a `?load=` boot path.
- ⬜ **Creations become the SEO inventory.** The `creations` table IS the catalogue — real, unique, user-made artifacts (far safer for SEO than synthetic templated pages). Rank by views / likes → a **Top-100 → Top-10,000** feed → into the sitemap with hreflang. Each `/made/<slug>` page is genuinely distinct: a server-rendered SVG preview of the actual part + computed specs (Ø, teeth, cut-time, contour length, recommended foam, machine type) + meshing/related links.
- ⬜ **Programmatic SEO route** `/make/<slug>` — a slug parser that turns long-tail search phrases (`bevel-gear-35-teeth`, `naca-2412-wing`) into generator params, canonicalises (301 variant phrasings → one slug), and renders the same rich landing page even for combos no user has made yet. **Curate the sitemap** (high-intent combos only) — do NOT dump infinite URLs (doorway / scaled-content penalty risk). Phase it: gears first, measure 4–8 weeks in Search Console, then wings/ambigrams/characters, then translate the winners ×10 locales.
- ⚠️ **Risk to manage:** thin/doorway content can demote the whole domain. Mitigation: every page carries a unique computed SVG + real specs + internal links; aggressive canonicalisation; curated (not infinite) sitemap; quality-first rollout on a young domain.

### 🔵 Phase 7c — Synchronised 5th axis + voxel foam-state (added 2026-06-03, Pete)

Today's rotation is **indexed** (rotate → stop → cut a silhouette → rotate; the visual-hull intersection). That spin never cuts. A **synchronised** cut moves the A-axis *while* the wire moves, tracing true helixes. The controller already coordinates all 5 axes (`A` is in our G-code), and the animation already interpolates every axis per move — so the live view shows all axes moving together *for free*. The work is in the toolpath planner, feed-rate coordination, and (the hard bit) the 3-D preview.

- ✅ **Screw / auger generator (β, shipped 2026-06-03).** First synchronised cut: wire plunged to the axis, descends in Y while A rotates in lockstep → sweeps a helicoid (Archimedes screw / auger ramp). Runs on its **own move list**, isolated from the indexed visual-hull carve so neither breaks the other. Params: diameter, length, pitch, starts, hand. **Caveats:** no solid carve yet (needs voxels — see below); machine-axis mapping needs bench validation.
- ⬜ **Cheap wins that reuse the synchronised plumbing** (each is "emit moves with A varying", analytic preview, no voxels):
  - **Variable-pitch augers** — pitch as a function of length (progressive material transport). *Impossible* with indexing or morphs — the flagship justification for synchronised.
  - **Worm gears** — a screw meshing a spur gear; same helical toolpath, tuned profile.
  - **Twist drills / spiral flutes / rifling grooves** — helical grooves at a set lead.
  - **Barley-twist / multi-start spiral columns** — decorative, multi-turn (where the 4-wire twist morph pinches and synchronised doesn't).
  - **Feed-rate coordination** — compensate combined linear+rotary surface speed so the wire neither burns nor stalls along the helix. Needed before any of the above cut real foam well.
  - **Continuous-twist preview helper** — a shared analytic helicoid mesh so these get a real 3-D solid preview *without* the voxel engine.

### 🔵 Phase 7d — Voxel foam-state engine (DISCUSSION ONLY — no decision yet, 2026-06-03)

The general solution for both **arbitrary synchronised cuts** and **true surface-following STL cuts** (replacing the visual-hull approximation). Represent the foam as a 3-D occupancy field; each wire move removes the swept volume; re-mesh (marching cubes) to display. **Open question — not committed.**

- **Why it's hard:** a 500 mm block at ~0.5–1 mm fidelity = 125 M–1 B voxels — too much for a dense browser grid. Needs sparse storage (octree / SDF / surface-only), swept-volume carving over thousands of moves, fast incremental re-meshing, and probably web-workers or WebGPU + level-of-detail to stay interactive. It's a subsystem, not a feature.
- **Why it's dangerous:** if it hooks the live carve path (`setT`, snapshots, WebGL render) the blast radius is the entire 3-D view for *every* cut. Must be built **isolated + flagged + low-res first**.
- **Why it can't be one-shot blind:** correctness + performance can only be judged by *running it in a browser and watching* (does it OOM the tab? freeze? carve mush? what frame rate?). It is a deliberate **test-in-the-loop** build, not a fire-and-forget.
- **Payoff if we do it:** true voxel carve preview for screws/augers, arbitrary synchronised 5-axis, and proper STL surfacing (far better than visual hull). The synchronised-motion plumbing from 7c is the prerequisite and is already underway.

### 🔵 Phase 8 — Beyond

- Fully-continuous 5-axis ruled cuts (rotation between gantries on a moving table).
- Plugin marketplace (community profile generators).
- White-label deployment for makerspaces and educators.
- Hosted cloud sim for users with weak laptops.
- Native desktop wrapper (Tauri) for users who insist.

---

## 🧠 Strategic open questions (Pete, 2026-05-29)

These are research / positioning questions to think through before committing more dev effort. Treat them as open items — each one is a follow-up conversation, not a coding task.

1. **devfoam vs cncfoam.com — what makes us different?** Map the feature surfaces side by side, identify our defensible edges. Where do we win on simulation, library, hardware kit, education, community? Where are they ahead?
2. **What does cncfoam.com need to become the leading authority on 2/3/4/5-axis CNC foam cutting?** Specifically: feature coverage, content depth, hardware accreditation, community size, search dominance, partnerships.
3. **Speed compensation for sharp corners — should it live in cncfoam.com or in GRBL/FluidNC?** Look-ahead deceleration is normally a controller-firmware concern, but generated G-code that pre-computes corner deceleration would be portable across controllers. Decide where it belongs.
4. **Hot-wire current control — in the tool or on the machine?** Trade-offs: tool-controlled means a single source of truth for material/feed/current; machine-controlled means closed-loop on temperature is faster + safer. Probably a hybrid (tool generates spindle PWM targets, machine handles the inner loop), but worth confirming.
5. **What free features can we expose now that competitors hide behind paywalls?** Quick audit of paid features in other foam-cutter suites — anything we can match for zero (within reason)? AI shape generation, simulation, transports, library are already free here.
6. **Could cncfoam.com replace FluidNC / GRBL by combining the web tool with a dynamic PiBot / RAMPS programmer?** I.e., would we be better off owning the whole stack from G-code generation → controller firmware? Likely scope creep, but worth thinking about. Tradeoffs: total control + tight integration vs huge maintenance burden vs losing the broad hardware-compat story we have today.
7. **How do we make cncfoam.com genuinely useful on mobile and tablet?** First pass shipped (gate logo + hamburger + simplified tool view). What's next — read-only browse mode for jobs prepared on desktop? Tablet as a remote-control / telemetry head for an active cut? Touch-first shape browser + AR preview of finished cuts?

---

## Reference: what the tool actually outputs

The browser tool produces a sequence of motion records in machine coordinates `(X, Y, U, V, Z, W, A, F, hot)` per step — serialised as standard 4-axis Foamcube/FluidNC G-code (`G01 X10.5 Y20 U10.5 V20 F400` with `M8`/`M9` for hot-wire on/off, `S` for wire-temperature target). With rotation enabled, A-axis commands get inserted between cut phases. That G-code goes out USB / SD / Wi-Fi — three flavours of transport, one payload format. The ESP32 + FluidNC controller is what turns the text stream into stepper pulses and PWM.

## Active project files

- `/index.php` — the tool itself (Three.js + WebSerial-ready simulator, ~5000 lines).
- `/about.php /hardware.php /uses.php /help.php /qa.php /privacy.php /terms.php /collaborate.php /contact.php /ai_help.php /shapes.php /shape.php /user.php` — content + library + author pages.
- `/login.php /signup.php /verify.php /logout.php /forgot.php /reset.php /account.php /admin.php /admin_users.php /bootstrap_admin.php` — auth + admin.
- `/shape_upload.php /shape_action.php /shape_file.php /shape_publish.php /project_action.php /user_settings.php` — library + project + per-user endpoints.
- `/helpdesk.php /thread.php /helpdesk_action.php /helpdesk_image.php` — community discussion board.
- `/svg_cleaner.php` — client-side SVG cleaner (drag-drop, batch, runs in browser).
- `/ai_generate.php` — procedural shape generator endpoint.
- `/visitor_ping.php` — daily unique visitor counter.
- `/sitemap.php /sitemap.xml /robots.txt` — SEO.
- `/backup.php` — CLI SQLite backup (cron'd daily).
- `/mail_test.php` — CLI mail-config diagnostic.
- `/seed_*.php` — CLI helpdesk Q&A + supporter seeders.
- `/includes/head.php /includes/footer.php` — shared header + nav + footer.
- `/includes/db.php /includes/auth.php /includes/mail.php /includes/shapes.php /includes/forum.php /includes/images.php` — backend modules.
- `/data/cncfoam.sqlite` — SQLite DB (created on first run, never committed).
- `/data/mail.config.php` — live SMTP creds (per-server, never committed).
- `/data/mail.config.example.php` — committed template.
- `/data/shapes/{sources,previews,comment_images}/` — library uploads + auto-generated thumbnails + user comment photos (all WebP).
- `/data/forum_images/` — helpdesk thread + reply attachments (all WebP).
- `/data/backups/` — gzipped SQLite snapshots from `backup.php`.
- `/data/php-error.log /data/backup.log` — runtime logs.
- `/assets/style.css` — site theme (with @media 720px + 380px mobile breakpoints).
- `/assets/cnctip.js` — site-wide edge-aware tooltips.
- `/images/cncfoam_og.png` — 1200×630 social-share card.
- `/initial_analysis.md /how_to_solve_software.md /hardware_fixes_solutions.md /roadmap.md` — internal docs.
- `/CLAUDE.md` — onboarding doc for Claude sessions (architecture, conventions, gotchas).
- `FOAMCUBE V4 WIT-…/` — original 2014–2018 archive (read-only reference).
