private void CheckPosition(LayerPosition bPosition) { if (!bPosition.IsValid) { throw new GraphicsException("Invalid BoxPosition: can not create box"); } }
/// <summary> /// if box bottom oriented to Z+, reverse box /// </summary> private LayerPosition AdjustLayerPosition(LayerPosition layerPos) { LayerPosition layerPosTemp = layerPos; if (layerPosTemp.HeightAxis == HalfAxis.HAxis.AXIS_Z_N) { if (layerPosTemp.LengthAxis == HalfAxis.HAxis.AXIS_X_P) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_Y_P; layerPosTemp.Position += new Vector3D(0.0, -_bProperties.Width, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_Y_P) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_X_N; layerPosTemp.Position += new Vector3D(_bProperties.Width, 0.0, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_X_N) { layerPosTemp.LengthAxis = HalfAxis.HAxis.AXIS_X_P; layerPosTemp.Position += new Vector3D(-_bProperties.Length, 0.0, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_Y_N) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_X_P; layerPosTemp.Position += new Vector3D(-_bProperties.Width, 0.0, -_bProperties.Height); } } return(layerPosTemp); }
/// <summary> /// if box bottom oriented to Z+, reverse box /// </summary> private LayerPosition AdjustLayerPosition(LayerPosition layerPos) { LayerPosition layerPosTemp = layerPos; if (layerPosTemp.HeightAxis == HalfAxis.HAxis.AXIS_Z_N) { if (layerPosTemp.LengthAxis == HalfAxis.HAxis.AXIS_X_P) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_Y_P; layerPosTemp.Position += new Vector3D(0.0, -_bProperties.Width, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_Y_P) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_X_N; layerPosTemp.Position += new Vector3D(_bProperties.Width, 0.0, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_X_N) { layerPosTemp.LengthAxis = HalfAxis.HAxis.AXIS_X_P; layerPosTemp.Position += new Vector3D(-_bProperties.Length, 0.0, -_bProperties.Height); } else if (layerPos.LengthAxis == HalfAxis.HAxis.AXIS_Y_N) { layerPosTemp.WidthAxis = HalfAxis.HAxis.AXIS_X_P; layerPosTemp.Position += new Vector3D(-_bProperties.Width, 0.0, -_bProperties.Height); } } return layerPosTemp; }
public Box(uint pickId, Packable packable, LayerPosition bPosition) { if (!bPosition.IsValid) { throw new GraphicsException("Invalid BoxPosition: can not create box"); } _pickId = pickId; _dim[0] = packable.Length; _dim[1] = packable.Width; _dim[2] = packable.Height; // set position Position = bPosition.Position; // set direction length LengthAxis = HalfAxis.ToVector3D(bPosition.LengthAxis); // set direction width WidthAxis = HalfAxis.ToVector3D(bPosition.WidthAxis); _colors = Enumerable.Repeat <Color>(Color.Chocolate, 6).ToArray(); BProperties bProperties = packable as BProperties; if (null != bProperties) { _colors = bProperties.Colors; BoxProperties boxProperties = packable as BoxProperties; if (null != boxProperties) { List <Pair <HalfAxis.HAxis, Texture> > textures = boxProperties.TextureList; foreach (Pair <HalfAxis.HAxis, Texture> tex in textures) { int iIndex = (int)tex.first; if (null == _textureLists[iIndex]) { _textureLists[iIndex] = new List <Texture>(); } _textureLists[iIndex].Add(tex.second); } _showTape = boxProperties.ShowTape; _tapeWidth = boxProperties.TapeWidth; _tapeColor = boxProperties.TapeColor; } // IsBundle ? _isBundle = bProperties.IsBundle; if (bProperties.IsBundle) { BundleProperties bundleProp = packable as BundleProperties; if (null != bundleProp) { _noFlats = bundleProp.NoFlats; } } } PackProperties packProperties = packable as PackProperties; if (null != packProperties) { } }
public Pack(uint pickId, PackProperties packProperties, LayerPosition position) : base(pickId, packProperties, position) { _packProperties = packProperties; _arrangement = _packProperties.Arrangement; _innerBox = new Box(0, packProperties.Box); _forceTransparency = false; }
public void ShouldGetTheNewPosition() { var position = TimeCode.FromSeconds(60d, SmpteFrameRate.Smpte2997NonDrop); var layerPosition = new LayerPosition { Position = position }; Assert.AreEqual(position, layerPosition.Position); }
public void ShouldGetTheLayerType() { var trackType = TrackType.Visual; var layerPosition = new LayerPosition { LayerType = trackType }; Assert.AreEqual(trackType, layerPosition.LayerType); }
public Box(uint pickId, PackableBrick packable, LayerPosition bPosition) { // sanity checks CheckPosition(bPosition); // dimensions PickId = pickId; _dim[0] = packable.Length; _dim[1] = packable.Width; _dim[2] = packable.Height; // weight _weight = packable.Weight; // set position BoxPosition = new BoxPosition(bPosition.Position, bPosition.LengthAxis, bPosition.WidthAxis); // colors Colors = Enumerable.Repeat <Color>(Color.Chocolate, 6).ToArray(); BProperties bProperties = PackableToBProperties(packable); if (null != bProperties) { Colors = bProperties.Colors; if (bProperties is BoxProperties boxProperties) { List <Pair <HalfAxis.HAxis, Texture> > textures = boxProperties.TextureList; foreach (Pair <HalfAxis.HAxis, Texture> tex in textures) { int iIndex = (int)tex.first; if (null == TextureLists[iIndex]) { TextureLists[iIndex] = new List <Texture>(); } TextureLists[iIndex].Add(tex.second); } TapeWidth = boxProperties.TapeWidth; TapeColor = boxProperties.TapeColor; _showTopLabel = boxProperties.ShowTopLabel; } // IsBundle ? IsBundle = bProperties.IsBundle; if (bProperties.IsBundle) { BundleProperties bundleProp = packable as BundleProperties; if (null != bundleProp) { BundleFlats = bundleProp.NoFlats; } } } if (packable is PackProperties packProperties) { } }
private void OnTileChanged(string layer, int x, int y) { var layerPos = new LayerPosition(layer, x, y); if (this.tileLights.TryGetValue(layerPos, out var lastLight)) { this.Penumbra.Lights.Remove(lastLight); this.tileLights.Remove(layerPos); } var tile = this.GetTile(x, y, layer); if (tile.IsBlank) { return; } var tileset = tile.GetTileset(this.Tiles); var tilesetTile = tileset.GetTilesetTile(tile, this.Tiles); var light = this.CreateTileLight(x + 0.5F, y + 0.5F, tilesetTile); if (light != null) { this.tileLights.Add(layerPos, light); this.Penumbra.Lights.Add(light); } foreach (var obj in tilesetTile.Objects) { if (obj.Name == "Hull") { this.Penumbra.Hulls.Add(new Hull(new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1)) { Position = obj.Position + new Vector2(x, y) * this.TileSize, Scale = obj.Size }); } } }
public void ShowWarningTooltip(string text, LayerPosition layerPosition) { }
private List <BoxCaseSolution> GenerateSolutions() { List <BoxCaseSolution> solutions = new List <BoxCaseSolution>(); int[] patternColumnCount = new int[6]; // loop throw all patterns foreach (LayerPattern pattern in LayerPattern.All) { // loop through all vertical axes for (int i = 0; i < 6; ++i) { HalfAxis.HAxis axisOrtho = (HalfAxis.HAxis)i; if (!_constraintSet.AllowOrthoAxis(axisOrtho)) { continue; } try { // build layer Layer2D layer = BuildLayer(_bProperties, _caseProperties, axisOrtho, false); double actualLength = 0.0, actualWidth = 0.0; if (!pattern.GetLayerDimensionsChecked(layer, out actualLength, out actualWidth)) { continue; } pattern.GenerateLayer(layer, actualLength, actualWidth); string title = string.Empty; BoxCaseSolution sol = new BoxCaseSolution(null, axisOrtho, pattern.Name); double offsetX = 0.5 * (_caseProperties.Length - _caseProperties.InsideLength); double offsetY = 0.5 * (_caseProperties.Width - _caseProperties.InsideWidth); double zLayer = 0.5 * (_caseProperties.Height - _caseProperties.InsideHeight); bool maxWeightReached = _constraintSet.UseMaximumCaseWeight && (_caseProperties.Weight + _bProperties.Weight > _constraintSet.MaximumCaseWeight); bool maxHeightReached = _bProperties.Dimension(axisOrtho) > _caseProperties.InsideHeight; bool maxNumberReached = false; int boxCount = 0; while (!maxWeightReached && !maxHeightReached && !maxNumberReached) { BoxLayer bLayer = sol.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in layer) { // increment ++boxCount; if (maxNumberReached = _constraintSet.UseMaximumNumberOfBoxes && (boxCount > _constraintSet.MaximumNumberOfBoxes)) { break; } double weight = _caseProperties.Weight + boxCount * _bProperties.Weight; maxWeightReached = _constraintSet.UseMaximumCaseWeight && weight > _constraintSet.MaximumCaseWeight; if (maxWeightReached) { break; } // insert new box in current layer LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position + offsetX * Vector3D.XAxis + offsetY * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); bLayer.Add(boxPos); } zLayer += layer.BoxHeight; if (!maxWeightReached && !maxNumberReached) { maxHeightReached = zLayer + layer.BoxHeight > 0.5 * (_caseProperties.Height + _caseProperties.InsideHeight); } } // set maximum criterion if (maxNumberReached) { sol.LimitReached = BoxCaseSolution.Limit.LIMIT_MAXNUMBERREACHED; } else if (maxWeightReached) { sol.LimitReached = BoxCaseSolution.Limit.LIMIT_MAXWEIGHTREACHED; } else if (maxHeightReached) { sol.LimitReached = BoxCaseSolution.Limit.LIMIT_MAXHEIGHTREACHED; } if (string.Equals(pattern.Name, "Column", StringComparison.CurrentCultureIgnoreCase)) { patternColumnCount[i] = Math.Max(patternColumnCount[i], sol.BoxPerCaseCount); } // insert solution if (sol.BoxPerCaseCount >= patternColumnCount[i]) { solutions.Add(sol); } } catch (NotImplementedException) { _log.Info(string.Format("Pattern {0} is not implemented", pattern.Name)); } catch (Exception ex) { _log.Error(string.Format("Exception caught: {0}", ex.Message)); } } // loop through all vertical axes } // loop through all patterns // sort solutions solutions.Sort(); /* * // removes solutions that do not equal the best number * if (solutions.Count > 0) * { * int indexFrom = 0, maxCount = solutions[0].BoxPerCaseCount; * while (indexFrom < solutions.Count && solutions[indexFrom].BoxPerCaseCount == maxCount) ++indexFrom; * solutions.RemoveRange(indexFrom, solutions.Count - indexFrom); * } */ return(solutions); }
private List <PackPalletSolution> GenerateSolutions() { var solutions = new List <PackPalletSolution>(); HalfAxis.HAxis[] axes = { HalfAxis.HAxis.AXIS_Z_N, HalfAxis.HAxis.AXIS_Z_P }; // loop throught all patterns foreach (LayerPatternBox pattern in LayerPatternBox.All) { // loop throught all axes foreach (HalfAxis.HAxis axis in axes) // axis { // loop through Layer2D layer = BuildLayer(_packProperties, _palletProperties, _constraintSet, axis, false, false); double actualLength = 0.0, actualWidth = 0.0; if (!pattern.GetLayerDimensionsChecked(layer, out actualLength, out actualWidth)) { continue; } pattern.GenerateLayer(layer, actualLength, actualWidth); // filter by layer weight if (_constraintSet.MaximumLayerWeight.Activated && (layer.Count * _packProperties.Weight > _constraintSet.MaximumLayerWeight.Value)) { continue; } // filter by maximum space if (_constraintSet.MaximumSpaceAllowed.Activated && layer.MaximumSpace > _constraintSet.MaximumSpaceAllowed.Value) { continue; } double layerHeight = layer.BoxHeight; string title = string.Format("{0}-{1}", pattern.Name, axis); double zLayer = 0.0; var boxLayer = new Layer3DBox(zLayer, 0); foreach (LayerPosition layerPos in layer) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); var boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); boxLayer.Add(boxPos); } boxLayer.MaximumSpace = layer.MaximumSpace; BBox3D layerBBox = boxLayer.BoundingBox(_packProperties); // filter by overhangX if (_constraintSet.MinOverhangX.Activated && (0.5 * (layerBBox.Length - _palletProperties.Length) < _constraintSet.MinOverhangX.Value)) { continue; } // filter by overhangY if (_constraintSet.MinOverhangY.Activated && (0.5 * (layerBBox.Width - _palletProperties.Width) < _constraintSet.MinOverhangY.Value)) { continue; } double interlayerThickness = null != _interlayerProperties ? _interlayerProperties.Thickness : 0; double interlayerWeight = null != _interlayerProperties ? _interlayerProperties.Weight : 0; var sol = new PackPalletSolution(null, title, boxLayer); int noLayer = 1, noInterlayer = (null != _interlayerProperties && _constraintSet.HasFirstInterlayer) ? 1 : 0; bool maxHeightReached = _constraintSet.MaximumPalletHeight.Activated && (_packProperties.Height + noInterlayer * interlayerThickness + noLayer * layer.BoxHeight) > _constraintSet.MaximumPalletHeight.Value; bool maxWeightReached = _constraintSet.MaximumPalletWeight.Activated && (_palletProperties.Weight + noInterlayer * interlayerWeight + noLayer * boxLayer.Count * _packProperties.Weight > _constraintSet.MaximumPalletWeight.Value); noLayer = 0; noInterlayer = 0; int iCountInterlayer = 0, iCountSwap = 1; bool bSwap = false; while (!maxHeightReached && !maxWeightReached) { bool bInterlayer = (0 == iCountInterlayer) && ((noLayer != 0) || _constraintSet.HasFirstInterlayer); // actually insert new layer sol.AddLayer(bSwap, bInterlayer); // increment number of layers noLayer++; noInterlayer += (bInterlayer ? 1 : 0); // update iCountInterlayer && iCountSwap ++iCountInterlayer; if (iCountInterlayer >= _constraintSet.InterlayerPeriod) { iCountInterlayer = 0; } ++iCountSwap; if (iCountSwap > _constraintSet.LayerSwapPeriod) { iCountSwap = 1; bSwap = !bSwap; } // update maxHeightReached & maxWeightReached maxHeightReached = _constraintSet.MaximumPalletHeight.Activated && (_palletProperties.Height + (noInterlayer + (iCountInterlayer == 0 ? 1 : 0)) * interlayerThickness + (noLayer + 1) * layer.BoxHeight) > _constraintSet.MaximumPalletHeight.Value; maxWeightReached = _constraintSet.MaximumPalletWeight.Activated && (_palletProperties.Weight + (noInterlayer + (iCountInterlayer == 0 ? 1 : 0)) * interlayerWeight + (noLayer + 1) * boxLayer.Count * _packProperties.Weight > _constraintSet.MaximumPalletWeight.Value); } if (sol.PackCount > 0) { solutions.Add(sol); } } // axis } // pattern solutions.Sort(); return(solutions); }
/// <summary> /// build optimal solutions with 2 layer types /// </summary> /// <returns></returns> private List <CasePalletSolution> GenerateOptimizedCombinationOfLayers() { List <CasePalletSolution> solutions = new List <CasePalletSolution>(); // generate best layers Layer2D[] bestLayers = new Layer2D[3]; bestLayers[0] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_X_P); bestLayers[1] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_Y_P); bestLayers[2] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_Z_P); string[] dir = { "X", "Y", "Z" }; for (int i = 0; i < 3; ++i) { HalfAxis.HAxis axisOrtho = (HalfAxis.HAxis)(2 * i + 1); HalfAxis.HAxis axis0 = (HalfAxis.HAxis)((2 * (i + 1)) % 6 + 1); HalfAxis.HAxis axis1 = (HalfAxis.HAxis)((2 * (i + 2)) % 6 + 1); int noLayer0 = 0, noLayer1 = 0; if (GetOptimalRequest( _bProperties.Dimension(axis0), bestLayers[i % 3].Count , _bProperties.Dimension(axis1), bestLayers[(i + 1) % 3].Count , out noLayer0, out noLayer1)) { Layer2D layer0 = bestLayers[i % 3]; Layer2D layer1 = bestLayers[(i + 1) % 3]; // sol0 CasePalletSolution sol0 = new CasePalletSolution(null, string.Format("combination_{0}{1}", dir[i % 3], dir[(i % 3) + 1]), false); double zLayer = _palletProperties.Height; double cornerThickness = null != _cornerProperties ? _cornerProperties.Thickness : 0.0; for (int j = 0; j < noLayer0; ++j) { Layer3DBox layer = sol0.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in layer0) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - 0.5 * _constraintSet.OverhangX * Vector3D.XAxis - 0.5 * _constraintSet.OverhangY * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } zLayer += layer0.BoxHeight; } for (int j = 0; j < noLayer1; ++j) { Layer3DBox layer = sol0.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in layer1) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX - cornerThickness) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY - cornerThickness) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } zLayer += layer1.BoxHeight; } solutions.Add(sol0); // sol1 CasePalletSolution sol1 = new CasePalletSolution(null, string.Format("combination_{0}{1}", dir[i % 3], dir[(i % 3) + 1]), false); zLayer = _palletProperties.Height; for (int j = 0; j < noLayer0; ++j) { Layer3DBox layer = sol1.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in layer1) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX - cornerThickness) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY - cornerThickness) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } zLayer += layer1.BoxHeight; } for (int j = 0; j < noLayer1; ++j) { Layer3DBox layer = sol1.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in layer0) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX - cornerThickness) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY - cornerThickness) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } zLayer += layer0.BoxHeight; } solutions.Add(sol1); } } return(solutions); }
private List <CasePalletSolution> GenerateSolutions() { // generate best layers Layer2D[] bestLayers = new Layer2D[3]; if (_constraintSet.AllowLastLayerOrientationChange) { bestLayers[0] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_X_P); bestLayers[1] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_Y_P); bestLayers[2] = GenerateBestLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, HalfAxis.HAxis.AXIS_Z_P); } List <CasePalletSolution> solutions = new List <CasePalletSolution>(); // loop through all patterns foreach (LayerPatternBox pattern in LayerPatternBox.All) { if (!_constraintSet.AllowPattern(pattern.Name)) { continue; } // loop through all swap positions (if layer can be swapped) for (int swapPos = 0; swapPos < (pattern.CanBeSwapped ? 2 : 1); ++swapPos) { // loop through all vertical axes for (int i = 0; i < 3; ++i) { HalfAxis.HAxis axisOrtho1 = (HalfAxis.HAxis)(2 * i); HalfAxis.HAxis axisOrtho2 = (HalfAxis.HAxis)(2 * i + 1); if (!_constraintSet.AllowOrthoAxis(axisOrtho2)) { continue; } try { // build 2 layers (pallet length/width) Layer2D layer1 = BuildLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, axisOrtho1, swapPos == 1, false); Layer2D layer1_inv = BuildLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, axisOrtho1, swapPos == 1, true); Layer2D layer2 = BuildLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, axisOrtho2, swapPos == 1, false); Layer2D layer2_inv = BuildLayer(_bProperties, _palletProperties, _cornerProperties, _constraintSet, axisOrtho2, swapPos == 1, true); double actualLength1 = 0.0, actualLength2 = 0.0, actualWidth1 = 0.0, actualWidth2 = 0.0; bool bResult1 = pattern.GetLayerDimensionsChecked(layer1, out actualLength1, out actualWidth1); bool bResult2 = pattern.GetLayerDimensionsChecked(layer2, out actualLength2, out actualWidth2); string layerAlignment = string.Empty; for (int j = 0; j < 6; ++j) { Layer2D layer1T = null, layer2T = null; if (0 == j && _constraintSet.AllowAlignedLayers && bResult1) { pattern.GenerateLayer(layer1, actualLength1, actualWidth1); layer1T = layer1; layer2T = layer1; layerAlignment = "aligned-1"; } else if (1 == j && _constraintSet.AllowAlignedLayers && bResult2) { pattern.GenerateLayer(layer2, actualLength2, actualWidth2); layer1T = layer2; layer2T = layer2; layerAlignment = "aligned-2"; } else if (2 == j && _constraintSet.AllowAlternateLayers && bResult1 && bResult2) { pattern.GenerateLayer(layer1, Math.Max(actualLength1, actualLength2), Math.Max(actualWidth1, actualWidth2)); pattern.GenerateLayer(layer2, Math.Max(actualLength1, actualLength2), Math.Max(actualWidth1, actualWidth2)); layer1T = layer1; layer2T = layer2; layerAlignment = "alternate-12"; } else if (3 == j && _constraintSet.AllowAlternateLayers && bResult1 && bResult2) { pattern.GenerateLayer(layer1, Math.Max(actualLength1, actualLength2), Math.Max(actualWidth1, actualWidth2)); pattern.GenerateLayer(layer2, Math.Max(actualLength1, actualLength2), Math.Max(actualWidth1, actualWidth2)); layer1T = layer2; layer2T = layer1; layerAlignment = "alternate-21"; } else if (4 == j && _constraintSet.AllowAlternateLayers && pattern.CanBeInverted && bResult1) { pattern.GenerateLayer(layer1, actualLength1, actualWidth1); pattern.GenerateLayer(layer1_inv, actualLength1, actualWidth1); layer1T = layer1; layer2T = layer1_inv; layerAlignment = "inv-1"; } else if (5 == j && _constraintSet.AllowAlternateLayers && pattern.CanBeInverted && bResult2) { pattern.GenerateLayer(layer2, actualLength2, actualWidth2); pattern.GenerateLayer(layer2_inv, actualLength2, actualWidth2); layer1T = layer2; layer2T = layer2_inv; layerAlignment = "inv-2"; } if (null == layer1T || null == layer2T || 0 == layer1T.Count || 0 == layer2T.Count) { continue; } // counters string axisName = string.Empty; switch (i) { case 0: axisName = "X"; break; case 1: axisName = "Y"; break; case 2: axisName = "Z"; break; default: break; } string title = string.Format("{0}-{1}-{2}{3}", pattern.Name, axisName, layerAlignment, swapPos == 1 ? "-swapped" : ""); CasePalletSolution sol = new CasePalletSolution(null, title, layer1T == layer2T); int iLayerIndex = 0; double zLayer = _palletProperties.Height; double capThickness = null != _capProperties ? _capProperties.Thickness : 0; int iInterlayer = 0; int iCount = 0; bool maxWeightReached = _constraintSet.UseMaximumPalletWeight && (_palletProperties.Weight + _bProperties.Weight > _constraintSet.MaximumPalletWeight); bool maxHeightReached = _constraintSet.UseMaximumHeight && (zLayer + capThickness + _bProperties.Dimension(axisOrtho1) > _constraintSet.MaximumHeight); bool maxNumberReached = false; // insert anti-slip interlayer id there is one if (_constraintSet.HasInterlayerAntiSlip) { InterlayerPos interlayerPos = sol.CreateNewInterlayer(zLayer, 1); zLayer += _interlayerPropertiesAntiSlip.Thickness; } while (!maxWeightReached && !maxHeightReached && !maxNumberReached) { if (_constraintSet.HasInterlayer) { if (iInterlayer >= _constraintSet.InterlayerPeriod) { InterlayerPos interlayerPos = sol.CreateNewInterlayer(zLayer, 0); zLayer += _interlayerProperties.Thickness; iInterlayer = 0; } ++iInterlayer; } // select current layer type double cornerThickness = null != _cornerProperties ? _cornerProperties.Thickness : 0.0; Layer2D currentLayer = iLayerIndex % 2 == 0 ? layer1T : layer2T; Layer3DBox layer = sol.CreateNewLayer(zLayer, 0); layer.MaximumSpace = currentLayer.MaximumSpace; foreach (LayerPosition layerPos in currentLayer) { ++iCount; maxWeightReached = _constraintSet.UseMaximumPalletWeight && ((iCount * _bProperties.Weight + _palletProperties.Weight) > _constraintSet.MaximumPalletWeight); maxNumberReached = _constraintSet.UseMaximumNumberOfCases && (iCount > _constraintSet.MaximumNumberOfItems); if (!maxWeightReached && !maxNumberReached) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX - cornerThickness) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY - cornerThickness) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } else { break; } } // increment layer index ++iLayerIndex; zLayer += currentLayer.BoxHeight; // check height maxHeightReached = _constraintSet.UseMaximumHeight && (zLayer + _bProperties.Dimension(axisOrtho1) > _constraintSet.MaximumHeight); // check number maxNumberReached = _constraintSet.UseMaximumNumberOfCases && (iCount + 1 > _constraintSet.MaximumNumberOfItems); // check weight maxWeightReached = _constraintSet.UseMaximumPalletWeight && (((iCount + 1) * _bProperties.Weight + _palletProperties.Weight) > _constraintSet.MaximumPalletWeight); } if (maxHeightReached && _constraintSet.AllowLastLayerOrientationChange) { // remaining height double remainingHeight = _constraintSet.MaximumHeight - zLayer; // test to complete with best layer Layer2D bestLayer = null; int ibestLayerCount = 0; for (int iLayerDir = 0; iLayerDir < 3; ++iLayerDir) { // another direction than the current direction if (iLayerDir == i) { continue; } Layer2D layer = bestLayers[iLayerDir]; if (null == layer) { continue; } int layerCount = Convert.ToInt32(Math.Floor(remainingHeight / layer.BoxHeight)); if (layerCount < 1) { continue; } if (null == bestLayer || ibestLayerCount * bestLayer.Count < layerCount * layer.Count) { bestLayer = layer; ibestLayerCount = layerCount; } } if (null != bestLayer) { double cornerThickness = null != _cornerProperties ? _cornerProperties.Thickness : 0.0; for (int iAddLayer = 0; iAddLayer < ibestLayerCount; ++iAddLayer) { Layer3DBox layer = sol.CreateNewLayer(zLayer, 0); foreach (LayerPosition layerPos in bestLayer) { LayerPosition layerPosTemp = AdjustLayerPosition(layerPos); BoxPosition boxPos = new BoxPosition( layerPosTemp.Position - (0.5 * _constraintSet.OverhangX - cornerThickness) * Vector3D.XAxis - (0.5 * _constraintSet.OverhangY - cornerThickness) * Vector3D.YAxis + zLayer * Vector3D.ZAxis , layerPosTemp.LengthAxis , layerPosTemp.WidthAxis ); layer.Add(boxPos); } zLayer += bestLayer.BoxHeight; } } } // set maximum criterion if (maxNumberReached) { sol.LimitReached = CasePalletSolution.Limit.LIMIT_MAXNUMBERREACHED; } else if (maxWeightReached) { sol.LimitReached = CasePalletSolution.Limit.LIMIT_MAXWEIGHTREACHED; } else if (maxHeightReached) { sol.LimitReached = CasePalletSolution.Limit.LIMIT_MAXHEIGHTREACHED; } // insert solution if (sol.Count > 0) { solutions.Add(sol); } } } catch (NotImplementedException) { _log.Info(string.Format("Pattern {0} is not implemented", pattern.Name)); } catch (Exception ex) { _log.Error(string.Format("Exception caught: {0}", ex.Message)); } } // loop through all vertical axes } // loop through all swap positions (if layer can be swapped) } // loop through all patterns // sort solutions solutions.Sort(); if (ConstraintSet.AllowTwoLayerOrientations && solutions.Count > 0) { // get best solution count int iBestSolutionCount = solutions[0].CaseCount; // if solutions exceeds List <CasePalletSolution> multiOrientSolution = GenerateOptimizedCombinationOfLayers(); foreach (CasePalletSolution sol in multiOrientSolution) { if (sol.CaseCount > iBestSolutionCount) { solutions.Add(sol); } } solutions.Sort(); } // remove unwanted solutions if (_constraintSet.UseNumberOfSolutionsKept && solutions.Count > _constraintSet.NumberOfSolutionsKept) { // get minimum box count int minBoxCount = solutions[_constraintSet.NumberOfSolutionsKept].CaseCount; // remove any solution with less boxes than minBoxCount while (solutions[solutions.Count - 1].CaseCount < minBoxCount) { solutions.RemoveAt(solutions.Count - 1); } } return(solutions); }