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 maxIter = p_Model.GetIterator();
            Cl3DModel.Cl3DModelPointIterator iter    = maxIter.CopyIterator();

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

            if (maxIter.IsValid())
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), maxIter);
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            int maxX = (int)iter.X;
            int minX = (int)iter.X;
            int maxY = (int)iter.Y;
            int minY = (int)iter.Y;

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

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

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

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

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

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

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

                        float MeanU = 0;
                        float MeanV = 0;

                        float MeanRangeX = 0;
                        float MeanRangeY = 0;

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

                        Cl3DModel.Cl3DModelPointIterator MaxPoint = null;

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

                        foreach (Cl3DModel.Cl3DModelPointIterator point in connections)
                        {
                            pt.AddNeighbor(point);
                        }
                    }
                }
            }
        }
Beispiel #4
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            CORFile landmarkFile = ReadCORFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".cor");

            //search for the closest point from the model to the read landmark
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
            {
                throw new Exception("Iterator in the model is not valid!");
            }

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

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

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

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

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

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

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

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

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



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

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

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

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

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

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


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

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

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

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

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

            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip, SavedUpperLip);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip, SavedBottomLip);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeUpperEyelid, SavedLeftEyeUpperEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeBottomEyelid, SavedLeftEyeBottomEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeUpperEyelid, SavedRightEyeUpperEyelid);
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeBottomEyelid, SavedRightEyeBottomEyelid);
        }
Beispiel #5
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            RemoveUnconnectedParts(ref p_Model);
            p_Model.ResetVisitedPoints();
            List <List <Cl3DModel.Cl3DModelPointIterator> > listOfHoles = new List <List <Cl3DModel.Cl3DModelPointIterator> >();

            List <Cl3DModel.Cl3DModelPointIterator> ListToCheck    = new List <Cl3DModel.Cl3DModelPointIterator>();
            List <Cl3DModel.Cl3DModelPointIterator> newListToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();

            Cl3DModel.Cl3DModelPointIterator iter = null;
            int listNo = 0;

            while ((iter = GetRandomUnseenPointOfHole(ref p_Model)) != null)
            {
                ListToCheck.Add(iter);
                listOfHoles.Add(new List <Cl3DModel.Cl3DModelPointIterator>());
                do
                {
                    foreach (Cl3DModel.Cl3DModelPointIterator ElementFromListToCheck in ListToCheck)
                    {
                        if (!ElementFromListToCheck.AlreadyVisited && ElementFromListToCheck.GetListOfNeighbors().Count < 8)
                        {
                            listOfHoles[listNo].Add(ElementFromListToCheck);
                            ElementFromListToCheck.AlreadyVisited = true;
                            foreach (Cl3DModel.Cl3DModelPointIterator it in ElementFromListToCheck.GetListOfNeighbors())
                            {
                                if (!it.AlreadyVisited && it.GetListOfNeighbors().Count < 8)
                                {
                                    newListToCheck.Add(it);
                                }
                            }
                        }
                    }

                    ListToCheck.Clear();
                    foreach (Cl3DModel.Cl3DModelPointIterator it in newListToCheck)
                    {
                        ListToCheck.Add(it);
                    }
                    newListToCheck.Clear();
                } while (ListToCheck.Count != 0);
                ListToCheck.Clear();
                listNo++;
            }
            //-------------------------------- End of searching holes

            //-------------------------------- Removing the longest hole - border of the face
            if (listOfHoles.Count == 0)
            {
                return;
            }
            int maxCount = listOfHoles[0].Count;;
            int maxI     = 0;

            for (int i = 1; i < listOfHoles.Count; i++)
            {
                if (listOfHoles[i].Count > maxCount)
                {
                    maxI     = i;
                    maxCount = listOfHoles[i].Count;
                }
            }

            listOfHoles.RemoveAt(maxI);
            //-------------------------------- End of removing the longest hole

            if (m_bColorIt)
            {
                for (int i = 0; i < listOfHoles.Count; i++)
                {
                    for (int j = 0; j < listOfHoles[i].Count; j++)
                    {
                        listOfHoles[i][j].Color = Color.FromArgb(255, 0, 255);//ClTools.GetColorRGB(((float)i) / listOfHoles.Count, 1);
                    }
                }
            }

            p_Model.ResetVisitedPoints();
            //----------------- Fill holes
            foreach (List <Cl3DModel.Cl3DModelPointIterator> hole in listOfHoles)
            {
                double A = 0;
                double B = 0;
                double C = 0;
                double D = 0;
                double E = 0;
                double F = 0;
                List <Cl3DModel.Cl3DModelPointIterator> holeToEstimateSurface = new List <Cl3DModel.Cl3DModelPointIterator>();
                foreach (Cl3DModel.Cl3DModelPointIterator it in hole) // we are adding new points to other list becouse all the time its used to aproximate surface
                {
                    holeToEstimateSurface.Add(it.CopyIterator());
                    it.AlreadyVisited = true;
                    List <Cl3DModel.Cl3DModelPointIterator> Neighborhood;
                    ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, it, 20);
                    foreach (Cl3DModel.Cl3DModelPointIterator Neighbor in Neighborhood)
                    {
                        if (!Neighbor.AlreadyVisited)
                        {
                            holeToEstimateSurface.Add(Neighbor);
                            Neighbor.AlreadyVisited = true;
                        }
                    }
                }

                List <Cl3DModel.Cl3DModelPointIterator> PointsOfHole       = new List <Cl3DModel.Cl3DModelPointIterator>();
                List <Cl3DModel.Cl3DModelPointIterator> SortedPointsOfHole = new List <Cl3DModel.Cl3DModelPointIterator>();

                foreach (Cl3DModel.Cl3DModelPointIterator itOut in hole)
                {
                    SortedPointsOfHole.Add(itOut.CopyIterator());

                    foreach (Cl3DModel.Cl3DModelPointIterator itIn in hole)
                    {
                        if (itIn.PointID == itOut.PointID)
                        {
                            continue;
                        }

                        float NewPointX = itOut.X;
                        float NewPointY = itIn.Y;

                        bool exist = false;
                        Cl3DModel.Cl3DModelPointIterator ExistPoint = p_Model.GetIterator();
                        if (!ExistPoint.IsValid())
                        {
                            throw new Exception("Iterator in Model isn't valid");
                        }

                        do
                        {
                            if (Math.Abs(ExistPoint.X - NewPointX) < m_Delta && Math.Abs(ExistPoint.Y - NewPointY) < m_Delta)
                            {
                                exist = true;
                                break;
                            }
                        } while (ExistPoint.MoveToNext());

                        if (!exist)
                        {
                            if (!ClTools.CountSurfaceCoefficients(holeToEstimateSurface, ref A, ref B, ref C, ref D, ref E, ref F))
                            {
                                throw new Exception("Cannot calculate surface coefficients");
                            }

                            float NewPointZ = (float)(A + B * NewPointX + C * NewPointY + D * NewPointX * NewPointX + E * NewPointX * NewPointY + F * NewPointY * NewPointY);

                            Cl3DModel.Cl3DModelPointIterator newPoint = p_Model.AddPointToModel(NewPointX, NewPointY, NewPointZ);
                            holeToEstimateSurface.Add(newPoint.CopyIterator());

                            PointsOfHole.Add(newPoint.CopyIterator());
                            SortedPointsOfHole.Add(newPoint.CopyIterator());
                            if (m_bColorIt)
                            {
                                newPoint.Color = Color.Pink;
                            }
                        }
                    }
                }
                foreach (Cl3DModel.Cl3DModelPointIterator iterPoint in PointsOfHole)
                {
                    SortedPointsOfHole.Sort(new Compare2DDistance(iterPoint));
                    iterPoint.AddNeighbor(SortedPointsOfHole[1]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[2]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[3]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[4]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[5]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[6]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[7]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[8]);
                }
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    string line         = "";
                    int    NoOfVertexes = 0;
                    int    NoOfFaces    = 0;

                    if ((line = FileStream.ReadLine()) == null || !line.Equals("OFF"))
                    {
                        throw new Exception("Incorrect Header");
                    }

                    if ((line = FileStream.ReadLine()) == null)
                    {
                        throw new Exception("Incerrect Header");
                    }

                    string[] splitted = line.Split(' ');
                    NoOfVertexes = Int32.Parse(splitted[0]);
                    NoOfFaces    = Int32.Parse(splitted[1]);

                    for (int i = 0; i < NoOfVertexes; i++)
                    {
                        if ((line = FileStream.ReadLine()) == null)
                        {
                            throw new Exception("Incerrect Header");
                        }

                        splitted = line.Split(' ');
                        float X = float.Parse(splitted[0].Replace('.', ','));
                        float Y = float.Parse(splitted[1].Replace('.', ','));
                        float Z = float.Parse(splitted[2].Replace('.', ','));
                        p_mModel3D.AddPointToModel(X, Y, Z);
                    }
                    for (int i = 0; i < NoOfFaces; i++)
                    {
                        if ((line = FileStream.ReadLine()) == null)
                        {
                            throw new Exception("Incorrect Header");
                        }

                        splitted = line.Split(' ');
                        int noOfVect = int.Parse(splitted[0]);
                        if (noOfVect != 3)
                        {
                            throw new Exception("Wrong number of vertexes in the face");
                        }

                        int vertex1 = int.Parse(splitted[1]);
                        int vertex2 = int.Parse(splitted[2]);
                        int vertex3 = int.Parse(splitted[3]);

                        Cl3DModel.Cl3DModelPointIterator iter  = p_mModel3D.GetIterator();
                        Cl3DModel.Cl3DModelPointIterator iter2 = p_mModel3D.GetIterator();

                        if (!iter.MoveToPoint((uint)vertex1))
                        {
                            throw new Exception("Cannot find the point with ID: " + vertex1.ToString());
                        }
                        if (!iter2.MoveToPoint((uint)vertex2))
                        {
                            throw new Exception("Cannot find the point with ID: " + vertex2.ToString());
                        }

                        iter.AddNeighbor(iter2.CopyIterator());
                        if (!iter2.MoveToPoint((uint)vertex3))
                        {
                            throw new Exception("Cannot find the point with ID: " + vertex3.ToString());
                        }

                        iter.AddNeighbor(iter2.CopyIterator());
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    string line = "";

                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Length == 0)
                        {
                            continue;
                        }

                        if (line[0] == '#')
                        {
                            continue;
                        }

                        string[] splitted = line.Split(' ');
                        if (splitted[0].Equals("v"))
                        {
                            float X = float.Parse(splitted[1].Replace('.', ','));
                            float Y = float.Parse(splitted[2].Replace('.', ','));
                            float Z = float.Parse(splitted[3].Replace('.', ','));
                            p_mModel3D.AddPointToModel(X, Y, Z);
                        }
                        else if (splitted[0].Equals("f"))
                        {
                            if (splitted.Length != 4)
                            {
                                throw new Exception("Wrong number of vertexes in the face");
                            }

                            int vertex1 = int.Parse(splitted[1]);
                            int vertex2 = int.Parse(splitted[2]);
                            int vertex3 = int.Parse(splitted[3]);

                            Cl3DModel.Cl3DModelPointIterator iter  = p_mModel3D.GetIterator();
                            Cl3DModel.Cl3DModelPointIterator iter2 = p_mModel3D.GetIterator();

                            if (!iter.MoveToPoint((uint)--vertex1))
                            {
                                throw new Exception("Cannot find the point with ID: " + vertex1.ToString());
                            }
                            if (!iter2.MoveToPoint((uint)--vertex2))
                            {
                                throw new Exception("Cannot find the point with ID: " + vertex2.ToString());
                            }

                            iter.AddNeighbor(iter2.CopyIterator());

                            if (!iter2.MoveToPoint((uint)--vertex3))
                            {
                                throw new Exception("Cannot find the point with ID: " + vertex3.ToString());
                            }

                            iter.AddNeighbor(iter2.CopyIterator());
                        }
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }
        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>();
            }
        }
        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)
        {
            if (p_Model.ModelType != "abs")
            {
                throw new Exception("Remove Half Of The Face works only for ABS files");
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
            {
                throw new Exception("Model iterator not Valid");
            }

            int MinX;
            int MaxX;
            int MinY;
            int MaxY;

            MinX = iter.RangeImageX;
            MaxX = iter.RangeImageX;
            MinY = iter.RangeImageY;
            MaxY = iter.RangeImageY;

            do
            {
                if (MinX > iter.RangeImageX)
                {
                    MinX = iter.RangeImageX;
                }
                if (MaxX < iter.RangeImageX)
                {
                    MaxX = iter.RangeImageX;
                }

                if (MinY > iter.RangeImageY)
                {
                    MinY = iter.RangeImageY;
                }
                if (MaxY < iter.RangeImageY)
                {
                    MaxY = iter.RangeImageY;
                }
            } while (iter.MoveToNext());

            int Width  = (MaxX - MinX) + 1;
            int Height = (MaxY - MinY) + 1;

            Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height];

            iter = p_Model.GetIterator();
            do
            {
                map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator();
            } while (iter.MoveToNext());

            int procent = (int)(Width * m_procentToRemove);

            for (int i = procent; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    p_Model.RemovePointFromModel(map[i, j]);
                }
            }
        }
        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);
             */
            //---------------------------------------------------------------------------
        }
