Skip to main content

U-Nesting

A high-performance 2D/3D spatial optimization engine for nesting and bin packing problems.

PyPI version License: MIT

Features

  • 2D Nesting: Optimal placement of irregular polygons on sheets
  • 3D Bin Packing: Efficient box placement in containers
  • Multiple Algorithms: BLF, NFP-guided, Genetic Algorithm, BRKGA, Simulated Annealing
  • High Performance: Written in Rust with Python bindings
  • Type Hints: Full type annotation support

Installation

pip install u-nesting

Quick Start

2D Nesting

import u_nesting

# Define polygons to nest
geometries = [
    {
        "id": "part1",
        "polygon": [[0, 0], [100, 0], [100, 50], [0, 50]],
        "quantity": 5,
        "rotations": [0, 90, 180, 270]
    },
    {
        "id": "triangle",
        "polygon": [[0, 0], [80, 0], [40, 60]],
        "quantity": 3
    }
]

# Define sheet boundary
boundary = {"width": 500, "height": 300}

# Configure solver
config = {
    "strategy": "nfp",      # Options: blf, nfp, ga, brkga, sa
    "spacing": 2.0,         # Gap between parts
    "time_limit_ms": 30000  # 30 second timeout
}

# Solve
result = u_nesting.solve_2d(geometries, boundary, config)

print(f"Utilization: {result['utilization']:.1%}")
print(f"Placed: {len(result['placements'])} items")
for p in result['placements']:
    print(f"  {p['geometry_id']}[{p['instance']}]: ({p['position'][0]:.1f}, {p['position'][1]:.1f})")

3D Bin Packing

import u_nesting

# Define boxes to pack
geometries = [
    {
        "id": "small",
        "dimensions": [20, 20, 20],
        "quantity": 10
    },
    {
        "id": "large",
        "dimensions": [40, 30, 25],
        "quantity": 5,
        "mass": 2.5  # Optional weight
    }
]

# Define container
boundary = {
    "dimensions": [200, 150, 100],
    "max_mass": 50.0,    # Optional mass limit
    "gravity": True,     # Stack from bottom
    "stability": True    # Require stable placement
}

# Configure solver
config = {
    "strategy": "ep",       # Extreme Point heuristic
    "time_limit_ms": 10000
}

# Solve
result = u_nesting.solve_3d(geometries, boundary, config)

print(f"Utilization: {result['utilization']:.1%}")
print(f"Containers used: {result['boundaries_used']}")

API Reference

solve_2d(geometries, boundary, config=None) -> dict

Solve a 2D nesting problem.

Parameters:

  • geometries: List of geometry definitions
    • id (str): Unique identifier
    • polygon (list): Vertices as [[x, y], ...]
    • quantity (int): Number of copies (default: 1)
    • rotations (list): Allowed rotation angles in degrees
    • allow_flip (bool): Allow horizontal flip
    • holes (list): Interior holes as list of polygons
  • boundary: Sheet definition
    • width, height (float): Rectangle dimensions, OR
    • polygon (list): Custom boundary shape
  • config: Solver configuration (optional)
    • strategy (str): "blf", "nfp", "ga", "brkga", "sa"
    • spacing (float): Gap between geometries
    • margin (float): Gap from boundary
    • time_limit_ms (int): Timeout in milliseconds
    • population_size (int): GA/BRKGA population
    • max_generations (int): GA/BRKGA generations
    • multi_sheet (bool): Distribute overflow across multiple sheets (default: False). When True, parts that do not fit on one sheet spill onto extra sheets instead of becoming unplaced; boundaries_used reports the sheet count and each placement's boundary_index selects its sheet with sheet-local coordinates.

Returns: Dictionary with:

  • success (bool): Whether solve succeeded
  • placements (list): Placement results (instance-level)
  • utilization (float): Area utilization ratio
  • boundaries_used (int): Number of sheets used (>1 only when multi_sheet=True)
  • total_requested (int): Σ of every geometry's quantity (instance-level total). Unplaced instance count = total_requested - len(placements)
  • unplaced (list): Deduplicated IDs of items that couldn't be placed (not per-instance, so len(unplaced) under-reports the failed-instance count)
  • computation_time_ms (int): Solve time

