protected double GetPalletWidth(CylLoad load)
 {
     if (!_swapped)
     {
         return(load.PalletWidth);
     }
     else
     {
         return(load.PalletLength);
     }
 }
        public override void Generate(CylLoad load, int maxCount, double actualLength, double actualWidth, double maxHeight)
        {
            load.Clear();

            double palletLength = GetPalletLength(load);
            double palletWidth  = GetPalletWidth(load);
            double radius       = load.CylinderRadius;
            double diameter     = 2.0 * load.CylinderRadius;
            double length       = load.CylinderLength;

            int sizeX = Convert.ToInt32(Math.Floor(GetPalletLength(load) / load.CylinderLength));
            int sizeY = Convert.ToInt32(Math.Floor(GetPalletWidth(load) / (2.0 * load.CylinderRadius)));

            double offsetX = 0.5 * (palletLength - actualLength);
            double offsetY = 0.5 * (palletWidth - actualWidth);
            double offsetZ = load.PalletHeight + radius;

            int iLayer = 0;

            while (true)
            {
                // max height reached ?
                if ((iLayer + 1) * diameter > maxHeight)
                {
                    load.LimitReached = Limit.LIMIT_MAXHEIGHTREACHED;
                    return;
                }

                for (int j = 0; j < sizeY; ++j)
                {
                    for (int i = 0; i < sizeX; ++i)
                    {
                        AddPosition(
                            load
                            , new CylPosition(
                                new Vector3D(
                                    offsetX + i * length
                                    , offsetY + radius + j * diameter
                                    , offsetZ + iLayer * (diameter + load.RowSpacing))
                                , HalfAxis.HAxis.AXIS_X_P)
                            );
                        // max number of items reached ?
                        if (maxCount > 0 && load.Count >= maxCount)
                        {
                            load.LimitReached = Limit.LIMIT_MAXNUMBERREACHED;
                            return;
                        }
                    }
                }
                ++iLayer;
            }
        }
        public void AddPosition(CylLoad load, CylPosition pos)
        {
            Matrix4D matRot       = Matrix4D.Identity;
            Vector3D vTranslation = Vector3D.Zero;

            if (_swapped)
            {
                matRot = new Matrix4D(
                    0.0, -1.0, 0.0, 0.0
                    , 1.0, 0.0, 0.0, 0.0
                    , 0.0, 0.0, 1.0, 0.0
                    , 0.0, 0.0, 0.0, 1.0
                    );
                vTranslation = new Vector3D(load.PalletLength, 0.0, 0.0);

                matRot.M14 = vTranslation[0];
                matRot.M24 = vTranslation[1];
                matRot.M34 = vTranslation[2];
            }

            load.Add(pos.Transform(new Transform3D(matRot)));
        }
        public virtual void GetDimensions(CylLoad load, int maxCount, out double length, out double width)
        {
            length = 0.0; width = 0.0;
            // using XP direction
            int noX = Convert.ToInt32(Math.Floor(GetPalletLength(load) / load.CylinderLength));
            int noY = Convert.ToInt32(Math.Floor(GetPalletWidth(load) / (2.0 * load.CylinderRadius)));

            if (-1 != maxCount && maxCount < noX * (noY - 1))
            {
                if (maxCount < noX)
                {
                    noX = maxCount;
                    noY = 1;
                }
                else
                {
                    noY = maxCount / noX + 1;
                }
            }
            length = noX * load.CylinderLength;
            width  = 2.0 * noY * load.CylinderRadius;
        }
 abstract public void Generate(CylLoad layer, int maxCount, double actualLength, double actualWidth, double maxHeight);
        private List <HCylinderPalletSolution> GenerateSolutions()
        {
            List <HCylinderPalletSolution> solutions = new List <HCylinderPalletSolution>();

            // loop through all patterns
            foreach (HCylinderLoadPattern pattern in _patterns)
            {
                if (!_constraintSet.AllowPattern(pattern.Name))
                {
                    continue;
                }
                // loop through directions
                for (int iDir = 0; iDir < (pattern.CanBeSwapped ? 2 : 1); ++iDir)
                {
                    string title = string.Format("{0}-{1}", pattern.Name, iDir);
                    HCylinderPalletSolution sol = new HCylinderPalletSolution(null, title);

                    double actualLength = 0.0, actualWidth = 0.0;
                    double maxHeight = _constraintSet.UseMaximumPalletHeight ? _constraintSet.MaximumPalletHeight : -1;

                    pattern.Swapped = (iDir % 2 != 0);

                    int maxCountNoItems = -1;
                    if (_constraintSet.UseMaximumNumberOfItems)
                    {
                        maxCountNoItems = _constraintSet.MaximumNumberOfItems;
                    }
                    int maxCountWeight = -1;
                    if (_constraintSet.UseMaximumPalletWeight)
                    {
                        maxCountWeight = (int)Math.Floor((_constraintSet.MaximumPalletWeight - _palletProperties.Weight) / _cylProperties.Weight);
                    }
                    int maxCount = -1;
                    if (-1 != maxCountNoItems && -1 == maxCountWeight)
                    {
                        maxCount = maxCountNoItems;
                    }
                    else if (-1 == maxCountNoItems && -1 != maxCountWeight)
                    {
                        maxCount = maxCountWeight;
                    }
                    else if (-1 != maxCountNoItems && -1 != maxCountWeight)
                    {
                        maxCount = Math.Min(maxCountWeight, maxCountNoItems);
                    }
                    try
                    {
                        CylLoad load = new CylLoad(_cylProperties, _palletProperties, _constraintSet);
                        pattern.GetDimensions(load, maxCount, out actualLength, out actualWidth);
                        pattern.Generate(load, maxCount, actualLength, actualWidth, maxHeight - _palletProperties.Height);

                        // Limit reached ?
                        sol.LimitReached = load.LimitReached;
                        // maxCount might actually max weight reached
                        if (load.LimitReached == Limit.LIMIT_MAXNUMBERREACHED && maxCount == maxCountWeight)
                        {
                            sol.LimitReached = Limit.LIMIT_MAXWEIGHTREACHED;
                        }

                        // copies all cylinder positions
                        foreach (CylPosition pos in load)
                        {
                            sol.Add(new CylPosition(
                                        pos.XYZ
                                        - 0.5 * _constraintSet.OverhangX * Vector3D.XAxis
                                        - 0.5 * _constraintSet.OverhangY * Vector3D.YAxis,
                                        pos.Direction
                                        ));
                        }
                    }
                    catch (NotImplementedException ex)
                    {
                        _log.Debug(ex.Message);
                        continue;
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex.Message);
                        continue;
                    }
                    // add solution
                    if (sol.Count > 0)
                    {
                        solutions.Add(sol);
                    }
                } // loop on directions
            }     // loop through all patterns
            // sort solution
            solutions.Sort();
            return(solutions);
        }