Beispiel #12
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator SavedLeftEyeRightCorner   = null;
            Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfRightEye = null;
            Cl3DModel.Cl3DModelPointIterator SavedNoseTip = null;

            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString(), ref SavedLeftEyeRightCorner))
            {
                throw new Exception("Cannot find specific point EyePoint");
            }
            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString(), ref SavedLeftCornerOfRightEye))
            {
                throw new Exception("Cannot find specific point EyePoint");
            }
            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), ref SavedNoseTip))
            {
                throw new Exception("Cannot find specific point NosePoint");
            }

            // Normalized Generic Model (distance between eyes = 1) from IV2
            Vector GenNoseTip              = new Vector(new double[] { 0f, 0f, 0f });
            Vector GenLeftEyeRightCorner   = new Vector(new double[] { -0.5f, 0.88f, -1f });
            Vector GenLeftCornerOfRightEye = new Vector(new double[] { 0.5f, 0.88f, -1f });

            Vector GenLeftCornerOfLeftEye   = new Vector(new double[] { -1.2f, 0.85f, -1f });
            Vector GenRightCornerOfRightEye = new Vector(new double[] { 1.2f, 0.85f, -1f });

            Vector GenLeftCornerOfNose  = new Vector(new double[] { -0.45f, -0.05f, -0.73f });
            Vector GenRightCornerOfNose = new Vector(new double[] { 0.45f, -0.05f, -0.73f });

            Vector GenLeftCornerOfLips  = new Vector(new double[] { -0.66f, -0.8f, -0.82f });
            Vector GenRightCornerOfLips = new Vector(new double[] { 0.66f, -0.8f, -0.82f });

            float DistBetweenEyes            = (float)Math.Sqrt(Math.Pow(SavedLeftCornerOfRightEye.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(SavedLeftCornerOfRightEye.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(SavedLeftCornerOfRightEye.Z - SavedLeftEyeRightCorner.Z, 2));
            float SavedDistBetweenEyeAndNose = (float)Math.Sqrt(Math.Pow(SavedNoseTip.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(SavedNoseTip.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(SavedNoseTip.Z - SavedLeftEyeRightCorner.Z, 2));

            GenNoseTip               *= DistBetweenEyes;
            GenLeftEyeRightCorner    *= DistBetweenEyes;
            GenLeftCornerOfRightEye  *= DistBetweenEyes;
            GenLeftCornerOfLeftEye   *= DistBetweenEyes;
            GenRightCornerOfRightEye *= DistBetweenEyes;
            GenLeftCornerOfNose      *= DistBetweenEyes;
            GenRightCornerOfNose     *= DistBetweenEyes;
            GenLeftCornerOfLips      *= DistBetweenEyes;
            GenRightCornerOfLips     *= DistBetweenEyes;

            float DistBetweenEyeAndNoseAfterScale = (float)Math.Sqrt(Math.Pow(GenNoseTip[0] - GenLeftEyeRightCorner[0], 2) + Math.Pow(GenNoseTip[1] - GenLeftEyeRightCorner[1], 2) + Math.Pow(GenNoseTip[2] - GenLeftEyeRightCorner[2], 2));

            float muntipltBy = SavedDistBetweenEyeAndNose / DistBetweenEyeAndNoseAfterScale;

            GenNoseTip *= muntipltBy;
            GenLeftEyeRightCorner[1] *= muntipltBy;
            GenLeftEyeRightCorner[2] *= muntipltBy;

            GenLeftCornerOfRightEye[1] *= muntipltBy;
            GenLeftCornerOfRightEye[2] *= muntipltBy;

            GenLeftCornerOfLeftEye[1] *= muntipltBy;
            GenLeftCornerOfLeftEye[2] *= muntipltBy;

            GenRightCornerOfRightEye[1] *= muntipltBy;
            GenRightCornerOfRightEye[2] *= muntipltBy;

            GenLeftCornerOfNose[1] *= muntipltBy;
            GenLeftCornerOfNose[2] *= muntipltBy;

            GenRightCornerOfNose[1] *= muntipltBy;
            GenRightCornerOfNose[2] *= muntipltBy;

            GenLeftCornerOfLips[1] *= muntipltBy;
            GenLeftCornerOfLips[2] *= muntipltBy;

            GenRightCornerOfLips[1] *= muntipltBy;
            GenRightCornerOfLips[2] *= muntipltBy;

            Vector MeanValOfGenModel = new Vector(new double[] { (GenNoseTip[0] + GenLeftEyeRightCorner[0] + GenLeftCornerOfRightEye[0]) / 3,
                                                                 (GenNoseTip[1] + GenLeftEyeRightCorner[1] + GenLeftCornerOfRightEye[1]) / 3,
                                                                 (GenNoseTip[2] + GenLeftEyeRightCorner[2] + GenLeftCornerOfRightEye[2]) / 3 });

            Vector MeanValOfModel = new Vector(new double[] { (SavedNoseTip.X + SavedLeftEyeRightCorner.X + SavedLeftCornerOfRightEye.X) / 3,
                                                              (SavedNoseTip.Y + SavedLeftEyeRightCorner.Y + SavedLeftCornerOfRightEye.Y) / 3,
                                                              (SavedNoseTip.Z + SavedLeftEyeRightCorner.Z + SavedLeftCornerOfRightEye.Z) / 3 });

            Iridium.Numerics.LinearAlgebra.Matrix Model    = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);
            Iridium.Numerics.LinearAlgebra.Matrix ModelGen = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);
            // Row Column
            Model[0, 0] = (SavedNoseTip.X - MeanValOfModel[0]);
            Model[1, 0] = (SavedNoseTip.Y - MeanValOfModel[1]);
            Model[2, 0] = (SavedNoseTip.Z - MeanValOfModel[2]);

            Model[0, 1] = (SavedLeftEyeRightCorner.X - MeanValOfModel[0]);
            Model[1, 1] = (SavedLeftEyeRightCorner.Y - MeanValOfModel[1]);
            Model[2, 1] = (SavedLeftEyeRightCorner.Z - MeanValOfModel[2]);

            Model[0, 2] = (SavedLeftCornerOfRightEye.X - MeanValOfModel[0]);
            Model[1, 2] = (SavedLeftCornerOfRightEye.Y - MeanValOfModel[1]);
            Model[2, 2] = (SavedLeftCornerOfRightEye.Z - MeanValOfModel[2]);

            ModelGen[0, 0] = (GenNoseTip[0] - MeanValOfGenModel[0]);
            ModelGen[1, 0] = (GenNoseTip[1] - MeanValOfGenModel[1]);
            ModelGen[2, 0] = (GenNoseTip[2] - MeanValOfGenModel[2]);

            ModelGen[0, 1] = (GenLeftEyeRightCorner[0] - MeanValOfGenModel[0]);
            ModelGen[1, 1] = (GenLeftEyeRightCorner[1] - MeanValOfGenModel[1]);
            ModelGen[2, 1] = (GenLeftEyeRightCorner[2] - MeanValOfGenModel[2]);

            ModelGen[0, 2] = (GenLeftCornerOfRightEye[0] - MeanValOfGenModel[0]);
            ModelGen[1, 2] = (GenLeftCornerOfRightEye[1] - MeanValOfGenModel[1]);
            ModelGen[2, 2] = (GenLeftCornerOfRightEye[2] - MeanValOfGenModel[2]);

            ModelGen.Transpose();

            Iridium.Numerics.LinearAlgebra.Matrix Covariance = Model * ModelGen;

            Iridium.Numerics.LinearAlgebra.SingularValueDecomposition SVD = new Iridium.Numerics.LinearAlgebra.SingularValueDecomposition(Covariance);
            Iridium.Numerics.LinearAlgebra.Matrix U = SVD.LeftSingularVectors;
            Iridium.Numerics.LinearAlgebra.Matrix V = SVD.RightSingularVectors;

            Iridium.Numerics.LinearAlgebra.Matrix s = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1.0);

            if (Covariance.Rank() < 2)
            {
                throw new Exception("Cannot allign generic model (cov rank is less than 2)");
            }

            if (Covariance.Rank() == 2) // m-1 where m is dimension space (3D)
            {
                double detU = Math.Round(U.Determinant());
                double detV = Math.Round(V.Determinant());
                double detC = Covariance.Determinant();
                if ((int)detU * (int)detV == 1)
                {
                    s[2, 2] = 1;
                }
                else if ((int)detU * (int)detV == -1)
                {
                    s[2, 2] = -1;
                }
                else
                {
                    throw new Exception("Determinant of U and V are not in conditions");
                }
            }
            else
            {
                if (Covariance.Determinant() < 0)
                {
                    s[2, 2] = -1;
                }
            }

            V.Transpose();
            Iridium.Numerics.LinearAlgebra.Matrix Roatation = U * s * V;


            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfGenModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
            MeanValOfGenModelMatrix[0, 0] = MeanValOfGenModel[0];
            MeanValOfGenModelMatrix[1, 0] = MeanValOfGenModel[1];
            MeanValOfGenModelMatrix[2, 0] = MeanValOfGenModel[2];

            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
            MeanValOfModelMatrix[0, 0] = MeanValOfModel[0];
            MeanValOfModelMatrix[1, 0] = MeanValOfModel[1];
            MeanValOfModelMatrix[2, 0] = MeanValOfModel[2];

            Iridium.Numerics.LinearAlgebra.Matrix Translation = MeanValOfModelMatrix - Roatation * MeanValOfGenModelMatrix;


            Iridium.Numerics.LinearAlgebra.Matrix q    = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
            Iridium.Numerics.LinearAlgebra.Matrix NewQ = null;

            //------------- Code to show triangles created to check distance between them and features points -----------------------------------

            /*
             * q[0, 0] = GenNoseTip.X;
             * q[1, 0] = GenNoseTip.Y;
             * q[2, 0] = GenNoseTip.Z;
             * NewQ = Roatation * q + Translation;
             * Cl3DModel.Cl3DModelPointIterator iter1 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
             * iter1.Color = Color.Green;
             *
             * q[0, 0] = GenLeftEyeRightCorner.X;
             * q[1, 0] = GenLeftEyeRightCorner.Y;
             * q[2, 0] = GenLeftEyeRightCorner.Z;
             * NewQ = Roatation * q + Translation;
             * Cl3DModel.Cl3DModelPointIterator iter2 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
             * iter2.Color = Color.White;
             *
             * q[0, 0] = GenLeftCornerOfRightEye.X;
             * q[1, 0] = GenLeftCornerOfRightEye.Y;
             * q[2, 0] = GenLeftCornerOfRightEye.Z;
             * NewQ = Roatation * q + Translation;
             * Cl3DModel.Cl3DModelPointIterator iter3 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
             * iter3.Color = Color.Orange;
             *
             * iter1.AddNeighbor(iter2);
             * iter1.AddNeighbor(iter3);
             * iter2.AddNeighbor(iter3);
             */
            //---------------------------------------------------------------------------

            Cl3DModel.Cl3DModelPointIterator iter = null;
            float MinDistance = 0;

            Cl3DModel.Cl3DModelPointIterator MinIter = null;

            //------------------ Code to correct nose tip and eyes position -----------------------------------

            /*
             * GenNoseTip.X = (float)NewQ[0, 0];
             * GenNoseTip.Y = (float)NewQ[1, 0];
             * GenNoseTip.Z = (float)NewQ[2, 0];
             *
             * iter = p_Model.GetIterator();
             * MinDistance = (float)Math.Sqrt(Math.Pow(GenNoseTip.X - iter.X, 2) + Math.Pow(GenNoseTip.Y - iter.Y, 2) + Math.Pow(GenNoseTip.Z - iter.Z, 2));
             * MinIter = iter;
             * do
             * {
             *  float NewDistance = (float)Math.Sqrt(Math.Pow(GenNoseTip.X - iter.X, 2) + Math.Pow(GenNoseTip.Y - iter.Y, 2) + Math.Pow(GenNoseTip.Z - iter.Z, 2));
             *  if (NewDistance < MinDistance)
             *  {
             *      MinDistance = NewDistance;
             *      MinIter = iter.CopyIterator();
             *  }
             * } while (iter.MoveToNext());
             * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, MinIter);
             *
             * q[0, 0] = GenLeftEyeRightCorner.X;
             * q[1, 0] = GenLeftEyeRightCorner.Y;
             * q[2, 0] = GenLeftEyeRightCorner.Z;
             * NewQ = Roatation * q + Translation;
             * GenLeftEyeRightCorner.X = (float)NewQ[0, 0];
             * GenLeftEyeRightCorner.Y = (float)NewQ[1, 0];
             * GenLeftEyeRightCorner.Z = (float)NewQ[2, 0];
             * iter = p_Model.GetIterator();
             * MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftEyeRightCorner.X - iter.X, 2) + Math.Pow(GenLeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(GenLeftEyeRightCorner.Z - iter.Z, 2));
             * MinIter = iter;
             * do
             * {
             *  float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftEyeRightCorner.X - iter.X, 2) + Math.Pow(GenLeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(GenLeftEyeRightCorner.Z - iter.Z, 2));
             *  if (NewDistance < MinDistance)
             *  {
             *      MinDistance = NewDistance;
             *      MinIter = iter.CopyIterator();
             *  }
             * } while (iter.MoveToNext());
             * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, MinIter);
             *
             * q[0, 0] = GenLeftCornerOfRightEye.X;
             * q[1, 0] = GenLeftCornerOfRightEye.Y;
             * q[2, 0] = GenLeftCornerOfRightEye.Z;
             * NewQ = Roatation * q + Translation;
             * GenLeftCornerOfRightEye.X = (float)NewQ[0, 0];
             * GenLeftCornerOfRightEye.Y = (float)NewQ[1, 0];
             * GenLeftCornerOfRightEye.Z = (float)NewQ[2, 0];
             * iter = p_Model.GetIterator();
             * MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(GenLeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(GenLeftCornerOfRightEye.Z - iter.Z, 2));
             * MinIter = iter;
             * do
             * {
             *  float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(GenLeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(GenLeftCornerOfRightEye.Z - iter.Z, 2));
             *  if (NewDistance < MinDistance)
             *  {
             *      MinDistance = NewDistance;
             *      MinIter = iter.CopyIterator();
             *  }
             * } while (iter.MoveToNext());
             * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, MinIter);
             */
            //---------------------------------------------------------------------------------------------------------

            q[0, 0] = GenLeftCornerOfLeftEye[0];
            q[1, 0] = GenLeftCornerOfLeftEye[1];
            q[2, 0] = GenLeftCornerOfLeftEye[2];
            NewQ    = Roatation * q + Translation;
            GenLeftCornerOfLeftEye[0] = (float)NewQ[0, 0];
            GenLeftCornerOfLeftEye[1] = (float)NewQ[1, 0];
            GenLeftCornerOfLeftEye[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLeftEye[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLeftEye[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLeftEye[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLeftEye[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLeftEye[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLeftEye[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, MinIter);
            }

            q[0, 0] = GenRightCornerOfRightEye[0];
            q[1, 0] = GenRightCornerOfRightEye[1];
            q[2, 0] = GenRightCornerOfRightEye[2];
            NewQ    = Roatation * q + Translation;
            GenRightCornerOfRightEye[0] = (float)NewQ[0, 0];
            GenRightCornerOfRightEye[1] = (float)NewQ[1, 0];
            GenRightCornerOfRightEye[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfRightEye[0] - iter.X, 2) + Math.Pow(GenRightCornerOfRightEye[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfRightEye[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfRightEye[0] - iter.X, 2) + Math.Pow(GenRightCornerOfRightEye[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfRightEye[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, MinIter);
            }


            q[0, 0] = GenLeftCornerOfNose[0];
            q[1, 0] = GenLeftCornerOfNose[1];
            q[2, 0] = GenLeftCornerOfNose[2];
            NewQ    = Roatation * q + Translation;
            GenLeftCornerOfNose[0] = (float)NewQ[0, 0];
            GenLeftCornerOfNose[1] = (float)NewQ[1, 0];
            GenLeftCornerOfNose[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfNose[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfNose[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfNose[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfNose[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, MinIter);
            }


            q[0, 0] = GenRightCornerOfNose[0];
            q[1, 0] = GenRightCornerOfNose[1];
            q[2, 0] = GenRightCornerOfNose[2];
            NewQ    = Roatation * q + Translation;
            GenRightCornerOfNose[0] = (float)NewQ[0, 0];
            GenRightCornerOfNose[1] = (float)NewQ[1, 0];
            GenRightCornerOfNose[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfNose[0] - iter.X, 2) + Math.Pow(GenRightCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfNose[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfNose[0] - iter.X, 2) + Math.Pow(GenRightCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfNose[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, MinIter);
            }

            q[0, 0] = GenLeftCornerOfLips[0];
            q[1, 0] = GenLeftCornerOfLips[1];
            q[2, 0] = GenLeftCornerOfLips[2];
            NewQ    = Roatation * q + Translation;
            GenLeftCornerOfLips[0] = (float)NewQ[0, 0];
            GenLeftCornerOfLips[1] = (float)NewQ[1, 0];
            GenLeftCornerOfLips[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLips[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLips[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLips[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLips[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, MinIter);
            }

            q[0, 0] = GenRightCornerOfLips[0];
            q[1, 0] = GenRightCornerOfLips[1];
            q[2, 0] = GenRightCornerOfLips[2];
            NewQ    = Roatation * q + Translation;
            GenRightCornerOfLips[0] = (float)NewQ[0, 0];
            GenRightCornerOfLips[1] = (float)NewQ[1, 0];
            GenRightCornerOfLips[2] = (float)NewQ[2, 0];
            iter        = p_Model.GetIterator();
            MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfLips[0] - iter.X, 2) + Math.Pow(GenRightCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfLips[2] - iter.Z, 2));
            MinIter     = iter;
            do
            {
                float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfLips[0] - iter.X, 2) + Math.Pow(GenRightCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfLips[2] - iter.Z, 2));
                if (NewDistance < MinDistance)
                {
                    MinDistance = NewDistance;
                    MinIter     = iter.CopyIterator();
                }
            } while (iter.MoveToNext());
            if (MinDistance < m_MinDistanceToAddPoint)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, MinIter);
            }
        }
Beispiel #13
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            //  if (!(p_Model.ModelType == "abs" || p_Model.ModelType == "binaryModel" || p_Model.ModelType == "model" || p_Model.ModelType == "bnt"))
            //      throw new Exception("Remove Holes based on Range Image works only for ABS and BNT like aslo for binaryModel and model files with range image informations");

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
            {
                throw new Exception("Model iterator not Valid");
            }

            int MinX;
            int MaxX;
            int MinY;
            int MaxY;

            MinX = iter.RangeImageX;
            MaxX = iter.RangeImageX;
            MinY = iter.RangeImageY;
            MaxY = iter.RangeImageY;

            do
            {
                if (MinX > iter.RangeImageX)
                {
                    MinX = iter.RangeImageX;
                }
                if (MaxX < iter.RangeImageX)
                {
                    MaxX = iter.RangeImageX;
                }

                if (MinY > iter.RangeImageY)
                {
                    MinY = iter.RangeImageY;
                }
                if (MaxY < iter.RangeImageY)
                {
                    MaxY = iter.RangeImageY;
                }
            } while (iter.MoveToNext());

            int Width  = (MaxX - MinX) + 1;
            int Height = (MaxY - MinY) + 1;

            Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height];

            iter = p_Model.GetIterator();
            do
            {
                map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator();
            } while (iter.MoveToNext());


            for (int y = 0; y < Height; y++)
            {
                bool bFoundHole   = false;
                bool bFaceStarted = false;
                int  iHoleBegin   = 0;
                int  iHoleEnd     = 0;
                for (int x = 0; x < Width; x++)
                {
                    if (map[x, y] == null && bFaceStarted)
                    {
                        // found hole begin
                        iHoleBegin = x - 1;
                        for (int j = x + 1; j < Width; j++) // try to find hole end
                        {
                            if (map[j, y] != null)
                            {
                                iHoleEnd   = j;
                                bFoundHole = true;
                                break;
                            }
                        }
                    }
                    else if (bFaceStarted == false && map[x, y] != null)
                    {
                        bFaceStarted = true;
                    }

                    if (bFoundHole)
                    {
                        for (int ix = iHoleBegin + 1; ix < iHoleEnd; ix++)
                        {
                            float proc = (float)(ix - iHoleBegin) / (iHoleEnd - iHoleBegin);
                            float addZ = InterpolateCubic(iHoleBegin, iHoleEnd, y, map, proc, Height, Width);
                            float addX = LinearInterpolate(map[iHoleBegin, y].X, map[iHoleEnd, y].X, proc);

                            int R = (int)LinearInterpolate(map[iHoleBegin, y].Color.R, map[iHoleEnd, y].Color.R, proc);
                            int G = (int)LinearInterpolate(map[iHoleBegin, y].Color.G, map[iHoleEnd, y].Color.G, proc);
                            int B = (int)LinearInterpolate(map[iHoleBegin, y].Color.B, map[iHoleEnd, y].Color.B, proc);

                            map[ix, y] = p_Model.AddPointToModel(addX, map[iHoleBegin, y].Y, addZ, MinX + ix, MinY + y);
                            map[ix, y].AlreadyVisited = true;
                            map[ix, y].Color          = Color.FromArgb(R, G, B);
                            //  map[ix, y].Color = Color.Green;

                            Cl3DModel.Cl3DModelPointIterator testBegin = map[iHoleBegin, y];
                            Cl3DModel.Cl3DModelPointIterator testEnd   = map[iHoleEnd, y];

                            if (ix - 1 > 0 && y - 1 > 0 && map[ix - 1, y - 1] != null)
                            {
                                map[ix - 1, y - 1].AddNeighbor(map[ix, y]);
                            }

                            if (ix - 1 > 0 && map[ix - 1, y] != null)
                            {
                                map[ix - 1, y].AddNeighbor(map[ix, y]);
                            }

                            if (ix - 1 > 0 && y + 1 < Height && map[ix - 1, y + 1] != null)
                            {
                                map[ix - 1, y + 1].AddNeighbor(map[ix, y]);
                            }

                            if (y - 1 > 0 && map[ix, y - 1] != null)
                            {
                                map[ix, y - 1].AddNeighbor(map[ix, y]);
                            }

                            if (y + 1 < Height && map[ix, y + 1] != null)
                            {
                                map[ix, y + 1].AddNeighbor(map[ix, y]);
                            }

                            if (ix + 1 < Width && y - 1 > 0 && map[ix + 1, y - 1] != null)
                            {
                                map[ix + 1, y - 1].AddNeighbor(map[ix, y]);
                            }

                            if (ix + 1 < Width && map[ix + 1, y] != null)
                            {
                                map[ix + 1, y].AddNeighbor(map[ix, y]);
                            }

                            if (ix + 1 < Width && y + 1 < Height && map[ix + 1, y + 1] != null)
                            {
                                map[ix + 1, y + 1].AddNeighbor(map[ix, y]);
                            }
                        }
                        bFoundHole = false;
                    }
                }
            }



            for (int x = 0; x < Width; x++)
            {
                bool bFoundHole   = false;
                bool bFaceStarted = false;
                int  iHoleBegin   = 0;
                int  iHoleEnd     = 0;
                for (int y = 0; y < Height; y++)
                {
                    if ((map[x, y] == null || map[x, y].AlreadyVisited) && bFaceStarted)
                    {
                        // found hole begin
                        iHoleBegin = y - 1;
                        for (int j = y + 1; j < Height; j++) // try to find hole end
                        {
                            if (map[x, j] != null)
                            {
                                if (map[x, j].AlreadyVisited)
                                {
                                    continue;
                                }

                                iHoleEnd   = j;
                                bFoundHole = true;
                                break;
                            }
                        }
                    }
                    else if (bFaceStarted == false && (map[x, y] != null))
                    {
                        bFaceStarted = true;
                    }

                    if (bFoundHole)
                    {
                        for (int iy = iHoleBegin + 1; iy < iHoleEnd; iy++)
                        {
                            float proc = (float)(iy - iHoleBegin) / (iHoleEnd - iHoleBegin);


                            float beforeBeginHoleVal = map[x, iHoleBegin].Z;
                            float afterBeginHoleVal  = map[x, iHoleEnd].Z;
                            if (iHoleBegin > 2)
                            {
                                if (map[x, iHoleBegin - 1] != null)
                                {
                                    beforeBeginHoleVal = map[x, iHoleBegin - 1].Z;
                                }
                            }

                            if (iHoleEnd < Height - 1)
                            {
                                if (map[x, iHoleEnd + 1] != null)
                                {
                                    afterBeginHoleVal = map[x, iHoleEnd + 1].Z;
                                }
                            }


                            float addZ = CubicInterpolate(beforeBeginHoleVal,
                                                          map[x, iHoleBegin].Z,
                                                          map[x, iHoleEnd].Z,
                                                          afterBeginHoleVal,
                                                          proc);

                            if (map[x, iy] == null)
                            {
                                float addY = LinearInterpolate(map[x, iHoleBegin].Y, map[x, iHoleEnd].Y, proc);

                                map[x, iy] = p_Model.AddPointToModel(map[x, iHoleBegin].X, addY, addZ, MinX + x, MinY + iy);
                                //     map[x, iy].Color = Color.Red;

                                int R = (int)LinearInterpolate(map[x, iHoleBegin].Color.R, map[x, iHoleEnd].Color.R, proc);
                                int G = (int)LinearInterpolate(map[x, iHoleBegin].Color.G, map[x, iHoleEnd].Color.G, proc);
                                int B = (int)LinearInterpolate(map[x, iHoleBegin].Color.B, map[x, iHoleEnd].Color.B, proc);

                                map[x, iy].AlreadyVisited = true;
                                map[x, iy].Color          = Color.FromArgb(R, G, B);


                                Cl3DModel.Cl3DModelPointIterator testBegin = map[x, iHoleBegin];
                                Cl3DModel.Cl3DModelPointIterator testEnd   = map[x, iHoleEnd];

                                if (x - 1 > 0 && iy - 1 > 0 && map[x - 1, iy - 1] != null)
                                {
                                    map[x - 1, iy - 1].AddNeighbor(map[x, iy]);
                                }

                                if (x - 1 > 0 && map[x - 1, iy] != null)
                                {
                                    map[x - 1, iy].AddNeighbor(map[x, iy]);
                                }

                                if (x - 1 > 0 && iy + 1 < Height && map[x - 1, iy + 1] != null)
                                {
                                    map[x - 1, iy + 1].AddNeighbor(map[x, iy]);
                                }

                                if (iy - 1 > 0 && map[x, iy - 1] != null)
                                {
                                    map[x, iy - 1].AddNeighbor(map[x, iy]);
                                }

                                if (iy + 1 < Height && map[x, iy + 1] != null)
                                {
                                    map[x, iy + 1].AddNeighbor(map[x, iy]);
                                }

                                if (x + 1 < Width && iy - 1 > 0 && map[x + 1, iy - 1] != null)
                                {
                                    map[x + 1, iy - 1].AddNeighbor(map[x, iy]);
                                }

                                if (x + 1 < Width && map[x + 1, iy] != null)
                                {
                                    map[x + 1, iy].AddNeighbor(map[x, iy]);
                                }

                                if (x + 1 < Width && iy + 1 < Height && map[x + 1, iy + 1] != null)
                                {
                                    map[x + 1, iy + 1].AddNeighbor(map[x, iy]);
                                }
                            }
                            else
                            {
                                map[x, iy].Z = (map[x, iy].Z + addZ) / 2;
                                //         map[x, iy].Color = Color.Orange;
                            }
                        }
                        bFoundHole = false;
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            CRRFile landmarkFile = ReadCRRFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".crr");

            //search for the closest point from the model to the read landmark
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
            {
                throw new Exception("Iterator in the model is not valid!");
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            if (SavedNoseTip != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, SavedNoseTip);
            }
            if (SavedRightEyeLeftCorner != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, SavedRightEyeLeftCorner);
            }
            if (SavedLeftEyeRightCorner != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, SavedLeftEyeRightCorner);
            }
            if (SavedLeftEyeLeftCorner != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, SavedLeftEyeLeftCorner);
            }
            if (SavedRightEyeRightCorner != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, SavedRightEyeRightCorner);
            }
            if (SavedLeftCornerOfNose != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, SavedLeftCornerOfNose);
            }
            if (SavedRightCornerOfNose != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, SavedRightCornerOfNose);
            }
            if (SavedLeftCornerOfLips != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, SavedLeftCornerOfLips);
            }
            if (SavedRightCornerOfLips != null)
            {
                p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, SavedRightCornerOfLips);
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            // if (!(p_Model.ModelType == "abs" || p_Model.ModelType == "binaryModel" || p_Model.ModelType == "model"))
            //     throw new Exception("Remove Holes based on Range Image works only for abs, binaryModel and model files");

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (!iter.IsValid())
            {
                throw new Exception("Model iterator not Valid");
            }

            int MinX;
            int MaxX;
            int MinY;
            int MaxY;

            MinX = iter.RangeImageX;
            MaxX = iter.RangeImageX;
            MinY = iter.RangeImageY;
            MaxY = iter.RangeImageY;

            do
            {
                if (MinX > iter.RangeImageX)
                {
                    MinX = iter.RangeImageX;
                }
                if (MaxX < iter.RangeImageX)
                {
                    MaxX = iter.RangeImageX;
                }

                if (MinY > iter.RangeImageY)
                {
                    MinY = iter.RangeImageY;
                }
                if (MaxY < iter.RangeImageY)
                {
                    MaxY = iter.RangeImageY;
                }
            } while (iter.MoveToNext());

            int Width  = (MaxX - MinX) + 1;
            int Height = (MaxY - MinY) + 1;

            Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height];

            iter = p_Model.GetIterator();
            do
            {
                map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator();
                foreach (Cl3DModel.Cl3DModelPointIterator pts in iter.GetListOfNeighbors())
                {
                    iter.RemoveNeighbor(pts);
                }
            } while (iter.MoveToNext());

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (map[x, y] == null)
                    {
                        continue;
                    }

                    if (x - 1 >= 0 && y + 1 < Height && map[x - 1, y + 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x - 1, y + 1]);
                    }

                    if (x - 1 >= 0 && map[x - 1, y] != null)
                    {
                        map[x, y].AddNeighbor(map[x - 1, y]);
                    }

                    if (x - 1 >= 0 && y - 1 >= 0 && map[x - 1, y - 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x - 1, y - 1]);
                    }

                    if (y - 1 >= 0 && map[x, y - 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x, y - 1]);
                    }

                    if (x + 1 < Width && y - 1 >= 0 && map[x + 1, y - 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x + 1, y - 1]);
                    }

                    if (x + 1 < Width && map[x + 1, y] != null)
                    {
                        map[x, y].AddNeighbor(map[x + 1, y]);
                    }

                    if (x + 1 < Width && y + 1 < Height && map[x + 1, y + 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x + 1, y + 1]);
                    }

                    if (y + 1 < Height && map[x, y + 1] != null)
                    {
                        map[x, y].AddNeighbor(map[x, y + 1]);
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            if (p_Model.ModelFileName.Equals("Neutral"))
            {
                NeutralModel = p_Model;
            }
            else
            {
                ExpressionModel = p_Model;
            }

            if (NeutralModel == null || ExpressionModel == null)
            {
                return;
            }

            Cl3DModel.Cl3DModelPointIterator NeutralSavedNoseTip = null;
            Cl3DModel.Cl3DModelPointIterator NeutralLeftEye      = null;
            Cl3DModel.Cl3DModelPointIterator NeutralRightEye     = null;

            if (!NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref NeutralSavedNoseTip) || !NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, ref NeutralLeftEye) || !NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, ref NeutralRightEye))
            {
                throw new Exception("Cannot get all specific points (Neutral model)");
            }

            Cl3DModel.Cl3DModelPointIterator ExpressionSavedNoseTip = null;
            Cl3DModel.Cl3DModelPointIterator ExpressionLeftEye      = null;
            Cl3DModel.Cl3DModelPointIterator ExpressionRightEye     = null;

            if (!ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref ExpressionSavedNoseTip) || !ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, ref ExpressionLeftEye) || !ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, ref ExpressionRightEye))
            {
                throw new Exception("Cannot get all specific points (Exprssion model)");
            }

            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralSavedNoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralLeftEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralRightEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye.ToString());

            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionSavedNoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionLeftEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionRightEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye.ToString());

            Cl3DModel.Cl3DModelPointIterator iterNeutral = NeutralModel.GetIterator();
            do
            {
                // search for the closest point in distance geodesic distance domain
                Cl3DModel.Cl3DModelPointIterator iterExpression = ExpressionModel.GetIterator();
                Cl3DModel.Cl3DModelPointIterator ClossestPoint  = null;
                double ClosestPointDistance = 0;
                bool   first = true;
                double NoseDistanceNeutral     = 0;
                double LeftEyeDistanceNeutral  = 0;
                double RightEyeDistanceNeutral = 0;

                if (!iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out NoseDistanceNeutral) || !iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye, out LeftEyeDistanceNeutral) || !iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye, out RightEyeDistanceNeutral))
                {
                    throw new Exception("Cannot get specific value");
                }

                double NoseDistanceExpression;
                double LeftEyeDistanceExpression;
                double RightEyeDistanceExpression;

                do
                {
                    if (!iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out NoseDistanceExpression) || !iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye, out LeftEyeDistanceExpression) || !iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye, out RightEyeDistanceExpression))
                    {
                        throw new Exception("Cannot get specific value");
                    }

                    double newClosestPointDistance = Math.Sqrt(Math.Pow(NoseDistanceNeutral - NoseDistanceExpression, 2) + Math.Pow(LeftEyeDistanceNeutral - LeftEyeDistanceExpression, 2) + Math.Pow(RightEyeDistanceNeutral - RightEyeDistanceExpression, 2));
                    if (first)
                    {
                        ClossestPoint        = iterExpression.CopyIterator();
                        ClosestPointDistance = newClosestPointDistance;
                        first = false;
                        continue;
                    }

                    if (ClosestPointDistance > newClosestPointDistance)
                    {
                        ClossestPoint        = iterExpression.CopyIterator();
                        ClosestPointDistance = newClosestPointDistance;
                    }
                } while (iterExpression.MoveToNext());


                double ValNatural;
                double ValExpression;

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Mean_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Mean_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_HCurvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Gaussian_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Gaussian_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_KCurvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_K1Curvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K2_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K2_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_K2Curvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.ShapeIndex_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.ShapeIndex_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_ShapeIndexCurvatures_25, ValNatural - ValExpression);
            } while (iterNeutral.MoveToNext());
        }
        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();
                    }
                }
            }
        }
