Giter Club home page Giter Club logo

3d-bin-packing's Introduction

3D Bin Packing

3D Bin Packing improvements based on this repository.

OutLine

Improvement

  1. fix item float :

    • [fix_point = False/True] type bool The original packaging method did not consider the gravity problem. After the packaging was completed, there were items floating in the air, which greatly reduced the space utilization of the box. I solved this problem and improved the boxing rate.
    Original packaging Used fix point
  2. Item bearing problem :

    • [loadbear = X] type int The original method did not consider the problem of project load-bearing, because load-bearing involves the structure, I used the priority to sort the projects with higher load-bearing capacity.The higher the number, the higher the priority.
  3. Item need to pack :

    • [level = X] type int The priority can be set to sort which items should be packaged first, to ensure that these items will be packaged in bin.The lower the number, the higher the priority.
  4. Items can be placed upside down or not :

    • [updown = False/True] type bool True means the item can be placed upside down.
  5. Make a set of items :

    • [binding = [(orange,apple),(computer,hat,watch)]] type tuple in list The number of items in the set must be the same in the bin.
    • eg. binding = [(orange,apple),(computer,hat,watch)].
  6. Container coner :

    • [corner = X] type int Set the size of container corner, the unit is cm, color is black.
  7. Paint picture :

    • [painter.plotBoxAndItems()] Draw pictures.
  8. Calculate gravity distribution :

    • print("gravity distribution : ",bin.gravity) Divide the bin into four equal parts, and calculate the weight ratio of the equal parts. Ideally, the weight ratio of each equal part tends to be close.
  9. Add the order of placing items :

    • put_type = 0 or 1 (0 : general & 1 : open top) Added the order of placing items. There are two placement methods. Set the bin to open top or general, and the returned results are sorted according to this method.
  10. Mixed cube and cylinder :

    • typeof = cube or cylinder mixed with cube and cylinder .
  11. Check stability on item :

    • If you want to use this function,fix_point = True and check_stable=True and 0 < support_surface_ratio <= 1 .
    • Rule :
      1. Define a support ratio(support_surface_ratio), if the ratio below the support surface does not exceed this ratio, compare the next rule.
      2. If there is no support under any of the bottom four vertices of the item, then remove the item.
    ! check stable check stable
  12. distribute items :

    • If you have multiple boxes, you can change distribute_items to achieve different packaging purposes.
    • Rule :
      1. distribute_items=True , put the items into the box in order, if the box is full, the remaining items will continue to be loaded into the next box until all the boxes are full or all the items are packed.
      2. distribute_items=False, compare the packaging of all boxes, that is to say, each box packs all items, not the remaining items.
    img distribute_items ! distribute_items
    Bin1
    Bin2
  13. Write part number on item :

    • Check Painting in how to use.
    • In order to better distinguish each item, I write part no in the middle of the item, but if I do this, it will be blocked by the color, so it is best to set the alpha value to about 0.2.

How to use

Init bin :

box1 = Bin(
    partno='Bin',         # partno / PN of item (unique value)
    WHD=(589,243,259),    # (width , height , depth)
    max_weight=28080,     # box can bear the weight
    corner=15             # container coner
    put_type= 1           # add the order of placing items
)

Init item :

item1 = Item(
    partno='testItem', # partno / PN of item (unique value)
    name='wash',       # type of item
    typeof='cube',     # cube or cylinder
    WHD=(85, 60, 60),  # (width , height , depth)
    weight=10,         # item weight
    level=1,           # priority (Item need to pack)
    loadbear=100,      # item bearing
    updown=True,       # item fall down or not
    color='#FFFF37'    # set item color , you also can use color='red' or color='r'
)

Init packer :

packer = Packer()          # packer init

Add bin and items to packer : (Warning : You can only add one bin,but you can add many items.) Now you can add multiple bins/boxes,plz check example7.

packer.addBin(box1)       # adding bins to packer
packer.addItem(item1)     # adding items to packer

Start pack items :

packer.pack(
    bigger_first=True,                 # bigger item first.
    fix_point=True,                    # fix item float problem.
    binding=[('server','cabint')],     # make a set of items.
    distribute_items=True,             # If multiple bin, to distribute or not.
    check_stable=True,                 # check stability on item.
    support_surface_ratio=0.75,        # set support surface ratio.
    number_of_decimals=0
)

Results :

packer.bins              # get bin of packer
packer.bin[i].items      # get fitted items in bin
packer.unfit_items       # get unfitted items 

Painting :

