Skip to main content

2D/3D spatial optimization engine for nesting and bin packing

Project description

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

Project details


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.5.0-cp38-abi3-win_amd64.whl (472.8 kB view details)

Uploaded CPython 3.8+Windows x86-64

u_nesting-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (597.5 kB view details)

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

u_nesting-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (545.2 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.8+macOS 11.0+ ARM64

u_nesting-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl (561.7 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: u_nesting-0.5.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 472.8 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.5.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 225f14bfd0071e51f09cc631a626297651e77a899beaea852ccedfab00823bdc
MD5 f15da1800fa78fffd84a27c3b074a05c
BLAKE2b-256 97b4895aa44cfcfcc762e49ebe6fa8264a47d94697bfa39423d572c3740d5505

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.5.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.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for u_nesting-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9dacc44bdaccef1345277eb5be12d1b47f0d58ead371f18b71fa0a22788d1ce9
MD5 edc209814f1d0f355dea9c3194632932
BLAKE2b-256 8ff8fd170025ce58425486008a3389a94e6eecf522b829018dff360a6e33f442

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.5.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.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for u_nesting-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3f79e9b6106153a3e611944efb874cf4efcd5542e25b94647992f34727e5a913
MD5 eb95d3d7fe832ce2fc81315c4d590cfd
BLAKE2b-256 9a1be9fadbdcd13afff692668af0368610984fde21d03c13699ca199b88a1466

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.5.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.5.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for u_nesting-0.5.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b898b664e2ed3ed8e90ea5a4251aa4564371a3acea236693c5b132fd3d952ef9
MD5 6f527a40caf461d3d1926c2da24b9233
BLAKE2b-256 f277f1863ac8303e9fba37cc538c9395a48fe53b1896962b4fb811d899f3fc12

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.5.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.5.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for u_nesting-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 14a1493c15997b6660170964cda2acf7da4f0a381dd4457d9051128643c38924
MD5 abe0f0732641da4352ce568d5794181c
BLAKE2b-256 36d7dcbeedd09dfc0083dc55917107b3b3f1a064e2560177b33edcfb74e30bef

See more details on using hashes here.

Provenance

The following attestation bundles were made for u_nesting-0.5.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 Pingdom Monitoring Sentry Error logging StatusPage Status page