Beispiel #18
0
        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)
        {
            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;
             * }
             */
        }
Beispiel #20
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            if (!iter.IsValid())
            {
                return;
            }

            List <Cl3DModel.Cl3DModelPointIterator> ListOfNosePoints = new List <Cl3DModel.Cl3DModelPointIterator>();
            List <Cl3DModel.Cl3DModelPointIterator> ListOfEyesPoints = new List <Cl3DModel.Cl3DModelPointIterator>();
            string gausString = "Gaussian_" + m_iNeighborhoodSize.ToString();
            string meanString = "Mean_" + m_iNeighborhoodSize.ToString();

            do
            {
                double H = 0;
                double K = 0;

                if (!iter.GetSpecificValue(gausString, out K))
                {
                    continue;
                }
                if (!iter.GetSpecificValue(meanString, out H))
                {
                    continue;
                }

                if (H < 0 && K > m_NoseThresholdK) //  Nose
                {
                    ListOfNosePoints.Add(iter.CopyIterator());
                }
                else if (H > 0 && K > m_EyesThresholdK) //  Eyes
                {
                    ListOfEyesPoints.Add(iter.CopyIterator());
                }
            }while (iter.MoveToNext());

            List <List <Cl3DModel.Cl3DModelPointIterator> > NoseRegions = null;
            List <List <Cl3DModel.Cl3DModelPointIterator> > EyesRegions = null;

            // NOSE
            DivideToTheRegions(ListOfNosePoints, out NoseRegions);

            // EYES
            DivideToTheRegions(ListOfEyesPoints, out EyesRegions);

            // COLOR IT

            /*for (int i = 0; i < NoseRegions.Count; i++)
             * {
             *  foreach (Cl3DModel.Cl3DModelPointIterator point in NoseRegions[i])
             *      point.Color = ClTools.GetColorRGB((float)i / (NoseRegions.Count + EyesRegions.Count), 1);
             * }
             * for (int i = 0; i < EyesRegions.Count; i++)
             * {
             *  foreach (Cl3DModel.Cl3DModelPointIterator point in EyesRegions[i])
             *      point.Color = ClTools.GetColorRGB((float)(i + NoseRegions.Count) / (EyesRegions.Count + NoseRegions.Count), 1);
             * }
             */

            // -----------------  NOSE
            // remove smallest regions leave only 3 biggest one
            List <Cl3DModel.Cl3DModelPointIterator> NoseTipsPoints = new List <Cl3DModel.Cl3DModelPointIterator>();

            if (NoseRegions.Count > m_iMaxCountOfNoseRegions)
            {
                NoseRegions.Sort(new ClCompareCount());
                for (int i = NoseRegions.Count - 1; i >= m_iMaxCountOfNoseRegions; i--)
                {
                    NoseRegions.RemoveAt(i);
                }
            }
            //----------- NOSE searching for one point in each region
            for (int i = 0; i < NoseRegions.Count; i++)
            {
                double MaxKVal = 0;
                Cl3DModel.Cl3DModelPointIterator MaxPoint = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in NoseRegions[i])
                {
                    double K;
                    if (!point.GetSpecificValue(gausString, out K))
                    {
                        continue;
                    }

                    if (MaxPoint == null)
                    {
                        MaxPoint = point;
                        MaxKVal  = K;
                        continue;
                    }

                    if (MaxKVal < K)
                    {
                        MaxKVal  = K;
                        MaxPoint = point;
                    }
                }
                NoseTipsPoints.Add(MaxPoint);
            }

            // ---------------  EYES
            // remove smallest regions leave only 5 biggest one
            List <Cl3DModel.Cl3DModelPointIterator> EyesPoints = new List <Cl3DModel.Cl3DModelPointIterator>();

            if (EyesRegions.Count > m_iMaxCountOfEyeRegions)
            {
                EyesRegions.Sort(new ClCompareCount());
                for (int i = EyesRegions.Count - 1; i >= m_iMaxCountOfEyeRegions; i--)
                {
                    EyesRegions.RemoveAt(i);
                }
            }
            //--------------------------- EYES searching for one point in each region
            for (int i = 0; i < EyesRegions.Count; i++)
            {
                double MaxKval = 0;
                Cl3DModel.Cl3DModelPointIterator MinPoint = null;

                foreach (Cl3DModel.Cl3DModelPointIterator point in EyesRegions[i])
                {
                    double val;
                    if (!point.GetSpecificValue(gausString, out val))
                    {
                        continue;
                    }

                    if (MinPoint == null)
                    {
                        MinPoint = point;
                        MaxKval  = val;
                        continue;
                    }

                    if (MaxKval < val)
                    {
                        MaxKval  = val;
                        MinPoint = point;
                    }
                }
                EyesPoints.Add(MinPoint);
            }
            //------------- Looking for three face points ------------------------------
            Iridium.Numerics.LinearAlgebra.Matrix Model    = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);
            Iridium.Numerics.LinearAlgebra.Matrix ModelGen = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);

            // Generic model
            Vector GenericNoseTip  = new Vector(new double[] { 0, 0, 0 });
            Vector GenericLeftEye  = new Vector(new double[] { -21f, 40.5f, -41.5f });
            Vector GenericRightEye = new Vector(new double[] { 21f, 40.5f, -41.5f });

            Vector GenLeftCornerOfLeftEye   = new Vector(new double[] { -44f, 40f, -44f });
            Vector GenRightCornerOfRightEye = new Vector(new double[] { 44f, 40f, -44f });

            Vector GenLeftCornerOfNose  = new Vector(new double[] { -20f, -2f, -31f });
            Vector GenRightCornerOfNose = new Vector(new double[] { 20f, -2f, -31f });

            Vector GenLeftCornerOfLips  = new Vector(new double[] { -28f, -32f, -34f });
            Vector GenRightCornerOfLips = new Vector(new double[] { 28f, -32f, -34f });


            Vector MeanGenericModel = new Vector(new double[] { (GenericNoseTip[0] + GenericLeftEye[0] + GenericRightEye[0]) / 3,
                                                                (GenericNoseTip[1] + GenericLeftEye[1] + GenericRightEye[1]) / 3,
                                                                (GenericNoseTip[2] + GenericLeftEye[2] + GenericRightEye[2]) / 3 });

            // Centered generic model (generic model - mean)
            ModelGen[0, 0] = (GenericNoseTip[0] - MeanGenericModel[0]);
            ModelGen[1, 0] = (GenericNoseTip[1] - MeanGenericModel[1]);
            ModelGen[2, 0] = (GenericNoseTip[2] - MeanGenericModel[2]);

            ModelGen[0, 1] = (GenericLeftEye[0] - MeanGenericModel[0]);
            ModelGen[1, 1] = (GenericLeftEye[1] - MeanGenericModel[1]);
            ModelGen[2, 1] = (GenericLeftEye[2] - MeanGenericModel[2]);

            ModelGen[0, 2] = (GenericRightEye[0] - MeanGenericModel[0]);
            ModelGen[1, 2] = (GenericRightEye[1] - MeanGenericModel[1]);
            ModelGen[2, 2] = (GenericRightEye[2] - MeanGenericModel[2]);
            ModelGen.Transpose();

            List <KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > > deltaOfDistanceBetweenModelAndPoints = new List <KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > >();

            for (int iEye = 0; iEye < EyesPoints.Count - 1; iEye++)
            {
                for (int jEye = iEye + 1; jEye < EyesPoints.Count; jEye++)
                {
                    for (int iNose = 0; iNose < NoseTipsPoints.Count; iNose++)
                    {
                        Cl3DModel.Cl3DModelPointIterator eyeLeft  = EyesPoints[iEye];
                        Cl3DModel.Cl3DModelPointIterator eyeRight = EyesPoints[jEye];
                        Cl3DModel.Cl3DModelPointIterator noseTip  = NoseTipsPoints[iNose];

                        if (eyeLeft.Y < noseTip.Y || eyeRight.Y < noseTip.Y)
                        {
                            continue;
                        }

                        for (int c = 0; c < 2; c++)
                        {
                            if (c == 1)
                            {
                                eyeLeft  = EyesPoints[jEye]; // zmiana oczu nie wiemy ktore punkty to oczy prawdziwe sa
                                eyeRight = EyesPoints[iEye];
                            }

                            float MeanValX = (noseTip.X + eyeLeft.X + eyeRight.X) / 3.0f;
                            float MeanValY = (noseTip.Y + eyeLeft.Y + eyeRight.Y) / 3.0f;
                            float MeanValZ = (noseTip.Z + eyeLeft.Z + eyeRight.Z) / 3.0f;

                            Model[0, 0] = (noseTip.X - MeanValX);
                            Model[1, 0] = (noseTip.Y - MeanValY);
                            Model[2, 0] = (noseTip.Z - MeanValZ);

                            Model[0, 1] = (eyeLeft.X - MeanValX);
                            Model[1, 1] = (eyeLeft.Y - MeanValY);
                            Model[2, 1] = (eyeLeft.Z - MeanValZ);

                            Model[0, 2] = (eyeRight.X - MeanValX);
                            Model[1, 2] = (eyeRight.Y - MeanValY);
                            Model[2, 2] = (eyeRight.Z - MeanValZ);


                            //----------------- Finding best rotation and translation SVD algorithm

                            Iridium.Numerics.LinearAlgebra.Matrix Covariance = Model * ModelGen;

                            Iridium.Numerics.LinearAlgebra.SingularValueDecomposition SVD = new Iridium.Numerics.LinearAlgebra.SingularValueDecomposition(Covariance);
                            Iridium.Numerics.LinearAlgebra.Matrix U = SVD.LeftSingularVectors;
                            Iridium.Numerics.LinearAlgebra.Matrix V = SVD.RightSingularVectors;

                            Iridium.Numerics.LinearAlgebra.Matrix s = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1.0);

                            if (Covariance.Rank() < 2)
                            {
                                throw new Exception("Cannot allign generic model (cov rank is less than 2)");
                            }

                            if (Covariance.Rank() == 2) // m-1 where m is dimension space (3D)
                            {
                                double detU = Math.Round(U.Determinant());
                                double detV = Math.Round(V.Determinant());
                                double detC = Covariance.Determinant();
                                if ((int)detU * (int)detV == 1)
                                {
                                    s[2, 2] = 1;
                                }
                                else if ((int)detU * (int)detV == -1)
                                {
                                    s[2, 2] = -1;
                                }
                                else
                                {
                                    throw new Exception("Determinant of U and V are not in conditions");
                                }
                            }
                            else
                            {
                                if (Covariance.Determinant() < 0)
                                {
                                    s[2, 2] = -1;
                                }
                            }

                            V.Transpose();
                            Iridium.Numerics.LinearAlgebra.Matrix Roatation = U * s * V;

                            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfGenModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            MeanValOfGenModelMatrix[0, 0] = MeanGenericModel[0];
                            MeanValOfGenModelMatrix[1, 0] = MeanGenericModel[1];
                            MeanValOfGenModelMatrix[2, 0] = MeanGenericModel[2];

                            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            MeanValOfModelMatrix[0, 0] = MeanValX;
                            MeanValOfModelMatrix[1, 0] = MeanValY;
                            MeanValOfModelMatrix[2, 0] = MeanValZ;

                            Iridium.Numerics.LinearAlgebra.Matrix Translation = MeanValOfModelMatrix - Roatation * MeanValOfGenModelMatrix;

                            //--------------------------- End now we have translation and rotation

                            float GenericModelDistance = 0;;

                            Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            q[0, 0] = GenericNoseTip[0];
                            q[1, 0] = GenericNoseTip[1];
                            q[2, 0] = GenericNoseTip[2];
                            Iridium.Numerics.LinearAlgebra.Matrix NewQ = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(noseTip.X - NewQ[0, 0], 2) + Math.Pow(noseTip.Y - NewQ[1, 0], 2) + Math.Pow(noseTip.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it1 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it1.AddNeighbor(noseTip);
                            //    it1.Color = Color.Green;
                            //---------
                            q[0, 0] = GenericLeftEye[0];
                            q[1, 0] = GenericLeftEye[1];
                            q[2, 0] = GenericLeftEye[2];
                            NewQ    = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(eyeLeft.X - NewQ[0, 0], 2) + Math.Pow(eyeLeft.Y - NewQ[1, 0], 2) + Math.Pow(eyeLeft.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it2 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it2.AddNeighbor(eyeLeft);
                            //    it2.Color = Color.White;
                            //---------

                            q[0, 0] = GenericRightEye[0];
                            q[1, 0] = GenericRightEye[1];
                            q[2, 0] = GenericRightEye[2];
                            NewQ    = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(eyeRight.X - NewQ[0, 0], 2) + Math.Pow(eyeRight.Y - NewQ[1, 0], 2) + Math.Pow(eyeRight.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it3 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it3.AddNeighbor(eyeRight);
                            //    it3.Color = Color.Orange;

                            //    it1.AddNeighbor(it2);
                            //    it1.AddNeighbor(it3);
                            //    it2.AddNeighbor(it3);
                            //---------

                            // ---------- Rest of generic model to find closest points and count distance;
                            q[0, 0] = GenLeftCornerOfLeftEye[0];
                            q[1, 0] = GenLeftCornerOfLeftEye[1];
                            q[2, 0] = GenLeftCornerOfLeftEye[2];
                            NewQ    = Roatation * q + Translation;
                            Cl3DModel.Cl3DModelPointIterator closestPoint = null;
                            float MinDistance;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfRightEye[0];
                            q[1, 0] = GenRightCornerOfRightEye[1];
                            q[2, 0] = GenRightCornerOfRightEye[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenLeftCornerOfNose[0];
                            q[1, 0] = GenLeftCornerOfNose[1];
                            q[2, 0] = GenLeftCornerOfNose[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfNose[0];
                            q[1, 0] = GenRightCornerOfNose[1];
                            q[2, 0] = GenRightCornerOfNose[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenLeftCornerOfLips[0];
                            q[1, 0] = GenLeftCornerOfLips[1];
                            q[2, 0] = GenLeftCornerOfLips[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfLips[0];
                            q[1, 0] = GenRightCornerOfLips[1];
                            q[2, 0] = GenRightCornerOfLips[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;
                            // ----------


                            ClInformationSender.SendInformation("One of distances between generic model and face before thresholding: " + GenericModelDistance.ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eDebugText);

                            if (GenericModelDistance > m_fDistanceMinValueFromGenModel)
                            {
                                continue;
                            }

                            // Check if between eyes and nose there is other region (it should be not)

                            /*bool isBetweenNoseRegion = false;
                             * foreach (Cl3DModel.Cl3DModelPointIterator noseTmp in NoseTipsPoints)
                             * {
                             *  if (noseTmp.PointID == noseTip.PointID)
                             *      continue;
                             *
                             *  if (noseTmp.X > eyeLeft.X && noseTmp.X < eyeRight.X && noseTmp.Y > noseTip.Y && (noseTip.Y < eyeLeft.Y || noseTip.Y < eyeRight.Y))
                             *      isBetweenNoseRegion = true;
                             * }
                             * if (isBetweenNoseRegion)
                             *  continue;
                             */
                            List <Cl3DModel.Cl3DModelPointIterator> list = new List <Cl3DModel.Cl3DModelPointIterator>();
                            list.Add(noseTip);
                            list.Add(eyeLeft);
                            list.Add(eyeRight);

                            KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > KeyVal = new KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> >(GenericModelDistance, list);

                            deltaOfDistanceBetweenModelAndPoints.Add(KeyVal);
                        }
                    }
                }
            }

            if (deltaOfDistanceBetweenModelAndPoints.Count == 0)
            {
                throw new Exception("Cannot find nose and eyes points");
            }

            float min = deltaOfDistanceBetweenModelAndPoints[0].Key;
            int   no  = 0;

            for (int i = 1; i < deltaOfDistanceBetweenModelAndPoints.Count; i++)
            {
                if (deltaOfDistanceBetweenModelAndPoints[i].Key < min)
                {
                    min = deltaOfDistanceBetweenModelAndPoints[i].Key;
                    no  = i;
                }
            }

            ClInformationSender.SendInformation("Correct MIN distance between generic model and face: " + min.ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eDebugText);

            p_Model.AddSpecificPoint(NameOfNoseTip, deltaOfDistanceBetweenModelAndPoints[no].Value[0]);
            p_Model.AddSpecificPoint(NameLeftEyeRightCorner, deltaOfDistanceBetweenModelAndPoints[no].Value[1]);
            p_Model.AddSpecificPoint(NameRightEyeLeftCorner, deltaOfDistanceBetweenModelAndPoints[no].Value[2]);
        }
        private void SampleUVParametriztion(Cl3DModel p_Model, out Cl3DModel.Cl3DModelPointIterator[,] SampledModel, int MatrixWidth, int MatrixHeight)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float maxU = iter.U;
            float minU = iter.U;
            float maxV = iter.V;
            float minV = iter.V;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        SampledModel[i, j] = pt;

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

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

                        foreach (Cl3DModel.Cl3DModelPointIterator point in connections)
                        {
                            pt.AddNeighbor(point);
                        }
                    }
                }
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                ReadTexture(p_sFilePath);
                // using ( cannot be used cause we open file stream once again
                StreamReader FileStream = File.OpenText(p_sFilePath);
                {
                    bool foundTocken = FindTockenInFile("Coordinate", FileStream);
                    if (!foundTocken)
                    {
                        FileStream  = File.OpenText(p_sFilePath);
                        foundTocken = FindTockenInFile("Coordinate3", FileStream);
                        if (!foundTocken)
                        {
                            throw new Exception("Wrong file format, cannot find 'Coordinate' tocken");
                        }
                    }

                    bool   finishReading = false;
                    String line;
                    int    pointNO = 0;
                    while ((line = FileStream.ReadLine()) != null && !finishReading)
                    {
                        if (line.Contains("point"))
                        {
                            continue;
                        }

                        string[] parts = line.Split(' ');
                        for (int i = 0; i < parts.Length; i++)
                        {
                            if (parts[i].Contains("]"))
                            {
                                finishReading = true;
                                break;
                            }
                        }
                        if (finishReading)
                        {
                            break;
                        }

                        List <string> numbers = new List <string>();

                        foreach (string s in parts)
                        {
                            if (s.Equals(""))
                            {
                                continue;
                            }
                            else
                            {
                                numbers.Add(s);
                            }
                        }

                        if (numbers.Count != 3)
                        {
                            throw new Exception("Wrong file format, less coordinates than expected");
                        }

                        float X = Single.Parse(numbers[0].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture);
                        float Y = Single.Parse(numbers[1].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture);
                        float Z = Single.Parse(numbers[2].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture);

                        Cl3DModel.Cl3DModelPointIterator newPoint = p_mModel3D.AddPointToModel(X, Y, Z);
                        if (texture != null && TextureCoord.Count != 0)
                        {
                            newPoint.Color = texture.GetPixel((int)(TextureCoord[pointNO].no1 * texture.Width),
                                                              (int)(TextureCoord[pointNO].no2 * texture.Height));
                            newPoint.AddSpecificValue("Texture", newPoint.Color.ToArgb());
                        }
                        pointNO++;
                    }

                    foundTocken = FindTockenInFile("coordIndex", FileStream);
                    if (!foundTocken)
                    {
                        throw new Exception("Wrong file format, cannot find 'coordIndex' tocken");
                    }

                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Contains("]"))
                        {
                            break;
                        }


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

                        Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.GetIterator();
                        string[] parts     = line.Split(new Char [] { ' ', ',' });
                        bool     EndOfLine = false;
                        foreach (string part in parts)
                        {
                            if (part.Length == 0)
                            {
                                continue;
                            }

                            int no = Int32.Parse(part);

                            if (no == -1)
                            {
                                EndOfLine = true;
                            }

                            if (EndOfLine)
                            {
                                for (int i = 0; i < points.Count; i++)
                                {
                                    if (i == points.Count - 2)
                                    {
                                        points[i].AddNeighbor(points[i + 1]);
                                        points[i + 1].AddNeighbor(points[0]);
                                        break;
                                    }
                                    if (i == points.Count - 3)
                                    {
                                        points[i].AddNeighbor(points[i + 1]);
                                        points[i + 1].AddNeighbor(points[i + 2]);
                                        points[i + 2].AddNeighbor(points[i]);
                                    }
                                    else
                                    {
                                        points[i].AddNeighbor(points[i + 1]);
                                        points[i + 1].AddNeighbor(points[i + 2]);
                                        points[i + 2].AddNeighbor(points[i]);
                                    }
                                }
                                points.Clear();
                                EndOfLine = false;
                            }
                            else
                            {
                                if (!iter.MoveToPoint((uint)no))
                                {
                                    throw new Exception("Cannot find point no: " + no);
                                }
                                points.Add(iter.CopyIterator());
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }