U-Nesting
2D/3D Spatial Optimization Engine - High-performance nesting and bin packing algorithms in Rust with C FFI support
Overview
U-Nesting provides domain-agnostic spatial optimization algorithms for 2D nesting and 3D bin packing problems:
- 2D Nesting - Optimal polygon placement on bounded surfaces
- 3D Bin Packing - Optimal volume arrangement in containers
- Genetic Algorithm - Metaheuristic optimization for complex layouts
- NFP/NFR Computation - Precise collision-free placement
Design Philosophy
U-Nesting is a pure computation engine with no domain-specific logic. Industry context (manufacturing, textile, logistics, etc.) is determined by consuming applications.
┌─────────────────────────────────────────┐
│ Consuming Applications │
│ (Manufacturing, Textile, Logistics) │
└─────────────────┬───────────────────────┘
│ Domain Context
▼
┌─────────────────────────────────────────┐
│ U-Nesting Engine │
│ Pure Geometry + Optimization Math │
│ (Domain Agnostic) │
└─────────────────────────────────────────┘
Features
- 🚀 High Performance - Written in Rust; the
parallelfeature evaluates GA/BRKGA populations and no-fit polygons on Rayon's thread pool - 🎯 Domain Agnostic - Abstract models adaptable to any spatial optimization
- 📐 2D Support - Polygon nesting with NFP and holes (curves are supplied as polylines — flatten with a tolerance before submitting)
- 📦 3D Support - Box packing with physical constraints (gravity, stability, mass limits)
- 🔌 C FFI Support - Use from C#, Python, or any language with C bindings
- 📦 Zero Domain Dependencies - Pure mathematical optimization
Demo
Sample Dataset
A test dataset with 9 different polygon shapes and 50 total pieces on a 500×500 boundary:
Algorithm Comparison
Optimization results using different algorithms on the same dataset (50 pieces, 500×500 boundary, 2 strips):
| Algorithm | Result | Utilization | Time |
|---|---|---|---|
| GA (Genetic Algorithm) | 70.6% | 19.5s | |
| GDRR (Goal-Driven Ruin & Recreate) | 69.4% | 30.5s | |
| ALNS (Adaptive Large Neighborhood Search) | 69.1% | 30.2s | |
| NFP (No-Fit Polygon Guided) | 68.5% | 5.0s | |
| BRKGA (Biased Random-Key GA) | 67.8% | 23.5s | |
| SA (Simulated Annealing) | 64.1% | 34.3s | |
| BLF (Bottom-Left Fill) | 60.0% | 338ms |
Note: Higher utilization = better material efficiency. Results may vary depending on piece shapes, quantities, and constraints. Run your own benchmarks to find the best algorithm for your specific use case.
These figures were captured before 0.11.0. Layouts and times differ from 0.11.0 on, which changed how placement follows the sheet's length, enforces
spacingandmargin, and honourstime_limit_ms.
Installation
From crates.io
[]
= "0.24" # 2D + 3D (default features)
= { = "0.24", = false, = ["d2"] } # 2D only
Features: d2 and d3 (default) select the dimensions, cutting adds cutting
path optimization for a 2D layout, serde serialization, and parallel runs a
search's population evaluation and the no-fit polygon computation on Rayon's
thread pool (without it a solve runs on the calling thread; bound the pool with
rayon::ThreadPool::install or RAYON_NUM_THREADS).
From GitHub
[]
= { = "https://github.com/iyulab/u-nesting" }
Quick Start
2D Nesting
use ;
use ;
// Define geometries to place
let geometries = vec!;
// Define boundary
let boundary = rectangle;
// Configure and run
let config = new
.with_strategy
.with_spacing
.with_margin;
let result = new.solve.unwrap;
assert_eq!;
println!;
3D Bin Packing
use ;
use ;
// Define geometries to place
let geometries = vec!;
// Define boundary; gravity and stability are properties of the container
let boundary = new
.with_max_mass
.with_gravity
.with_stability;
// Configure and run
let config = new.with_strategy;
let result = new.solve.unwrap;
assert_eq!;
println!;
Core Concepts
| Concept | Description | 2D | 3D |
|---|---|---|---|
| Geometry | Shape to be placed | Polygon | Box |
| Boundary | Containing region | Rectangle, Polygon | Box |
| Placement | Position + orientation | x, y, θ | x, y, z, rotation |
| Spacing | Minimum distance between two placed geometries | Float | Float |
| Margin | Minimum distance from a geometry to the boundary edge | Float | Float |
| Constraint | Placement rules | Rotation, Direction | Orientation, Stability |
Module Structure
u-nesting/
├── core/ # Shared abstractions
│ ├── geometry.rs # Geometry, Boundary traits
│ ├── solver.rs # Solver trait, Config, Strategy
│ ├── ga.rs, brkga.rs, sa.rs, gdrr.rs, alns.rs # Search frameworks
│ ├── api_types.rs # JSON request / response types
│ └── result.rs # Unified result types
│
├── d2/ # 2D Module
│ ├── geometry.rs # Polygon geometry (Geometry2D)
│ ├── boundary.rs # 2D boundary definitions
│ ├── nfp.rs # No Fit Polygon
│ ├── nester.rs # Nester2D: placement and search strategies
│ └── *_nesting.rs # GA, BRKGA, SA, GDRR, ALNS for 2D
│
├── d3/ # 3D Module
│ ├── geometry.rs # Box (Geometry3D)
│ ├── boundary.rs # 3D boundary definitions
│ ├── packer.rs # Packer3D: placement and search strategies
│ ├── extreme_point.rs
│ └── physics.rs, stability.rs # Gravity, stability
│
├── cutting/ # Cutting path optimization for a 2D layout
└── ffi/ # C FFI interface
Algorithms
2D Algorithms
| Algorithm | Description | Quality | Speed |
|---|---|---|---|
| BLF (Bottom-Left Fill) | Greedy placement at bottom-left positions | ★★★☆☆ | ★★★★★ |
| NFP (No-Fit Polygon Guided) | NFP-based collision-free placement | ★★★★☆ | ★★★☆☆ |
| GA (Genetic Algorithm) | Sequence optimization with crossover/mutation | ★★★★★ | ★★☆☆☆ |
| BRKGA (Biased Random-Key GA) | Random-key encoding with elite inheritance | ★★★★★ | ★★☆☆☆ |
| SA (Simulated Annealing) | Temperature-based neighborhood search | ★★★★☆ | ★★★☆☆ |
| GDRR (Goal-Driven Ruin and Recreate) | Removes and re-inserts parts of the layout | ★★★★☆ | ★★★☆☆ |
| ALNS (Adaptive Large Neighborhood Search) | Destroy-repair with operator selection | ★★★★★ | ★★☆☆☆ |
What the 2D heuristic and search strategies guarantee
BLF, NFP, GA, BRKGA, SA, GDRR and ALNS (the optional exact MILP strategies are not covered here):
spacingis the minimum distance between any two placed parts (it may be exceeded by at most 0.12 %, the allowance for rounded offsets). It does not apply to the boundary.marginis the minimum distance from any part to every boundary edge, including slanted edges of a polygon boundary and the edges of holes.- Parts are placed inside the boundary polygon, never over a hole.
- Layouts advance along the boundary's longer side (the strip's length) and fill across the shorter one.
time_limit_msbounds the whole solve: the search strategies return the best layout found within it, plus the time of the bottom-left pass they are compared against.- The search strategies (GA, BRKGA, SA, GDRR, ALNS) never return a layout that places fewer parts, or uses more length, than bottom-left fill on the same input — nor than greedy NFP placement, whenever that pass completes within the time limit (it runs first, inside the limit).
3D Algorithms
| Algorithm | Description | Quality | Speed |
|---|---|---|---|
Extreme Point (ep) |
Placement at extreme points | ★★★☆☆ | ★★★★★ |
Layer Packing (blf) |
Layer-based bottom-up placement | ★★★☆☆ | ★★★★☆ |
Genetic Algorithm (ga) |
Sequence and orientation optimization | ★★★★★ | ★★☆☆☆ |
BRKGA (brkga) |
Random-key encoding with elite inheritance | ★★★★★ | ★★☆☆☆ |
Simulated Annealing (sa) |
Temperature-based neighborhood search | ★★★★☆ | ★★★☆☆ |
Configuration
2D Configuration
use ;
// One `Config` serves 2D and 3D; every setting has a builder method.
let config = new
.with_spacing // Minimum distance between geometries
.with_margin // Minimum distance to the boundary edge
.with_strategy
.with_time_limit // Whole solve, in milliseconds (0 = unlimited)
.with_target_utilization
.with_seed; // Reproducible runs
Rotation and mirroring are per geometry (Geometry2D::with_rotations_deg,
with_flip), not part of the configuration.
3D Configuration
use OrientationConstraint;
use ;
use ;
let config = new
.with_margin // Boundary wall offset
.with_strategy
.with_time_limit;
// Physics lives on the container, orientation on each geometry.
let boundary = new
.with_gravity
.with_stability;
let item = new
.with_orientation;
FFI Interface
JSON Request (2D)
JSON Request (3D)
Gravity and stability are properties of the container (boundary), not of the
configuration. Every key a request takes is in the
JSON schemas; a key the engine does not read is
refused (malformed_input), not ignored.
C Interface
// 2D or 3D by the request's "mode" ("2d" when absent).
int ;
int ;
int ;
void ;
The response is JSON with success, a stable code and details on a
refusal. The .NET package (UNesting) wraps this interface; see
its README and the
FFI guide.
Result Structure
SolveResult {
placements: Vec<Placement>, // Position + orientation for each placed instance
boundaries_used: usize, // Number of boundaries needed
utilization: f64, // Area/volume efficiency (0.0 - 1.0)
unplaced: Vec<String>, // Deduplicated IDs of geometries that couldn't fit
total_requested: usize, // Σ quantity; unplaced instances = total_requested - placements.len()
computation_time_ms: u64,
}
Performance
2D Benchmarks (GA)
| Geometries | Complexity | Time | Utilization |
|---|---|---|---|
| 20 | Simple | 200ms | 92% |
| 100 | Mixed | 2s | 88% |
| 500 | Complex | 15s | 85% |
3D Benchmarks (Extreme Point)
| Geometries | Complexity | Time | Utilization |
|---|---|---|---|
| 50 | Uniform | 100ms | 85% |
| 200 | Mixed | 1.5s | 78% |
| 100 | Constrained | 3s | 72% |
Architecture
┌──────────────────────────────────────────────┐
│ U-Nesting Engine │
├──────────────────────────────────────────────┤
│ Core: Traits, GA Framework, Config │
├─────────────────────┬────────────────────────┤
│ 2D Module │ 3D Module │
├─────────────────────┼────────────────────────┤
│ Polygon, NFP │ Box, NFR │
│ BLF, GA Nester │ EP, LAFF, GA Packer │
└─────────────────────┴────────────────────────┘
▲ ▲
│ │
┌─────────┴────────────────────┴───────────────┐
│ Consuming Applications │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Sheet │ │ Mold │ │Container│ ... │
│ │ Metal │ │ Design │ │ Loading │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└──────────────────────────────────────────────┘
License
Licensed under either of:
- MIT license (LICENSE)
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
Related
- u-numflow — Mathematical primitives
- u-metaheur — Metaheuristic optimization (GA, SA, ALNS, CP)
- u-geometry — Computational geometry
- u-schedule — Scheduling framework