Bin-Packing Add-on¶
This add-on is based on the 3D bin packing module py3dbp hosted on PyPI. Both sources of this package are MIT licensed like ezdxf itself.
The Bin Packing Problem¶
Quote from the Wikipedia article:
The bin packing problem is an optimization problem, in which items of different sizes must be packed into a finite number of bins or containers, each of a fixed given capacity, in a way that minimizes the number of bins used.
Example¶
This code replicates the example used by the py3dbp package:
from typing import List
import ezdxf
from ezdxf import colors
from ezdxf.addons import binpacking as bp
SMALL_ENVELOPE = ("small-envelope", 11.5, 6.125, 0.25, 10)
LARGE_ENVELOPE = ("large-envelope", 15.0, 12.0, 0.75, 15)
SMALL_BOX = ("small-box", 8.625, 5.375, 1.625, 70.0)
MEDIUM_BOX = ("medium-box", 11.0, 8.5, 5.5, 70.0)
MEDIUM_BOX2 = ("medium-box-2", 13.625, 11.875, 3.375, 70.0)
LARGE_BOX = ("large-box", 12.0, 12.0, 5.5, 70.0)
LARGE_BOX2 = ("large-box-2", 23.6875, 11.75, 3.0, 70.0)
ALL_BINS = [
SMALL_ENVELOPE,
LARGE_ENVELOPE,
SMALL_BOX,
MEDIUM_BOX,
MEDIUM_BOX2,
LARGE_BOX,
LARGE_BOX2,
]
def build_packer():
packer = bp.Packer()
packer.add_item("50g [powder 1]", 3.9370, 1.9685, 1.9685, 1)
packer.add_item("50g [powder 2]", 3.9370, 1.9685, 1.9685, 2)
packer.add_item("50g [powder 3]", 3.9370, 1.9685, 1.9685, 3)
packer.add_item("250g [powder 4]", 7.8740, 3.9370, 1.9685, 4)
packer.add_item("250g [powder 5]", 7.8740, 3.9370, 1.9685, 5)
packer.add_item("250g [powder 6]", 7.8740, 3.9370, 1.9685, 6)
packer.add_item("250g [powder 7]", 7.8740, 3.9370, 1.9685, 7)
packer.add_item("250g [powder 8]", 7.8740, 3.9370, 1.9685, 8)
packer.add_item("250g [powder 9]", 7.8740, 3.9370, 1.9685, 9)
return packer
def make_doc():
doc = ezdxf.new()
doc.layers.add("FRAME", color=colors.YELLOW)
doc.layers.add("ITEMS")
doc.layers.add("TEXT")
return doc
def main(filename):
bins: List[bp.Bin] = []
for box in ALL_BINS:
packer = build_packer()
packer.add_bin(*box)
packer.pack(bp.PickStrategy.BIGGER_FIRST)
bins.extend(packer.bins)
doc = make_doc()
bp.export_dxf(doc.modelspace(), bins, offset=(0, 20, 0))
doc.saveas(filename)
if __name__ == "__main__":
main("py3dbp_example.dxf")
Packer Classes¶
- class ezdxf.addons.binpacking.AbstractPacker¶
- bins¶
List of containers to fill.
- property is_packed: bool¶
Returns
True
if packer is packed, each packer can only be used once.
- __str__() str ¶
Return str(self).
- get_fill_ratio() float ¶
Return the fill ratio of all bins.
- get_capacity() float ¶
Returns the maximum fill volume of all bins.
- get_total_weight() float ¶
Returns the total weight of all fitted items in all bins.
- get_total_volume() float ¶
Returns the total volume of all fitted items in all bins.
- pack(pick=PickStrategy.BIGGER_FIRST) None ¶
Pack items into bins. Distributes all items across all bins.
Packer¶
- class ezdxf.addons.binpacking.Packer¶
3D Packer inherited from
AbstractPacker
.
FlatPacker¶
- class ezdxf.addons.binpacking.FlatPacker¶
2D Packer inherited from
AbstractPacker
. All containers and items used by this packer must have a depth of 1.
Bin Classes¶
- class ezdxf.addons.binpacking.Bin(name, width: float, height: float, depth: float, max_weight: float = UNLIMITED_WEIGHT)¶
- name¶
Name of then container as string.
- width¶
- height¶
- depth¶
- max_weight¶
- property is_empty: bool¶
- __str__() str ¶
Return str(self).
- copy()¶
Returns a copy.
- reset()¶
Reset the container to empty state.
- get_capacity() float ¶
Returns the maximum fill volume of the bin.
- get_total_weight() float ¶
Returns the total weight of all fitted items.
- get_total_volume() float ¶
Returns the total volume of all fitted items.
- get_fill_ratio() float ¶
Return the fill ratio.
Box Class¶
Envelope Class¶
Item Class¶
- class ezdxf.addons.binpacking.Item(payload, width: float, height: float, depth: float, weight: float = 0.0)¶
3D container item.
- payload¶
Arbitrary Python object.
- width¶
- height¶
- depth¶
- weight¶
- property bbox: AbstractBoundingBox¶
- property rotation_type: RotationType¶
- property position: tuple[float, float, float]¶
Returns the position of then lower left corner of the item in the container, the lower left corner is the origin (0, 0, 0).
- copy()¶
Returns a copy, all copies have a reference to the same payload object.
- __str__()¶
Return str(self).
- get_volume() float ¶
Returns the volume of the item.
- get_dimension() tuple[float, float, float] ¶
Returns the item dimension according the
rotation_type
.
FlatItem Class¶
Functions¶
- ezdxf.addons.binpacking.shuffle_pack(packer: AbstractPacker, attempts: int) AbstractPacker ¶
Random shuffle packing. Returns a new packer with the best packing result, the input packer is unchanged.