Git Product home page Git Product logo

3dcontainerpacking's Introduction

3D Container Packing in C#

NuGet

This is a C# library that can be used to find 3D container packing solutions (also known as 3D bin packing). It includes an implementation of the EB-AFIT packing algorithm originally developed as a master's thesis project by Erhan Baltacıoğlu (EB) at the U.S. Air Force Institute of Technology (AFIT) in 2001. This algorithm is also described in The Distributor's Three-Dimensional Pallet-Packing Problem: A Human Intelligence-Based Heuristic Approach, by Erhan Baltacıoğlu, James T. Moore, and Raymond R. Hill Jr., published in the International Journal of Operational Research in 2006 (volume 1, issue 3).

The EB-AFIT algorithm supports full item rotation and has excellent runtime performance and container utilization.

Usage

Start by including the ContainerPacking project in your solution.

Create a list of Container objects, which describes the dimensions of the containers:

List<Container> containers = new List<Container>();
containers.Add(new Container(id, length, width, height));
...

Create a list of items to pack:

List<Item> itemsToPack = new List<Item>();
itemsToPack.Add(new Item(id, dim1, dim2, dim3, quantity));
...

Create a list of algorithm IDs corresponding to the algorithms you would like to use. (Currently EB-AFIT is the only algorithm implemented.) Algorithm IDs are listed in the AlgorithmType enum.

List<int> algorithms = new List<int>();
algorithms.Add((int)AlgorithmType.EB_AFIT);
...

Call the Pack method on your container list, item list, and algorithm list:

List<ContainerPackingResult> result = PackingService.Pack(containers, itemsToPack, algorithms);

The list of ContainerPackingResults contains a ContainerPackingResult object for each container. Within each ContainerPackingResult is the container ID and a list of AlgorithmPackingResult objects, one for each algorithm requested. Within each algorithm packing result is the name and ID of the algorithm used, a list of items that were successfully packed, a list of items that could not be packed, and a few other packing metrics. The items in the packed list are in pack order and include x, y, and z coordinates and x, y, and z pack dimensions. This information is useful if you want to attach a visualization tool to display the packed items in their proper pack locations and orientations.

Internally, the Pack() method will try to pack all the containers with all the items using all the requested algorithms in parallel. If you have a list of containers you want to try, but want them to run serially, then you can call Pack() with one container at a time. For example, if you want to run a large set of containers but would like to update the user interface as each one finishes, then you would want to call Pack() multiple times asynchronously and update the UI as each result returns.

Demo WebAPI Application

This project also includes a demo web application that lets the user specify an arbitrary set of items, an arbitrary set of containers, and the packing algorithms to use. AJAX packing requests are sent to the server and handled by a WebAPI controller. Once returned, each pack solution can be viewed in the WebGL visualization tool by clicking the camera icon.

Container packing visualization

Acknowledgements and Related Projects

This project would not have been possible without the support of Dr. Raymond Hill at the Air Force Institute of Technology. It also leans heavily on the original C code included in Erhan Baltacıoğlu's thesis, which was discovered and resurrected by Bill Knechtel (GitHub user wknechtel), and ported to JavaScript by GitHub user keremdemirer.

https://github.com/wknechtel/3d-bin-pack/

https://github.com/keremdemirer/3dbinpackingjs

3dcontainerpacking's People

Contributors

davidchapman avatar davidmchapman avatar edgarfroes 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

3dcontainerpacking's Issues

Enhancement suggestion

First off thank you for this. It's amazing how little there is in C# for the 3D Bin Packing problem. I do have a feature enhancement suggestion that you might want to consider. Some shippers have a weight limit for boxes and it would be beneficial if you could add a max weight for containers. This way you wont get overloaded on packing containers.

Thanks again!

Question: Find largest containers that fits inside volume

Hi,
Would be possible to find the largest container that fit into the shape.
We are looking for some nice centre point inside 3D geometry. So I thought we could get the largest volume container and its middle of diagonal using your workflow. Not sure if this would work...or maybe you have some idea?
Does it work if we have volume like doughnut shape?
What are the limitation yo my volumes?

Max Weight addition

Thanks very much for this code, that's nice.
Do you think this is possible to add (easily) maximum weight in a container in this algorithm?
Kind regards

how to trigger the WebAPI

Dear david,

