Coder Social home page Coder Social logo

3dbinpacking's People

Contributors

bellini666 avatar enzoruiz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

3dbinpacking's Issues

bin packing stable problem

Does this algorithm take into account the problem of packing stability? For example, an item may not be supported by another item under it.

Rotation_type of fitted items not correct

If I add the print statement below to main.py, the appended items don't match the returned "fitted items". More specifically, it seems like the rotation_type can continue to loop to 5 but I don't know what causes this behavior. The result is that the items exceed the bounds of the bin.

if fit:
if self.get_total_weight() + item.weight > self.max_weight:
fit = False
return fit

            print("item appended to bin:", item.string())
            self.items.append(item)

Adding option to sort by bigger bin first and by bigger item first separately.

Hello,

I would like to propose to add the functionality to sort by bigger bin first and by bigger item first separately. This enhances the algorithm efficiency when trying to determine the number of bins necessary to pack all items.

See py3dbp_test-example.zip.

By starting to fit the largest item in the smallest box first, I'm able to pack all my items in one large box less!

I also added the Bin.weight and Bin.empty_bin_weight attribute so we get the real total weight.

py3dbp_test

LinkedIn
Twitter

Best regards,
Jonathan Rhau

Not working on a single item test case

packer = Packer()
packer.add_bin(Bin('Main', int(200), int(200), int(300),int(630)))
for x in range(1,101):
packer.add_item(Item('mm' + str(x),int(65) ,int(66),int(83),int(19) ))
packer.pack(bigger_first=True)
for b in packer.bins:
for item in b.items:
print("====> ", item.string())

The result is 24 - In reality 27 should fit.

z-dimension stacking isn't accurate

As the code only compares whether there is an overlapping part between two items in xy-plane, z-dimension stacking isn't accurate.
Just tested with
-> Bin('large-3-box', 23.6875, 11.75, 35.0, 1000.0)
and items
-> packer.add_item(Item('50g [powder 1]', 3.9370, 1.9685, 11.9685, 1))
packer.add_item(Item('50g [powder 2]', 3.9370, 1.9685, 1.9685, 2))
packer.add_item(Item('50g [powder 3]', 3.9370, 1.9685, 1.9685, 3))
packer.add_item(Item('250g [powder 4]', 7.8740, 3.9370, 1.9685, 4))
packer.add_item(Item('250g [powder 5]', 7.8740, 3.9370, 1.9685, 5))
packer.add_item(Item('250g [powder 6]', 7.8740, 3.9370, 1.9685, 6))
packer.add_item(Item('250g [powder 7]', 7.8740, 3.9370, 1.9685, 7))
packer.add_item(Item('250g [powder 8]', 7.8740, 3.9370, 1.9685, 8))
packer.add_item(Item('250g [powder 9]', 7.8740, 3.9370, 1.9685, 9))
packer.add_item(Item('250g [powder 10]', 7.8740, 3.9370, 1.9685, 10))
packer.add_item(Item('250g [powder 11]', 7.8740, 3.9370, 1.9685, 11))
packer.add_item(Item('250g [powder 12]', 7.8740, 3.9370, 1.9685, 6))
packer.add_item(Item('250g [powder 7]', 7.8740, 3.9370, 1.9685, 7))
packer.add_item(Item('250g [powder 8]', 7.8740, 3.9370, 1.9685, 8))
packer.add_item(Item('250g [powder 9]', 7.8740, 3.9370, 1.9685, 9))
packer.add_item(Item('250g [powder 4]', 7.8740, 3.9370, 1.9685, 4))
packer.add_item(Item('250g [powder 5]', 7.8740, 3.9370, 1.9685, 5))
packer.add_item(Item('250g [powder 6]', 7.8740, 3.9370, 1.9685, 6))
packer.add_item(Item('250g [powder 7]', 7.8740, 3.9370, 1.9685, 7))
packer.add_item(Item('250g [powder 8]', 7.8740, 3.9370, 1.9685, 8))
packer.add_item(Item('250g [powder 9]', 7.8740, 3.9370, 1.9685, 9))

I have arbitrarily given 11.9685 as the height of 'powder 1' for a bigger box with dimension [23.6875, 11.75, 35.0] just for the sake of random experiment. Each item gets stacked fine in the base layer (z=0) but when the base layer is all filled, things get stacked at z=11.9685 for the remainder of items, which makes the items float.

remove the item that do not stack on top of each other

Hello folks,

I am new to 3dbinpacking and python in general, so go easy on me.

I've been trying to use 3dbinpacking to create a simulation in Anylogic in which operators use a pallet-trolley to pick boxes/items in a specific order from a warehouse. The pick order is based on the results of the Bin-Packing algorithm.

the container/bin is based on the standard dimension of a EuroPallet and the boxes are standard carton boxes with different sizes.

My issue is that some of the boxes do not overlap 100%. This is ok if the pallet is actually enclosed but in a real-world scenario like using a pallet trolley to pick boxes if the boxes are not put one on top of the other they will probably fall down

my question is there a way to remove the items/boxes that do not stack on top of each other?

Current results of running 3dbinpacking

boxesissue2 DXF_001

Desire results after removing items/boxes with the surface not overlapping 100% another item/box (the remaining boxes should be packed in another container/bin)

boxes issue 2 DXF

Simple test case

Hey, this package is a good idea. However, I tried running a simple test case with one very large bin and a number of items. The solver fails to put them in the bin. I might be missing something though. Test case and result is below:

#TEST CASE:

from py3dbp import Packer, Bin, Item
packer = Packer()
packer.add_bin(Bin('very-very-large-box', 10000.6875, 10000.75, 10000.0, 2000000.0))
packer.add_item(Item('50g [powder 1]', 1.1, 1.9685, 1.9685, 1))
packer.add_item(Item('50g [powder 2]', 1.1, 1.9685, 1.9685, 2))
packer.add_item(Item('50g [powder 3]', 1.1, 1.9685, 1.9685, 3))
packer.add_item(Item('250g [powder 4]', 1.1, 3.9370, 1.9685, 4))
packer.add_item(Item('250g [powder 5]', 7.8740, 3.9370, 1.9685, 5))
packer.add_item(Item('250g [powder 6]', 7.8740, 3.9370, 1.9685, 6))
packer.add_item(Item('250g [powder 7]', 7.8740, 3.9370, 1.9685, 7))
packer.add_item(Item('250g [powder 8]', 7.8740, 3.9370, 1.9685, 8))
packer.add_item(Item('250g [powder 9]', 7.8740, 3.9370, 1.9685, 9))

packer.add_item(Item('50g [powder 10]', 3.9370, 1.9685, 1.9685, 10))
packer.add_item(Item('50g [powder 11]', 3.9370, 1.9685, 1.9685, 11))
packer.add_item(Item('50g [powder 12]', 3.9370, 1.9685, 1.9685, 12))
packer.add_item(Item('250g [powder 12]', 7.8740, 3.9370, 1.9685, 13))
packer.add_item(Item('250g [powder 13]', 7.8740, 3.9370, 1.9685, 14))
packer.add_item(Item('250g [powder 14]', 7.8740, 3.9370, 1.9685, 15))
packer.add_item(Item('250g [powder 15]', 7.8740, 3.9370, 1.9685, 16))
packer.add_item(Item('250g [powder 16]', 1.1, 3.9370, 1.9685, 17))
packer.add_item(Item('250g [powder 17]', 1.8740, 3.9370, 1.9685, 18))

packer.pack()

for b in packer.bins:
print(":::::::::::", b.string())

print("FITTED ITEMS:")
for item in b.items:
    print("====> ", item.string())

print("UNFITTED ITEMS:")
for item in b.unfitted_items:
    print("====> ", item.string())

print("***************************************************")
print("***************************************************")

RESULT

