Ejemplo n.º 1
0
        private void TryAndStackItemsIntoSpace(PackedLayer layer,
                                               PackedItem prevItem,
                                               ItemList nextItems,
                                               int maxWidth,
                                               int maxLength,
                                               int maxDepth,
                                               int x,
                                               int y,
                                               int z,
                                               int rowLength
                                               )
        {
            while (items.Count() > 0 && CheckNonDimensionalConstraints(items.Top()))
            {
                var stackedItem = GetOrientationForItem(
                    items.Top(),
                    prevItem,
                    nextItems,
                    items.Count == 1,
                    maxWidth,
                    maxLength,
                    maxDepth,
                    rowLength,
                    x,
                    y,
                    z
                    );

                if (stackedItem != null)
                {
                    remainingWeight -= items.Top().Weight;

                    layer.Insert(PackedItem.FromOrientatedItem(stackedItem, x, y, z));
                    items.Extract();

                    maxDepth -= stackedItem.Depth;
                    z        += stackedItem.Depth;
                }
                else
                {
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Pack items into an individual vertical layer.
        /// </summary>
        /// <param name="startDepth"></param>
        /// <param name="widthLeft"></param>
        /// <param name="lengthLeft"></param>
        /// <param name="depthLeft"></param>
        protected void PackLayer(int startDepth, int widthLeft, int lengthLeft, int depthLeft)
        {
            var newLayer = new PackedLayer();

            layers.Add(newLayer);

            int x, y, rowWidth, rowLength, layerDepth;

            x = y = rowWidth = rowLength = layerDepth = 0;

            PackedItem prevItem = null;

            while (items.Count > 0)
            {
                var itemToPack = items.Extract();

                //skip items that are simply too heavy or too large
                if (!CheckNonDimensionalConstraints(itemToPack))
                {
                    RebuildItemList();
                    continue;
                }

                var orientedItem = GetOrientationForItem(itemToPack,
                                                         prevItem,
                                                         items,
                                                         !HasItemsLeftToPack(),
                                                         widthLeft,
                                                         lengthLeft,
                                                         depthLeft,
                                                         rowLength,
                                                         x,
                                                         y,
                                                         startDepth
                                                         );

                if (orientedItem != null)
                {
                    var packedItem = PackedItem.FromOrientatedItem(orientedItem, x, y, startDepth);
                    newLayer.Insert(packedItem);
                    remainingWeight -= orientedItem.Item.Weight;
                    widthLeft       -= orientedItem.Width;

                    rowWidth  += orientedItem.Width;
                    rowLength  = Math.Max(rowLength, orientedItem.Length);
                    layerDepth = Math.Max(layerDepth, orientedItem.Depth);

                    //allow items to be stacked in place within the same footprint up to current layer depth
                    var stackableDepth = layerDepth - orientedItem.Depth;
                    TryAndStackItemsIntoSpace(newLayer,
                                              prevItem,
                                              items,
                                              orientedItem.Width,
                                              orientedItem.Length,
                                              stackableDepth,
                                              x,
                                              y,
                                              startDepth + orientedItem.Depth,
                                              rowLength
                                              );
                    x += orientedItem.Width;

                    prevItem = packedItem;
                    if (items.Count == 0)
                    {
                        RebuildItemList();
                    }
                }
                else if (newLayer.Items.Count == 0)
                {
                    // zero items on layer
                    // doesn't fit on layer even when empty, skipping for good
                    continue;
                }
                else if (widthLeft > 0 && items.Count > 0)
                {
                    // skip for now, move on to the next item
                    skippedItems.Add(itemToPack);

                    // abandon here if next item is the same, no point trying to keep going. Last time is not skipped, need that to trigger appropriate reset logic
                    while (items.Count > 2 && orientatedItemFactory.IsSameDimensions(itemToPack, items.Top()))
                    {
                        this.skippedItems.Add(items.Extract());
                    }
                }
                else if (x > 0 && lengthLeft >= Math.Min(Math.Min(itemToPack.Width, itemToPack.Length), itemToPack.Depth))
                {
                    // No more fit in width wise, resetting for new row
                    widthLeft  += rowWidth;
                    lengthLeft -= rowLength;
                    y          += rowLength;
                    x           = rowWidth = rowLength = 0;
                    skippedItems.Add(itemToPack);
                    RebuildItemList();
                    prevItem = null;
                    continue;
                }
                else
                {
                    // no items fit, so starting next vertical layer
                    skippedItems.Add(itemToPack);
                    RebuildItemList();
                    return;
                }
            }
        }