protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator leftLipsCorner = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips);
            Cl3DModel.Cl3DModelPointIterator rightLipsCorner = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips);

            Cl3DModel.Cl3DModelPointIterator UpperLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip);
            Cl3DModel.Cl3DModelPointIterator BottomLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip);

            Edge[] edges = new Edge[3];

            int Width = 0;
            int Height = 0;
            int OffsetX = 0;
            int OffsetY = 0;

            ClTools.CreateGridBasedOnRangeValues(p_Model, out Map, out Width, out Height, out OffsetX, out OffsetY);

            edges[0] = new Edge((int)leftLipsCorner.RangeImageX - OffsetX, (int)leftLipsCorner.RangeImageY - OffsetY, (int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY);
            edges[1] = new Edge((int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY, (int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY);
            edges[2] = new Edge((int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY, (int)leftLipsCorner.RangeImageX - OffsetX, (int)leftLipsCorner.RangeImageY - OffsetY);
            RemoveTriangle(edges);

            edges[0] = new Edge((int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY, (int)rightLipsCorner.RangeImageX - OffsetX, (int)rightLipsCorner.RangeImageY - OffsetY);
            edges[1] = new Edge((int)rightLipsCorner.RangeImageX - OffsetX, (int)rightLipsCorner.RangeImageY - OffsetY, (int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY);
            edges[2] = new Edge((int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY, (int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY);
            RemoveTriangle(edges);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float maxX = iter.X;
            float minX = iter.X;
            float maxY = iter.Y;
            float minY = iter.Y;

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

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

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

            Bitmap map = new Bitmap(width, height);

            ClRaserizer rasterizer = new ClRaserizer(map, width, height);

            List<ClTools.ClTriangle> triangles = null;

            iter = p_Model.GetIterator();
            do
            {
                ClTools.GetListOfTriangles(out triangles, iter);

                foreach (ClTools.ClTriangle triangle in triangles)
                {
                    int x1 = (int)(((triangle.m_point1.X - minX)/(maxX-minX)) * (width-1));
                    int y1 = (int)(((triangle.m_point1.Y - minY)/(maxY-minY)) * (height-1));

                    int x2 = (int)(((triangle.m_point2.X - minX)/(maxX-minX)) * (width-1));
                    int y2 = (int)(((triangle.m_point2.Y - minY)/(maxY-minY)) * (height-1));

                    int x3 = (int)(((triangle.m_point3.X - minX)/(maxX-minX)) * (width-1));
                    int y3 = (int)(((triangle.m_point3.Y - minY)/(maxY-minY)) * (height-1));

                    rasterizer.DrawTriangle(    triangle.m_point1.Color, x1, y1,
                                                triangle.m_point2.Color, x2, y2,
                                                triangle.m_point3.Color, x3, y3
                                                );
                }
            } while (iter.MoveToNext());

            if (CenterFaceBasedOnNoseTip)
            {
                Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

                int NoseTipX = (int)(((NoseTip.X - minX) / (maxX - minX)) * (width - 1));
                int NoseTipY = (int)(((NoseTip.Y - minY) / (maxY - minY)) * (height - 1));

                int MaxDistanceFromTheNoseTip = (int)Math.Max(Math.Max(NoseTipX, NoseTipY), Math.Max(Math.Abs(width - NoseTipX), Math.Abs(height - NoseTipY)));

                int OffsetX = (int)((MaxDistanceFromTheNoseTip) - NoseTipX);
                int OffsetY = (int)((MaxDistanceFromTheNoseTip) - NoseTipY);

                Bitmap NewMap = new Bitmap((MaxDistanceFromTheNoseTip * 2), (MaxDistanceFromTheNoseTip * 2));

                for (int i = 0; i < width; i++)
                    for (int j = 0; j < height; j++)
                        NewMap.SetPixel(OffsetX + i, OffsetY + j, map.GetPixel(i, j));

                map = NewMap;
            }

            if (m_FixedSize)
            {
                Bitmap bmp = new Bitmap(NewWidth, NewHeight);
                Graphics graphic = Graphics.FromImage((Image)bmp);
                graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphic.DrawImage(map, 0, 0, NewWidth, NewHeight);
                graphic.Dispose();
                map = bmp;
            }

            if (rotate180)
                map.RotateFlip(RotateFlipType.Rotate180FlipNone);
            map.Save(p_Model.ModelFilePath + m_sFilePostFix + ".bmp");
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator Center = p_Model.GetSpecificPoint( Cl3DModel.eSpecificPoints.NoseTip);

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            List<Cl3DModel.Cl3DModelPointIterator> BoundaryVertexes = new List<Cl3DModel.Cl3DModelPointIterator>();
            Cl3DModel.Cl3DModelPointIterator BeginningPoint = null;
            do
            {
                if (iter.GetListOfNeighbors().Count <= 7)
                {
                    iter.AlreadyVisited = true;
                   // iter.Color = Color.Red;

                    if (BeginningPoint == null)
                        BeginningPoint = iter.CopyIterator();

                    BoundaryVertexes.Add(iter.CopyIterator());
                }
            } while (iter.MoveToNext());

            Cl3DModel.Cl3DModelPointIterator CurrentPoint = BeginningPoint.CopyIterator();
            Vector NormalVector = new Vector(3);
            bool IsNextInTheQue = false;
            float CurrentNo = 0;
            do
            {
                CurrentPoint.AlreadyVisited = false;
                Cl3DModel.Cl3DModelPointIterator NextPoint = null;
                IsNextInTheQue = false;
                foreach (Cl3DModel.Cl3DModelPointIterator neighbor in CurrentPoint.GetListOfNeighbors())
                {
                    if (neighbor.AlreadyVisited) // means next in the que
                    {
                        NextPoint = neighbor.CopyIterator();
                        IsNextInTheQue = true;
                        break;
                    }
                }
                if (NextPoint == null)
                    break;

                Vector tmpVectorCurr = new Vector(new double[] { (CurrentPoint.X - Center.X), (CurrentPoint.Y - Center.Y), (CurrentPoint.Z - Center.Z) });
                Vector tmpVectorNext = new Vector(new double[] { (NextPoint.X - Center.X), (NextPoint.Y - Center.Y), (NextPoint.Z - Center.Z) });

                NormalVector[0] += (tmpVectorNext[1] * tmpVectorCurr[2] - tmpVectorNext[2] * tmpVectorCurr[1]);
                NormalVector[1] += (tmpVectorNext[2] * tmpVectorCurr[0] - tmpVectorNext[0] * tmpVectorCurr[2]);
                NormalVector[2] += (tmpVectorNext[0] * tmpVectorCurr[1] - tmpVectorNext[1] * tmpVectorCurr[0]);

                NormalVector /= 2;
                CurrentPoint.Color = ClTools.GetColorRGB(CurrentNo / BoundaryVertexes.Count, 1f);
                CurrentNo++;

                CurrentPoint = NextPoint.CopyIterator();
            } while (IsNextInTheQue);

            //NormalVector = NormalVector.Normalize();
            Center.AddNeighbor(p_Model.AddPointToModel((float)NormalVector[0]+ Center.X, (float)NormalVector[1] + Center.Y, (float)NormalVector[2] + Center.Z));

             /*   Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            while(iter.IsValid())
            {
                float X = iter.X;
                float Y = iter.Y;
                float Z = iter.Z;
                ClTools.RotateXDirection(X, Y, Z, agnleX, out X, out Y, out Z);
                ClTools.RotateYDirection(X, Y, Z, angleY, out X, out Y, out Z);
                ClTools.RotateZDirection(X, Y, Z, agnleZ, out X, out Y, out Z);

                iter.X = X;
                iter.Y = Y;
                iter.Z = Z;

                if (!iter.MoveToNext())
                    break;
            }
              */
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator nose = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());

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

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                double distance = 0;
                if (iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out distance))
                {
                    if (distance > m_fDistence)
                        iter = p_Model.RemovePointFromModel(iter);
                    else
                    {
                        if (!iter.MoveToNext())
                            break;
                    }
                }
                else
                    iter = p_Model.RemovePointFromModel(iter);

            }while(iter.IsValid());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator ManualNoseTip = p_Model.GetSpecificPoint("NoseTip");
            Cl3DModel.Cl3DModelPointIterator ManualLeftEyeCorner = p_Model.GetSpecificPoint("LeftEyeRightCorner");
            Cl3DModel.Cl3DModelPointIterator ManualRightEyeCorner = p_Model.GetSpecificPoint("RightEyeLeftCorner");

            Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint("AutomaticNoseTip");
            Cl3DModel.Cl3DModelPointIterator LeftEyeRightCorner = p_Model.GetSpecificPoint("AutomaticLeftEyeRightCorner");
            Cl3DModel.Cl3DModelPointIterator RightEyeLeftCorner = p_Model.GetSpecificPoint("AutomaticRightEyeLeftCorner");

            float NoseDistance = ManualNoseTip - NoseTip;
            float RightEyeDistance = ManualRightEyeCorner - RightEyeLeftCorner;
            float LeftEyeDistance = ManualLeftEyeCorner - LeftEyeRightCorner;
            TotalModels++;

            if (NoseDistance > 20 || RightEyeDistance > 20 || LeftEyeDistance > 20)
            {
                TextWriter rr = new StreamWriter("d:\\Incorrect.txt", true);
                rr.WriteLine(p_Model.ModelFilePath + " " + NoseDistance.ToString() + " " + RightEyeDistance.ToString() + " " + LeftEyeDistance.ToString());
                rr.Close();
            }

            Dictionary<int, int[]> Dict = null;
            if(!Precision.TryGetValue("NoseTip", out Dict))
            {
                Dict = new Dictionary<int, int[]>();
                Precision.Add("NoseTip", Dict);
            }
            int[] outVal = null;
            if (!Dict.TryGetValue((int)NoseDistance, out outVal))
            {
                outVal = new int[1];
                Dict.Add((int)NoseDistance, outVal);
            }
            outVal[0]++;

            if (!Precision.TryGetValue("LeftEye", out Dict))
            {
                Dict = new Dictionary<int, int[]>();
                Precision.Add("LeftEye", Dict);
            }
            if (!Dict.TryGetValue((int)LeftEyeDistance, out outVal))
            {
                outVal = new int[1];
                Dict.Add((int)LeftEyeDistance, outVal);
            }
            outVal[0]++;

            if (!Precision.TryGetValue("RightEye", out Dict))
            {
                Dict = new Dictionary<int, int[]>();
                Precision.Add("RightEye", Dict);
            }
            if (!Dict.TryGetValue((int)RightEyeDistance, out outVal))
            {
                outVal = new int[1];
                Dict.Add((int)RightEyeDistance, outVal);
            }
            outVal[0]++;

            TextWriter tw = new StreamWriter("d:\\PointsPrecision.txt", false);
            foreach(KeyValuePair<string, Dictionary<int, int[]>> prc in Precision)
            {
                tw.WriteLine(prc.Key);
                string Line1 = "";
                string Line2 = "";
                foreach (KeyValuePair<int, int[]> dd in prc.Value)
                {
                    Line1 += " " + dd.Key.ToString();
                    Line2 += " " + dd.Value[0].ToString();
                }
                tw.WriteLine(Line1);
                tw.WriteLine(Line2);
            }
            tw.Close();
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator EyePoint1 = null;
            Cl3DModel.Cl3DModelPointIterator EyePoint2 = null;
            Cl3DModel.Cl3DModelPointIterator NosePoint = null;

            if (!p_Model.GetSpecificPoint(LeftEyeLabel, ref EyePoint1))
                throw new Exception("Cannot find specific point labeled as: " + LeftEyeLabel);
            if (!p_Model.GetSpecificPoint(RightEyeLabel, ref EyePoint2))
                throw new Exception("Cannot find specific point labeled as: " + RightEyeLabel);
            if (!p_Model.GetSpecificPoint(NoseLabel, ref NosePoint))
                throw new Exception("Cannot find specific point labeled as: " + NoseLabel);

            Matrix GenModel = new Matrix(3, 3);
            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose
            GenModel[2, 0] = 0;

            GenModel[0, 1] = -22f;
            GenModel[1, 1] = 34f; // left eye
            GenModel[2, 1] = -35f;

            GenModel[0, 2] = 22f;
            GenModel[1, 2] = 34f; // right eye
            GenModel[2, 2] = -35f;

            Matrix Model = new Matrix(3, 3);

            Cl3DModel.Cl3DModelPointIterator point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Model[0, 0] = point.X;
            Model[1, 0] = point.Y; // nose
            Model[2, 0] = point.Z;

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Model[0, 1] = point.X;
            Model[1, 1] = point.Y; // left eye
            Model[2, 1] = point.Z;

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
            Model[0, 2] = point.X;
            Model[1, 2] = point.Y; // right eye
            Model[2, 2] = point.Z;

            Matrix rotationMatrix = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                Matrix V = rotationMatrix * iter + translationMatrix;
                iter.X = (float)V[0, 0];
                iter.Y = (float)V[1, 0];
                iter.Z = (float)V[2, 0];

            } while (iter.MoveToNext());

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            float x = point.X;
            float y = point.Y;
            float z = point.Z;
            iter = p_Model.GetIterator();
            do
            {
                iter.X = iter.X - x;
                iter.Y = iter.Y - y;
                iter.Z = iter.Z - z;
            } while (iter.MoveToNext());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator CenterPoint = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            Cl3DModel.Cl3DModelPointIterator max = iter.CopyIterator();
            float distanceMax = 0;

            do
            {
                float distance = (float)Math.Sqrt(Math.Pow(iter.U, 2) + Math.Pow(iter.V, 2));
                if (distanceMax < distance)
                    distanceMax = distance;

            } while (iter.MoveToNext());

            Complex z0 = new Complex(CenterPoint.U / distanceMax, CenterPoint.V / distanceMax);
            iter = p_Model.GetIterator();
            do
            {
                Complex newPoint = Mobius(m_Theta, z0, new Complex((iter.U / distanceMax), (iter.V / distanceMax)));
                iter.U = (float)newPoint.Real * distanceMax;
                iter.V = (float)newPoint.Imag * distanceMax;
            } while (iter.MoveToNext());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;
            if (!p_Model.GetSpecificPoint(m_point, ref NoseTip))
                throw new Exception("Cannot get point " + m_point);

             //   p_Model.RemoveAllSpecificPoints();
            p_Model.RemovePointFromModel(NoseTip);
        }
        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);
            */
            //---------------------------------------------------------------------------
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            if(m_sFileName.Length == 0)
                m_sFileName = p_Model.ModelFileFolder + p_Model.ModelFileName + ".m2";

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

            using (TextWriter tw = new StreamWriter(m_sFileName, false))
            {
                Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
                tw.WriteLine("CenterVertex " + (NoseTip.PointID + 1).ToString());
                do
                {
                    uint ID = iter.PointID + 1;

                    double geodesicDistance = 0;
                    if (!iter.GetSpecificValue("GeodesicDistanceToNoseTip", out geodesicDistance))
                    {
                        geodesicDistance = 100;
                    }

                    int R = 0;
                    R = (R << 8) + (int)iter.Color.R;
                    int G = 0;
                    G = (G << 8) + (int)iter.Color.G;
                    int B = 0;
                    B = (B << 8) + (int)iter.Color.B;

                    string line = "Vertex " + ID.ToString(System.Globalization.CultureInfo.InvariantCulture) + "  "
                                            + iter.X.ToString(System.Globalization.CultureInfo.InvariantCulture) + " "
                                            + iter.Y.ToString(System.Globalization.CultureInfo.InvariantCulture) + " "
                                            + iter.Z.ToString(System.Globalization.CultureInfo.InvariantCulture) + " "
                                            + geodesicDistance.ToString(System.Globalization.CultureInfo.InvariantCulture) + " {rgb=("
                                            + ((float)R / 255.0f).ToString(System.Globalization.CultureInfo.InvariantCulture) + " "
                                            + ((float)G / 255.0f).ToString(System.Globalization.CultureInfo.InvariantCulture) + " "
                                            + ((float)B / 255.0f).ToString(System.Globalization.CultureInfo.InvariantCulture) + ")}";

                    tw.WriteLine(line);

                } while (iter.MoveToNext());

                // --- create faces
                iter = p_Model.GetIterator();
                uint FaceNO = 1;
                do
                {
                    iter.AlreadyVisited = true;

                    List<Cl3DModel.Cl3DModelPointIterator> neighbors = iter.GetListOfNeighbors();

                    uint MainPointID = iter.PointID+1;

                    uint point1 = 0;
                    bool point1Founded = false;
                    uint point2 = 0;
                    bool point2Founded = false;
                    uint point3 = 0;
                    bool point3Founded = false;
                    uint point4Exc = 0;
                    bool point4ExcFounded = false;
                    uint point5Exc = 0;
                    bool point5ExcFounded = false;
                    uint point6Exc = 0;
                    bool point6ExcFounded = false;

                    foreach (Cl3DModel.Cl3DModelPointIterator point in neighbors)
                    {
                        if (point.RangeImageY == iter.RangeImageY && point.RangeImageX > iter.RangeImageX) // first point
                        {
                            point1 = point.PointID+1;
                            point1Founded = true;
                        }
                        if (point.RangeImageY > iter.RangeImageY && point.RangeImageX > iter.RangeImageX) // second point
                        {
                            point2 = point.PointID+1;
                            point2Founded = true;
                        }
                        if (point.RangeImageY > iter.RangeImageY && point.RangeImageX == iter.RangeImageX) // third point
                        {
                            point3 = point.PointID+1;
                            point3Founded = true;
                        }
                        if (point.RangeImageY < iter.RangeImageY && point.RangeImageX > iter.RangeImageX) // second point
                        {
                            point4Exc = point.PointID + 1;
                            point4ExcFounded = true;
                        }
                        if (point.RangeImageY > iter.RangeImageY && point.RangeImageX < iter.RangeImageX) // second point
                        {
                            point5Exc = point.PointID + 1;
                            point5ExcFounded = true;
                        }
                        if (point.RangeImageY < iter.RangeImageY && point.RangeImageX == iter.RangeImageX) // second point
                        {
                            point6Exc = point.PointID + 1;
                            point6ExcFounded = true;
                        }
                    }

                    string line = "";
                    if (point1Founded && point2Founded)
                    {
                        line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point2.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point1.ToString(System.Globalization.CultureInfo.InvariantCulture) + "\n";
                        FaceNO++;
                        if (point3Founded)
                        {
                            line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point3.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point2.ToString(System.Globalization.CultureInfo.InvariantCulture)+"\n";
                            FaceNO++;
                        }
                        if (!point6ExcFounded && point4ExcFounded)
                        {
                            line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point1.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point4Exc.ToString(System.Globalization.CultureInfo.InvariantCulture) + "\n";
                            FaceNO++;
                        }

                    }
                    else if (point1Founded && point3Founded)
                    {
                        line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point3.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point1.ToString(System.Globalization.CultureInfo.InvariantCulture) +"\n";
                        FaceNO++;
                    }
                    else if (point2Founded && point3Founded)
                    {
                        line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point3.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point2.ToString(System.Globalization.CultureInfo.InvariantCulture) +"\n";
                        FaceNO++;

                    }
                    /*else if (point1Founded && !point2Founded && !point3Founded && point4ExcFounded)
                    {
                        line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point4Exc.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point1.ToString(System.Globalization.CultureInfo.InvariantCulture) + "\n";
                        FaceNO++;

                    }
                     */
                    /*else if (!point1Founded && !point2Founded && point3Founded && point5ExcFounded)
                    {
                        line += "Face " + FaceNO.ToString() + "  " + MainPointID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point3.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                                        point5Exc.ToString(System.Globalization.CultureInfo.InvariantCulture) + "\n";
                        FaceNO++;

                    }
                */
                    tw.Write(line);

                } while (iter.MoveToNext());
                tw.Close();
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string name = p_Model.ModelFileFolder + p_Model.ModelFileName + m_sFilePostFix;

            if (!OnlyIDs)
            {
                name += ".pts";
                List<KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>> specPoints = p_Model.GetAllSpecificPoints();
                using (TextWriter tw = new StreamWriter(name, false))
                {
                    tw.WriteLine("@----------------------------------------");
                    tw.WriteLine("@      Przemyslaw Szeptycki LIRIS 2009");
                    tw.WriteLine("@           [email protected]");
                    tw.WriteLine("@     Model Specific Points Coordinates");
                    tw.WriteLine("@    ID = ID + 1 the same like in M file");
                    tw.WriteLine("@   Model name: " + p_Model.ModelFileName);
                    tw.WriteLine("@----------------------------------------");
                    tw.WriteLine("@ Name Id X Y Z");
                    foreach (KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator> point in specPoints)
                    {
                        uint ID = point.Value.PointID + 1; // in the M  file all IDs starts from 1 and in our case from 0
                        string line = point.Key + " " + ID.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " + point.Value.X.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " + point.Value.Y.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " + point.Value.Z.ToString(System.Globalization.CultureInfo.InvariantCulture);
                        tw.WriteLine(line);
                    }
                    tw.Close();
                }
            }
            else
            {
                List<Cl3DModel.Cl3DModelPointIterator> PointsToSave = new List<Cl3DModel.Cl3DModelPointIterator>();
                PointsToSave.Add(p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip));
                PointsToSave.Add(p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner));
                PointsToSave.Add(p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner));

                string nameID = name + ".ptsID";
                using (TextWriter tw = new StreamWriter(nameID, false))
                {
                    tw.WriteLine(PointsToSave.Count.ToString());
                    foreach (Cl3DModel.Cl3DModelPointIterator point in PointsToSave)
                    {
                        uint ID = point.PointID + 1;
                        tw.WriteLine(ID.ToString());
                    }
                    tw.Close();
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator InnerRightEyeCorner = p_Model.GetSpecificPoint("Inner right eye corner");
            Cl3DModel.Cl3DModelPointIterator OuterLeftEyeCorner = p_Model.GetSpecificPoint("Outer left eye corner");
            Cl3DModel.Cl3DModelPointIterator InnerLeftEyeCorner = p_Model.GetSpecificPoint("Inner left eye corner");
            Cl3DModel.Cl3DModelPointIterator OuterRightEyeCorner = p_Model.GetSpecificPoint("Outer right eye corner");

             //   List<Cl3DModel.Cl3DModelPointIterator> InnerPath= null;
             //   List<Cl3DModel.Cl3DModelPointIterator> OuterPath = null;
             //   ClTools.GetPathBetweenPoints(InnerRightEyeCorner, InnerLeftEyeCorner, out InnerPath);
             //   ClTools.GetPathBetweenPoints(OuterLeftEyeCorner, OuterRightEyeCorner, out OuterPath);

            float InnerDistance = InnerRightEyeCorner - InnerLeftEyeCorner;
            float OuterDistance = OuterRightEyeCorner - OuterLeftEyeCorner;
            float distanceBetweenCenter = InnerDistance + ((OuterDistance - InnerDistance) / 2);

            double RangeInnerDistance = Math.Sqrt(Math.Pow(InnerRightEyeCorner.X - InnerLeftEyeCorner.X, 2) + Math.Pow(InnerRightEyeCorner.Y - InnerLeftEyeCorner.Y, 2));
            double RangeOuterDistance = Math.Sqrt(Math.Pow(OuterRightEyeCorner.X - OuterLeftEyeCorner.X, 2) + Math.Pow(OuterRightEyeCorner.Y - OuterLeftEyeCorner.Y, 2));
            double RangedistanceBetweenCenter = RangeInnerDistance + ((RangeOuterDistance - RangeInnerDistance) / 2);

            noOfFiles++;
            MeanDistance += distanceBetweenCenter;
            RangeMeanDistance += RangedistanceBetweenCenter;

            TextWriter rr = new StreamWriter("d:\\Distance between eyes.txt", true);
            rr.WriteLine("\n[" + p_Model.ModelFileName + "] Euclidean 3D distance between center of eyes: " + distanceBetweenCenter.ToString() + " \t Mean distance using: " + noOfFiles.ToString() +" models - equals: " + (MeanDistance/noOfFiles).ToString());
            rr.WriteLine("[" + p_Model.ModelFileName + "] Euclidean 2D distance between center of eyes: " + RangedistanceBetweenCenter.ToString() + " \t Mean distance using: " + noOfFiles.ToString() + " models - equals: " + (RangeMeanDistance / noOfFiles).ToString());
            rr.Close();

            /*	Outer left eyebrow(ID: 26920)
             Middle left eyebrow(ID: 30354)
             Inner left eyebrow(ID: 29548)
             Inner right eyebrow(ID: 29249)
             Middle right eyebrow(ID: 30463)
             Outer right eyebrow(ID: 26540)
             Outer left eye corner(ID: 24998)
             Inner left eye corner(ID: 25394)
             Inner right eye corner(ID: 25612)
             Outer right eye corner(ID: 24768)
             Nose saddle left(ID: 23625)
             Nose saddle right(ID: 23641)
             Left nose peak(ID: 17116)
             Nose tip(ID: 18581)
             Right nose peak(ID: 17161)
             Left mouth corner(ID: 8618)
             Upper lip outer middle(ID: 10022)
             Right mouth corner(ID: 8854)
             Upper lip inner middle(ID: 9332)
             Lower lip inner middle(ID: 8819)
             Lower lip outer middle(ID: 7971)
             Chin middle(ID: 1082)/*

             //            File.Delete(p_Model.ModelFilePath);

             /*

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

             while (iter.MoveToNext())
             {
                 double GroundK = iter.GetSpecificValue("GroundK");
                 double GroundH = iter.GetSpecificValue("GroundH");

                 double K_25 = iter.GetSpecificValue("Gaussian_25");
                 double H_25 = iter.GetSpecificValue("Mean_25");

                 iter.AddSpecificValue("DiffK", GroundK - K_25);
                 iter.AddSpecificValue("DiffH", GroundH - Math.Sqrt(H_25));
             }
             */
               // List<Cl3DModel.Cl3DModelPointIterator> Neighb = maxIter.GetListOfNeighbors();
              //      ClTools.GetNeighborhoodWithGeodesicDistance(out Neighb, maxIter, 30);
              //  foreach (Cl3DModel.Cl3DModelPointIterator it in Neighb)
               //     it.Color = Color.Red;

               //     if (maxIter.IsValid())
               //     {
               //         p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), maxIter);
               //     }

            /*
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                if (iter.Z < 0)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                    iter.MoveToNext();

            } while (iter.IsValid());
            */

              /*  Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                double mean25 = 0;
                double meanmena25 = 0;

                double Gaussian = 0;
                double meanGaussian = 0;

                if(!iter.GetSpecificValue("Mean_15",out mean25) || !iter.GetSpecificValue("Mean_Mean_15", out meanmena25))
                    continue;
                if (!iter.GetSpecificValue("Gaussian_15", out Gaussian) || !iter.GetSpecificValue("Mean_Gaussian_15", out meanGaussian))
                    continue;

                if (mean25 * meanmena25 < 0.0f)
                    iter.Color = Color.Red;

                if (Gaussian * meanGaussian < 0.0f)
                    iter.Color = Color.Blue;

            } while (iter.MoveToNext());

            return;
            */
            /*
            //------------------------------
            double distances = 0;
            int count = 0;
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                foreach (Cl3DModel.Cl3DModelPointIterator neighb in iter.GetListOfNeighbors())
                {
                    if (!neighb.AlreadyVisited)
                    {
                        double tmpDist = iter - neighb;
                        distances += tmpDist;
                        count++;
                        neighb.AlreadyVisited = true;
                    }
                }

            } while (iter.MoveToNext());

            TextWriter tw = new StreamWriter("d:\\CurvatureStability.txt", true);
            tw.WriteLine("\n"+p_Model.ModelFileName+" Vetrex count: "+p_Model.ModelPointsCount.ToString());
            tw.WriteLine("Mean distance between points: " + (distances / count).ToString());
            tw.WriteLine("Distances between points: " + distances.ToString());
            tw.WriteLine("No of added distances: " + count.ToString());
            List<KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>> SpecificPoints = new List<KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>>();
            SpecificPoints.Add(new KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>("NoseTip", p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip)));
            SpecificPoints.Add(new KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>("LeftEye", p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner)));
            SpecificPoints.Add(new KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator>("RightEye", p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner)));

            foreach (KeyValuePair<string, Cl3DModel.Cl3DModelPointIterator> sp in SpecificPoints)
            {
                tw.WriteLine(sp.Key);
                Cl3DModel.Cl3DModelPointIterator iter2 = sp.Value;
                foreach (string valueName in iter2.GetListOfSpecificValues())
                {
                    double value = iter2.GetSpecificValue(valueName);
                    tw.WriteLine("\t"+valueName + " " + value.ToString(System.Globalization.CultureInfo.InvariantCulture));
                }
            }
            tw.Close();
            */

            //------------------------------------ POINTS DISTANCES FO NEAR ISOMETRIC FACE TREATING
            /*Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint("NoseTip");
             Cl3DModel.Cl3DModelPointIterator point5 = p_Model.GetSpecificPoint("point4");
             Cl3DModel.Cl3DModelPointIterator point8 = p_Model.GetSpecificPoint("point7");
             Cl3DModel.Cl3DModelPointIterator point2 = p_Model.GetSpecificPoint("point3");
             Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
             List<Cl3DModel.Cl3DModelPointIterator> Boundarys = new List<Cl3DModel.Cl3DModelPointIterator>();
             do
             {
                 if (iter.GetListOfNeighbors().Count < 6 &&
                     iter.Y < NoseTip.Y && iter.Y > point5.Y &&
                     iter.X > point8.X && iter.X < point2.X
                     )
                 {
                     Boundarys.Add(iter.CopyIterator());
                 //    iter.Color = Color.Red;
                 }
             } while (iter.MoveToNext());

             Cl3DModel.Cl3DModelPointIterator MaxLeft = Boundarys[0];
             Cl3DModel.Cl3DModelPointIterator MaxRight = Boundarys[0];
             foreach (Cl3DModel.Cl3DModelPointIterator pt in Boundarys)
             {
                 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 Boundarys)
             {
                 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);

                         Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                         LowerPoint.Color = cl;
                         UpperPoint.Color = cl;
                         movingPoints.Add(UpperPoint.PointID, LowerPoint.PointID);
                     }
                 }
             }

             ClTools.CalculateGeodesicDistanceFromSourcePointToAllPointsWithMovement(NoseTip, "GeodesicWithTheMovingPoints", movingPoints);
             */
            /*
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NoseTip, "GeodesicWith");
            return;

            List<Cl3DModel.Cl3DModelPointIterator> InterestingPoint = new List<Cl3DModel.Cl3DModelPointIterator>();
            InterestingPoint.Add(p_Model.GetSpecificPoint("point1"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point2"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point3"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point4"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point5"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point6"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point7"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point8"));
            InterestingPoint.Add(p_Model.GetSpecificPoint("point9"));

            TextWriter tw = new StreamWriter("d:\\PointsDistanceEuclidean.txt", true);
            tw.WriteLine(p_Model.ModelFileName);
            foreach (Cl3DModel.Cl3DModelPointIterator pt in InterestingPoint)
            {
                double distance = pt - NoseTip;//.GetSpecificValue("GeodesicWith");
                string label = "";
                pt.IsLabeled(out label);
                tw.WriteLine(label + " " + distance.ToString(System.Globalization.CultureInfo.InvariantCulture));
            }
            tw.Close();
             */
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;

            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref NoseTip))
                throw new Exception("Cannot find specific point NoseTip");

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            while(iter.IsValid())
            {
                bool isOk = false;
                if (iter.Z < NoseTip.X && iter.Z > NoseTip.Z - m_fPlaneDistanceZ)
                {
                    isOk = true;
                }

                if (!isOk)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    if (!iter.MoveToNext())
                        break;
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator LeftEyeRightCornerPoint = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEyeLeftCornerPoint = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
            Cl3DModel.Cl3DModelPointIterator NoseTipPoint = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

            if (m_bEuclidean)
            {
                CalculateEuclideanDistancesFromPoint("XYZ_LeftEyeRightCornerDistance", LeftEyeRightCornerPoint, p_Model);
                CalculateEuclideanDistancesFromPoint("XYZ_RightEyeLeftCornerDistance", RightEyeLeftCornerPoint, p_Model);
                CalculateEuclideanDistancesFromPoint("XYZ_NoseTipDistance", NoseTipPoint, p_Model);
            }
            else
            {
                Cl3DModel.Cl3DModelPointIterator iterRmoeve = p_Model.GetIterator();
                do
                {
                    iterRmoeve.RemoveSpecificValue("XYZ_LeftEyeRightCornerDistance");
                    iterRmoeve.RemoveSpecificValue("XYZ_RightEyeLeftCornerDistance");
                    iterRmoeve.RemoveSpecificValue("XYZ_NoseTipDistance");
                } while (iterRmoeve.MoveToNext());
                CalculateGeodesicDistancesFromPoint("XYZ_LeftEyeRightCornerDistance", LeftEyeRightCornerPoint, p_Model);
                CalculateGeodesicDistancesFromPoint("XYZ_RightEyeLeftCornerDistance", RightEyeLeftCornerPoint, p_Model);
                CalculateGeodesicDistancesFromPoint("XYZ_NoseTipDistance", NoseTipPoint, p_Model);
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                double XYZ_LeftEyeRightCornerDistance = 0;
                iter.GetSpecificValue("XYZ_LeftEyeRightCornerDistance", out XYZ_LeftEyeRightCornerDistance);

                double XYZ_RightEyeLeftCornerDistance = 0;
                iter.GetSpecificValue("XYZ_RightEyeLeftCornerDistance", out XYZ_RightEyeLeftCornerDistance);

                double XYZ_NoseTipDistance = 0;
                iter.GetSpecificValue("XYZ_NoseTipDistance", out XYZ_NoseTipDistance);

                double alldistances = Math.Sqrt(Math.Pow(XYZ_LeftEyeRightCornerDistance, 2) + Math.Pow(XYZ_RightEyeLeftCornerDistance, 2) + Math.Pow(XYZ_NoseTipDistance, 2));
                iter.AddSpecificValue("AllDistancesXYZ", alldistances);
            } while (iter.MoveToNext());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;

            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref NoseTip))
                throw new Exception("Cannot find specific point NoseTip");

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float MaxZ = float.MinValue;
            float MinZ = float.MaxValue;
            do
            {
                if(MaxZ < iter.Z)
                    MaxZ = iter.Z;
                if(MinZ > iter.Z)
                    MinZ = iter.Z;
            }while(iter.MoveToNext());

            float step = 1f;
            int name = (int)step;
            List<Cl3DModel.Cl3DModelPointIterator> PointsToRemove = new List< Cl3DModel.Cl3DModelPointIterator>();
            for (float Threshold = NoseTip.Z - step; Threshold > MinZ; Threshold -= step)
            {
                List<Cl3DModel.Cl3DModelPointIterator> PointsToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                List<Cl3DModel.Cl3DModelPointIterator> NewPoinsToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                List<Cl3DModel.Cl3DModelPointIterator> VisitedPoints = new List<Cl3DModel.Cl3DModelPointIterator>();
                PointsToCheck.Add(NoseTip.CopyIterator());
                while (PointsToCheck.Count != 0)
                {
                    foreach (Cl3DModel.Cl3DModelPointIterator point in PointsToCheck)
                    {
                        if(point.IsSpecificValueCalculated("ToRemove"))
                            continue;

                        point.AlreadyVisited = true;
                        VisitedPoints.Add(point.CopyIterator());

                        List<Cl3DModel.Cl3DModelPointIterator> Neighbors = point.GetListOfNeighbors();
                        foreach (Cl3DModel.Cl3DModelPointIterator Neighb in Neighbors)
                        {
                            if(Neighb.IsSpecificValueCalculated("ToRemove"))
                                continue;
                            if (Neighb.Z > Threshold && !Neighb.AlreadyVisited)
                            {
                                Neighb.AlreadyVisited = true;
                                NewPoinsToCheck.Add(Neighb.CopyIterator());
                            }
                        }
                    }
                    PointsToCheck = NewPoinsToCheck;
                    NewPoinsToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                }
                Cl3DModel.Cl3DModelPointIterator unconnected = p_Model.GetIterator();
                do
                {
                    if (!unconnected.AlreadyVisited && unconnected.Z > Threshold && !unconnected.IsSpecificValueCalculated("ToRemove"))
                    {
                        if (m_SaveScreenShots)
                            unconnected.Color = Color.Red;
                        unconnected.AddSpecificValue("ToRemove", 1.0f);
                        PointsToRemove.Add(unconnected.CopyIterator());
                    }
                } while (unconnected.MoveToNext());

                foreach (Cl3DModel.Cl3DModelPointIterator pts in VisitedPoints)
                {
                    if (m_SaveScreenShots)
                        pts.Color = Color.Green;
                    pts.AlreadyVisited = false;
                }
                if (m_SaveScreenShots)
                {
                    Bitmap mapa;
                    p_Model.GetBMPImage(out mapa, 1.0f);
                    mapa.Save(p_Model.ModelFilePath + name.ToString() + ".bmp");
                    name += (int)step;
                }
            }
            List<Cl3DModel.Cl3DModelPointIterator> RemPointsVisited = new List<Cl3DModel.Cl3DModelPointIterator>();
            foreach (Cl3DModel.Cl3DModelPointIterator RemPoint in PointsToRemove)
            {
                if(!RemPoint.IsValid() || RemPoint.AlreadyVisited)
                    continue;

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

                PointsToCheck.Add(RemPoint);
                bool remove = false;
                while (PointsToCheck.Count != 0)
                {
                    List<Cl3DModel.Cl3DModelPointIterator> NewPtsToCheck = new List<Cl3DModel.Cl3DModelPointIterator>();
                    foreach (Cl3DModel.Cl3DModelPointIterator pt in PointsToCheck)
                    {
                        if (!pt.IsValid() || pt.AlreadyVisited)
                            continue;
                        pt.AlreadyVisited = true;

                        RemPointsVisited.Add(pt);

                        List<Cl3DModel.Cl3DModelPointIterator> Neighbors = pt.GetListOfNeighbors();
                        if (Neighbors.Count != 8)
                        {
                            remove = true;
                        }
                        else
                        {
                            foreach(Cl3DModel.Cl3DModelPointIterator ne in Neighbors)
                            {
                                if (ne.IsSpecificValueCalculated("ToRemove") && !ne.AlreadyVisited)
                                    NewPtsToCheck.Add(ne);
                            }
                        }
                    }
                    PointsToCheck = NewPtsToCheck;
                }
                if (remove)
                {
                    foreach (Cl3DModel.Cl3DModelPointIterator ppt in RemPointsVisited)
                        p_Model.RemovePointFromModel(ppt);
                }
                RemPointsVisited = new List<Cl3DModel.Cl3DModelPointIterator>();
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string name = p_Model.ModelFileFolder + p_Model.ModelFileName + m_sFilePostFix +".Angle";

            Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());
            Cl3DModel.Cl3DModelPointIterator rightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Cl3DModel.Cl3DModelPointIterator leftEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());

            float MeanX = (rightEye.X + leftEye.X) / 2;
            float MeanY = (rightEye.Y + leftEye.Y) / 2;

            float rotation = ClTools.GetAngle2D(MeanX, MeanY, 0, 1);

            rotation = rotation * ((float)Math.PI / 180);

            using (TextWriter tw = new StreamWriter(name, false))
            {
                tw.WriteLine(
                    NoseTip.X.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                    NoseTip.Y.ToString(System.Globalization.CultureInfo.InvariantCulture));

                tw.WriteLine(rotation.ToString(System.Globalization.CultureInfo.InvariantCulture));

                tw.Close();
            }
        }
        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)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;

            if (!p_Model.GetSpecificPoint(m_NoseTipName, ref NoseTip))
                throw new Exception("Cannot find specific point NoseTip");

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            while(iter.IsValid())
            {
                bool isOk = false;
                if (ClTools.IsItInsideSphere(iter.X, iter.Y, iter.Z, NoseTip.X, NoseTip.Y, NoseTip.Z + m_fBottomSphereNoseTipZoffset, m_fBottomSphereRadious))
                {
                    if (ClTools.IsItInsideSphere(iter.X, iter.Y, iter.Z, NoseTip.X, NoseTip.Y, NoseTip.Z + m_fUpperSphereNoseTipZoffset, m_fUpperSphereRadious))
                    {
                        isOk = true;
                    }
                }

                if (!isOk)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    if (!iter.MoveToNext())
                        break;
                }
            }
        }
        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)
        {
            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();
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            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 eyesDistance = LeftEye - RightEye;

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            do
            {
                float NoseDistance = NoseTip - iter;
                float LeftEyeDistance = LeftEye - iter;
                float RightEyeDistance = RightEye - iter;

                if (NoseDistance > 40 && NoseDistance < 50 && LeftEyeDistance > 50 && LeftEyeDistance < 70 && RightEyeDistance > 50 && RightEyeDistance < 70)
                {
                    iter.Color = Color.Red;
                }
            } while (iter.MoveToNext());

            /*List<Cl3DModel.Cl3DModelPointIterator> neighbors;
            ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out neighbors, MinPoint, 20);

            foreach (Cl3DModel.Cl3DModelPointIterator pt in neighbors)
                pt.Color = Color.Red;
            */

            /*
            iter = p_Model.GetIterator();
            minDistance = float.MaxValue;
            MinPoint = iter;
            do
            {
                float currDistance = (float)Math.Sqrt(Math.Pow(NoseTip - iter - 30, 2) + Math.Pow(LeftEye - iter - 64, 2) + Math.Pow(RightEye - iter - 64, 2));
                if (currDistance < minDistance)
                {
                    minDistance = currDistance;
                    MinPoint = iter.CopyIterator();
                }
            } while (iter.MoveToNext());

            ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out neighbors, MinPoint, 20);

            foreach (Cl3DModel.Cl3DModelPointIterator pt in neighbors)
                pt.Color = Color.Green;

            */

            /*
            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);

            Cl3DModel.Cl3DModelPointIterator RightLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips);
            Cl3DModel.Cl3DModelPointIterator UpperLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip);
            Cl3DModel.Cl3DModelPointIterator LeftLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips);
            Cl3DModel.Cl3DModelPointIterator BottomLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip);

            TextWriter tw = new StreamWriter("d:\\Model.txt", true);

            String toWrite = (LeftEye - RightEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (RightLip - NoseTip).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (RightLip - LeftEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (RightLip - RightEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";

            toWrite += (UpperLip - NoseTip).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (UpperLip - LeftEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (UpperLip - RightEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";

            toWrite += (LeftLip - NoseTip).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (LeftLip - LeftEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (LeftLip - RightEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";

            toWrite += (BottomLip - NoseTip).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (BottomLip - LeftEye).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ";
            toWrite += (BottomLip - RightEye).ToString(System.Globalization.CultureInfo.InvariantCulture);
            tw.WriteLine(toWrite);

            tw.Close();
            */
        }
        private void MarkHighCurvEdges(ref Cl3DModel Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Cl3DModel.Cl3DModelPointIterator LeftEye = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);

            float diistance = (float)Math.Sqrt(Math.Pow(NoseTip - LeftEye, 2) + Math.Pow(NoseTip - RightEye, 2) + Math.Pow(LeftEye - RightEye, 2)) * 1.15f;

            List<Cl3DModel.Cl3DModelPointIterator> pointsIn = new List<Cl3DModel.Cl3DModelPointIterator>();
            Cl3DModel.Cl3DModelPointIterator iter = Model.GetIterator();
            do
            {
                float dist = (float)Math.Sqrt(Math.Pow((float)(iter - NoseTip), 2) + Math.Pow((float)(iter - LeftEye), 2) + Math.Pow((float)(iter - RightEye), 2));
                if (dist < diistance)
                    pointsIn.Add(iter.CopyIterator());

            } while (iter.MoveToNext());

            double MaxK1_10 = double.MinValue;
            double MinK1_10 = double.MaxValue;

            double MaxK1_15 = double.MinValue;
            double MinK1_15 = double.MaxValue;

            double MaxK1_20 = double.MinValue;
            double MinK1_20 = double.MaxValue;

            double MaxK1_25 = double.MinValue;
            double MinK1_25 = double.MaxValue;

            double MaxK1_55 = double.MinValue;
            double MinK1_40 = double.MaxValue;

            foreach (Cl3DModel.Cl3DModelPointIterator PointIn in pointsIn)
            {
                double valK1_10;
                if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_10, out valK1_10))
                {
                    ClInformationSender.SendInformation("K1 10 unavailable for the point "+PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText);
                    continue;
                }

                double valK1_15;
                if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_15, out valK1_15))
                {
                    ClInformationSender.SendInformation("K1 15 unavailable for the point "+PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText);
                    continue;
                }

                double valK1_20;
                if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_20, out valK1_20))
                {
                    ClInformationSender.SendInformation("K1 20 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText);
                    continue;
                }

                double valK1_25;
                if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out valK1_25))
                {
                    ClInformationSender.SendInformation("K1 25 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText);
                    continue;
                }

                double valK1_40;
                if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_40, out valK1_40))
                {
                    ClInformationSender.SendInformation("K1 40 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText);
                    continue;
                }

                if (MinK1_10 > valK1_10)
                    MinK1_10 = valK1_10;
                if (MaxK1_10 < valK1_10)
                    MaxK1_10 = valK1_10;

                if (MinK1_15 > valK1_15)
                    MinK1_15 = valK1_15;
                if (MaxK1_15 < valK1_15)
                    MaxK1_15 = valK1_15;

                if (MinK1_20 > valK1_20)
                    MinK1_20 = valK1_20;
                if (MaxK1_20 < valK1_20)
                    MaxK1_20 = valK1_20;

                if (MinK1_25 > valK1_25)
                    MinK1_25 = valK1_25;
                if (MaxK1_25 < valK1_25)
                    MaxK1_25 = valK1_25;

                if (MinK1_40 > valK1_40)
                    MinK1_40 = valK1_40;
                if (MaxK1_55 < valK1_40)
                    MaxK1_55 = valK1_40;
            }

            iter = Model.GetIterator();
            do
            {
                double valK1_10;
                if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_10, out valK1_10))
                    continue;

                double valK1_15;
                if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_15, out valK1_15))
                    continue;

                double valK1_20;
                if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_20, out valK1_20))
                    continue;

                double valK1_25;
                if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out valK1_25))
                    continue;

                double valK1_40;
                if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_40, out valK1_40))
                    continue;

                if (valK1_10 < MinK1_10 || valK1_10 > MaxK1_10 ||
                    valK1_15 < MinK1_15 || valK1_15 > MaxK1_15 ||
                    valK1_20 < MinK1_20 || valK1_20 > MaxK1_20 ||
                    valK1_25 < MinK1_25 || valK1_25 > MaxK1_25 ||
                    valK1_40 < MinK1_40 || valK1_40 > MaxK1_55
                    )
                {
                   // iter.Color = Color.LightBlue;
                    iter.AddSpecificValue("ToRemove_HighCurvature", 1.0f);
                }

            } while (iter.MoveToNext());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            Cl3DModel.Cl3DModelPointIterator max = iter.CopyIterator();
            float distanceMax = 0;

            do
            {
                float distance = (float)Math.Sqrt(Math.Pow(iter.U, 2) + Math.Pow(iter.V, 2));
                if (distanceMax < distance)
                    distanceMax = distance;

            } while (iter.MoveToNext());

            iter = p_Model.GetIterator();
            do
            {
                iter.U = (iter.U / distanceMax) * m_RadiousOfConformalMap;
                iter.V = (iter.V / distanceMax) * m_RadiousOfConformalMap;
            } while (iter.MoveToNext());

            Cl3DModel.Cl3DModelPointIterator LeftEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
            Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

            Cl3DModel.Cl3DModelPointIterator tmp;
            if (LeftEye.X > RightEye.X)
            {
                tmp = LeftEye.CopyIterator();
                RightEye = LeftEye.CopyIterator();
                LeftEye = tmp.CopyIterator();
            }

            double EyesDistance = Math.Sqrt(Math.Pow(LeftEye.U - RightEye.U,2) + Math.Pow(LeftEye.V - RightEye.V,2));
            double NoseLeftEyeDistance = Math.Sqrt(Math.Pow(LeftEye.U - NoseTip.U, 2) + Math.Pow(LeftEye.V - NoseTip.V, 2));
            double NoseRightEyeDistance = Math.Sqrt(Math.Pow(NoseTip.U - RightEye.U, 2) + Math.Pow(NoseTip.V - RightEye.V, 2));

            double AverageNoseTipEyeDistance = (NoseLeftEyeDistance + NoseRightEyeDistance) / 2;

            Matrix GenModel = new Matrix(2, 3);
            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose

            GenModel[0, 1] = (EyesDistance / 2);
            GenModel[1, 1] = AverageNoseTipEyeDistance; // left eye

            GenModel[0, 2] = -(EyesDistance / 2);
            GenModel[1, 2] = AverageNoseTipEyeDistance; // right eye

            Matrix Model = new Matrix(2, 3);

            Model[0, 0] = NoseTip.U;
            Model[1, 0] = NoseTip.V; // nose

            Model[0, 1] = LeftEye.U;
            Model[1, 1] = LeftEye.V; // left eye

            Model[0, 2] = RightEye.U;
            Model[1, 2] = RightEye.V; // right eye

            Matrix rotationMatrix = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(2, 1);
            iter = p_Model.GetIterator();
            do
            {
                q[0, 0] = iter.U;
                q[1, 0] = iter.V;
                Iridium.Numerics.LinearAlgebra.Matrix NewQ = rotationMatrix * q +translationMatrix;
                iter.U = (float)NewQ[0, 0];
                iter.V = (float)NewQ[1, 0];
            } while (iter.MoveToNext());

            float U = NoseTip.U;
            float V = NoseTip.V;
            iter = p_Model.GetIterator();
            do
            {
                iter.U -= U;
                iter.V -= V;
            } while (iter.MoveToNext());

            if (centerConformalMaps)
            {
                float middleU = 0;
                float middleV = 0;
                iter = p_Model.GetIterator();
                do
                {
                    middleU += iter.U;
                    middleV += iter.V;
                } while (iter.MoveToNext());

                middleU /= p_Model.ModelPointsCount;
                middleV /= p_Model.ModelPointsCount;
                iter = p_Model.GetIterator();
                do
                {
                    iter.U -= middleU;
                    iter.V -= middleV;
                } while (iter.MoveToNext());

            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Matrix GenModel = new Matrix(3,3);
            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose
            GenModel[2, 0] = 0;

            GenModel[0, 1] = -22f;
            GenModel[1, 1] = 34f; // left eye
            GenModel[2, 1] = -35f;

            GenModel[0, 2] = 22f;
            GenModel[1, 2] = 34f; // right eye
            GenModel[2, 2] = -35f;
            Matrix Model = new Matrix(3,3);

            Cl3DModel.Cl3DModelPointIterator point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());
            Model[0, 0] = point.X;
            Model[1, 0] = point.Y; // nose
            Model[2, 0] = point.Z;

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());
            Model[0, 1] = point.X;
            Model[1, 1] = point.Y; // left eye
            Model[2, 1] = point.Z;

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Model[0, 2] = point.X;
            Model[1, 2] = point.Y; // right eye
            Model[2, 2] = point.Z;

            Matrix rotationMatrix = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            string name = p_Model.ModelFileFolder + p_Model.ModelFileName + ".rt";

               // List<KeyValuePair<string,Cl3DModel.Cl3DModelPointIterator>> specPoints = p_Model.GetAllSpecificPoints();
            using (TextWriter tw = new StreamWriter(name, false))
            {
                tw.WriteLine("@----------------------------------------");
                tw.WriteLine("@           3DModelsPreprocessing");
                tw.WriteLine("@      Przemyslaw Szeptycki LIRIS 2009");
                tw.WriteLine("@ Rotation and Translation Matrix to normalize face model");
                tw.WriteLine("@ Rotation:");
                tw.WriteLine(rotationMatrix.ToString());
                tw.WriteLine("@ Translation:");
                tw.WriteLine(translationMatrix.ToString());
                tw.Close();
            }
               /*
            Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                q[0, 0] = iter.X;
                q[1, 0] = iter.Y;
                q[2, 0] = iter.Z;
                Iridium.Numerics.LinearAlgebra.Matrix NewQ = rotationMatrix * q + translationMatrix;
                iter.X = (float)NewQ[0, 0];
                iter.Y = (float)NewQ[1, 0];
                iter.Z = (float)NewQ[2, 0];
            } while (iter.MoveToNext());
             */
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;
            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), ref NoseTip))
                throw new Exception("Cannot get Nose Tip");

            List<Cl3DModel.Cl3DModelPointIterator> Neighborhood = null;
            ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, NoseTip, m_NeighborhoodSize);

            foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                point.Color = Color.Red;
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            if (!iter.IsValid())
                throw new Exception("Iter is not valid");

            if (m_ResetColor)
            {
                do
                {
                    iter.Color = Color.White;
                } while (iter.MoveToNext());
                return;
            }

            if (!m_bMinMaxPreset)
            {
                bool firstTime = true;
                do
                {
                    double Value;

                    if (m_RangeColor)
                        Value = iter.Z;
                    else if (!iter.GetSpecificValue(m_SpecificValue, out Value))
                        continue;

                    if (firstTime)
                    {
                        m_dMaxValue = Value;
                        m_dMinValue = Value;
                        firstTime = false;
                        continue;
                    }

                    if (Value > m_dMaxValue)
                        m_dMaxValue = Value;
                    if (Value < m_dMinValue)
                        m_dMinValue = Value;
                } while (iter.MoveToNext());

            }

            if (m_SpecificValue.Contains("ShapeIndex") && !m_RangeColor)
            {
                m_dMinValue = 0;
                m_dMaxValue = 1;
            }

            if (m_bMaxMinFromNoseAndEyes)
            {

                Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
                List<Cl3DModel.Cl3DModelPointIterator> NeighborhoodNose = null;
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodNose, NoseTip, 10f);

                if (m_sMinValuePointName.Equals("Nose"))
                {
                    m_dMinValue = NoseTip.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodNose)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal < m_dMinValue)
                            m_dMinValue = currVal;
                    }
                }
                else if (m_sMaxValuePointName.Equals("Nose"))
                {
                    m_dMaxValue = NoseTip.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodNose)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal > m_dMaxValue)
                            m_dMaxValue = currVal;
                    }
                }
                NeighborhoodNose = null;

                Cl3DModel.Cl3DModelPointIterator Eye1 = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
                Cl3DModel.Cl3DModelPointIterator Eye2 = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
                List<Cl3DModel.Cl3DModelPointIterator> NeighborhoodEye1 = null;
                List<Cl3DModel.Cl3DModelPointIterator> NeighborhoodEye2 = null;
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodEye1, Eye1, 10f);
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodEye2, Eye2, 10f);

                NeighborhoodEye1.Add(Eye2);
                foreach (Cl3DModel.Cl3DModelPointIterator ne in NeighborhoodEye2)
                    NeighborhoodEye1.Add(ne);

                if (m_sMinValuePointName.Equals("Eye"))
                {
                    m_dMinValue = Eye1.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodEye1)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal < m_dMinValue)
                            m_dMinValue = currVal;
                    }
                }
                else if (m_sMaxValuePointName.Equals("Eye"))
                {
                    m_dMaxValue = Eye1.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodEye1)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal > m_dMaxValue)
                            m_dMaxValue = currVal;
                    }
                }
             }

            iter = p_Model.GetIterator();
            do
            {
                double Value;
                if (m_RangeColor)
                    Value = iter.Z;
                else if (!iter.GetSpecificValue(m_SpecificValue, out Value))
                    continue;

                double divide = 1;
                if (m_dMaxValue != m_dMinValue)
                    divide = (m_dMaxValue - m_dMinValue);

                if(m_Color == ColorType.RGB)
                    iter.Color = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);
                else if(m_Color == ColorType.Gray)
                    iter.Color = ClTools.GetColorGray((float)((Value - m_dMinValue) / divide), 1.0f);
                else if (m_Color == ColorType.R)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb((R+G+B)/3, iter.Color.G, iter.Color.B);

                    iter.Color = newColor;
                }
                else if (m_Color == ColorType.G)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb(iter.Color.R, (R + G + B) / 3, iter.Color.B);
                    iter.Color = newColor;
                }
                else if (m_Color == ColorType.B)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb(iter.Color.R, iter.Color.G, (R + G + B) / 3);
                    iter.Color = newColor;
                }
            } while (iter.MoveToNext());
            ClInformationSender.SendInformation(m_SpecificValue.ToString() + " Max: " + m_dMaxValue.ToString() + " Min: " + m_dMinValue.ToString(), ClInformationSender.eInformationType.eColorMapChanged);
        }