for b in packer :
    painter = Painter(b)
    fig = painter.plotBoxAndItems(
        title=b.partno,
        alpha=0.2,         # set item alpha
        write_num=True,    # open/close write part number 
        fontsize=10        # control write_num fontsize
    )
fig.show() 

Example

Simple example

from py3dbp import Packer, Bin, Item
import time

start = time.time()

# init packing function
packer = Packer()

#  init bin
box = Bin('example',(30, 10, 15), 99,0)
packer.addBin(box)

#  add item
packer.addItem(Item('test1', 'test','cube',(9, 8, 7), 1, 1, 100, True,'red'))
packer.addItem(Item('test2', 'test','cube',(4, 25, 1), 1, 1, 100, True,'blue'))
packer.addItem(Item('test3', 'test','cube',(2, 13, 5), 1, 1, 100, True,'gray'))
packer.addItem(Item('test4', 'test','cube',(7, 5, 4), 1, 1, 100, True,'orange'))
packer.addItem(Item('test5', 'test','cube',(10, 5, 2), 1, 1, 100, True,'lawngreen'))

# calculate packing 
packer.pack(
    bigger_first=True,
    fix_point=True,
    distribute_items=True,
    check_stable=True,
    support_surface_ratio=0.75,
    number_of_decimals=0
)

# paint the results
for b in packer :
    painter = Painter(b)
    fig = painter.plotBoxAndItems(
        title=b.partno,
        alpha=0.2,         
        write_num=True,   
        fontsize=10        
    )
fig.show()

example0

  • This example can be used to compare the fix_point function with and without the fix_point function.

example1

  • This example is used to demonstrate the mixed packing of cube and cylinder.

example2

  • This case is used to demonstrate an example of a packing complex situation.

example3

  • This example is used to demonstrate that the algorithm does not optimize.

example4

  • This example can be used to test large batch calculation time and binding functions.

example5

  • Check stability on item - first rule
  • Define a support ratio, if the ratio below the support surface does not exceed this ratio, compare the second rule.

example6

  • Check stability on item - second rule
  • If there is no support under any of the bottom four vertices of the item, then remove the item.

example7

  • If you have multiple boxes, you can change distribute_items to achieve different packaging purposes.
  • distribute_items=True , put the items into the box in order, if the box is full, the remaining items will continue to be loaded into the next box until all the boxes are full or all the items are packed.
  • distribute_items=False, compare the packaging of all boxes, that is to say, each box packs all items, not the remaining items.

Issue

  • Optimizing using GA or PSO...

Bug

  • Make set of items funcn crash.

History

  • 20230621 Add a rule to check item stability.
  • 20230621 Fix issue : there can only creat one bin.
  • 20230628 Modify Readme.md.
  • 20230629 Fix issue : can not write anything on cube.

Reference

License

MIT

3d-bin-packing's People

Contributors

dependabot[bot] avatar jerry800416 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

3d-bin-packing's Issues

Python version

Hi Jerry,
I am sorry if this is a stupid question but I tried to run the bin packing code from the examples but it would not work. It could not load the module "Painter" and also the syntax seemed wrong.

I am running python 3.11.1 - is that the issue ? (Do I need 3.6.5?)
Or I found another bin packing package with the same name from enzo ruiz. Could that be an issue ?

I would be very happy over an answer :))

ZeroDivisionError: float division by zero

Hi Jerry,

I was having a problem from the original 3dbin py library.
enzoruiz/3dbinpacking#31
When I can't solve the problem. I wanted to use your library. But I'm having another problem with your library.

The problem occurs when the package weight is entered as a float value.
Like this:
lbs = 0.0345
packer.addItem(Item('test1', 'itemname','cube',(2, 5, 6), lbs , 1, 100, True,'red'))

  File "D:\anaconda3\lib\site-packages\py3dbp\main.py", line 482, in gravityCenter
    result.append(round(i / sum(r) * 100,2))
ZeroDivisionError: float division by zero

Actually, I will be using this code for packaging small products. Not for any container filling operation.
My product dimensions are in inches and my weight is in lbs.
Do you have a suggestion for me?

Thank you.

Does it only support one bin?

Hi @jerry800416 !
First of all, thanks a lot for your work on this - You've really done tremendous progress compared to the original repo!
I had a question - You've mentioned here "Warning : You can only add one bin,but you can add many items." - Can you please help me understand whether the package supports multiple bins and the distribution of items among those available bins? Or does it support the distribution of items only with a single bin? (Also I'm assuming Bin = Box)
TIA!