thanks for this nice rebuild from the algorithm in c#.
a short question:
how can i trigger the web api, i have seen theres running a webserver with a api, must i send the data to it via json?
there is nothing in the documentation, when you me we could create a documentation together.
Greets.

Possible implementations?

Thanks for this fantastic library!

Is it possible to implement this library for further functionality?

Example:

  • Load Side
    The loading side specifies the open part of the container from where the boxes can
    be loaded. The Load Side can be in 3 way:
    a. For Width side: the boxes will be loaded from Width side
    b. For Length side: the boxes will be loaded from Length side
    c. For Top side: the boxes will be loaded from Top side
    image

  • Load Direction
    The Load Direction is defined in this way:
    a. From Left to Right: the boxes will be loaded from left to right
    b. From Right to Left: the boxes will be loaded from right to left
    in both cases the load will go from back to front (or from below to above)
    The following examples explain the load direction, red is the primary direction, blue is the secondary direction.
    Load direction example “Left to Right” in Width load side.
    image
    Load direction example “Right to Left” in Width load side.
    image
    Load direction example “Left to Right” in Length load side.
    image
    Load direction example “Right to Left” in Length load side.
    image
    Load direction example “Left to Right” in Top load side.
    image
    Load direction example “Right to Left” in Top load side.
    image

  • Box Stackable (boolean)
    If false, no box can be placed on above, but it can be place above other box.

  • Box Sorting (int)
    More lower the sorting is, and more first be processed. If 0, the sorting is irrelevant. This property is useful if you have boxes that must be left closer to the loading side to be able to download them before the others. Or for an order, if we think of a courier who has to make orderly deliveries. Example: we could have 7 boxes with a sorting 1, 3 with another sorting 2, 9 with another 3, etc. All boxes with the same number go close to be downloaded in the same moment.

  • Use Weight Distribution (boolean)
    This property define if the process use the weight distribution.
    With the weight distribution the load must be distributed uniformly for each container so that there are no points where the weight is too high compared to other points of the load. This feature need to have a Box Weight property.

  • Use Stability Constraint (boolean)
    This property define if the process use the stability constraint. If use, the boxes must be stable.
    Stable box means that box is supported by container floor or top of other box. Also at least 3 side of box is supported by container or other box.
    image

  • Type Of Saving
    This property define the Nesting process.
    There are two way:
    a. Space The processing will use the containers optimally saving space, and using the fewest containers and possibly the smallest ones. Which is what the algorithm does now, I think.
    b. Cost The processing will use the containers optimally saving costs, choosing the containers that will cost less the total processing. This feature need to have a Container Cost property.

Invalid layer index reference

In testing scenarios with overly large items (i.e., one that will not fit in the box), I'm finding that it will break on EB_AFIT.cs line 1083, with bestIteration referencing a layer index that doesn't exist.

Bug + fix found in reference implementation

Hey there!
I recently searched for the EB-AFIT algorithm and I found this bug in the original C-Code project that seems to have also found his way to this C# project.

As Robertson also suggests a fix you might have a look at these two lines in your code

smallestZ.CumX = smallestZ.CumX - cboxx;
itemsToPack[cboxi].CoordX = smallestZ.CumX - cboxx;

where it might be a mistake to decrement cboxx twice from the itemsToPack[cboxi].CoordX

Floating box

Hi there!
First off, great library, thank you very much for it!

Just trying to work out why the below issue may be occurring (Reference to the floating box)
I cant even begin to understand the maths behind this, but thought I should mention it just in case my input parameters are incorrect
image

image

Restrict rotations of boxes and container

Hi

How do we enforce rotation constraints to the boxes and containers (maintain original orientation of boxes and container) ?