::::::::::: very-very-large-box(10000.6875x10000.75x10000.0, max_weight:2000000.0) vol(1000143755156.25)
FITTED ITEMS:
====> 50g [powder 1](1.1x1.9685x1.9685, weight: 1) pos([0, 0, 0]) rt(0) vol(4.26)
====> 50g [powder 2](1.1x1.9685x1.9685, weight: 2) pos([1.1, 0, 0]) rt(0) vol(4.26)
====> 50g [powder 3](1.1x1.9685x1.9685, weight: 3) pos([0, 1.9685, 0]) rt(0) vol(4.26)
====> 250g [powder 4](1.1x3.937x1.9685, weight: 4) pos([1.1, 1.9685, 0]) rt(0) vol(8.52)
====> 250g [powder 16](1.1x3.937x1.9685, weight: 17) pos([0, 3.937, 0]) rt(0) vol(8.52)
====> 250g [powder 17](1.874x3.937x1.9685, weight: 18) pos([2.2, 0, 0]) rt(0) vol(14.52)
====> 50g [powder 10](3.937x1.9685x1.9685, weight: 10) pos([1.1, 5.9055, 0]) rt(0) vol(15.26)
====> 50g [powder 11](3.937x1.9685x1.9685, weight: 11) pos([0, 0, 1.9685]) rt(0) vol(15.26)
====> 50g [powder 12](3.937x1.9685x1.9685, weight: 12) pos([3.937, 0, 1.9685]) rt(0) vol(15.26)
====> 250g [powder 5](7.874x3.937x1.9685, weight: 5) pos([5.037, 5.9055, 0]) rt(0) vol(61.02)
====> 250g [powder 6](7.874x3.937x1.9685, weight: 6) pos([7.874, 0, 1.9685]) rt(0) vol(61.02)
====> 250g [powder 7](7.874x3.937x1.9685, weight: 7) pos([0, 1.9685, 1.9685]) rt(0) vol(61.02)
====> 250g [powder 8](7.874x3.937x1.9685, weight: 8) pos([5.037, 9.8425, 0]) rt(0) vol(61.02)
====> 250g [powder 9](7.874x3.937x1.9685, weight: 9) pos([7.874, 3.937, 1.9685]) rt(0) vol(61.02)
====> 250g [powder 12](7.874x3.937x1.9685, weight: 13) pos([0, 5.9055, 1.9685]) rt(0) vol(61.02)
====> 250g [powder 13](7.874x3.937x1.9685, weight: 14) pos([0, 9.8425, 1.9685]) rt(0) vol(61.02)
====> 250g [powder 14](7.874x3.937x1.9685, weight: 15) pos([7.874, 9.8425, 1.9685]) rt(0) vol(61.02)
UNFITTED ITEMS:
====> 250g [powder 15](7.874x3.937x1.9685, weight: 16) pos([0, 0, 0]) rt(0) vol(61.02)



Empty Spaces in Container

I have tried Py3dbp for arrangement. After loading the items in the container, there remains empty spaces. Is there any method to find the dimension of the empty spaces?
How can I get empty space dimension?

Any better suggestions?

example.py output not reasonable

Running the provide example.py gives:

***************************************************
::::::::::: large-box(12.000x12.000x5.500, max_weight:70.000) vol(792.000)
FITTED ITEMS:
====>  50g [powder 1](3.937x1.968x1.968, weight: 1.000) pos([0, 0, 0]) rt(0) vol(15.248)
====>  50g [powder 2](3.937x1.968x1.968, weight: 2.000) pos([Decimal('3.937'), 0, 0]) rt(0) vol(15.248)
====>  50g [powder 3](3.937x1.968x1.968, weight: 3.000) pos([Decimal('7.874'), 0, 0]) rt(0) vol(15.248)
====>  250g [powder 4](7.874x3.937x1.968, weight: 4.000) pos([Decimal('11.811'), 0, 0]) rt(0) vol(61.008)
====>  250g [powder 5](7.874x3.937x1.968, weight: 5.000) pos([Decimal('19.685'), 0, 0]) rt(1) vol(61.008)
====>  250g [powder 6](7.874x3.937x1.968, weight: 6.000) pos([0, Decimal('1.968'), 0]) rt(0) vol(61.008)
====>  250g [powder 7](7.874x3.937x1.968, weight: 7.000) pos([Decimal('11.811'), Decimal('3.937'), 0]) rt(0) vol(61.008)
====>  250g [powder 8](7.874x3.937x1.968, weight: 8.000) pos([0, Decimal('5.905'), 0]) rt(0) vol(61.008)
====>  250g [powder 9](7.874x3.937x1.968, weight: 9.000) pos([Decimal('7.874'), 0, Decimal('1.968')]) rt(5) vol(61.008)
UNFITTED ITEMS:
***************************************************

