protected override void Algorithm(ref Cl3DModel p_Model)
        {
            MarkHighCurvEdges(ref p_Model);

            p_Model.ResetVisitedPoints();
            //-------------------------------- Cropping
            Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Cl3DModel.Cl3DModelPointIterator LeftEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);

            float distanceBetweenEyes = LeftEye - RightEye;
            float ossfest = distanceBetweenEyes * 0.4f; //20% of distance between eyes will be taken as a stripe down to search for the mouth hole
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            Dictionary<uint, Cl3DModel.Cl3DModelPointIterator> pointsToRemove = new Dictionary<uint, Cl3DModel.Cl3DModelPointIterator>();
            do
            {
                if (iter.X > LeftEye.X + ossfest && iter.X < RightEye.X - ossfest && iter.Y < NoseTip.Y - 20 && iter.Y > NoseTip.Y - 43)
                {
                   // iter.Color = Color.LightBlue;
                    if (iter.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                    {
                        pointsToRemove.Add(iter.PointID, iter.CopyIterator());
                    }
                }

            } while (iter.MoveToNext());

            List<List<Cl3DModel.Cl3DModelPointIterator>> ListOfRegions = new List<List<Cl3DModel.Cl3DModelPointIterator>>();

            while (pointsToRemove.Count != 0)
            {
                Cl3DModel.Cl3DModelPointIterator test = new List<Cl3DModel.Cl3DModelPointIterator>(pointsToRemove.Values)[0];
                pointsToRemove.Remove(test.PointID);

                bool toRemove = false;
                List<Cl3DModel.Cl3DModelPointIterator> CurrentList = new List<Cl3DModel.Cl3DModelPointIterator>();
                ListOfRegions.Add(CurrentList);

                List<Cl3DModel.Cl3DModelPointIterator> ToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                ToCheck.Add(test);
                test.AlreadyVisited = true;
                do
                {
                    List<Cl3DModel.Cl3DModelPointIterator> NewToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                    foreach (Cl3DModel.Cl3DModelPointIterator pt in ToCheck)
                    {
                        CurrentList.Add(pt.CopyIterator());

                        foreach (Cl3DModel.Cl3DModelPointIterator ptNb in pt.GetListOfNeighbors())
                        {
                            if (ptNb.IsSpecificValueCalculated("ToRemove_HighCurvature") && ptNb.AlreadyVisited == false)
                            {
                                ptNb.AlreadyVisited = true;
                                NewToCheck.Add(ptNb.CopyIterator());
                                pointsToRemove.Remove(ptNb.PointID);
                                List<Cl3DModel.Cl3DModelPointIterator> Neighbors = ptNb.GetListOfNeighbors();

                             //   if (Neighbors.Count < 8) // that means the points from marked region went to the end of the model very rare happens that the open mouth region is the externatl region
                             //       toRemove = true;
                            }
                        }
                    }
                    ToCheck = NewToCheck;
                    NewToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                } while (ToCheck.Count != 0);
                if (toRemove)
                    ListOfRegions.Remove(CurrentList);
            }

            List<Cl3DModel.Cl3DModelPointIterator> BiggestRegion = null;
            int SizeOfTheBiggest = int.MinValue;
            for (int i = 0; i < ListOfRegions.Count; i++)
            {
                if (ListOfRegions[i].Count > SizeOfTheBiggest)
                {
                    SizeOfTheBiggest = ListOfRegions[i].Count;
                    BiggestRegion = ListOfRegions[i];
                }
            }

            //------------------- Creating image of localized mouth part
             /*   int NoseX = NoseTip.RangeImageX;
            int NoseY = NoseTip.RangeImageY;
            //BiggestRegion
            int[,] FMap = null;
            if (!FaceMaps.TryGetValue(p_Model.m_sExpression, out FMap))
            {
                FMap = new int[200, 200];
                FaceMaps.Add(p_Model.m_sExpression, FMap);
            }
            Cl3DModel.Cl3DModelPointIterator its = p_Model.GetIterator();
            do
            {
                int currX = its.RangeImageX;
                int currY = its.RangeImageY;

                int x = currX - NoseX + 100;
                int y = currY - NoseY + 100;

                FMap[x, y]++;
            } while (its.MoveToNext());

            int MaxF = int.MinValue;
            for (int i = 0; i < 200; i++)
                for(int j=0; j< 200; j++)
                    if (FMap[i, j] > MaxF)
                        MaxF = FMap[i, j];

            //-
            int[,] FRem = null;
            if (!RemovedMaps.TryGetValue(p_Model.m_sExpression, out FRem))
            {
                FRem = new int[200, 200];
                RemovedMaps.Add(p_Model.m_sExpression, FRem);
            }

            if (BiggestRegion != null)
            {
                foreach (Cl3DModel.Cl3DModelPointIterator pp in BiggestRegion)
                {
                    int currX = pp.RangeImageX;
                    int currY = pp.RangeImageY;

                    int x = currX - NoseX + 100;
                    int y = currY - NoseY + 100;

                    FRem[x, y]++;
                }
            }

            FRem[NoseTip.RangeImageX - NoseX + 100, NoseTip.RangeImageY - NoseY + 100]++;
              //  FRem[LeftEye.RangeImageX - NoseX + 100, LeftEye.RangeImageY - NoseY + 100]++;
              //  FRem[RightEye.RangeImageX - NoseX + 100, RightEye.RangeImageY - NoseY + 100]++;

            int MaxR = int.MinValue;
            for (int i = 0; i < 200; i++)
                for (int j = 0; j < 200; j++)
                    if (FRem[i, j] > MaxR)
                        MaxR = FRem[i, j];

            Bitmap map = new Bitmap(200, 200);
            for (int i = 0; i < 200; i++)
            {
                for (int j = 0; j < 200; j++)
                {
                    map.SetPixel(i, j, ClTools.GetColorGray(((float)FMap[i, j]) / MaxF, 1.0f));
                    if(FRem[i, j] != 0)
                        map.SetPixel(i, j, ClTools.GetColorGray( 1 - ((float)FRem[i, j]) / MaxR, 1.0f));
                }
            }
            map.Save("d:\\" + p_Model.m_sExpression + ".bmp");
            return;
              */
            //------------------------------------------------------------

              /*  TextWriter tw = new StreamWriter("d:\\MouthSizeBosphorus2.txt", false);

            int ssize = 0;
            if (BiggestRegion != null)
                ssize = BiggestRegion.Count;

            int[] OldSize;
            if(!mouthSize.TryGetValue(p_Model.m_sExpression, out OldSize))
            {
                OldSize = new int[2];
                mouthSize.Add(p_Model.m_sExpression, OldSize);
            }
            OldSize[0] += ssize;
            OldSize[1]++;

            foreach(KeyValuePair<string, int[]> val in mouthSize)
                tw.WriteLine(val.Key+" "+ val.Value[0].ToString()+ " " + val.Value[1].ToString());

            tw.Close();

            return;
               */
            //----------------------------------------------------------------

            //---------------------- NO mouth REGION LOCALIZED
            if (BiggestRegion == null)
            {
                ClInformationSender.SendInformation("No mouth localized, normal Geodesic distance calculation", ClInformationSender.eInformationType.eDebugText);
                if (m_bRemoveRegions) // still there can be vertexes with high curvature (edges between hair and the face)
                {
                    Cl3DModel.Cl3DModelPointIterator remover = p_Model.GetIterator();
                    while (remover.IsValid())
                    {
                        if (remover.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                            remover = p_Model.RemovePointFromModel(remover);
                        else
                            remover.MoveToNext();
                    }
                }

                ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());

                if (!m_bCrop)
                    return;

                iter = p_Model.GetIterator();
                while (iter.IsValid())
                {
                    if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                        if (distance > m_fDistence)
                            iter = p_Model.RemovePointFromModel(iter);
                        else
                            iter.MoveToNext();
                    }
                }
                return;
            }

            //------------------------- Mouth REGION LOCALiZED
            p_Model.ResetVisitedPoints();
            List<Cl3DModel.Cl3DModelPointIterator> BorderOfTheBigestRegion = new List<Cl3DModel.Cl3DModelPointIterator>();
            foreach (Cl3DModel.Cl3DModelPointIterator pts in BiggestRegion)
            {
                if (m_bMarkRegion)
                    pts.Color = Color.Red;

                List<Cl3DModel.Cl3DModelPointIterator> neighb = pts.GetListOfNeighbors();
                foreach (Cl3DModel.Cl3DModelPointIterator ppt in neighb)
                {
                    if(!ppt.AlreadyVisited && !ppt.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                    {
                        BorderOfTheBigestRegion.Add(ppt);
                        ppt.AlreadyVisited = true;
                    }
                }
            }

            if (m_bRemoveRegions) // After we have border of the mouth region we can remove them
            {
                Cl3DModel.Cl3DModelPointIterator remover = p_Model.GetIterator();
                while (remover.IsValid())
                {
                    if (remover.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                        remover = p_Model.RemovePointFromModel(remover);
                    else
                        remover.MoveToNext();
                }
            }

            Cl3DModel.Cl3DModelPointIterator MaxLeft = BorderOfTheBigestRegion[0];
            Cl3DModel.Cl3DModelPointIterator MaxRight = BorderOfTheBigestRegion[0];
            foreach (Cl3DModel.Cl3DModelPointIterator pt in BorderOfTheBigestRegion)
            {
                if (pt.X < MaxLeft.X)
                    MaxLeft = pt;
                if (pt.X > MaxRight.X)
                    MaxRight = pt;
            }

            int size = (int)Math.Abs(MaxLeft.X - MaxRight.X) + 1;
            List<Cl3DModel.Cl3DModelPointIterator>[] histogram = new List<Cl3DModel.Cl3DModelPointIterator>[size];

            foreach (Cl3DModel.Cl3DModelPointIterator pt in BorderOfTheBigestRegion)
            {
                int pos = (int)(pt.X - MaxLeft.X);
                if (histogram[pos] == null)
                    histogram[pos] = new List<Cl3DModel.Cl3DModelPointIterator>();

                histogram[pos].Add(pt);
            }

            Dictionary<uint, uint> movingPoints = new Dictionary<uint, uint>();
            for (int i = 0; i < size; i++)
            {
                if (histogram[i] != null && histogram[i].Count != 0)
                {
                    //Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                    Cl3DModel.Cl3DModelPointIterator UpperPoint = histogram[i][0];
                    Cl3DModel.Cl3DModelPointIterator LowerPoint = histogram[i][0];
                    foreach (Cl3DModel.Cl3DModelPointIterator pts in histogram[i])
                    {
                        //  pts.Color = cl;
                        if (UpperPoint.Y < pts.Y)
                            UpperPoint = pts;
                        if (LowerPoint.Y > pts.Y)
                            LowerPoint = pts;
                    }
                    //UpperPoint from this one
                    if (UpperPoint.PointID != LowerPoint.PointID)
                    {
                        float distance = Math.Min(LowerPoint - MaxLeft, LowerPoint - MaxRight);
                        List<Cl3DModel.Cl3DModelPointIterator> neighborhood = null;
                        ClTools.GetNeighborhoodWithGeodesicDistance(out neighborhood, LowerPoint, distance);
                        Cl3DModel.Cl3DModelPointIterator ClosestPoint = LowerPoint;
                        float MinDistance = LowerPoint - UpperPoint;
                        foreach (Cl3DModel.Cl3DModelPointIterator ptNeighb in neighborhood)
                        {
                            // ptNeighb.Color = Color.Pink;
                            float newDistance = ptNeighb - UpperPoint;
                            if (newDistance < MinDistance)
                            {
                                MinDistance = newDistance;
                                ClosestPoint = ptNeighb;
                            }
                        }
                        Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                    //    ClosestPoint.Color = cl;
                    //    UpperPoint.Color = cl;
                        movingPoints.Add(UpperPoint.PointID, ClosestPoint.PointID);
                    }
                }
            }

            //-------------------------------- Calculation of the geodesic using movement points
            p_Model.ResetVisitedPoints();
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPointsWithMovement(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString(), movingPoints);

            if (!m_bCrop)
                return;

            iter = p_Model.GetIterator();
            while (iter.IsValid())
            {
                if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                    if (distance > m_fDistence)
                        iter = p_Model.RemovePointFromModel(iter);
                    else
                        iter.MoveToNext();
                }
            }
        }
        public virtual void MakeAlgorithm(ref Cl3DModel p_Model)
        {
            if (p_Model == null)
                throw new Exception("NULL model");

            ClInformationSender.SendInformation("-> In progress: " + m_sAlgorithmName +" for: " +p_Model.ModelFileName, ClInformationSender.eInformationType.eTextInternal);
            p_Model.ResetVisitedPoints();
            DateTime start = DateTime.Now;
            m_AlgorithmTime = TimeSpan.Zero;

                Algorithm(ref p_Model);

            DateTime stop = DateTime.Now;
            m_AlgorithmTime = (stop - start);
            p_Model.IsModelChanged = true;
            ClInformationSender.SendInformation("-] Finished: " + m_sAlgorithmName + " for: " + p_Model.ModelFileName+" [time: " + m_AlgorithmTime.TotalSeconds + " sec.]", ClInformationSender.eInformationType.eTextInternal);

            string fullAlgorithmAdditionalData = GetAlgorithmFullPath() + "\n";
            foreach (KeyValuePair<string, string> prop in GetProperitis())
                fullAlgorithmAdditionalData += "\t" + prop.Key + " -> " + prop.Value + "\n";
            p_Model.AddDoneProcessingAlgorithm(fullAlgorithmAdditionalData);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            // Looking for a hole and connecting points ---- Later should be removed
            Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Cl3DModel.Cl3DModelPointIterator LeftEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);

            float distanceBetweenEyes = LeftEye - RightEye;
            float ossfest = distanceBetweenEyes * 0.4f; //20% of distance between eyes will be taken as a stripe down to search for the mouth hole
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            Dictionary<uint, Cl3DModel.Cl3DModelPointIterator> pointsLowerBoundary = new Dictionary<uint, Cl3DModel.Cl3DModelPointIterator>();
            do
            {
                if (iter.X > LeftEye.X + ossfest && iter.X < RightEye.X - ossfest && iter.Y < NoseTip.Y - 20 && iter.Y > NoseTip.Y - 40)
                {
                   // iter.Color = Color.LightGreen;
                    if (iter.GetListOfNeighbors().Count != 8)
                    {
                       // iter.Color = Color.LightBlue;
                        pointsLowerBoundary.Add(iter.PointID, iter.CopyIterator());
                    }
                }

            } while (iter.MoveToNext());

            List<List<Cl3DModel.Cl3DModelPointIterator>> ListOfBoundarie = new List<List<Cl3DModel.Cl3DModelPointIterator>>();

            while (pointsLowerBoundary.Count != 0)
            {
                Cl3DModel.Cl3DModelPointIterator test = new List<Cl3DModel.Cl3DModelPointIterator>(pointsLowerBoundary.Values)[0];
                pointsLowerBoundary.Remove(test.PointID);

                bool toRemove = false;
                List<Cl3DModel.Cl3DModelPointIterator> CurrentList = new List<Cl3DModel.Cl3DModelPointIterator>();
                ListOfBoundarie.Add(CurrentList);

                List<Cl3DModel.Cl3DModelPointIterator> ToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                ToCheck.Add(test);
                test.AlreadyVisited = true;
                do
                {
                    List<Cl3DModel.Cl3DModelPointIterator> NewToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                    foreach (Cl3DModel.Cl3DModelPointIterator pt in ToCheck)
                    {
                        CurrentList.Add(pt.CopyIterator());
                        if(pt.Y > NoseTip.Y)
                            toRemove = true;

                        foreach (Cl3DModel.Cl3DModelPointIterator ptNb in pt.GetListOfNeighbors())
                        {
                            if (ptNb.GetListOfNeighbors().Count != 8 && ptNb.AlreadyVisited == false)
                            {
                                ptNb.AlreadyVisited = true;
                                NewToCheck.Add(ptNb.CopyIterator());
                                pointsLowerBoundary.Remove(ptNb.PointID);
                            }
                        }
                    }
                    ToCheck = NewToCheck;
                    NewToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                } while (ToCheck.Count != 0);
                if (toRemove)
                    ListOfBoundarie.Remove(CurrentList);
            }

            List<Cl3DModel.Cl3DModelPointIterator> BiggestBoundary = null;
            int SizeOfTheBiggest = int.MinValue;
            for (int i = 0; i < ListOfBoundarie.Count; i++)
            {
                if(ListOfBoundarie[i].Count > SizeOfTheBiggest)
                {
                    SizeOfTheBiggest = ListOfBoundarie[i].Count;
                    BiggestBoundary = ListOfBoundarie[i];
                }

            }

            if (BiggestBoundary == null)
            {
                ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
                iter = p_Model.GetIterator();
                while (iter.IsValid())
                {
                    if(!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                        if (distance > m_fDistence)
                            iter = p_Model.RemovePointFromModel(iter);
                        else
                            iter.MoveToNext();
                    }
                }
                return;
            }

            Cl3DModel.Cl3DModelPointIterator MaxLeft = BiggestBoundary[0];
            Cl3DModel.Cl3DModelPointIterator MaxRight = BiggestBoundary[0];
            foreach (Cl3DModel.Cl3DModelPointIterator pt in BiggestBoundary)
            {
                if (pt.X < MaxLeft.X)
                    MaxLeft = pt;
                if (pt.X > MaxRight.X)
                    MaxRight = pt;
            }

            int size = (int)Math.Abs(MaxLeft.X - MaxRight.X)+1;
            List<Cl3DModel.Cl3DModelPointIterator>[] histogram = new List<Cl3DModel.Cl3DModelPointIterator>[size];

            foreach (Cl3DModel.Cl3DModelPointIterator pt in BiggestBoundary)
            {
                int pos = (int)(pt.X - MaxLeft.X);
                if (histogram[pos] == null)
                    histogram[pos] = new List<Cl3DModel.Cl3DModelPointIterator>();

                histogram[pos].Add(pt);
            }

            Dictionary<uint, uint> movingPoints = new Dictionary<uint, uint>();
            for (int i = 0; i < size; i++)
            {
                if (histogram[i] != null && histogram[i].Count != 0)
                {
                    //Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                    Cl3DModel.Cl3DModelPointIterator UpperPoint = histogram[i][0];
                    Cl3DModel.Cl3DModelPointIterator LowerPoint = histogram[i][0];
                    foreach (Cl3DModel.Cl3DModelPointIterator pts in histogram[i])
                    {
                      //  pts.Color = cl;
                        if (UpperPoint.Y < pts.Y)
                            UpperPoint = pts;
                        if (LowerPoint.Y > pts.Y)
                            LowerPoint = pts;
                    }
                    //UpperPoint from this one
                    if (UpperPoint.PointID != LowerPoint.PointID)
                    {
                        float distance = Math.Min(LowerPoint - MaxLeft, LowerPoint - MaxRight);
                        List<Cl3DModel.Cl3DModelPointIterator> neighborhood = null;
                        ClTools.GetNeighborhoodWithGeodesicDistance(out neighborhood, LowerPoint, distance);
                        Cl3DModel.Cl3DModelPointIterator ClosestPoint = LowerPoint;
                        float MinDistance = LowerPoint - UpperPoint;
                        foreach (Cl3DModel.Cl3DModelPointIterator ptNeighb in neighborhood)
                        {
                           // ptNeighb.Color = Color.Pink;
                            float newDistance = ptNeighb - UpperPoint;
                            if (newDistance < MinDistance)
                            {
                                MinDistance = newDistance;
                                ClosestPoint = ptNeighb;
                            }
                        }
                        Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                        ClosestPoint.Color = cl;
                        UpperPoint.Color = cl;
                        movingPoints.Add(UpperPoint.PointID, ClosestPoint.PointID);
                    }
                }
            }
            p_Model.ResetVisitedPoints();
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPointsWithMovement(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString(), movingPoints);

            iter = p_Model.GetIterator();
            while (iter.IsValid())
            {
                if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                    if (distance > m_fDistence)
                        iter = p_Model.RemovePointFromModel(iter);
                    else
                        iter.MoveToNext();
                }
            }
            return;

            //------------------------ PCA ----------------------
            /*
            float MeanX = 0;
            float MeanY = 0;
            float MeanZ = 0;
            Matrix xy = new Matrix(3, BiggestBoundary.Count);
            for (int i = 0; i < BiggestBoundary.Count; i++)
            {
                xy[0,i] = BiggestBoundary[i].X;
                xy[1,i] = BiggestBoundary[i].Y
                xy[2, i] = BiggestBoundary[i].Z;

                MeanX += BiggestBoundary[i].X;
                MeanY += BiggestBoundary[i].Y;
                MeanZ += BiggestBoundary[i].Z;

                BiggestBoundary[i].Color = Color.Red;
            }
            MeanX /= BiggestBoundary.Count;
            MeanY /= BiggestBoundary.Count;
            MeanZ /= BiggestBoundary.Count;

            for (int i = 0; i < BiggestBoundary.Count; i++)
            {
                xy[0, i] -= MeanX;
                xy[1, i] -= MeanY;
                xy[2, i] -= MeanZ;
            }

            Matrix Transpose = xy.Clone();
            Transpose.Transpose();
            Matrix Corelation = xy * Transpose;

            SingularValueDecomposition SVD = new SingularValueDecomposition(Corelation);

            Cl3DModel.Cl3DModelPointIterator point = p_Model.AddPointToModel(MeanX, MeanY, MeanZ);
            Cl3DModel.Cl3DModelPointIterator point2 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 0] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 0] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 0] * 10);
            Cl3DModel.Cl3DModelPointIterator point3 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 1] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 1] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 1] * 10);
            Cl3DModel.Cl3DModelPointIterator point4 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 2] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 2] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 2] * 10);
            point2.Color = Color.Red;
            point3.Color = Color.Green;
            point4.Color = Color.Blue;
            point.AddNeighbor(point2);
            point.AddNeighbor(point3);
            point.AddNeighbor(point4);
            */
            //---------------------------------------------------------------------------
        }