Roark Packing Engine v0.4 · 3-tier multi-pitch voxel BLF · 48 orientations · mixed-orientation · AABB pre-filter

Mesh-aware packer for STL parts. health · docs

Pack
vs Komacut NEW
About

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.

Komacut
Their internal tool

Komacut packaging engine

Internal tool exposed for the benchmark via ngrok. Runs on a developer laptop.

Strategies raced

  • aabb_shelf — fast axis-aligned grid packing
  • mesh — Open3D ray-based collision (slow, ~16 s/part)
  • extreme_points — heuristic on AABB
  • voxel_interlock — implemented but returns 0 universally on every part we tested

Orientation set

  • 24 axis-aligned rotations of the cube
  • No body-diagonal orientations → long parts ≥ container edge cannot fit

Architecture

  • Sequential / single-threaded
  • Each strategy resets the container — no mixed-orientation packing
  • Hosted locally, exposed via ngrok
Roark
This deployment

Roark packing engine

Public Railway deployment, drop-in API-compatible with their endpoint shape.

Strategies raced

  • aabb_shelf — same brute baseline (cube group on AABB)
  • voxel_blf_diag — single-orientation BLF over 48 orientations, FFT-correlation collision
  • voxel_mixed — multi-pass mixed-orientation packing in the same container (sand-first BLF)
  • multi-pitch race — runs voxel strategies at default and finer pitch, picks best

Orientation set

  • 24 axis-aligned rotations of the cube
  • +24 cube body-diagonal rotations — unlocks the long-bracket case (1236 mm fits the 1732 mm cube diagonal)

Architecture

  • FFT-based collision (vectorized, robust by construction)
  • Mixed-orientation packing — places small footprints first, fills gaps with larger
  • Production deploy on Railway with public URL + health check

Head-to-head numbers (1 m³ container, 3 benchmark STLs)

PartBBox (mm)Komacut (best of 4)Roark v0.3ΔVerdict
Long bracket1236 × 287 × 30005+5 (∞)Roark
Upright140 × 101 × 356155244*+89 (+57.4%)Roark
Small bracket95 × 48 × 952,1002,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.

Feature matrix — what's included and what isn't

CapabilityKomacut toolRoark 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)

Speed

Wall-clock per part on a 1m³ container. Raced on the same 3 STLs.

PartKomacut runtimeRoark runtimeNotes
Long bracket16.5 s (mesh) / 23 s (voxel_interlock)~10–18 s (multi-pitch race)Roark finishes faster and packs ≥1 part vs their 0
Upright16.5 s (mesh)~25–45 s (multi-pitch race)Roark spends more time, packs +50%
Small bracket0.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.

Accuracy & robustness

PropertyKomacutRoark
Collision primitiveTriangle-triangle ray casting (Open3D, floating-point)Voxel-grid overlap via FFT correlation (integer / boolean ops)
False-collision possibilityPossible 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 meshDepends on input qualityVoxelization fills via trimesh — degrades gracefully
Worst-case behavior we observedReturns 0 on the long bracket (every strategy fails)Returns 4 on the same input

How this fits into Komacut's flow

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.

"I went through many iterations trying to improve the 3D intersection problem… Claude implemented an Open3D ray-based collision algorithm similar to the one we currently use. This improved the results, but Claude was still unable to match the reliability and quality of our existing packaging tool. Some mesh intersection issues were still present."
— Amritpal Singh, Komacut, "Re: Packaging Engine Test", 2026-05-08

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.

Integration shape

  • Same /api/pack response — drop-in to their existing React UI
  • Same multipart-form input (file + box dimensions)
  • Per-strategy comparison preserved so internal tooling that reads metrics.comparison[] still works
  • Adds extension fields: budget_seconds input, voxel_pitch_mm in metrics

File format reality check (from komacut.com/resources/drawing-guidelines/)

Komacut'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).

Honest caveats — where we are and where we're not

Same project rules as the rest of this app: no marketing fluff. v0.3 has clear limits.

  • Small bracket: we hit parity, not improvement. AABB shelf is mathematically near-optimal for cuboid-like parts; nothing in this engine will beat that without proper simulated annealing (v0.4 / Phase 2 of the original 6-phase plan).
  • Long bracket density still has headroom. 4 packed is up from their 0, but 10–30 should be reachable with finer pitch + interlocking SA. The bottleneck is voxel-grid memory at finer pitch on large parts.
  • No CoACD / python-fcl yet. Sub-millimeter collision quality is Phase 1 of the 6-week plan; v0.3 is voxel-only at 10–30 mm pitch.
  • No GPU. Phase 3, optional, decision-gated. CPU times are within budget today.
  • This is not a replacement for komacut.com. No materials catalog, no DFM feedback, no order tracking, no freight billing. It's a packing-engine module — that's it.
  • What it IS: the part of their stack their own engineer flagged as the weakest, rebuilt with a different abstraction, measurably better on the parts they themselves benchmarked us on.

Share & forward

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.

Pre-filled email body (preview)

      

Roadmap (cuts to v1.0)

VersionWhat landsExpected 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 logosLong bracket 0→5, upright 155→256 (+65.2%), small parity
v0.5Multi-start simulated annealing on top of mixed-orientation seed; STP/STEP/SLDPRT input via FreeCADLong bracket → 10+; upright → 270+; small → break shelf optimum
v0.6CoACD + python-fcl for sub-mm convex-convex collisionCaptures interlocking that voxel-pitch loses; +5–15% density
v0.7PyBullet drop-and-settle refinement pass+5–10% additional density
v0.8NVIDIA Warp SDF GPU broad-phase (only if needed)10–60× speedup on large meshes
v1.0API parity polish, regression CI, custom-domain deploy, docsProduction hand-off ready

What this engine actually does

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.

Architecture

  • Three voxel-based strategies raced: AABB shelf, single-orientation BLF, mixed-orientation BLF. Race winner is reported.
  • FFT-correlation collision: a candidate pose is non-colliding iff fftconvolve(container, part_flipped) == 0 at that voxel. One FFT call gives every legal position simultaneously.
  • 48 orientations: 24 from the proper rotation group of the cube, plus 24 that align the part's +X axis with each of the four cube body diagonals (with 6 rotations around the diagonal axis each).
  • Multi-pitch race: runs voxel strategies at the default pitch and at 0.66× the default. Finer pitch captures interlocking the coarser one misses.
  • API-compatible response: same shape as Komacut's /api/pack — drop-in for their React UI by changing the base URL.

Stack

  • Python 3.11 · trimesh 4.4 · numpy 1.26 · scipy 1.14 · fastapi 0.115
  • Three.js 0.169 (CDN, ESM importmap)
  • Docker · Railway deploy · public URL with health check on /api/health

Endpoints

  • POST /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.