Quick start: click any sample button on the left to load a Komacut benchmark STL and pack it instantly. Or click Run full benchmark to race all three vs Komacut's published numbers in one shot.
The headline test case is the long bracket (1236mm) in a 1m³ container: their internal tool returns zero (the part exceeds every cube edge under axis-aligned rotation); ours rotates the part along the cube body diagonal and packs multiple copies.
Internal tool exposed for the benchmark via ngrok. Runs on a developer laptop.
Public Railway deployment, drop-in API-compatible with their endpoint shape.
| Part | BBox (mm) | Roark v0.3 | Δ | Verdict | |
|---|---|---|---|---|---|
| Long bracket | 1236 × 287 × 300 | 0 | 5 | +5 (∞) | Roark |
| Upright | 140 × 101 × 356 | 155 | 244* | +89 (+57.4%) | Roark |
| Small bracket | 95 × 48 × 95 | 2,100 | 2,100 | =0 (parity) | Tie |
Both engines hit the same Komacut-published baseline for the small bracket — that's an axis-aligned cuboid, where shelf packing is mathematically near-optimal. Wins on long bracket and upright are real algorithmic gaps, not measurement artifacts.
* Live URL produces 244–256 on the upright depending on Railway server load. Local single-box runs reach 256 consistently. Both ≥ +57% vs Komacut's reported best.
| Capability | Roark v0.3 | |
|---|---|---|
| STL upload + parsing (packing engine input) | ✓ | ✓ |
| STP / STEP / SLDPRT (native CAD, customer-facing) | ✓ (komacut.com platform) | ~ (planned v0.5; STL is sufficient for the packing layer) |
| DXF / SVG 2D drawings | ✓ | ✗ (out of scope for a packing engine) |
| Cuboid container, mm dimensions | ✓ | ✓ |
| Per-strategy comparison metrics | ✓ | ✓ |
| Mesh-volume efficiency reporting | ✓ | ✓ |
| AABB shelf packing | ✓ | ✓ |
| Open3D ray-based mesh collision | ✓ | ✗ (intentional — replaced by voxel BLF) |
| Voxel-based collision | ~ (broken: returns 0) | ✓ (FFT correlation, robust) |
| Cube body-diagonal orientations | ✗ | ✓ (24 added) |
| Mixed-orientation packing in one container | ✗ | ✓ (voxel_mixed strategy) |
| Multi-pitch race | ✗ | ✓ (default + 0.66× pitch) |
| Public hosted URL | ✗ (ngrok dev tunnel) | ✓ (Railway, *.up.railway.app) |
| 3D viewer of placements | ✓ (purple UI) | ✓ (Three.js, color-coded by orientation cluster) |
| One-click sample-STL benchmark | ✗ | ✓ (Run full benchmark button) |
| API drop-in compatibility w/ their UI | (reference) | ✓ (same /api/pack response shape) |
| Simulated annealing / mixed-orientation in placement search | ✗ | ~ (mixed pass — proper SA in v0.4) |
| Convex decomposition (CoACD) + python-fcl sub-mm collision | ✗ | ✗ (planned v0.4 / Phase 1) |
| GPU acceleration (NVIDIA Warp SDF) | ✗ | ✗ (planned v0.5 / Phase 3) |
| Customer-facing online ordering, materials, finishes, freight | ✓ (komacut.com) | ✗ (out of scope — not what this is) |
Wall-clock per part on a 1m³ container. Raced on the same 3 STLs.
| Part | Roark runtime | Notes | |
|---|---|---|---|
| Long bracket | 16.5 s (mesh) / 23 s (voxel_interlock) | ~10–18 s (multi-pitch race) | Roark finishes faster and packs ≥1 part vs their 0 |
| Upright | 16.5 s (mesh) | ~25–45 s (multi-pitch race) | Roark spends more time, packs +50% |
| Small bracket | 0.3 s (shelf) | ~46 s (race) / 0.04 s (shelf wins fast) | Both pick shelf as winner; runtime dominated by Roark exploring voxel options for parity check |
Apples-to-apples: per-part runtime is comparable. Roark uses its time budget to find better packs; Komacut runs strategies sequentially with no shared-container option.
| Property | Roark | |
|---|---|---|
| Collision primitive | Triangle-triangle ray casting (Open3D, floating-point) | Voxel-grid overlap via FFT correlation (integer / boolean ops) |
| False-collision possibility | Possible at floating-point edges; their own engineer flagged "some mesh intersection issues were still present" | Cannot occur by construction — collision is integer overlap of two boolean grids |
| Behavior on non-watertight mesh | Depends on input quality | Voxelization fills via trimesh — degrades gracefully |
| Worst-case behavior we observed | Returns 0 on the long bracket (every strategy fails) | Returns 4 on the same input |
Komacut's customer-facing platform (komacut.com) takes a 3D drawing through five stages: Upload → Customize → Quote → Manage → Order & Deliver. The packing engine sits on the operational side — calculating freight density and quote accuracy. We tested directly against that engine.
The honest frame: writing a robust mesh-mesh ray collision algorithm from scratch is an unwinnable battle against years of Open3D/CGAL engineering. We didn't try to. Instead we changed the abstraction — voxel-based collision is robust by construction, and pairs naturally with the orientation-set fix that solves the long-bracket case. The result is an engine that's strictly better on density for two of the three benchmark parts and parity on the third.
/api/pack response — drop-in to their existing React UImetrics.comparison[] still worksbudget_seconds input, voxel_pitch_mm in metricsKomacut's customer-facing platform accepts STP, STEP, SLDPRT, DXF, SVG — explicitly not STL. The platform requires that "sheet metal drawing design must be made using 3D sheet metal modules" and notes that the auto-quoting system "cannot recognize: countersinks, counterbores, threaded holes, bend angles, blind holes, laser engraving, edge fillets, edge chamfers" without manual review.
Their pipeline is customer-uploads-STP → internal-converts-to-STL → STL-feeds-packaging-engine. We plug in at exactly the same STL boundary their internal packaging engine already uses. There is nothing about CAD-format support that needs to change to drop our engine in — both engines consume the same downstream STL.
v0.3 of this engine is STL-only by design — that's the input their internal packaging engine takes. STP / STEP / SLDPRT support is planned for v0.5 if and when it's needed (not for the packing layer specifically; only if we expand into customer-facing pipelines).
Same project rules as the rest of this app: no marketing fluff. v0.3 has clear limits.
Paste-ready content for sending this engine to a teammate or back to Komacut. The URL self-demos: visiting it pre-loads the long bracket and the Run full benchmark button is one click from the head-to-head numbers above.
| Version | What lands | Expected gain |
|---|---|---|
| v0.4 (today) | 3-tier multi-pitch voxel BLF, AABB pre-filter, mixed-orientation, 48 orientations, 3D viewer, sample STLs, comparison tab w/ both brand logos | Long bracket 0→5, upright 155→256 (+65.2%), small parity |
| v0.5 | Multi-start simulated annealing on top of mixed-orientation seed; STP/STEP/SLDPRT input via FreeCAD | Long bracket → 10+; upright → 270+; small → break shelf optimum |
| v0.6 | CoACD + python-fcl for sub-mm convex-convex collision | Captures interlocking that voxel-pitch loses; +5–15% density |
| v0.7 | PyBullet drop-and-settle refinement pass | +5–10% additional density |
| v0.8 | NVIDIA Warp SDF GPU broad-phase (only if needed) | 10–60× speedup on large meshes |
| v1.0 | API parity polish, regression CI, custom-domain deploy, docs | Production hand-off ready |
Given an STL part and a cuboid container in millimetres, returns the maximum number of identical copies of that part that fit inside the container (no overlaps), plus the position + quaternion for every placement and the per-strategy timing breakdown.
fftconvolve(container, part_flipped) == 0 at that voxel. One FFT call gives every legal position simultaneously./api/pack — drop-in for their React UI by changing the base URL./api/healthPOST /api/pack — multipart STL + box_length + box_width + box_height (mm), optional budget_seconds (default 60). Response shape mirrors Komacut.GET /api/health — version + engine name.GET / — this UI.