diff --git a/Packer.php b/Packer.php index b4a2a5fc..b9438ca1 100644 --- a/Packer.php +++ b/Packer.php @@ -284,6 +284,23 @@ public function packIntoBox(Box $aBox, ItemList $aItems) { $layerWidth = max($itemLength, $layerWidth); } $layerDepth = max($layerDepth, $itemToPack->getDepth()); //greater than 0, items will always be less deep + + //allow items to be stacked in place within the same footprint up to current layerdepth + $maxStackDepth = $layerDepth - $itemToPack->getDepth(); + while(!$aItems->isEmpty()) { + $potentialStackItem = $aItems->top(); + if ($potentialStackItem->getDepth() <= $maxStackDepth && + $potentialStackItem->getWeight() <= $remainingWeight && + $potentialStackItem->getWidth() <= $itemToPack->getWidth() && + $potentialStackItem->getLength() <= $itemToPack->getLength()) { + $remainingWeight -= $potentialStackItem->getWeight(); + $maxStackDepth -= $potentialStackItem->getDepth(); + $packedItems->insert($aItems->extract()); + } + else { + break; + } + } } else { if ($remainingWidth >= min($itemWidth, $itemLength) && $layerDepth > 0) { diff --git a/tests/PackerTest.php b/tests/PackerTest.php index d4c97c22..82791ca2 100644 --- a/tests/PackerTest.php +++ b/tests/PackerTest.php @@ -350,6 +350,17 @@ public function testIssue9() { self::assertEquals(1, $packedBoxes->count()); } + public function testIssue11() { + $packer = new Packer(); + $packer->addBox(new TestBox('4x4x4Box', 4, 4, 4, 4, 4, 4, 4, 100)); + + $packer->addItem(new TestItem('BigItem', 2, 2, 4, 1), 2); + $packer->addItem(new TestItem('SmallItem', 1, 1, 1, 1), 32); + $packedBoxes = $packer->pack(); + + self::assertEquals(1, $packedBoxes->count()); + } + public function testIssue13() { $packer = new Packer(); $packer->addBox(new TestBox('Le petite box', 12, 12, 12, 10, 10, 10, 10, 1000));