The position of the 5th item pos([Decimal('19.685'), 0, 0]) seems to be outside the box, which is set as 12.000x12.000x5.500

Is this a bug, or my understanding of the notation is wrong?

Run condition:
git checkout latest master
python 3.8.10

Bin orientation makes difference in finding a solution

I've a very simple test case, where the algorithm can't fit all items. But when I change the orientation of the bin, it can fit all. Is this a bug or is the algorithm very limited and can't solve such a simple combination?

from py3dbp import Packer, Bin, Item

packer = Packer()

packer.add_bin(Bin('Bin-1', 6, 1, 5, 100))
packer.add_bin(Bin('Bin-2', 5, 1, 6, 100))
packer.add_item(Item('Box-1', 3, 1, 2, 1))
packer.add_item(Item('Box-2', 3, 1, 2, 1))
packer.add_item(Item('Box-3', 3, 1, 2, 1))
packer.add_item(Item('Box-4', 3, 1, 2, 1))
packer.add_item(Item('Box-5', 3, 1, 2, 1))

packer.pack()

for b in packer.bins:
    print(":::::::::::", b.string())

    print("FITTED ITEMS:")
    for item in b.items:
        print("====> ", item.string())

    print("UNFITTED ITEMS:")
    for item in b.unfitted_items:
        print("====> ", item.string())

    print("***************************************************")
    print("***************************************************")

Result:

::::::::::: Bin-1(6.000x1.000x5.000, max_weight:100.000) vol(30.000)
FITTED ITEMS:
====>  Box-1(3.000x1.000x2.000, weight: 1.000) pos([0, 0, 0]) rt(0) vol(6.000)
====>  Box-2(3.000x1.000x2.000, weight: 1.000) pos([Decimal('3.000'), 0, 0]) rt(3) vol(6.000)
====>  Box-3(3.000x1.000x2.000, weight: 1.000) pos([0, 0, Decimal('2.000')]) rt(0) vol(6.000)
====>  Box-4(3.000x1.000x2.000, weight: 1.000) pos([Decimal('3.000'), 0, Decimal('3.000')]) rt(3) vol(6.000)
UNFITTED ITEMS:
====>  Box-5(3.000x1.000x2.000, weight: 1.000) pos([0, 0, Decimal('4.000')]) rt(0) vol(6.000)
***************************************************
***************************************************
::::::::::: Bin-2(5.000x1.000x6.000, max_weight:100.000) vol(30.000)
FITTED ITEMS:
====>  Box-1(3.000x1.000x2.000, weight: 1.000) pos([0, 0, 0]) rt(0) vol(6.000)
====>  Box-2(3.000x1.000x2.000, weight: 1.000) pos([Decimal('3.000'), 0, 0]) rt(3) vol(6.000)
====>  Box-3(3.000x1.000x2.000, weight: 1.000) pos([0, 0, Decimal('2.000')]) rt(0) vol(6.000)
====>  Box-4(3.000x1.000x2.000, weight: 1.000) pos([Decimal('3.000'), 0, Decimal('3.000')]) rt(3) vol(6.000)
====>  Box-5(3.000x1.000x2.000, weight: 1.000) pos([0, 0, Decimal('4.000')]) rt(0) vol(6.000)
UNFITTED ITEMS:
***************************************************
***************************************************

Interested in your assistance

Hi there,

Is there a way to contact you via email?
I have some questions about the 3d packing.
Are you considered with weight? rotatable items? stacking /unstacking/ self stacking items?
Can we communicate via email?
betzalel.racovsky at gmail
Thanks
B

Answer changes if I manually interchange the wdh parameters of the item

Hi,