solve_3d(geometries, boundary, config=None) -> dict

Solve a 3D bin packing problem.

Parameters:

  • geometries: List of box definitions
    • id (str): Unique identifier
    • dimensions (list): [width, depth, height]
    • quantity (int): Number of copies
    • mass (float): Weight (optional)
  • boundary: Container definition
    • dimensions (list): [width, depth, height]
    • max_mass (float): Weight limit (optional)
    • gravity (bool): Enable gravity constraint
    • stability (bool): Enable stability constraint
  • config: Same as solve_2d, plus:
    • strategy: "blf", "ep", "ga", "brkga", "sa"

Returns: Same structure as solve_2d

Strategy Selection Guide

Strategy Speed Quality Best For
blf Fast Good Large instances, quick results
nfp Medium Better 2D with complex shapes
ep Fast Good 3D bin packing
ga Slow Best Small instances, max quality
brkga Slow Best Complex constraints
sa Medium Better Balanced speed/quality

Requirements

  • Python 3.8+
  • No additional dependencies

License

MIT License - see LICENSE for details.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

u_nesting-0.6.0-cp38-abi3-win_amd64.whl (472.7 kB view details)

Uploaded CPython 3.8+Windows x86-64

u_nesting-0.6.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (597.3 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

u_nesting-0.6.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (545.5 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

u_nesting-0.6.0-cp38-abi3-macosx_11_0_arm64.whl (512.1 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

u_nesting-0.6.0-cp38-abi3-macosx_10_12_x86_64.whl (562.7 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file u_nesting-0.6.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: u_nesting-0.6.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 472.7 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for u_nesting-0.6.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 90b704f4cfe3478afd68eb77185a640bbc046eaef436dc63dce070fed2db0b53
MD5 4c36ef3c683b6fabb740136457d48644
BLAKE2b-256 b42aa0e4eac3da947d795a0f8af41fcec183fa98d89b6ed280b624b673055289

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.6.0-cp38-abi3-win_amd64.whl:

Publisher: python-publish.yml on iyulab/u-nesting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file u_nesting-0.6.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for u_nesting-0.6.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0a197c90e4ad112f0dff46a08bea8bc121a449f192b29c707c381089f2cc99e1
MD5 e1af7863d392b47366d9d5f7cb164b78
BLAKE2b-256 33d853bdd5336642ac58bdcb0a327eb28d2dd7ca1e551065064d66040a688724

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.6.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: python-publish.yml on iyulab/u-nesting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file u_nesting-0.6.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for u_nesting-0.6.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8b8dfcf98294ebffb6a6f131466c951a397316b189ca254804370537aa65cd3e
MD5 fd1be9b701638af266b144c32a0899c6
BLAKE2b-256 e25e6df8776e7cba6dfd1f895bb689f22c0e6165ccc41ac35461a6c3e16ec1e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.6.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: python-publish.yml on iyulab/u-nesting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file u_nesting-0.6.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for u_nesting-0.6.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8974c7bbbc08ced578fbdaac4419dd84bbcf7d32bc18f3250721e1638826ac1e
MD5 cb1a23ac822c996bdef891ed40c15d71
BLAKE2b-256 721914276428375329de4ed1d998b6329748fe33ca2fa7c2c6889f7bd2c81964

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.6.0-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: python-publish.yml on iyulab/u-nesting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file u_nesting-0.6.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for u_nesting-0.6.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 053ff9c0b7a7bf5bbf1babe8dfd89719ee4c937efb86f8f57ac7d451a4985115
MD5 a3c7ee060c308e15f443b280337f4682
BLAKE2b-256 c13ab02a2514748ddf79a7d292d45a47b35efa433c9947025cf75963496f7a2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.6.0-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: python-publish.yml on iyulab/u-nesting

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page