protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator maxIter = p_Model.GetIterator();
            Cl3DModel.Cl3DModelPointIterator iter = maxIter.CopyIterator();

            while (iter.MoveToNext())
            {
                if (maxIter.Z < iter.Z)
                    maxIter = iter.CopyIterator();
            }

            if (maxIter.IsValid())
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), maxIter);
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string name = p_Model.ModelFileName;

            if(m_CharsToSubstract != 0)
                name = name.Substring(0, name.Length - m_CharsToSubstract);

            if (!IDS)
            {
                string fileName = p_Model.ModelFileFolder + name + m_sFilePostFix + ".pts";
                Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
                using (StreamReader FileStream = File.OpenText(fileName))
                {
                    string line = "";
                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Length == 0)
                            continue;

                        if (line[0].Equals('@'))
                            continue;

                        string[] splited = line.Split(' ');

                        Cl3DModel.eSpecificPoints type = Cl3DModel.eSpecificPoints.LeftEyeRightCorner;

                        if (splited[0].Equals("LeftEyeRightCorner"))
                            type = Cl3DModel.eSpecificPoints.LeftEyeRightCorner;
                        else if (splited[0].Equals("RightEyeLeftCorner"))
                            type = Cl3DModel.eSpecificPoints.RightEyeLeftCorner;
                        else if (splited[0].Equals("NoseTip"))
                            type = Cl3DModel.eSpecificPoints.NoseTip;
                        else
                            continue;

                        uint ID = UInt32.Parse(splited[1]);
                        if (!iter.MoveToPoint(ID))
                            throw new Exception("Cannot find point with ID: " + splited[1]);

                        p_Model.AddSpecificPoint(type, iter);
                    }
                }
            }
            else
            {
                string fileName = p_Model.ModelFileFolder + name + m_sFilePostFix + ".ptsID";
                Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
                using (StreamReader FileStream = File.OpenText(fileName))
                {
                    string line = "";
                    int count = 0;
                    uint NoOfPoints = 0;
                    bool ReadHeader = false;
                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (!ReadHeader)
                        {
                            NoOfPoints = UInt32.Parse(line);
                            if (NoOfPoints != 3)
                                throw new Exception("Method ready to read 3 points");
                            ReadHeader = true;
                        }
                        else
                        {
                            uint id = UInt32.Parse(line);
                            iter.MoveToPoint(id);
                            if (count == 0)
                                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, iter);
                            if (count == 1)
                                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, iter);
                            if (count == 2)
                                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, iter);

                            count++;
                        }
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            CORFile landmarkFile = ReadCORFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".cor");
            //search for the closest point from the model to the read landmark
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
                throw new Exception("Iterator in the model is not valid!");

            Cl3DModel.Cl3DModelPointIterator SavedNoseTip = iter.CopyIterator();
            float NoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NoseTip.X - SavedNoseTip.X,2)+Math.Pow(landmarkFile.NoseTip.Y - SavedNoseTip.Y,2)+Math.Pow(landmarkFile.NoseTip.Z - SavedNoseTip.Z,2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeRightCorner = iter.CopyIterator();
            float LeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - SavedLeftEyeRightCorner.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightEyeLeftCorner = iter.CopyIterator();
            float RightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeLeftCorner.X - SavedRightEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Y - SavedRightEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Z - SavedRightEyeLeftCorner.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightEyeRightCorner = iter.CopyIterator();
            float RightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeRightCorner.X - SavedRightEyeRightCorner.X, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Y - SavedRightEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Z - SavedRightEyeRightCorner.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeLeftCorner = iter.CopyIterator();
            float LeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeLeftCorner.X - SavedLeftEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Y - SavedLeftEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Z - SavedLeftEyeLeftCorner.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfNose = iter.CopyIterator();
            float LeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - SavedLeftCornerOfNose.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - SavedLeftCornerOfNose.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - SavedLeftCornerOfNose.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfNose = iter.CopyIterator();
            float RightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - SavedRightCornerOfNose.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - SavedRightCornerOfNose.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - SavedRightCornerOfNose.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfLips = iter.CopyIterator();
            float LeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - SavedLeftCornerOfLips.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - SavedLeftCornerOfLips.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - SavedLeftCornerOfLips.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfLips = iter.CopyIterator();
            float RightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - SavedRightCornerOfLips.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - SavedRightCornerOfLips.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - SavedRightCornerOfLips.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedUpperLip = iter.CopyIterator();
            float UpperLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.UpperLip.X - SavedUpperLip.X, 2) + Math.Pow(landmarkFile.UpperLip.Y - SavedUpperLip.Y, 2) + Math.Pow(landmarkFile.UpperLip.Z - SavedUpperLip.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedBottomLip = iter.CopyIterator();
            float BottomLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.BottomLip.X - SavedBottomLip.X, 2) + Math.Pow(landmarkFile.BottomLip.Y - SavedBottomLip.Y, 2) + Math.Pow(landmarkFile.BottomLip.Z - SavedBottomLip.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeUpperEyelid = iter.CopyIterator();
            float LeftEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeUpperEyelid.X - SavedLeftEyeUpperEyelid.X, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Y - SavedLeftEyeUpperEyelid.Y, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Z - SavedLeftEyeUpperEyelid.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeBottomEyelid = iter.CopyIterator();
            float LeftEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeBottomEyelid.X - SavedLeftEyeBottomEyelid.X, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Y - SavedLeftEyeBottomEyelid.Y, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Z - SavedLeftEyeBottomEyelid.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightEyeUpperEyelid = iter.CopyIterator();
            float RightEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeUpperEyelid.X - SavedRightEyeUpperEyelid.X, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Y - SavedRightEyeUpperEyelid.Y, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Z - SavedRightEyeUpperEyelid.Z, 2));

            Cl3DModel.Cl3DModelPointIterator SavedRightEyeBottomEyelid = iter.CopyIterator();
            float RightEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeBottomEyelid.X - SavedRightEyeBottomEyelid.X, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Y - SavedRightEyeBottomEyelid.Y, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Z - SavedRightEyeBottomEyelid.Z, 2));

            do
            {
                float NewNoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NoseTip.X - iter.X, 2) + Math.Pow(landmarkFile.NoseTip.Y - iter.Y, 2) + Math.Pow(landmarkFile.NoseTip.Z - iter.Z, 2));
                float NewLeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - iter.Z, 2));
                float NewRightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeLeftCorner.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Z - iter.Z, 2));
                float NewLeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeLeftCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Z - iter.Z, 2));
                float NewRightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Z - iter.Z, 2));
                float NewLeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - iter.Z, 2));
                float NewRightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - iter.Z, 2));
                float NewLeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - iter.Z, 2));
                float NewRightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - iter.Z, 2));

                float NewUpperLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.UpperLip.X - iter.X, 2) + Math.Pow(landmarkFile.UpperLip.Y - iter.Y, 2) + Math.Pow(landmarkFile.UpperLip.Z - iter.Z, 2));
                float NewBottomLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.BottomLip.X - iter.X, 2) + Math.Pow(landmarkFile.BottomLip.Y - iter.Y, 2) + Math.Pow(landmarkFile.BottomLip.Z - iter.Z, 2));
                float NewLeftEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeUpperEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Z - iter.Z, 2));
                float NewLeftEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeBottomEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Z - iter.Z, 2));
                float NewRightEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeUpperEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Z - iter.Z, 2));
                float NewRightEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeBottomEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Z - iter.Z, 2));

                if (NewNoseTipDistance < NoseTipDistance)
                {
                    NoseTipDistance = NewNoseTipDistance;
                    SavedNoseTip = iter.CopyIterator();
                }
                if (NewLeftEyeRightCornerDistance < LeftEyeRightCornerDistance)
                {
                    LeftEyeRightCornerDistance = NewLeftEyeRightCornerDistance;
                    SavedLeftEyeRightCorner = iter.CopyIterator();
                }
                if (NewRightEyeLeftCornerDistance < RightEyeLeftCornerDistance)
                {
                    RightEyeLeftCornerDistance = NewRightEyeLeftCornerDistance;
                    SavedRightEyeLeftCorner = iter.CopyIterator();
                }
                if (NewRightEyeRightCornerDistance < RightEyeRightCornerDistance)
                {
                    RightEyeRightCornerDistance = NewRightEyeRightCornerDistance;
                    SavedRightEyeRightCorner = iter.CopyIterator();
                }
                if (NewLeftEyeLeftCornerDistance < LeftEyeLeftCornerDistance)
                {
                    LeftEyeLeftCornerDistance = NewLeftEyeLeftCornerDistance;
                    SavedLeftEyeLeftCorner = iter.CopyIterator();
                }
                if (NewLeftCornerOfNoseDistance < LeftCornerOfNoseDistance)
                {
                    LeftCornerOfNoseDistance = NewLeftCornerOfNoseDistance;
                    SavedLeftCornerOfNose = iter.CopyIterator();
                }
                if (NewRightCornerOfNoseDistance < RightCornerOfNoseDistance)
                {
                    RightCornerOfNoseDistance = NewRightCornerOfNoseDistance;
                    SavedRightCornerOfNose = iter.CopyIterator();
                }
                if (NewLeftCornerOfLipsDistance < LeftCornerOfLipsDistance)
                {
                    LeftCornerOfLipsDistance = NewLeftCornerOfLipsDistance;
                    SavedLeftCornerOfLips = iter.CopyIterator();
                }
                if (NewRightCornerOfLipsDistance < RightCornerOfLipsDistance)
                {
                    RightCornerOfLipsDistance = NewRightCornerOfLipsDistance;
                    SavedRightCornerOfLips = iter.CopyIterator();
                }

                if (NewUpperLipDistance < UpperLipDistance)
                {
                    UpperLipDistance = NewUpperLipDistance;
                    SavedUpperLip = iter.CopyIterator();
                }
                if (NewBottomLipDistance < BottomLipDistance)
                {
                    BottomLipDistance = NewBottomLipDistance;
                    SavedBottomLip = iter.CopyIterator();
                }
                if (NewLeftEyeUpperEyelidDistance < LeftEyeUpperEyelidDistance)
                {
                    LeftEyeUpperEyelidDistance = NewLeftEyeUpperEyelidDistance;
                    SavedLeftEyeUpperEyelid = iter.CopyIterator();
                }
                if (NewLeftEyeBottomEyelidDistance < LeftEyeBottomEyelidDistance)
                {
                    LeftEyeBottomEyelidDistance = NewLeftEyeBottomEyelidDistance;
                    SavedLeftEyeBottomEyelid = iter.CopyIterator();
                }
                if (NewRightEyeUpperEyelidDistance < RightEyeUpperEyelidDistance)
                {
                    RightEyeUpperEyelidDistance = NewRightEyeUpperEyelidDistance;
                    SavedRightEyeUpperEyelid = iter.CopyIterator();
                }
                if (NewRightEyeBottomEyelidDistance < RightEyeBottomEyelidDistance)
                {
                    RightEyeBottomEyelidDistance = NewRightEyeBottomEyelidDistance;
                    SavedRightEyeBottomEyelid = iter.CopyIterator();
                }

            } while (iter.MoveToNext());

            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, SavedNoseTip);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, SavedRightEyeLeftCorner);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, SavedLeftEyeRightCorner);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, SavedLeftEyeLeftCorner);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, SavedRightEyeRightCorner);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, SavedLeftCornerOfNose);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, SavedRightCornerOfNose);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, SavedLeftCornerOfLips);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, SavedRightCornerOfLips);

            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip, SavedUpperLip);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip, SavedBottomLip);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeUpperEyelid, SavedLeftEyeUpperEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeBottomEyelid, SavedLeftEyeBottomEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeUpperEyelid, SavedRightEyeUpperEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeBottomEyelid, SavedRightEyeBottomEyelid);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            //------------------- LeftCornerOfLips -------------------------
            Cl3DModel.Cl3DModelPointIterator basicPoint = null;
            List<Cl3DModel.Cl3DModelPointIterator> Neighborhood;
            double max = 0;
            Cl3DModel.Cl3DModelPointIterator NewCorner = null;

            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips.ToString(), ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 15);

                Neighborhood.Add(basicPoint);

                max = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List<Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Magenta;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H = 0;
                    double K = 0;
                    double k1 = 0;
                    double k2 = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                        continue;

                    double dx = B + 2 * D * point.X + E * point.Y;
                    double dy = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1 = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2 = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, NewCorner);
                }
            }

            //------------------- RightCornerOfLips -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 15);
                Neighborhood.Add(basicPoint);

                max = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List<Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Magenta;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H = 0;
                    double K = 0;
                    double k1 = 0;
                    double k2 = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                        continue;

                    double dx = B + 2 * D * point.X + E * point.Y;
                    double dy = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1 = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2 = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, NewCorner);
                }
            }
            //------------------- LeftCornerOfNose -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 10);
                Neighborhood.Add(basicPoint);

                max = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List<Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Orchid;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H = 0;
                    double K = 0;
                    double k1 = 0;
                    double k2 = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                        continue;

                    double dx = B + 2 * D * point.X + E * point.Y;
                    double dy = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1 = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2 = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, NewCorner);
                }
            }
            //------------------- RightCornerOfNose -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 10);
                Neighborhood.Add(basicPoint);

                max = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List<Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Orchid;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H = 0;
                    double K = 0;
                    double k1 = 0;
                    double k2 = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                        continue;

                    double dx = B + 2 * D * point.X + E * point.Y;
                    double dy = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1 = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2 = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, NewCorner);
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Cl3DModel.Cl3DModelPointIterator LeftEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());

            Cl3DModel.Cl3DModelPointIterator[,] Map = null;
            int Width, Height, Xoffset, Yoffset;
            ClTools.CreateGridBasedOnRangeValues(p_Model, out Map, out Width, out Height, out Xoffset, out Yoffset);

            int RightEyeX = RightEye.RangeImageX - Xoffset;
            int RightEyeY = RightEye.RangeImageY - Yoffset;
            int LeftEyeX = LeftEye.RangeImageX - Xoffset;
            int LeftEyeY = LeftEye.RangeImageY - Yoffset;

            int MiddleX = (RightEyeX + LeftEyeX) / 2;
            int MiddleY = (RightEyeY + LeftEyeY) / 2;

            Cl3DModel.Cl3DModelPointIterator MiddlePoint = Map[MiddleX, MiddleY];
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.UnspecifiedPoint, MiddlePoint);

            List<Cl3DModel.Cl3DModelPointIterator> Neighborhood = null;
            ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, MiddlePoint, m_fEyesPartRadious);
            foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                point.AlreadyVisited = true;

            MiddlePoint.AlreadyVisited = true;

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                if (!iter.IsValid())
                    break;

                if (!iter.AlreadyVisited)
                    iter = p_Model.RemovePointFromModel(iter);
                else
                    if (!iter.MoveToNext())
                        break;

            } while (true);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            CRRFile landmarkFile = ReadCRRFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".crr");
            //search for the closest point from the model to the read landmark
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
                throw new Exception("Iterator in the model is not valid!");

            Cl3DModel.Cl3DModelPointIterator SavedNoseTip = null;
            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeRightCorner = null;
            Cl3DModel.Cl3DModelPointIterator SavedRightEyeLeftCorner = null;
            Cl3DModel.Cl3DModelPointIterator SavedRightEyeRightCorner = null;
            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeLeftCorner = null;
            Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfNose = null;
            Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfNose = null;
            Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfLips = null;
            Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfLips = null;
            float RightCornerOfLipsDistance = 0;
            float NoseTipDistance = 0;
            float LeftEyeRightCornerDistance = 0;
            float RightEyeLeftCornerDistance = 0;
            float RightEyeRightCornerDistance = 0;
            float LeftEyeLeftCornerDistance = 0;
            float LeftCornerOfNoseDistance = 0;
            float RightCornerOfNoseDistance = 0;
            float LeftCornerOfLipsDistance = 0;

            if (landmarkFile.NostTip != null)
            {
                SavedNoseTip = iter.CopyIterator();
                NoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NostTip.X - SavedNoseTip.X, 2) + Math.Pow(landmarkFile.NostTip.Y - SavedNoseTip.Y, 2) + Math.Pow(landmarkFile.NostTip.Z - SavedNoseTip.Z, 2));
            }

            if (landmarkFile.LeftEyeRightCorner != null)
            {
                SavedLeftEyeRightCorner = iter.CopyIterator();
                LeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - SavedLeftEyeRightCorner.Z, 2));
            }

            if (landmarkFile.LeftCornerOfRightEye != null)
            {
                SavedRightEyeLeftCorner = iter.CopyIterator();
                RightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfRightEye.X - SavedRightEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Y - SavedRightEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Z - SavedRightEyeLeftCorner.Z, 2));
            }

            if (landmarkFile.RightCornerOfRightEye != null)
            {
                SavedRightEyeRightCorner = iter.CopyIterator();
                RightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfRightEye.X - SavedRightEyeRightCorner.X, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Y - SavedRightEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Z - SavedRightEyeRightCorner.Z, 2));
            }

            if (landmarkFile.LeftCornerOfLeftEye != null)
            {
                SavedLeftEyeLeftCorner = iter.CopyIterator();
                LeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLeftEye.X - SavedLeftEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Y - SavedLeftEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Z - SavedLeftEyeLeftCorner.Z, 2));
            }

            if (landmarkFile.LeftCornerOfNose != null)
            {
                SavedLeftCornerOfNose = iter.CopyIterator();
                LeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - SavedLeftCornerOfNose.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - SavedLeftCornerOfNose.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - SavedLeftCornerOfNose.Z, 2));
            }

            if (landmarkFile.RightCornerOfNose != null)
            {
                SavedRightCornerOfNose = iter.CopyIterator();
                RightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - SavedRightCornerOfNose.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - SavedRightCornerOfNose.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - SavedRightCornerOfNose.Z, 2));
            }

            if (landmarkFile.LeftCornerOfLips != null)
            {
                SavedLeftCornerOfLips = iter.CopyIterator();
                LeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - SavedLeftCornerOfLips.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - SavedLeftCornerOfLips.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - SavedLeftCornerOfLips.Z, 2));
            }

            if (landmarkFile.RightCornerOfLips != null)
            {
                SavedRightCornerOfLips = iter.CopyIterator();
                RightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - SavedRightCornerOfLips.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - SavedRightCornerOfLips.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - SavedRightCornerOfLips.Z, 2));
            }

            do
            {
                if (SavedNoseTip != null)
                {
                    float NewNoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NostTip.X - iter.X, 2) + Math.Pow(landmarkFile.NostTip.Y - iter.Y, 2) + Math.Pow(landmarkFile.NostTip.Z - iter.Z, 2));
                    if (NewNoseTipDistance < NoseTipDistance)
                    {
                        NoseTipDistance = NewNoseTipDistance;
                        SavedNoseTip = iter.CopyIterator();
                    }
                }

                if (SavedLeftEyeRightCorner != null)
                {
                    float NewLeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - iter.Z, 2));
                    if (NewLeftEyeRightCornerDistance < LeftEyeRightCornerDistance)
                    {
                        LeftEyeRightCornerDistance = NewLeftEyeRightCornerDistance;
                        SavedLeftEyeRightCorner = iter.CopyIterator();
                    }
                }

                if (SavedRightEyeLeftCorner != null)
                {
                    float NewRightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Z - iter.Z, 2));
                    if (NewRightEyeLeftCornerDistance < RightEyeLeftCornerDistance)
                    {
                        RightEyeLeftCornerDistance = NewRightEyeLeftCornerDistance;
                        SavedRightEyeLeftCorner = iter.CopyIterator();
                    }
                }

                if (SavedRightEyeRightCorner != null)
                {
                    float NewRightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfRightEye.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Z - iter.Z, 2));
                    if (NewRightEyeRightCornerDistance < RightEyeRightCornerDistance)
                    {
                        RightEyeRightCornerDistance = NewRightEyeRightCornerDistance;
                        SavedRightEyeRightCorner = iter.CopyIterator();
                    }
                }

                if (SavedLeftEyeLeftCorner != null)
                {
                    float NewLeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLeftEye.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Z - iter.Z, 2));
                    if (NewLeftEyeLeftCornerDistance < LeftEyeLeftCornerDistance)
                    {
                        LeftEyeLeftCornerDistance = NewLeftEyeLeftCornerDistance;
                        SavedLeftEyeLeftCorner = iter.CopyIterator();
                    }
                }

                if (SavedLeftCornerOfNose != null)
                {
                    float NewLeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - iter.Z, 2));
                    if (NewLeftCornerOfNoseDistance < LeftCornerOfNoseDistance)
                    {
                        LeftCornerOfNoseDistance = NewLeftCornerOfNoseDistance;
                        SavedLeftCornerOfNose = iter.CopyIterator();
                    }
                }

                if (SavedRightCornerOfNose != null)
                {
                    float NewRightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - iter.Z, 2));
                    if (NewRightCornerOfNoseDistance < RightCornerOfNoseDistance)
                    {
                        RightCornerOfNoseDistance = NewRightCornerOfNoseDistance;
                        SavedRightCornerOfNose = iter.CopyIterator();
                    }
                }

                if (SavedLeftCornerOfLips != null)
                {
                    float NewLeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - iter.Z, 2));
                    if (NewLeftCornerOfLipsDistance < LeftCornerOfLipsDistance)
                    {
                        LeftCornerOfLipsDistance = NewLeftCornerOfLipsDistance;
                        SavedLeftCornerOfLips = iter.CopyIterator();
                    }
                }

                if (SavedRightCornerOfLips != null)
                {
                    float NewRightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - iter.Z, 2));
                    if (NewRightCornerOfLipsDistance < RightCornerOfLipsDistance)
                    {
                        RightCornerOfLipsDistance = NewRightCornerOfLipsDistance;
                        SavedRightCornerOfLips = iter.CopyIterator();
                    }
                }

            } while (iter.MoveToNext());

            if(SavedNoseTip != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, SavedNoseTip);
            if (SavedRightEyeLeftCorner != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, SavedRightEyeLeftCorner);
            if (SavedLeftEyeRightCorner != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, SavedLeftEyeRightCorner);
            if (SavedLeftEyeLeftCorner != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, SavedLeftEyeLeftCorner);
            if (SavedRightEyeRightCorner != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, SavedRightEyeRightCorner);
            if (SavedLeftCornerOfNose != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, SavedLeftCornerOfNose);
            if (SavedRightCornerOfNose != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, SavedRightCornerOfNose);
            if (SavedLeftCornerOfLips != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, SavedLeftCornerOfLips);
            if (SavedRightCornerOfLips != null)
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, SavedRightCornerOfLips);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            int maxX = (int)iter.X;
            int minX = (int)iter.X;
            int maxY = (int)iter.Y;
            int minY = (int)iter.Y;

            do
            {
                if (maxX < iter.X)
                    maxX = (int)iter.X;
                if (maxY < iter.Y)
                    maxY = (int)iter.Y;

                if (minX > iter.X)
                    minX = (int)iter.X;
                if (minY > iter.Y)
                    minY = (int)iter.Y;
            } while (iter.MoveToNext());

            int width = (maxX - minX) + 1;
            int height = (maxY - minY) + 1;

            List<Cl3DModel.Cl3DModelPointIterator>[,] map = new List<Cl3DModel.Cl3DModelPointIterator>[width, height];

            iter = p_Model.GetIterator();
            do
            {
                int x = (int)iter.X - minX;
                int y = (int)iter.Y - minY;
                if(map[x,y] == null)
                    map[x,y] = new List<Cl3DModel.Cl3DModelPointIterator>();

                map[x,y].Add(iter.CopyIterator());
            } while (iter.MoveToNext());

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (map[x, y] != null)
                    {
                        int MeanR = 0;
                        int MeanG = 0;
                        int MeanB = 0;
                        float MeanX = 0;
                        float MeanY = 0;
                        float MeanZ = 0;

                        float MeanU = 0;
                        float MeanV = 0;

                        float MeanRangeX = 0;
                        float MeanRangeY = 0;

                        Dictionary<string, List<double>> MeanSpecificValues = new Dictionary<string, List<double>>();

                        Cl3DModel.Cl3DModelPointIterator MaxPoint = null;

                        string specPoint = Cl3DModel.eSpecificPoints.UnspecifiedPoint.ToString();
                        bool isSpecific = false;
                        foreach (Cl3DModel.Cl3DModelPointIterator point in map[x, y])
                        {
                            point.AlreadyVisited = true;
                            if(!isSpecific)
                                isSpecific = p_Model.IsThisPointInSpecificPoints(point, ref specPoint);

                            if (m_bMean)
                            {
                                MeanR += point.ColorR;
                                MeanG += point.ColorG;
                                MeanB += point.ColorB;
                                MeanX += point.X;
                                MeanY += point.Y;
                                MeanZ += point.Z;

                                MeanU += point.U;
                                MeanV += point.V;

                                MeanRangeX += point.RangeImageX;
                                MeanRangeY += point.RangeImageY;

                                List<string> listOfValuesNames = point.GetListOfSpecificValues();
                                foreach(string name in listOfValuesNames)
                                {
                                    List<double> listOfValues = null;
                                    if (!MeanSpecificValues.TryGetValue(name, out listOfValues))
                                    {
                                        listOfValues = new List<double>();
                                        MeanSpecificValues.Add(name, listOfValues);
                                    }
                                    double val = point.GetSpecificValue(name);
                                    listOfValues.Add(val);
                                }
                            }
                            else
                            {// search for max Z
                                if (MaxPoint == null)
                                    MaxPoint = point;
                                else if(MaxPoint.Z < point.Z)
                                    MaxPoint = point;
                            }
                        }

                        if (m_bMean)
                        {
                            MeanR /= map[x, y].Count;
                            MeanG /= map[x, y].Count;
                            MeanB /= map[x, y].Count;
                            MeanX /= map[x, y].Count;
                            MeanY /= map[x, y].Count;
                            MeanZ /= map[x, y].Count;

                            MeanU /= map[x, y].Count;
                            MeanV /= map[x, y].Count;

                            MeanRangeX /= map[x, y].Count;
                            MeanRangeY /= map[x, y].Count;
                        }
                        else
                        {
                            MeanR = MaxPoint.ColorR;
                            MeanG = MaxPoint.ColorG;
                            MeanB = MaxPoint.ColorB;
                            MeanX = MaxPoint.X;
                            MeanY = MaxPoint.Y;
                            MeanZ = MaxPoint.Z;

                            MeanU = MaxPoint.U;
                            MeanV = MaxPoint.V;

                            MeanRangeX = MaxPoint.RangeImageX;
                            MeanRangeY = MaxPoint.RangeImageY;
                        }

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

                        foreach (Cl3DModel.Cl3DModelPointIterator point in map[x, y])
                            foreach (Cl3DModel.Cl3DModelPointIterator InnerPoint in point.GetListOfNeighbors())
                                if(InnerPoint.AlreadyVisited == false)
                                    connections.Add(InnerPoint);

                        Cl3DModel.Cl3DModelPointIterator pt = p_Model.AddPointToModel((int)MeanX, (int)MeanY, MeanZ, x, width - y);
                        pt.Color = Color.FromArgb(MeanR, MeanG, MeanB);
                        pt.U = MeanU;
                        pt.V = MeanV;

                        foreach (KeyValuePair<string, List<double>> kvValues in MeanSpecificValues)
                        {
                            string valueName = kvValues.Key;
                            List<double> values = kvValues.Value;
                            double meanVal = 0;
                            foreach (double val in values)
                            {
                                meanVal += val;
                            }
                            meanVal /= values.Count;
                            pt.AddSpecificValue("Mean_" + valueName, meanVal);
                        }

                        if (isSpecific)
                            p_Model.AddSpecificPoint(specPoint, pt);

                        List<Cl3DModel.Cl3DModelPointIterator> lista =  map[x, y];
                        for (int i = 0; i < lista.Count; i++)
                        {
                            p_Model.RemovePointFromModel(lista[i]);
                        }

                        foreach (Cl3DModel.Cl3DModelPointIterator point in connections)
                            pt.AddNeighbor(point);
                    }
                }
            }
        }
        private void SampleUVParametriztion(Cl3DModel p_Model, out Cl3DModel.Cl3DModelPointIterator[,] SampledModel, int MatrixWidth, int MatrixHeight)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float maxU = iter.U;
            float minU = iter.U;
            float maxV = iter.V;
            float minV = iter.V;

            do
            {
                if (maxU < iter.U)
                    maxU = iter.U;
                if (maxV < iter.V)
                    maxV = iter.V;

                if (minU > iter.U)
                    minU = iter.U;
                if (minV > iter.V)
                    minV = iter.V;
            } while (iter.MoveToNext());

            List<Cl3DModel.Cl3DModelPointIterator>[,] SampledModelList = new List<Cl3DModel.Cl3DModelPointIterator>[MatrixWidth,MatrixHeight];
            SampledModel = new Cl3DModel.Cl3DModelPointIterator[MatrixWidth, MatrixHeight];

            iter = p_Model.GetIterator();
            do
            {
                float U = iter.U - minU;
                float V = iter.V - minV;

                int RoundU = (int)((U / (maxU - minU)) * (MatrixWidth - 1));
                int RoundV = (int)((V / (maxV - minV)) * (MatrixHeight - 1));

                if(SampledModelList[RoundU, RoundV] == null)
                    SampledModelList[RoundU, RoundV] = new List<Cl3DModel.Cl3DModelPointIterator>();

                SampledModelList[RoundU, RoundV].Add(iter.CopyIterator());

               } while (iter.MoveToNext());

            for(int i=0; i< MatrixWidth; i++)
            {
                for(int j=0; j<MatrixHeight; j++)
                {
                    if(SampledModelList[i,j]!= null)
                    {
                        float x = 0;
                        float y = 0;
                        float z = 0;
                        float u = 0;
                        float v = 0;
                        int ColorR = 0;
                        int ColorG = 0;
                        int ColorB = 0;
                        string specPoint = Cl3DModel.eSpecificPoints.UnspecifiedPoint.ToString();
                        bool isSpecific = false;

                        Dictionary<string, double> SumOfSpecificValues = new Dictionary<string, double>();
                        foreach(Cl3DModel.Cl3DModelPointIterator pts in SampledModelList[i,j])
                        {
                            pts.AlreadyVisited = true;
                            if (!isSpecific)
                                isSpecific = p_Model.IsThisPointInSpecificPoints(pts, ref specPoint);

                            List<string> specValues = pts.GetListOfSpecificValues();
                            foreach (string valueName in specValues)
                            {
                                double currentVal = 0;
                                pts.GetSpecificValue(valueName, out currentVal);
                                double countedVal = 0;
                                SumOfSpecificValues.TryGetValue(valueName, out countedVal);

                                SumOfSpecificValues.Remove(valueName);
                                SumOfSpecificValues.Add(valueName, countedVal + currentVal);
                            }
                            x += pts.X;
                            y += pts.Y;
                            z += pts.Z;
                            u += pts.U;
                            v += pts.V;
                            ColorR += pts.ColorR;
                            ColorG += pts.ColorG;
                            ColorB += pts.ColorB;
                        }

                        int Count = SampledModelList[i, j].Count;

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

                        foreach (Cl3DModel.Cl3DModelPointIterator point in SampledModelList[i, j])
                            foreach (Cl3DModel.Cl3DModelPointIterator InnerPoint in point.GetListOfNeighbors())
                                if (InnerPoint.AlreadyVisited == false)
                                    connections.Add(InnerPoint);

                        Cl3DModel.Cl3DModelPointIterator pt = p_Model.AddPointToModel(x / Count,
                                                                                        y / Count,
                                                                                        z / Count);
                        pt.Color = Color.FromArgb(ColorR / Count,
                                                    ColorG / Count,
                                                    ColorB / Count);

                        pt.U = (int)((u / SampledModelList[i, j].Count) / maxU * MatrixWidth);
                        pt.V = (int)((v / SampledModelList[i, j].Count) / maxV * MatrixHeight);

                        foreach (KeyValuePair<string, double> SpecVal in SumOfSpecificValues)
                            pt.AddSpecificValue(SpecVal.Key, SpecVal.Value / Count);

                        SampledModel[i, j] = pt;

                        if (isSpecific)
                            p_Model.AddSpecificPoint(specPoint, pt);

                        foreach(Cl3DModel.Cl3DModelPointIterator point in SampledModelList[i, j])
                            p_Model.RemovePointFromModel(point);

                        foreach (Cl3DModel.Cl3DModelPointIterator point in connections)
                            pt.AddNeighbor(point);

                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string FileName = p_Model.ModelFileFolder + p_Model.ModelFileName + ".lm3";

            string line = "";
            bool bName = false;
            string Name = "";
            ClTools.MainPoint3D point = null;
            List<ClTools.MainPoint3D> points = new List<ClTools.MainPoint3D>();
            using (StreamReader FileStream = File.OpenText(FileName))
            {
                while ((line = FileStream.ReadLine()) != null)
                {
                    if (line.Contains("#") || line.Length == 0)
                        continue;

                    if (line.Contains("landmarks"))
                    {
                        bName = true;
                        continue;
                    }

                    if (bName)
                    {
                        Name = line;
                        bName = false;
                    }
                    else
                    {
                        string[] coordinates = line.Split(' ');

                        if (coordinates.Length != 3)
                            throw new Exception("Incorrect format, less than 3 coordinates for a landmark");

                        points.Add(new ClTools.MainPoint3D(Single.Parse(coordinates[0], System.Globalization.CultureInfo.InvariantCulture),
                                            Single.Parse(coordinates[1], System.Globalization.CultureInfo.InvariantCulture),
                                            Single.Parse(coordinates[2], System.Globalization.CultureInfo.InvariantCulture),
                                            Name));
                        bName = true;
                    }
                }
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
                throw new Exception("Iterator in the model is not valid!");

            do
            {
                foreach (ClTools.MainPoint3D pts in points)
                    pts.CheckClosest(iter);

            } while (iter.MoveToNext());

            foreach (ClTools.MainPoint3D pts in points)
                p_Model.AddSpecificPoint(pts.Name, pts.ClosestPoint);
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                Dictionary<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>> modelNeighbors = new Dictionary<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>>();
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    string line;
                    bool Landmarks = false;
                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Length == 0)
                            continue;
                        if (line[0].Equals('@'))
                            continue;

                        if (line.Contains("Landmark points"))
                        {
                            Landmarks = true;
                            continue;
                        }

                        if (Landmarks)
                        {
                            //Landmark points (ptID): "+nop
                            string[] splitedLine = line.Split(' ');
                            String PointLabel = splitedLine[0];
                            uint PointID = UInt32.Parse(splitedLine[1]);

                            Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.GetIterator();
                            if(!iter.MoveToPoint(PointID))
                                throw new Exception("Cannot find point no: "+PointID.ToString());

                            p_mModel3D.AddSpecificPoint(PointLabel, iter);
                        }
                        else
                        {
                            string[] splitedLine = line.Split(' ');
                            uint PointId = UInt32.Parse(splitedLine[0], System.Globalization.CultureInfo.InvariantCulture);
                            float X = Single.Parse(splitedLine[1], System.Globalization.CultureInfo.InvariantCulture);
                            float Y = Single.Parse(splitedLine[2], System.Globalization.CultureInfo.InvariantCulture);
                            float Z = Single.Parse(splitedLine[3], System.Globalization.CultureInfo.InvariantCulture);

                            int XImage = Int32.Parse(splitedLine[5], System.Globalization.CultureInfo.InvariantCulture);
                            int YImage = Int32.Parse(splitedLine[6], System.Globalization.CultureInfo.InvariantCulture);

                            Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.AddPointToModel(X, Y, Z, XImage, YImage, PointId);
                            List<uint> neighbors = new List<uint>();
                            for (int i = 9; i < splitedLine.Length - 1; i++)
                            {
                                neighbors.Add(UInt32.Parse(splitedLine[i], System.Globalization.CultureInfo.InvariantCulture));
                            }
                            modelNeighbors.Add(PointId, new KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>(iter, neighbors));
                        }
                    }
                }
                foreach(KeyValuePair<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>> onePoint in modelNeighbors)
                {
                    foreach(uint neighboorNo in onePoint.Value.Value)
                    {
                        KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>> list;
                        if(modelNeighbors.TryGetValue(neighboorNo, out list))
                            onePoint.Value.Key.AddNeighbor(list.Key);
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }