/// <summary> /// Initializes everything. /// </summary> private void Initialize(Container container, List <Item> items) { itemsToPack = new List <Item>(); itemsPackedInOrder = new List <Item>(); // The original code uses 1-based indexing everywhere. This fake entry is added to the beginning // of the list to make that possible. itemsToPack.Add(new Item(0, 0, 0, 0, 0)); itemsToPackCount = 0; foreach (Item item in container.Items) { if (item.IsPacked) { itemsPackedInOrder.Add(item); } } foreach (Item item in items) { for (int i = 1; i <= item.Quantity; i++) { //ORIGINAL //Item newItem = new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, item.Quantity); //itemsToPack.Add(newItem); //ONLINE itemsToPack.Add(item); if (item.IsPacked) { itemsPackedInOrder.Add(item); } } itemsToPackCount += item.Quantity; } itemsToPack.Add(new Item(0, 0, 0, 0, 0)); totalItemVolume = 0.0M; for (var i = 1; i <= itemsToPackCount; i++) { totalItemVolume = totalItemVolume + itemsToPack[i].Volume; } scrapfirst = new ScrapPad(); scrapfirst.Pre = null; scrapfirst.Post = null; }
/// <summary> /// Finds the first to be packed gap in the layer edge. /// </summary> private void FindSmallestZ() { ScrapPad scrapmemb = scrapfirst; smallestZ = scrapmemb; while (scrapmemb.Post != null) { if (scrapmemb.Post.CumZ < smallestZ.CumZ) { smallestZ = scrapmemb.Post; } scrapmemb = scrapmemb.Post; } }
/// <summary> /// Initializes everything. /// </summary> private void Initialize(Container container, List <Item> items) { itemsToPack = new List <Item>(); itemsPackedInOrder = new List <Item>(); result = new ContainerPackingResult(); // The original code uses 1-based indexing everywhere. This fake entry is added to the beginning // of the list to make that possible. itemsToPack.Add(new Item(0, 0, 0, 0, 0)); layers = new List <Layer>(); itemsToPackCount = 0; foreach (Item item in items) { for (int i = 1; i <= item.Quantity; i++) { Item newItem = new Item(item.ID, item.Dim1, item.Dim2, item.Dim3, item.Quantity); itemsToPack.Add(newItem); } itemsToPackCount += item.Quantity; } itemsToPack.Add(new Item(0, 0, 0, 0, 0)); totalContainerVolume = container.Length * container.Height * container.Width; totalItemVolume = 0.0M; for (x = 1; x <= itemsToPackCount; x++) { totalItemVolume = totalItemVolume + itemsToPack[x].Volume; } scrapfirst = new ScrapPad(); scrapfirst.Pre = null; scrapfirst.Post = null; packingBest = false; hundredPercentPacked = false; quit = false; }
/// <summary> /// Packs the boxes found and arranges all variables and records properly. /// </summary> private void PackLayer() { decimal lenx; decimal lenz; decimal lpz; if (layerThickness == 0) { packing = false; return; } scrapfirst.CumX = px; scrapfirst.CumZ = 0; for (; !quit;) { FindSmallestZ(); if ((smallestZ.Pre == null) && (smallestZ.Post == null)) { //*** SITUATION-1: NO BOXES ON THE RIGHT AND LEFT SIDES *** lenx = smallestZ.CumX; lpz = remainpz - smallestZ.CumZ; FindBox(lenx, layerThickness, remainpy, lpz, lpz); CheckFound(); if (layerDone) { break; } if (evened) { continue; } itemsToPack[cboxi].CoordX = 0; itemsToPack[cboxi].CoordY = packedy; itemsToPack[cboxi].CoordZ = smallestZ.CumZ; if (cboxx == smallestZ.CumX) { smallestZ.CumZ = smallestZ.CumZ + cboxz; } else { smallestZ.Post = new ScrapPad(); smallestZ.Post.Post = null; smallestZ.Post.Pre = smallestZ; smallestZ.Post.CumX = smallestZ.CumX; smallestZ.Post.CumZ = smallestZ.CumZ; smallestZ.CumX = cboxx; smallestZ.CumZ = smallestZ.CumZ + cboxz; } } else if (smallestZ.Pre == null) { //*** SITUATION-2: NO BOXES ON THE LEFT SIDE *** lenx = smallestZ.CumX; lenz = smallestZ.Post.CumZ - smallestZ.CumZ; lpz = remainpz - smallestZ.CumZ; FindBox(lenx, layerThickness, remainpy, lenz, lpz); CheckFound(); if (layerDone) { break; } if (evened) { continue; } itemsToPack[cboxi].CoordY = packedy; itemsToPack[cboxi].CoordZ = smallestZ.CumZ; if (cboxx == smallestZ.CumX) { itemsToPack[cboxi].CoordX = 0; if (smallestZ.CumZ + cboxz == smallestZ.Post.CumZ) { smallestZ.CumZ = smallestZ.Post.CumZ; smallestZ.CumX = smallestZ.Post.CumX; trash = smallestZ.Post; smallestZ.Post = smallestZ.Post.Post; if (smallestZ.Post != null) { smallestZ.Post.Pre = smallestZ; } } else { smallestZ.CumZ = smallestZ.CumZ + cboxz; } } else { itemsToPack[cboxi].CoordX = smallestZ.CumX - cboxx; if (smallestZ.CumZ + cboxz == smallestZ.Post.CumZ) { smallestZ.CumX = smallestZ.CumX - cboxx; } else { smallestZ.Post.Pre = new ScrapPad(); smallestZ.Post.Pre.Post = smallestZ.Post; smallestZ.Post.Pre.Pre = smallestZ; smallestZ.Post = smallestZ.Post.Pre; smallestZ.Post.CumX = smallestZ.CumX; smallestZ.CumX = smallestZ.CumX - cboxx; smallestZ.Post.CumZ = smallestZ.CumZ + cboxz; } } } else if (smallestZ.Post == null) { //*** SITUATION-3: NO BOXES ON THE RIGHT SIDE *** lenx = smallestZ.CumX - smallestZ.Pre.CumX; lenz = smallestZ.Pre.CumZ - smallestZ.CumZ; lpz = remainpz - smallestZ.CumZ; FindBox(lenx, layerThickness, remainpy, lenz, lpz); CheckFound(); if (layerDone) { break; } if (evened) { continue; } itemsToPack[cboxi].CoordY = packedy; itemsToPack[cboxi].CoordZ = smallestZ.CumZ; itemsToPack[cboxi].CoordX = smallestZ.Pre.CumX; if (cboxx == smallestZ.CumX - smallestZ.Pre.CumX) { if (smallestZ.CumZ + cboxz == smallestZ.Pre.CumZ) { smallestZ.Pre.CumX = smallestZ.CumX; smallestZ.Pre.Post = null; } else { smallestZ.CumZ = smallestZ.CumZ + cboxz; } } else { if (smallestZ.CumZ + cboxz == smallestZ.Pre.CumZ) { smallestZ.Pre.CumX = smallestZ.Pre.CumX + cboxx; } else { smallestZ.Pre.Post = new ScrapPad(); smallestZ.Pre.Post.Pre = smallestZ.Pre; smallestZ.Pre.Post.Post = smallestZ; smallestZ.Pre = smallestZ.Pre.Post; smallestZ.Pre.CumX = smallestZ.Pre.Pre.CumX + cboxx; smallestZ.Pre.CumZ = smallestZ.CumZ + cboxz; } } } else if (smallestZ.Pre.CumZ == smallestZ.Post.CumZ) { //*** SITUATION-4: THERE ARE BOXES ON BOTH OF THE SIDES *** //*** SUBSITUATION-4A: SIDES ARE EQUAL TO EACH OTHER *** lenx = smallestZ.CumX - smallestZ.Pre.CumX; lenz = smallestZ.Pre.CumZ - smallestZ.CumZ; lpz = remainpz - smallestZ.CumZ; FindBox(lenx, layerThickness, remainpy, lenz, lpz); CheckFound(); if (layerDone) { break; } if (evened) { continue; } itemsToPack[cboxi].CoordY = packedy; itemsToPack[cboxi].CoordZ = smallestZ.CumZ; if (cboxx == smallestZ.CumX - smallestZ.Pre.CumX) { itemsToPack[cboxi].CoordX = smallestZ.Pre.CumX; if (smallestZ.CumZ + cboxz == smallestZ.Post.CumZ) { smallestZ.Pre.CumX = smallestZ.Post.CumX; if (smallestZ.Post.Post != null) { smallestZ.Pre.Post = smallestZ.Post.Post; smallestZ.Post.Post.Pre = smallestZ.Pre; } else { smallestZ.Pre.Post = null; } } else { smallestZ.CumZ = smallestZ.CumZ + cboxz; } } else if (smallestZ.Pre.CumX < px - smallestZ.CumX) { if (smallestZ.CumZ + cboxz == smallestZ.Pre.CumZ) { smallestZ.CumX = smallestZ.CumX - cboxx; itemsToPack[cboxi].CoordX = smallestZ.CumX - cboxx; } else { itemsToPack[cboxi].CoordX = smallestZ.Pre.CumX; smallestZ.Pre.Post = new ScrapPad(); smallestZ.Pre.Post.Pre = smallestZ.Pre; smallestZ.Pre.Post.Post = smallestZ; smallestZ.Pre = smallestZ.Pre.Post; smallestZ.Pre.CumX = smallestZ.Pre.Pre.CumX + cboxx; smallestZ.Pre.CumZ = smallestZ.CumZ + cboxz; } } else { if (smallestZ.CumZ + cboxz == smallestZ.Pre.CumZ) { smallestZ.Pre.CumX = smallestZ.Pre.CumX + cboxx; itemsToPack[cboxi].CoordX = smallestZ.Pre.CumX; } else { itemsToPack[cboxi].CoordX = smallestZ.CumX - cboxx; smallestZ.Post.Pre = new ScrapPad(); smallestZ.Post.Pre.Post = smallestZ.Post; smallestZ.Post.Pre.Pre = smallestZ; smallestZ.Post = smallestZ.Post.Pre; smallestZ.Post.CumX = smallestZ.CumX; smallestZ.Post.CumZ = smallestZ.CumZ + cboxz; smallestZ.CumX = smallestZ.CumX - cboxx; } } } else { //*** SUBSITUATION-4B: SIDES ARE NOT EQUAL TO EACH OTHER *** lenx = smallestZ.CumX - smallestZ.Pre.CumX; lenz = smallestZ.Pre.CumZ - smallestZ.CumZ; lpz = remainpz - smallestZ.CumZ; FindBox(lenx, layerThickness, remainpy, lenz, lpz); CheckFound(); if (layerDone) { break; } if (evened) { continue; } itemsToPack[cboxi].CoordY = packedy; itemsToPack[cboxi].CoordZ = smallestZ.CumZ; itemsToPack[cboxi].CoordX = smallestZ.Pre.CumX; if (cboxx == (smallestZ.CumX - smallestZ.Pre.CumX)) { if ((smallestZ.CumZ + cboxz) == smallestZ.Pre.CumZ) { smallestZ.Pre.CumX = smallestZ.CumX; smallestZ.Pre.Post = smallestZ.Post; smallestZ.Post.Pre = smallestZ.Pre; } else { smallestZ.CumZ = smallestZ.CumZ + cboxz; } } else { if ((smallestZ.CumZ + cboxz) == smallestZ.Pre.CumZ) { smallestZ.Pre.CumX = smallestZ.Pre.CumX + cboxx; } else if (smallestZ.CumZ + cboxz == smallestZ.Post.CumZ) { itemsToPack[cboxi].CoordX = smallestZ.CumX - cboxx; smallestZ.CumX = smallestZ.CumX - cboxx; } else { smallestZ.Pre.Post = new ScrapPad(); smallestZ.Pre.Post.Pre = smallestZ.Pre; smallestZ.Pre.Post.Post = smallestZ; smallestZ.Pre = smallestZ.Pre.Post; smallestZ.Pre.CumX = smallestZ.Pre.Pre.CumX + cboxx; smallestZ.Pre.CumZ = smallestZ.CumZ + cboxz; } } } VolumeCheck(); } }
/// <summary> /// After finding each box, the candidate boxes and the condition of the layer are examined. /// </summary> private void CheckFound() { evened = false; if (boxi != 0) { cboxi = boxi; cboxx = boxx; cboxy = boxy; cboxz = boxz; } else { if ((bboxi > 0) && (layerinlayer != 0 || (smallestZ.Pre == null && smallestZ.Post == null))) { if (layerinlayer == 0) { prelayer = layerThickness; lilz = smallestZ.CumZ; } cboxi = bboxi; cboxx = bboxx; cboxy = bboxy; cboxz = bboxz; layerinlayer = layerinlayer + bboxy - layerThickness; layerThickness = bboxy; } else { if (smallestZ.Pre == null && smallestZ.Post == null) { layerDone = true; } else { evened = true; if (smallestZ.Pre == null) { trash = smallestZ.Post; smallestZ.CumX = smallestZ.Post.CumX; smallestZ.CumZ = smallestZ.Post.CumZ; smallestZ.Post = smallestZ.Post.Post; if (smallestZ.Post != null) { smallestZ.Post.Pre = smallestZ; } } else if (smallestZ.Post == null) { smallestZ.Pre.Post = null; smallestZ.Pre.CumX = smallestZ.CumX; } else { if (smallestZ.Pre.CumZ == smallestZ.Post.CumZ) { smallestZ.Pre.Post = smallestZ.Post.Post; if (smallestZ.Post.Post != null) { smallestZ.Post.Post.Pre = smallestZ.Pre; } smallestZ.Pre.CumX = smallestZ.Post.CumX; } else { smallestZ.Pre.Post = smallestZ.Post; smallestZ.Post.Pre = smallestZ.Pre; if (smallestZ.Pre.CumZ < smallestZ.Post.CumZ) { smallestZ.Pre.CumX = smallestZ.CumX; } } } } } } }