I get different answers if I change the wdh for one of the boxes. For example, if I go with this:
#adding a bin
packer.add_bin(Bin('small-envelope', 3,3,3, 100))
#adding boxes
packer.add_item(Item('50g [powder 1]', 3,3,1, 1))
packer.add_item(Item('50g [powder 2]', 3,3,1, 2))
packer.add_item(Item('50g [powder 3]', 3,2,1, 3))
#answer I get
FITTED ITEMS:
====> 50g [powder 3](3.000x2.000x1.000, weight: 3.000) pos([0, 0, 0]) rt(0) vol(6.000)
====> 50g [powder 1](3.000x3.000x1.000, weight: 1.000) pos([0, Decimal('2.000'), 0]) rt(2) vol(9.000)
UNFITTED ITEMS:
====> 50g [powder 2](3.000x3.000x1.000, weight: 2.000) pos([0, 0, 0]) rt(5) vol(9.000)



It should be able to add all the three boxes in this particular bin.
But if I change the wdh positions for the third item,
#adding a bin
packer.add_bin(Bin('small-envelope', 3,3,3, 100))
#adding boxes
packer.add_item(Item('50g [powder 1]', 3,3,1, 1))
packer.add_item(Item('50g [powder 2]', 3,3,1, 2))
packer.add_item(Item('50g [powder 3]', 1,2,3, 3))
#answer I get
FITTED ITEMS:
====> 50g [powder 3](1.000x2.000x3.000, weight: 3.000) pos([0, 0, 0]) rt(0) vol(6.000)
====> 50g [powder 1](3.000x3.000x1.000, weight: 1.000) pos([Decimal('1.000'), 0, 0]) rt(3) vol(9.000)
====> 50g [powder 2](3.000x3.000x1.000, weight: 2.000) pos([Decimal('2.000'), 0, 0]) rt(3) vol(9.000)
UNFITTED ITEMS:



How to get better results in Blender?

Hi,

I am trying to make a crude packing implementation in Blender using this library. So far I have not gotten a good results. I am wondering if this is an issue with this lib in general, like working in 3d coordiates . Does it require the pivot to be in certain location other than the center?

Also I seem to be getting only 0 and 1 for the rotation type.

Please see the screenshot for the details (after running the script). As you can see the packing result shows some items positioned outside of the bin and there are overlaps, basically does not look like these boxes are packed inside the bin.

image

Output

***************************************************
::::::::::: Bin(6.072x6.072x6.072, max_weight:1000.000) vol(223.870)
FITTED ITEMS:
====>  Box.005(2.714x0.114x1.413, weight: 1.000) pos([0, 0, 0]) rt(0) vol(0.437)  ->  [0, 0, 0]
<Vector (0.0000, 0.0000, 0.0000)>
====>  Box.003(1.364x0.638x1.442, weight: 1.000) pos([Decimal('2.714'), 0, 0]) rt(0) vol(1.255)  ->  [Decimal('2.714'), 0, 0]
<Vector (2.7140, 0.0000, 0.0000)>
====>  Box(1.281x0.745x1.412, weight: 1.000) pos([Decimal('4.078'), 0, 0]) rt(0) vol(1.348)  ->  [Decimal('4.078'), 0, 0]
<Vector (4.0780, 0.0000, 0.0000)>
====>  Box.001(2.428x0.426x1.453, weight: 1.000) pos([Decimal('5.359'), 0, 0]) rt(1) vol(1.503)  ->  [Decimal('5.359'), 0, 0]
<Vector (5.3590, 0.0000, 0.0000)>
====>  Box.002(0.607x3.611x1.586, weight: 1.000) pos([0, Decimal('0.114'), 0]) rt(0) vol(3.476)  ->  [0, Decimal('0.114'), 0]
<Vector (0.0000, 0.1140, 0.0000)>
====>  Box.004(2.990x2.050x1.592, weight: 1.000) pos([0, Decimal('3.725'), 0]) rt(0) vol(9.758)  ->  [0, Decimal('3.725'), 0]
<Vector (0.0000, 3.7250, 0.0000)>

Something is wrong with the initialisation?

I have a use case where I try to fit a set of items that stays constant to a varying set of bins (or actually one bin at a time). Which means I would like to try different bins one at a time, starting with the cheapest package and then moving to more expensive ones if the items don't fit.

However, I am running into problems since it seems to me that the initialisation call of Packer() does not work properly. It would seem it maintains some history of the items I've tried to pack but clears the initialisation of bins, which leads to a situation where two subsequent packing attempts generate different results - the latter requiring a larger bin than on the previous run, and failing to pack in the bin it had found a solution for on the previous run. The only way to get stable results is if the kernel is restarted in between. I think one would expect the call to initialise Packer() to be equivalent to getting a fresh start, but that does not seem to be the case.

The problem is not visible in the results, which shows just the items I've tried to pack both times, but the fact that the 2nd attempt requires a larger bin makes the library where hard to use in practice.

First run:
Found solution:
::::::::::: 790713(800.000x270.000x330.000, max_weight:999.000) vol(71280000.000)
FITTED ITEMS:
====> 226(130.000x200.000x100.000, weight: 0.000) pos([0, 0, 0]) rt(0) vol(2600000.000)
====> 330(330.000x120.000x220.000, weight: 4.800) pos([Decimal('130.000'), 0, 0]) rt(0) vol(8712000.000)
====> 330(330.000x120.000x220.000, weight: 4.800) pos([Decimal('460.000'), 0, 0]) rt(0) vol(8712000.000)
====> 206(300.000x650.000x150.000, weight: 10.000) pos([Decimal('130.000'), Decimal('120.000'), 0]) rt(2) vol(29250000.000)
UNFITTED ITEMS:

Second run:
Found solution:
::::::::::: 790079(790.000x300.000x580.000, max_weight:999.000) vol(137460000.000)
FITTED ITEMS:
====> 226(130.000x200.000x100.000, weight: 0.000) pos([0, 0, 0]) rt(0) vol(2600000.000)
====> 330(330.000x120.000x220.000, weight: 4.800) pos([Decimal('130.000'), 0, 0]) rt(0) vol(8712000.000)
====> 330(330.000x120.000x220.000, weight: 4.800) pos([Decimal('460.000'), 0, 0]) rt(0) vol(8712000.000)
====> 206(300.000x650.000x150.000, weight: 10.000) pos([Decimal('130.000'), Decimal('120.000'), 0]) rt(2) vol(29250000.000)
UNFITTED ITEMS:

When reusing bins and items in a packer old data persists

This isn't so much of an issue moreso a problem I ran into which took some time to debug.

Since the three objects are built out as standalone classes bins keep their mutated data between runs. To work around this I had to manually reset the data back to the init values on every loop in each bin. This isn't really an issue with the code but more an issue with the implementation/design. If a new packer is initialized and bins are added those bins should be reinitialized as well.