There is a bug in example7

In your example7, there is a bug where the parameter level of the added item is set to different levels, and there may be a situation where all remaining items cannot be loaded when loaded into the second vehicle. At this point, the second car is empty. In the pack method, when iterating through enumerate (self. bins) to the second bin, there is a situation where bin. items are empty, and an error of dividing by 0 is reported. You need to add a check (if bin. items:) before "self. bins [idx]. activity=self. activityCenter (bin)"

Cannot write anything on cubes.

Cannot write anything on cubes.
I tried to add text like ,colors or box(Because operator cannot understand which box is which) no, on box. box cannot see them. have you got an idea?
when i create box on my codes, it works, i modified your Painter Class, please help.

you can see "li" on left.
image

but it should shown like this :

image

Summary is:

` xz_sizes = np.array(boyutlar)

    xz_sizes[:,1] = 0
    
    print(xz_sizes)
    label_pos = (np.array(pozisyon) + xz_sizes/2 ).tolist()
    labels = ["limegreen","blue","1","1","1","1","1","1","1"]

    # labels = ['12', '24']
    for pos, label in zip(label_pos, labels):
        axGlob.text( *pos, label, 'x', ha='center', va='center') 
        counter2 += 2
        if counter2 == 100:
            break ```

`

`
def init(self,bins):
self.items = bins.items
self.width = bins.width
self.height = bins.height
self.depth = bins.depth

def _plotCube(self, ax, x, y, z, dx, dy, dz, color='red',mode=2):
# stoppause = 5
""" Auxiliary function to plot a cube. code taken somewhere from the web. """
xx = [x, x, x+dx, x+dx, x]
yy = [y, y+dy, y+dy, y, y]

kwargs = {'alpha': 1, 'color': color,'linewidth':1 }
if mode == 1 :
    ax.plot3D(xx, yy, [z]*5, **kwargs)
    ax.plot3D(xx, yy, [z+dz]*5, **kwargs)
    ax.plot3D([x, x], [y, y], [z, z+dz], **kwargs)
    ax.plot3D([x, x], [y+dy, y+dy], [z, z+dz], **kwargs)
    ax.plot3D([x+dx, x+dx], [y+dy, y+dy], [z, z+dz], **kwargs)
    ax.plot3D([x+dx, x+dx], [y, y], [z, z+dz], **kwargs)
else :
    text='sadsadas'
    p = Rectangle((x,y),dx,dy,fc=color,ec='black')
   
    p2 = Rectangle((x,y),dx,dy,fc=color,ec='black',label = 'adad')
    p3 = Rectangle((y,z),dy,dz,fc=color,ec='black')
    p4 = Rectangle((y,z),dy,dz,fc=color,ec='black')
    p5 = Rectangle((x,z),dx,dz,fc=color,ec='black')
    p6 = Rectangle((x,z),dx,dz,fc=color,ec='black')
    ax.add_patch(p)
   # ax.annotate(text, (x+dx/2,y))
    ax.add_patch(p2)
   # ax.annotate(text, (x+dx/2,y))
    ax.add_patch(p3)
    ax.add_patch(p4)
    ax.add_patch(p5)
    ax.add_patch(p6)
   # ax.text(x+dx, y+dy/2, z, "red", color='red',rotation_mode= None,verticalalignment = 'top',animated = 'b')
    # ax.text
    ax.annotate(text, (x,y))
    art3d.pathpatch_2d_to_3d(p, z=z, zdir="z")
    # art3d.text(x+0.8,y+0.8,z+0.8, 'label', zdir="x")
    art3d.pathpatch_2d_to_3d(p2, z=z+dz, zdir="z")
    art3d.pathpatch_2d_to_3d(p3, z=x, zdir="x")
    art3d.pathpatch_2d_to_3d(p4, z=x + dx, zdir="x")
    art3d.pathpatch_2d_to_3d(p5, z=y, zdir="y")
    art3d.pathpatch_2d_to_3d(p6, z=y + dy, zdir="y")

def plotBoxAndItems(self,title=""):
counter2 = 0
with open('boyutlar.csv', newline='') as f:
reader = csv.reader(f)
boyutlar = list(reader)

boyutlar = [e for e in boyutlar if e]

# boyutlar = [[float(value) for value in sublist] for sublist in boyutlar]      
boyutlar = [list(map(float, y)) for y in boyutlar]         
      
with open('pozisyon.csv', newline='') as f:
    reader2 = csv.reader(f)
    pozisyon = list(reader2)
