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 with parallel computation via Rayon
- 🎯 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.15" # 2D only (default)
= { = "0.15", = ["3d"] } # 2D + 3D
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
│ ├── traits.rs # Geometry, Boundary, Solver
│ ├── ga.rs # Genetic algorithm framework
│ ├── config.rs # Common configuration
│ └── result.rs # Unified result types
│
├── d2/ # 2D Module
│ ├── geometry.rs # Polygon, Point, Segment
│ ├── boundary.rs # 2D boundary definitions
│ ├── nfp.rs # No Fit Polygon
│ ├── nester.rs # Placement algorithms
│ └── io.rs # Import/Export
│
├── d3/ # 3D Module
│ ├── geometry.rs # Box (Geometry3D)
│ ├── boundary.rs # 3D boundary definitions
│ ├── nfr.rs # No Fit Region
│ ├── packer.rs # Placement algorithms
│ ├── physics.rs # Gravity, stability
│ └── io.rs # Import/Export
│
└── 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 (Greedy Descent with Random Restarts) | Local search with restart diversification | ★★★★☆ | ★★★☆☆ |
| 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 | Placement at extreme points | ★★★☆☆ | ★★★★★ |
| Layer Packing | Layer-based bottom-up placement | ★★★☆☆ | ★★★★☆ |
| Genetic Algorithm | Sequence and rotation optimization | ★★★★★ | ★★☆☆☆ |
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)
C Interface
extern int ;
extern void ;
// C# example
[LibraryImport("u_nesting")]
public static partial int unesting_solve(string request, out IntPtr result);
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, 500 generations)
| 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