Is it simply limiting containerOrientationVariant to 1 in ExecuteIterations() [ EB_AFIT.cs line #291 ] :

for (int containerOrientationVariant = 1; (containerOrientationVariant <= 6) && !quit; containerOrientationVariant++)

and using original box orientation in FindBox() [ EB_AFIT.cs line #415 ] and skip AnalyseBox() using other box rotations :

AnalyzeBox(hmx, hy, hmy, hz, hmz, itemsToPack[x].Dim1, itemsToPack[x].Dim2, itemsToPack[x].Dim3);

or does it require additional changes ?

Thanks

Pack all items - many available boxes

David
Would you please suggest how one could modify the code so that rather than just packing only one box at a time, that it would have an infinite number of each of the specified containers, and find the 'optimal' (or very good ;) packing of all items, for the minimum total container volume.

item direct control

thank you for your programe.
i want to know how can i put my item to container without scale change.
for example:
i have a container with: 3x1x3
and have a item size is: 1x2x2
when i run application, it put item to container, with size 2x1x2. it is ok.
i want to set a param make the item not put in container.

Avoiding packing items at corners due to rounded corners of container

Hi, my container is a convex shape (cuboid with rounded corners), is it possible to avoid placing boxes at the corners as they will spill out of container shape ? Two ways I can think of:

  1. Can we place dummy boxes at the corners to avoid packing actual boxes at these corners
  2. Extract the largest cuboid we can inscribe in our convex shape and use it, but lots of space along the edges will be wasted

Orientation

@davidchapman I am in a project and I need to arrange the boxes in a container where the door is at the front. I could not fully understand the code so I could not change the orientation. Can you please add more information to explain the code or to add new feature to choose which orientation to arrange first? Thank you.

How did the javascript port of the algorithm helped you?

Thanks for your work, it is really appreciated!
This is not an issue, but I couldn't find any way to contact you, sorry for the inconveniences.

I found out from your README that there is a javascript port of the code: https://github.com/keremdemirer/3dbinpackingjs
Did you use something from that repository? Or you just listed it?
I'd like to run the JS version, but it's not working or I'm not aware of how it is working, it's doesn't output the packed boxes and their position in the container, as you can see in the image bellow:
solution

Thanks for any idea!

Teach Algorithmus do not put up items

Dear David,

is it possible to "teach" the algorithm do not put up items?

3dview_issue4_putup

So the algorithmus should only lay down packes, what must i change in the algorithm that this is possible?

Greets from austria.

Container with already packed items

Hi there,

what would have to be changed in the code so that you can continue to pack an already packed container with items?
For example: the container is half full and you want to pack more items into it.

Tanks!

Dealing with floats.

Sometimes one of the dimension of a box could be, say, 2 1/4", which translates into 2.25" In order to avoid dealing with floats, I move the decimal point two places to the right. When that happens the algorithm returns very weird results. It's like the algorithm was not designed to deal with numbers like 375 (3 3/4"), 713 (7 1/8").

If I change the dimensions to 4" and 7" the packing is smoother. Has anyone here dealt with this issue?

Rotation and Stacking

How it is possible to control rotation of certain items. Such as an Item cannot be rotated in specific Orientation. Also Does this Algorithm give ability to NO-TO-STACK-OVER certain items.
Ex. Some Heavy Items cannot be put above lighter Items.

Your Help Will be Greatly Appreciated. Thanks a Lot

When duplicating the cargo, 3x as many containers are created

I made software to calculate cargo for my Container.
When I got the following cargo:
grafik
screenshot mit einem gefülltem Truck

and duplicate the cargo afterwards (calling algorithm.calculate()), the result should look like:
grafik
screenshot richtig -> 2 Trucks

instead the algorithm made 3 Trucks
grafik
screenshot wrong 3 trucks


I found a bug in lines 149 and 182 ( in the forked projekt at this file: https://github.com/DigitecGalaxus/3DContainerPacking/blob/master/src/CromulentBisgetti.ContainerPacking/Algorithms/EB_AFIT.cs)
in both lines ther should be a less than or equal instead of less than:

else if (hy - dim2 == bfy && hmx - dim1 == bfx && Math.Abs(hz - dim3) <= bfz)

instead of:

else if (hy - dim2 == bfy && hmx - dim1 == bfx && Math.Abs(hz - dim3) < bfz)

@DigitecGalaxus in your project no issues are allowed, could you fix it in your NuGet

License?

I'm rather new to GitHub/public code, so apologizes if I've overlooked something. Is there a license for this code? I'd potentially like to use it for calculating postage for packages for commercial use.

I looked at some of the referenced GitHub repos you used and didn't immediately see licenses on them either.

Thanks!

Help me understand

You could help me understand the logic I have read the master's work but I have difficulties with the language. I made changes to the system and I'm already handling pallet rotation control. but I still do not understand very well the strategy used to define which pallets and in what position they will be placed in the container. From what I understand the layers function determines the best configuration for positioning the layers. But if you can give me an aid in understanding it would be much easier. What exactly is a layer and how it is mounted.
Thanks.

Does putting heavy boxes first makes sense?

Hello @davidmchapman,

I'm thinking of implementing a weighted variation, but I just can't make a decision. Is it better to just put heavy boxes first or try to keep an even surface so the weight is distributed around the boxes? Probably depends, if you have some experience with this I would love to hear.

Multiple Item Support. Cylinder as Item

Hey David, First of all thank you for a great implementation. I wonder how can I use cylinders along with the cubes as item to pack in the container ( Multiple Item support). I tried to tweak the algorithm but it's kinda hard as I was unable to understand the certain terminology you used (eg. hmx pz bfx) and others. Can you put a little light on it.

Desired Output

5f8a36e6eaf6e809813ddd6877f86cb60

Thanks a lot.

How to run the app

Hi All,

can you pls teach me how to run this app in vscode?
sorry I'm newbie in C# world, so kindly help me out
thanks

Packing issue on several containers

Hi,

I am trying to pack boxes into two containers. But the problem is that all boxes are packed separately for each container. I expected that second container will be filled only if first container is full is it right or not? Is this desired behavior or something wrong is with my code?
filling

       //Input
        List<Box> b_result = new List<Box>(); //Output of packed boxes
        List<Box> b0 = new List<Box>();
        List<Box> b1 = new List<Box>();

        DA.GetDataList(0, b0);//Gui to get containers
        DA.GetDataList(1, b1);//Gui to get items

        //Create a list of Container objects, which describes the dimensions of the containers:
        List<Container> containers = new List<Container>();

        for (int i = 0; i < b0.Count; i++) {
            containers.Add(new Container(i, Convert.ToDecimal(b0[i].X.Length), Convert.ToDecimal(b0[i].Z.Length), Convert.ToDecimal(b0[i].Y.Length)));
        }

        //Create a list of items to pack:
        List<Item> itemsToPack = new List<Item>();

        for (int i = 0; i < b1.Count; i++) {
            itemsToPack.Add(new Item(i, Convert.ToDecimal(b1[i].X.Length), Convert.ToDecimal(b1[i].Z.Length), Convert.ToDecimal(b1[i].Y.Length),1));
        }


        //Create a list of algorithm IDs corresponding to the algorithms you would like to use. (Currently EB-AFIT is the only algorithm implemented.) Algorithm IDs are listed in the AlgorithmType enum.
        List<int> algorithms = new List<int>();
        algorithms.Add((int)AlgorithmType.EB_AFIT);

        //Call the Pack method on your container list, item list, and algorithm list:
        List<ContainerPackingResult> result = PackingService.Pack(containers, itemsToPack, algorithms);


        //Extracting values
        for(int i = 0; i < result.Count; i++) {
            
            for (int j = 0; j < result[i].AlgorithmPackingResults.Count; j++) {

                for(int k = 0; k< result[i].AlgorithmPackingResults[j].PackedItems.Count; k++) {
                    Point3d origin = new Point3d(
                        Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].CoordX),
                        Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].CoordY),
                        Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].CoordZ)
                        );
                    origin += b0[result[i].ContainerID].BoundingBox.Min;

                    double x_ = Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].PackDimX);
                    double y_ = Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].PackDimY) ;
                    double z_ = Convert.ToDouble(result[i].AlgorithmPackingResults[j].PackedItems[k].PackDimZ) ;

                    b_result.Add(new Box(
                        new Plane(origin, Vector3d.ZAxis),
                        new Interval(0, x_),
                        new Interval(0, y_),
                        new Interval(0, z_)
                        ));

                }
                
            }
        }

View Results Locally

Rather than sending requests via WebAPI in order to view the results. Do you have the codes so that it may be developed locally? Thank you

Bigger items first?

I have seen this output with the following execution:
Having a container:

Id Length Width Height
1 12 8 8

Having three items:

Id Dim1 Dim2 Dim3 Quantity
3 8 12 2 2
2 8 12 1 1
1 2 4 2 2

Result:

Item Id Coord x Coord y Coord z
3 0 0 0
3 0 2.0 0
1 0 4.0 0
1 4.0 4.0 0
2 0 6.0 0

Which graphically would be this:

image

Is it a way to force the algorithm to use bigger items first so the purple items would be above the red and yellow ones? I'm just trying to achieve a more "human" output of the algorithm without messing up the results.

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.