More of a PSA I suppose since nobody in the gh issues brought this up (Except maybe #15 ?)

Adding Layers into Bin, i.e. Shelves, Walking room

I am using this library to fill a shipping container of parts. The shipping container has an option of adding shelves. I am trying to add this to the Bin class such that you can add an additional layer in the bin to add parts on. I am getting a handful of errors when trying to output the container with parts intersecting and the packer class not able to understand the layers in the bin. Is there a work around for this issue or do you have different recommendations on adding the shelves? Thank you.

Features

hello,

Is "[distribute_items=True]" or "[distribute_items=False]" some kind of parameter that can be configured?
If so, where can i configure it?

Objects locate outside bin

In my project, I want to pack image stacks (my packages) in a container using py3dbp. I can arrange them and know each image location inside the container I defined. After, I extract the locations of each image and try to use this information to place the "packages" in a NumPy array full of ones that is the same size as the container I defined previously. However, when I extract the image positions I notice that some of them are partially "outside" the bin, i.e if my bin is defined by:

final_image = Bin("final Image", 3300 , 3300, 17, 100000)

when I access some of the item's position and size information, I get the next

print(packer.items[514].position)
print(packer.items[514].width)
print(packer.items[514].height)
print(packer.items[514].depth)

Output: 
[Decimal('3278.000'), Decimal('264.000'), 0]
70.000
22.000
17.000

As you can see, the width of package 514 is bigger than the space left for it in the container, 70 against 22. My question is, How this can be possible? The package size corresponding to item 514 is the same as the image I want to locate. Besides, the list of unfitted objects is empty and the list of fitted objects corresponds to the total number of objects I have. The code I am using to pack the objects and locate them in the NumPy array is:

final_image2 = np.ones((17, 3300,  3300), dtype = int) 

packer = Packer()
final_image =  Bin("final Image", 3300 , 3300, 17, 100000)
packer.add_bin(final_image )

for label in unique_labels: 

    zero_padding =  np.pad(single_nuclei_dic[label], [(0, z_padding), (y_padding_2, y_padding_2), (x_padding_2, x_padding_2)],
                           mode='constant', constant_values=0)
    
    final_size_dic[label] = zero_padding.shape
    zero_padding_nuclei[label] = zero_padding.astype(int)

    my_item = Item(str(label), final_size_dic[label][2], final_size_dic[label][1], final_size_dic[label][0],  1)
    packer.add_item(my_item)
    

packer.pack(bigger_first=True, number_of_decimals=0) 

for image in packer.items: 
    
    label1= int(image.name) 

    z_incial = int(image.position[2])
    y_inicial = int(image.position[1])
    x_inicial  = int(image.position[0])
    
    items_position[label1] = [x_inicial, y_inicial, z_incial]
    
    box = zero_padding_nuclei[label1].astype(int)
    
    z_final = z_incial + box.shape[0] 
    y_final = y_inicial + box.shape[1] 
    x_final = x_inicial + box.shape[2] 
    
    final_image2[z_incial:z_final, y_inicial:y_final, x_inicial:x_final] = zero_padding_nuclei[label1]
 

Thank you for your help

It changes the x, y, z values of the package to fit the product in the package on the x plane.

It changes the x, y, z values of the package to fit the product in the package on the x plane.
I'm trying to fit 30 same products into the package. but It gives incorrect information because it changes the dimensions of some products.

#Package dimensions
packageHeightX = 7.5
packageWidthY = 12.5
packageLengthZ = 16.5

#item dimensions
itemX = 0.787
itemY = 3.937
itemZ = 3.937

But for some products, it changes the dimensions like this:
#item dimensions
itemX = 3.937
itemY = 3.937
itemZ = 0.787

I'm not sure exactly what causes the problem. Can anyone help?

!image
!image

Thank you

Limit number of rotations/pivots?

The packing goes through all 6 permutations of each item, which is awesome, but for my purposes, it makes sense to disallow certain rotations. In fact I only need 1, leading to 2 permutation.

Is it possible to include this as an option?

Pivot being summed with the wrong dimension when the item is rotated

Just notice a problem where when an item in the bin is rotated, the calculation for the pivot will use its dimensions as if the rotation was WHD which produces the wrong pivot.

e.g. we have a (1, 2, 3) WHD item already in the bin at position (0, 0, 0).

If the item is in the WHD rotation, that means that a pivot in the width axis for that item would be (1, 0, 0).

But if this item is rotated to, lets say, HWD, the same pivot for the width axis for that item would have to be (2, 0, 0).

The fix is easy, the dimensions need to be converted to the default WHD system, which you already have a function for (the get_dimensions).

I'm sending a PR in a few minutes with the fix.

Wrong answer

hello.
When I was testing the package I got the wrong answer in some cases.
For example. A container with shape [width, height, depth, weight] as [4, 4, 4, 10] can only contain 8 Items with shape [2, 2, 2, 1] (same dimension as above).
however, when running the code below,

'from py3dbp.main import Packer, Bin, Item
packer = Packer()

TESTBIN = Bin("Small Bin", 4, 4, 4, 10)
packer.add_bin(TESTBIN)

for i in range(10):
packer.add_item(Item(str(i+1), 2, 2, 2, 1))

packer.pack()

for b in packer.bins:
print(b.string())
for i in b.items:
print("====> ", i.string())'

I got the answer like this:

Small Bin(4x4x4, max_weight:10) ====> 1(2x2x2, weight: 1) pos([0, 0, 0]) rt(0) ====> 2(2x2x2, weight: 1) pos([0, 0, 4]) rt(5) ====> 3(2x2x2, weight: 1) pos([0, 0, 8]) rt(5) ====> 4(2x2x2, weight: 1) pos([0, 0, 12]) rt(5) ====> 5(2x2x2, weight: 1) pos([0, 0, 16]) rt(5) ====> 6(2x2x2, weight: 1) pos([0, 0, 20]) rt(5) ====> 7(2x2x2, weight: 1) pos([0, 0, 24]) rt(5) ====> 8(2x2x2, weight: 1) pos([0, 0, 28]) rt(5) ====> 9(2x2x2, weight: 1) pos([0, 0, 32]) rt(5) ====> 10(2x2x2, weight: 1) pos([0, 0, 36]) rt(5)

Did I use it in a wrong way?

Need to understand logic further

If I have 3 items and 1 box with following specs:
Bins:
packer.add_bin(Bin('MID-SIZE', 60,60,60, 10))

Items:
packer.add_item(Item('Item 1', 60,60,20, 1))
packer.add_item(Item('Item 2', 60,20,60, 2))
packer.add_item(Item('Item 3', 20,60,60, 3))

Output: The output is as expected with 100% of space being utilized.
::::::::::: MID-SIZE(60.000x60.000x60.000, max_weight:10.000) vol(216000.000)
FITTED ITEMS:
====> Item 1(60.000x60.000x20.000, weight: 1.000) pos([0, 0, 0]) rt(0) vol(72000.000)
====> Item 2(60.000x20.000x60.000, weight: 2.000) pos([0, 0, Decimal('20.000')]) rt(4) vol(72000.000)
====> Item 3(20.000x60.000x60.000, weight: 3.000) pos([0, 0, Decimal('40.000')]) rt(2) vol(72000.000)
UNFITTED ITEMS:

However, if I add one more item with same box, the suggested packing is:
Bins:
packer.add_bin(Bin('MID-SIZE', 60,60,60, 10))

Items:
packer.add_item(Item('Item 1', 60,60,20, 1))
packer.add_item(Item('Item 2', 60,20,60, 2))
packer.add_item(Item('Item 3', 20,60,60, 3))
packer.add_item(Item('Item 4', 20,20,20, 1))

Output: The suggested utilization falls to 70.3%; ideally the 4th item should have been shown in the unfitted items.

::::::::::: MID-SIZE(60.000x60.000x60.000, max_weight:10.000) vol(216000.000)
FITTED ITEMS:
====> Item 4(20.000x20.000x20.000, weight: 1.000) pos([0, 0, 0]) rt(0) vol(8000.000)
====> Item 1(60.000x60.000x20.000, weight: 1.000) pos([Decimal('20.000'), 0, 0]) rt(3) vol(72000.000)
====> Item 2(60.000x20.000x60.000, weight: 2.000) pos([Decimal('40.000'), 0, 0]) rt(1) vol(72000.000)
UNFITTED ITEMS:
====> Item 3(20.000x60.000x60.000, weight: 3.000) pos([0, 0, 0]) rt(5) vol(72000.000)

Can you check if this understanding is correct?

Best
Nitin

packer.pack() returns only 1 item for the final bin

As you can see, i have 5 Item objects.
They were all properly fit into a reasonable Bin

<py3dbp.main.Packer object at 0x7fbdbda04b00>
bins:[ ... ]
items:[]
total_items:5
unfit_items:[]

But when accessing the bin (the only one with contents)..
it says it contains just 1 item? Where are the other 4?

3:<py3dbp.main.Bin object at 0x7fbdbd772c18>
depth:5.5
height:8.5
items:[<py3dbp.main.Item ob...dbcb39198>]
0:<py3dbp.main.Item object at 0x7fbdbcb39198>
__len__:1
max_weight:70.0
name:'medium-box'
width:11.0

Can provide sample data if needed.

Thanks,
for providing such a wonderful library,
gg

bin packing with orientation or considering gravity

It appears that some solution would show some box half hanging over another smaller box. Is there any option to allow all boxes should be on a flat surface larger enough so that it does not fall?

Or this packing algorithm is considering packing without considering gravity or the pack layout is stable?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.