pozisyon = [e for e in pozisyon if e]
# print(pozisyon)

# pozisyon = [[float(value) for value in sublist] for sublist in pozisyon]   
pozisyon = [[float(value) for value in sublist] for sublist in pozisyon]
print(pozisyon)

""" side effective. Plot the Bin and the items it contains. """
fig = plt.figure()
axGlob = plt.axes(projection='3d')
stoppause = 1
counter=0
# fit rotation type
for item in self.items:
    rt = item.rotation_type  
    x,y,z = item.position
    [w,h,d] = item.getDimension()
    color = item.color
    # countt=countt+1
    if item.typeof == 'cube':
         # plot item of cube
        self._plotCube(axGlob, float(x), float(y), float(z), float(w),float(h),float(d),color=color,mode=2)
    elif item.typeof == 'cylinder':
        # plot item of cylinder
        self._plotCylinder(axGlob, float(x), float(y), float(z), float(w),float(h),float(d),color=color,mode=2)
    
    counter = counter + 1 
    if counter == stoppause:
        break
# plot bin 
self._plotCube(axGlob,0, 0, 0, float(self.width), float(self.height), float(self.depth),color='black',mode=1)

plt.title('result')
self.setAxesEqual(axGlob)
xz_sizes = np.array(boyutlar)

xz_sizes[:,1] = 0

print(xz_sizes)
label_pos = (np.array(pozisyon) + xz_sizes/2 ).tolist()
labels = ["limegreen","blue","1","1","1","1","1","1","1"]

# labels = ['12', '24']
for pos, label in zip(label_pos, labels):
    axGlob.text( *pos, label, 'x', ha='center', va='center') 
    counter2 += 1
    if counter2 == 1:
        break

    
              
    
    
plt.show()`

Empty space dimension

Is it possible to find the dimension of the empty spaces after packing the items in the bin.

solution is not optimal - problem of rotation

Here are three cubes with the length\width\height as 210\110\180.
the container length\width\height is 400\220\220

If I input the value with L\W\H as 210\110\180, the model gives me the sub-optimal result, in which the container can only contain two cubes.

image

If I input the value with L\W\H sequence as 110\210\180, the model gives me the optimal result, in which the container can contain all three cubes.

image

The question is: why cannot the model perform the automatical rotation to accomodate all three items in order to get the optimal solution? Is this the current limitation, or we can configure it to do this work better?

is it possible to fix the distribute_items=True

when I set the parameter to distribute_items=True, it reported error at :

File "C:\Users\usr\Desktop\3DBP\py3dbp\main.py", line 513, in pack
    self.items.remove(item)
ValueError: list.remove(x): x not in list

is this issue easy to fix?

Different output between the API and the examples

Hello,

I'm using your program to create a web application on top of it. By using your API I have setup a json sample like the example4.py, I have the same calculation results : both have 37 unfitted items and the same fitted item, but the difference is in the positions of the items. When I visualize your example4 with matplot , we have a beautiful and correct to the eye packing solution. But using the API and my front end ReactJS front, I have a weird stacking of the item, plus the API results is not the same, here's the logging sample :

API logs :

INFO:root:Creating and adding items for Dyson DC34 Animal
INFO:root:Creating and adding items for wash
INFO:root:Creating and adding items for cabint
INFO:root:Creating and adding items for server
INFO:root:Processing binding data...
INFO:root:Returning packer, box, and binding...
INFO:root:Possition of the box : (295.0, 122.0, 129.5)
INFO:root:Position of the item cabint-1 : [30, 40, 100]
INFO:root:Position of the item cabint-2 : [90, 40, 100]
INFO:root:Position of the item cabint-3 : [150, 40, 100]
INFO:root:Position of the item cabint-4 : [210, 40, 100]
INFO:root:Position of the item cabint-5 : [270, 40, 100]
INFO:root:Position of the item cabint-6 : [330, 40, 100]
INFO:root:Position of the item cabint-7 : [390, 40, 100]
INFO:root:Position of the item cabint-8 : [450, 40, 100]
INFO:root:Position of the item cabint-9 : [510, 40, 100]
INFO:root:Position of the item cabint-10 : [30, 120, 100]
INFO:root:Position of the item cabint-11 : [90, 120, 100]
INFO:root:Position of the item cabint-12 : [150, 120, 100]
INFO:root:Position of the item cabint-13 : [210, 120, 100]
INFO:root:Position of the item cabint-14 : [270, 120, 100]
INFO:root:Position of the item cabint-15 : [330, 120, 100]
INFO:root:Position of the item Dyson DC34 Animal-1 : [563, 41, 85]
INFO:root:Position of the item Dyson DC34 Animal-2 : [445, 121, 23]
INFO:root:Position of the item Dyson DC34 Animal-3 : [85, 201, 23]
INFO:root:Position of the item Dyson DC34 Animal-4 : [255, 201, 23]
INFO:root:Position of the item Dyson DC34 Animal-5 : [553, 123, 85]
INFO:root:Position of the item Dyson DC34 Animal-6 : [425, 203, 23]
INFO:root:Position of the item Dyson DC34 Animal-7 : [85, 41, 223]
INFO:root:Position of the item Dyson DC34 Animal-8 : [255, 41, 223]
INFO:root:Position of the item Dyson DC34 Animal-9 : [425, 41, 223]
INFO:root:Position of the item Dyson DC34 Animal-10 : [85, 123, 223]
INFO:root:Position of the item Dyson DC34 Animal-11 : [255, 123, 223]
INFO:root:Position of the item Dyson DC34 Animal-12 : [563, 85, 211]
INFO:root:Position of the item Dyson DC34 Animal-13 : [445, 121, 69]
INFO:root:Position of the item Dyson DC34 Animal-14 : [85, 201, 69]
INFO:root:Position of the item Dyson DC34 Animal-15 : [255, 201, 69]
INFO:root:Position of the item wash-1 : [540, 194, 42]
INFO:root:Position of the item wash-2 : [382, 192, 76]
INFO:root:Position of the item wash-3 : [467, 192, 76]
INFO:root:Position of the item wash-4 : [402, 110, 122]
INFO:root:Position of the item wash-5 : [487, 110, 122]
INFO:root:Position of the item wash-6 : [42, 190, 122]
INFO:root:Position of the item wash-7 : [127, 190, 122]
INFO:root:Position of the item wash-8 : [212, 190, 122]
INFO:root:Position of the item wash-9 : [297, 190, 122]
INFO:root:Position of the item wash-10 : [540, 194, 127]
INFO:root:Position of the item wash-11 : [382, 190, 136]
INFO:root:Position of the item wash-12 : [382, 190, 196]
INFO:root:Position of the item wash-13 : [402, 112, 182]
INFO:root:Position of the item wash-14 : [487, 112, 182]
INFO:root:Position of the item server-1 : [50, 195, 167]
INFO:root:Position of the item server-2 : [150, 195, 167]
INFO:root:Position of the item server-3 : [250, 195, 167]
INFO:root:Position of the item server-4 : [50, 199, 197]
INFO:root:Position of the item server-5 : [150, 199, 197]
INFO:root:Position of the item server-6 : [250, 199, 197]
INFO:root:Position of the item server-7 : [50, 199, 227]
INFO:root:Position of the item server-8 : [150, 199, 227]
INFO:root:Position of the item server-9 : [250, 199, 227]
INFO:root:Position of the item wash-15 : [42, 190, 90]
INFO:root:Position of the item wash-16 : [127, 190, 90]
INFO:root:Position of the item wash-17 : [212, 190, 90]
INFO:root:Position of the item wash-18 : [297, 190, 90]
INFO:root:Position of the item server-10 : [395, 95, 170]
INFO:root:Position of the item server-11 : [35, 175, 170]
INFO:root:Position of the item server-12 : [135, 175, 170]
INFO:root:Position of the item server-13 : [235, 175, 170]
INFO:root:Position of the item server-14 : [395, 95, 200]
INFO:root:Position of the item server-15 : [35, 175, 200]
INFO:root:Position of the item server-16 : [135, 175, 200]
INFO:root:Position of the item server-17 : [235, 175, 200]
INFO:root:Position of the item server-18 : [35, 175, 230]
INFO:root:Position of the item server-19 : [135, 175, 230]
INFO:root:Position of the item server-20 : [235, 175, 230]
INFO:root:Position of the item server-21 : [35, 15, 50]
INFO:root:Position of the item server-22 : [35, 15, 50]
INFO:root:Position of the item server-23 : [35, 15, 50]
INFO:root:Position of the item server-24 : [35, 15, 50]
INFO:root:Position of the item server-25 : [35, 15, 50]
INFO:root:Position of the item server-26 : [35, 15, 50]
INFO:root:Position of the item server-27 : [35, 15, 50]
INFO:root:Position of the item server-28 : [35, 15, 50]
INFO:root:Position of the item server-29 : [35, 15, 50]
INFO:root:Position of the item server-30 : [35, 15, 50]
INFO:root:Position of the item server-31 : [35, 15, 50]
INFO:root:Position of the item server-32 : [35, 15, 50]
INFO:root:Position of the item server-33 : [35, 15, 50]
INFO:root:Position of the item server-34 : [35, 15, 50]
INFO:root:Position of the item server-35 : [35, 15, 50]
INFO:root:Position of the item server-36 : [35, 15, 50]
INFO:root:Position of the item server-37 : [35, 15, 50]
INFO:root:Position of the item server-38 : [35, 15, 50]
INFO:root:Position of the item server-39 : [35, 15, 50]
INFO:root:Position of the item server-40 : [35, 15, 50]
INFO:root:Position of the item server-41 : [35, 15, 50]
INFO:root:Position of the item server-42 : [35, 15, 50]

Example4.py logs :

FITTED ITEMS:
partno : Cabinet1
type : cabint
color : #842B00
position : [Decimal('0'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet2
type : cabint
color : #842B00
position : [Decimal('60'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet3
type : cabint
color : #842B00
position : [Decimal('120'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet4
type : cabint
color : #842B00
position : [Decimal('180'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet5
type : cabint
color : #842B00
position : [Decimal('240'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet6
type : cabint
color : #842B00
position : [Decimal('300'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet7
type : cabint
color : #842B00
position : [Decimal('360'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet8
type : cabint
color : #842B00
position : [Decimal('420'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet9
type : cabint
color : #842B00
position : [Decimal('480'), Decimal('0'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet10
type : cabint
color : #842B00
position : [Decimal('0'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet11
type : cabint
color : #842B00
position : [Decimal('60'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet12
type : cabint
color : #842B00
position : [Decimal('120'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet13
type : cabint
color : #842B00
position : [Decimal('180'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet14
type : cabint
color : #842B00
position : [Decimal('240'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Cabinet15
type : cabint
color : #842B00
position : [Decimal('300'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 6080200
volume : 960000.0
weight : 80.0


partno : Dyson DC34 Animal1
type : Dyson
color : #FF0000
position : [Decimal('540'), Decimal('0'), Decimal('0')]
rotation type : 3
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal2
type : Dyson
color : #FF0000
position : [Decimal('360'), Decimal('80'), Decimal('0')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal3
type : Dyson
color : #FF0000
position : [Decimal('0'), Decimal('160'), Decimal('0')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal4
type : Dyson
color : #FF0000
position : [Decimal('170'), Decimal('160'), Decimal('0')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal5
type : Dyson
color : #FF0000
position : [Decimal('530'), Decimal('82'), Decimal('0')]
rotation type : 3
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal6
type : Dyson
color : #FF0000
position : [Decimal('340'), Decimal('162'), Decimal('0')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal7
type : Dyson
color : #FF0000
position : [Decimal('0'), Decimal('0'), Decimal('200')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal8
type : Dyson
color : #FF0000
position : [Decimal('170'), Decimal('0'), Decimal('200')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal9
type : Dyson
color : #FF0000
position : [Decimal('340'), Decimal('0'), Decimal('200')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal10
type : Dyson
color : #FF0000
position : [Decimal('0'), Decimal('82'), Decimal('200')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal11
type : Dyson
color : #FF0000
position : [Decimal('170'), Decimal('82'), Decimal('200')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal12
type : Dyson
color : #FF0000
position : [Decimal('540'), Decimal('0'), Decimal('170')]
rotation type : 4
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal13
type : Dyson
color : #FF0000
position : [Decimal('360'), Decimal('80'), Decimal('46')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal14
type : Dyson
color : #FF0000
position : [Decimal('0'), Decimal('160'), Decimal('46')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : Dyson DC34 Animal15
type : Dyson
color : #FF0000
position : [Decimal('170'), Decimal('160'), Decimal('46')]
rotation type : 0
WHD : 1708246
volume : 641240.0
weight : 85.0


partno : wash1
type : wash
color : #FFFF37
position : [Decimal('510'), Decimal('164'), Decimal('0')]
rotation type : 2
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash2
type : wash
color : #FFFF37
position : [Decimal('340'), Decimal('162'), Decimal('46')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash3
type : wash
color : #FFFF37
position : [Decimal('425'), Decimal('162'), Decimal('46')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash4
type : wash
color : #FFFF37
position : [Decimal('360'), Decimal('80'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash5
type : wash
color : #FFFF37
position : [Decimal('445'), Decimal('80'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash6
type : wash
color : #FFFF37
position : [Decimal('0'), Decimal('160'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash7
type : wash
color : #FFFF37
position : [Decimal('85'), Decimal('160'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash8
type : wash
color : #FFFF37
position : [Decimal('170'), Decimal('160'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash9
type : wash
color : #FFFF37
position : [Decimal('255'), Decimal('160'), Decimal('92')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash10
type : wash
color : #FFFF37
position : [Decimal('510'), Decimal('164'), Decimal('85')]
rotation type : 2
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash11
type : wash
color : #FFFF37
position : [Decimal('340'), Decimal('160'), Decimal('106')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash12
type : wash
color : #FFFF37
position : [Decimal('340'), Decimal('160'), Decimal('166')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash13
type : wash
color : #FFFF37
position : [Decimal('360'), Decimal('82'), Decimal('152')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash14
type : wash
color : #FFFF37
position : [Decimal('445'), Decimal('82'), Decimal('152')]
rotation type : 0
WHD : 856060
volume : 306000.0
weight : 10.0


partno : Server1
type : server
color : #0000E3
position : [Decimal('0'), Decimal('160'), Decimal('152')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server2
type : server
color : #0000E3
position : [Decimal('100'), Decimal('160'), Decimal('152')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server3
type : server
color : #0000E3
position : [Decimal('200'), Decimal('160'), Decimal('152')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server4
type : server
color : #0000E3
position : [Decimal('0'), Decimal('164'), Decimal('182')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server5
type : server
color : #0000E3
position : [Decimal('100'), Decimal('164'), Decimal('182')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server6
type : server
color : #0000E3
position : [Decimal('200'), Decimal('164'), Decimal('182')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server7
type : server
color : #0000E3
position : [Decimal('0'), Decimal('164'), Decimal('212')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server8
type : server
color : #0000E3
position : [Decimal('100'), Decimal('164'), Decimal('212')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server9
type : server
color : #0000E3
position : [Decimal('200'), Decimal('164'), Decimal('212')]
rotation type : 1
WHD : 7010030
volume : 210000.0
weight : 20.0



UNFITTED ITEMS:
partno : wash15
type : wash
color : #FFFF37
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash16
type : wash
color : #FFFF37
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash17
type : wash
color : #FFFF37
WHD : 856060
volume : 306000.0
weight : 10.0


partno : wash18
type : wash
color : #FFFF37
WHD : 856060
volume : 306000.0
weight : 10.0


partno : Server10
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server11
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server12
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server13
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server14
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server15
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server16
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server17
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server18
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server19
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server20
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server21
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server22
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server23
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server24
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server25
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server26
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server27
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server28
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server29
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server30
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server31
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server32
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server33
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server34
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server35
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server36
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server37
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server38
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server39
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server40
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server41
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0


partno : Server42
type : server
color : #0000E3
WHD : 7010030
volume : 210000.0
weight : 20.0

This bothering me as I don't find the source of this issue. FYI, I'm using the same parameters for the packer function. And here's a sample of my example4.json file :

{
"box": [
{
"name": "example 4 contenair",
"WHD": [
589.8,
243.8,
259.1
],
"weight": 28080,
"openTop": [
0
],
"corner": 15
}
],
"item": [
{
"name": "Dyson DC34 Animal",
"WHD": [
170,
82,
46
],
"count": 15,
"updown": true,
"type": "cube",
"level": 1,
"loadbear": 100,
"weight": 85.12,
"color": "1"
},
{
"name": "wash",
"WHD": [
85,
60,
60
],
"count": 18,
"updown": true,
"type": "cube",
"level": 1,
"loadbear": 100,
"weight": 10,
"color": "6"
},
{
"name": "cabint",
"WHD": [
60,
80,
200
],
"count": 15,
"updown": true,
"type": "cube",
"level": 1,
"loadbear": 100,
"weight": 80,
"color": "3"
},
{
"name": "server",
"WHD": [
70,
100,
30
],
"count": 42,
"updown": true,
"type": "cube",
"level": 1,
"loadbear": 100,
"weight": 20,
"color": "4"
}
],
"binding": [
[
"server",
"cabint",
"wash"
]
]
}

PS : thank you for your work, it's a great project.

Account for a walking path in bin

I really like the work you have done for this library but I have an issue with how the packing works if I try and add a walking path inside the bin. The reason for this is when packing a container such as a shipping container, we need room to walk into the container. I ended up adding an additional item in the list that is the area of the walking room, but is there any way you could clarify how I could either add an item at exact coordinates, or set an item to be the first packed in the container every time?

image
image

Painter

cannot import name 'Painter' from 'py3dbp'

problem of plotting Cylinder

There are some problem of plotting cylinder in example5.py

Traceback (most recent call last):
  File "C:/Users/mike/Desktop/3DBP/3D-bin-packing-master/example5.py", line 71, in <module>
    painter.plotBoxAndItems()
  File "C:\Users\mike\Desktop\3DBP\3D-bin-packing-master\py3dbp\main.py", line 615, in plotBoxAndItems
    self._plotCylinder(axGlob, float(x), float(y), float(z), float(w),float(h),float(d),color=color,mode=2)
  File "C:\Users\mike\Desktop\3DBP\3D-bin-packing-master\py3dbp\main.py", line 596, in _plotCylinder
    ax.plot_surface(x_grid, y_grid, z_grid,shade=False,fc=color,ec='black',alpha=1,color=color)
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 1736, in plot_surface
    polyc = art3d.Poly3DCollection(polys, *args, **kwargs)
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 518, in __init__
    PolyCollection.__init__(self, verts, *args, **kwargs)
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\collections.py", line 961, in __init__
    Collection.__init__(self, **kwargs)
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\collections.py", line 170, in __init__
    self.update(kwargs)
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\artist.py", line 888, in update
    for k, v in props.items()]
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\artist.py", line 888, in <listcomp>
    for k, v in props.items()]
  File "C:\Users\mike\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\artist.py", line 881, in _update_property
    raise AttributeError('Unknown property %s' % k)
AttributeError: Unknown property fc

Floating boxes with Fixpoint = True

Gravity feature is not working very well.

After placing the first layer of boxes on the floor, boxes going on top of the previous ones are not really taking support surface into consideration. In the gif, check for the placement of items "item 8", "item32" or "item 9"... this is quite a extreme case as there are 33 items placed and all are different.

48

This issue I think is related with Bin.checkDepth() function not working as it should:

if self.fix_point == True:
    [w,h,d] = dimension
    [x,y,z] = [float(pivot[0]),float(pivot[1]),float(pivot[2])]

    for i in range(3):
        # fix height
        y = self.checkHeight([x,x+float(w),y,y+float(h),z,z+float(d)])
        # fix width
        x = self.checkWidth([x,x+float(w),y,y+float(h),z,z+float(d)])
        # fix depth
        z = self.checkDepth([x,x+float(w),y,y+float(h),z,z+float(d)])

    self.fit_items = np.append(self.fit_items,np.array([[x,x+float(w),y,y+float(h),z,z+float(d)]]),axis=0)
    item.position = [set2Decimal(x),set2Decimal(y),set2Decimal(z)]
def checkDepth(self,unfix_point):
    ''' fix item position z '''
    z_ = [[0,0],[float(self.depth),float(self.depth)]]
    for j in self.fit_items:
        # creat x set
        x_bottom = set([i for i in range(int(j[0]),int(j[1]))])
        x_top = set([i for i in range(int(unfix_point[0]),int(unfix_point[1]))])
        # creat y set
        y_bottom = set([i for i in range(int(j[2]),int(j[3]))])
        y_top = set([i for i in range(int(unfix_point[2]),int(unfix_point[3]))])
        # find intersection on x set and y set.
        if len(x_bottom & x_top) != 0 and len(y_bottom & y_top) != 0 :
            z_.append([float(j[4]),float(j[5])])
    top_depth = unfix_point[5] - unfix_point[4]
    # find diff set on z_.
    z_ = sorted(z_, key = lambda z_ : z_[1])
    for j in range(len(z_)-1):
        if z_[j+1][0] -z_[j][1] >= top_depth:
            return z_[j][1]
    return unfix_point[4]

I tried to understand how checkHeight, checkWidth and specially for this case, checkDepth functions work, but I didn't succeed due to the compact coding.

It would be nice to create a new property which defines the minimum % of surface that has to be supported from below.
For example, a box w,h,d=8,5,10 and rotation=0, would have a surface of 40 u^2.
If we define a support_surface_ratio=0.75, then at least 30 u^2 of surface must be supported from below by other boxes to consider that position a valid placement.

Another option that could be implemented in parallel, would be to check if at least 3 out of the 4 vertices of the supporting face of a box are under support. If yes, then it can be placed in that position even if the surface under support is below the ratio.

I would really appreciate if you could find a solution for this, or if you don't have the time, to give me some insights about how a position is fixed using the functions above.

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.