public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                using (FileStream fs = File.OpenRead(p_sFilePath))
                {
                    BinaryReader ReaderBinary = new BinaryReader(fs);
                    while (true)
                    {
                        try
                        {
                            short number = ReaderBinary.ReadInt16();
                            for (short i = 0; i < number; i++)
                            {
                                short X = ReaderBinary.ReadInt16();
                                short Y = ReaderBinary.ReadInt16();
                                short Z = ReaderBinary.ReadInt16();

                                p_mModel3D.AddPointToModel((float)X/10.0f, (float)Y/10.0f, (float)-Z/10.0f);
                            }
                        }
                        catch (System.IO.EndOfStreamException)
                        {
                            break;
                        }
                    }
                    fs.Close();
                }
            }
            catch (Exception e)
            {
                p_mModel3D.ResetModel();
                throw e;
            }
        }
        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 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);
                    }
                }
            }
        }
        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;
            }
              */
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                using (FileStream fs = File.OpenRead(p_sFilePath))
                {
                    try
                    {
                        BinaryReader ReaderBinary = new BinaryReader(fs);
                        ushort nRows = ReaderBinary.ReadUInt16();
                        ushort nCols = ReaderBinary.ReadUInt16();
                        double zMin = ReaderBinary.ReadDouble();

                        ushort len = ReaderBinary.ReadUInt16();

                        char[] imFile = ReaderBinary.ReadChars((int)len);

                        p_mModel3D.ModelExpression = p_mModel3D.ModelFileName.Substring(6);

                        uint dataLen = ReaderBinary.ReadUInt32();

                        uint oneRead = dataLen / 5;

                        double[] X = new double[oneRead];
                        double[] Y = new double[oneRead];
                        double[] Z = new double[oneRead];
                        double[] RangeX = new double[oneRead];
                        double[] RangeY = new double[oneRead];

                        for (int i = 0; i < oneRead; i++)
                            X[i] = ReaderBinary.ReadDouble();

                        for (int i = 0; i < oneRead; i++)
                            Y[i] = ReaderBinary.ReadDouble();

                        for (int i = 0; i < oneRead; i++)
                            Z[i] = ReaderBinary.ReadDouble();

                        for (int i = 0; i < oneRead; i++)
                            RangeX[i] = ReaderBinary.ReadDouble();

                        for (int i = 0; i < oneRead; i++)
                            RangeY[i] = ReaderBinary.ReadDouble();

                        Cl3DModel.Cl3DModelPointIterator[,] tabOfElements = new Cl3DModel.Cl3DModelPointIterator[nCols, nRows];

                        for (int i = 0; i < oneRead; i++)
                        {
                            if (X[i] != zMin && Y[i] != zMin && Z[i] != zMin && RangeX[i] != zMin && RangeY[i] != zMin)
                            {
                                int rangeX = (int)(RangeX[i] * nCols);
                                int rangeY = (int)(RangeY[i] * nRows);
                                if (tabOfElements[rangeX, rangeY] == null)
                                    tabOfElements[rangeX, rangeY] = p_mModel3D.AddPointToModel((float)X[i], (float)Y[i], (float)Z[i], rangeX, rangeY);
                                else
                                    throw new Exception("The element is set to current position");
                            }
                        }

                        for (int x = 0; x < nCols; x++)
                        {
                            for (int y = 0; y < nRows; y++)
                            {
                                if (tabOfElements[x, y] == null)
                                    continue;

                                if (x - 1 >= 0 && y + 1 < nRows && tabOfElements[x - 1, y + 1] != null)
                                    tabOfElements[x, y].AddNeighbor(tabOfElements[x - 1, y + 1]);

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

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

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

                                if (x + 1 < nCols && y - 1 >= 0 && tabOfElements[x + 1, y - 1] != null)
                                    tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y - 1]);

                                if (x + 1 < nCols && tabOfElements[x + 1, y] != null)
                                    tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y]);

                                if (x + 1 < nCols && y + 1 < nRows && tabOfElements[x + 1, y + 1] != null)
                                    tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y + 1]);

                                if (y + 1 < nRows && tabOfElements[x, y + 1] != null)
                                    tabOfElements[x, y].AddNeighbor(tabOfElements[x, y + 1]);
                            }
                        }

                    }
                    catch (System.IO.EndOfStreamException)
                    {
                    }
                    fs.Close();
                }
            }
            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 || line.StartsWith("#"))
                            continue;

                        char[] delimiterChars = { ' ', '{', '}', '(', ')' };
                        string[] splited = line.Split(delimiterChars);
                        //splited.
                        if (splited[0].Equals("Vertex"))
                        {
                            int no=1;
                            uint ID = UInt32.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                            if (splited[no].Equals(""))
                                no++;
                            float x = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                            float y = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                            float z = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);

                            Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.AddPointToModel(x, y, z, ID);

                            if (splited.Length > 6)
                            {
                                if (splited[no].Equals(""))
                                    no++;

                                if (splited.Length > 6 && splited[no++].Equals("rgb="))
                                {
                                    float r = 1;
                                    float g = 1;
                                    float b = 1;

                                    r = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                                    g = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                                    b = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);

                                    iter.Color = Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
                                    iter.AddSpecificValue("Texture", iter.Color.ToArgb());
                                    no++;
                                }
                                if (splited.Length > 11 && splited[no++].Equals("uv="))
                                {
                                    float U = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                                    float V = Single.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);

                                    iter.U = U;
                                    iter.V = V;
                                }
                            }

                        }
                        else if (splited[0].Equals("Face"))
                        {
                            int no = 2;
                            if (splited[no].Equals(""))
                                no++;

                            uint ID1 = UInt32.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                            uint ID2 = UInt32.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);
                            uint ID3 = UInt32.Parse(splited[no++], System.Globalization.CultureInfo.InvariantCulture);

                           Cl3DModel.Cl3DModelPointIterator iter1 = p_mModel3D.GetIterator();
                           Cl3DModel.Cl3DModelPointIterator iter2 = p_mModel3D.GetIterator();
                           Cl3DModel.Cl3DModelPointIterator iter3 = p_mModel3D.GetIterator();

                           if (!iter1.MoveToPoint(ID1))
                               throw new Exception("Cannot find point with ID: " + ID1.ToString());

                           if (!iter2.MoveToPoint(ID2))
                               throw new Exception("Cannot find point with ID: " + ID2.ToString());

                           if (!iter3.MoveToPoint(ID3))
                               throw new Exception("Cannot find point with ID: " + ID3.ToString());

                           iter1.AddNeighbor(iter2);
                           iter2.AddNeighbor(iter3);
                           iter3.AddNeighbor(iter1);
                        }
                        else
                        {
                            throw new Exception("Unknown tocken: " + splited[0]);
                        }
                    }
                    FileStream.Close();
                }
            }
            catch (Exception e)
            {
                p_mModel3D.ResetModel();
                Exception ex = new Exception("Wrong M File Format: " + p_mModel3D.ModelFilePath, e);
                throw ex;
            }
        }
        private void SampleUVParametriztion(Cl3DModel p_Model, out Cl3DModel.Cl3DModelPointIterator[,] SampledModel, int MatrixWidth, int MatrixHeight)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float maxU = iter.U;
            float minU = iter.U;
            float maxV = iter.V;
            float minV = iter.V;

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

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

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

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

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

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

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

               } while (iter.MoveToNext());

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

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

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

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

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

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

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

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

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

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

                        SampledModel[i, j] = pt;

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

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

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

                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            if (NormalsAdded.Count != 0)
            {
                foreach (Cl3DModel.Cl3DModelPointIterator pt in NormalsAdded)
                    p_Model.RemovePointFromModel(pt);

                NormalsAdded = new List<Cl3DModel.Cl3DModelPointIterator>();
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                Vector NormalVector = null;
                if (UsePCA)
                {
                    ClTools.CalculateNormalVectorInPointUsingPCA(iter.X, iter.Y, iter.Z, iter.GetListOfNeighbors(), out NormalVector);
                }
                else
                {
                    ClTools.CalculateNormalVectorInPoint(iter.X, iter.Y, iter.Z, iter.GetListOfNeighbors(), out NormalVector);
                }

                double norm = Math.Sqrt(Math.Pow(NormalVector[0], 2) + Math.Pow(NormalVector[1], 2) + Math.Pow(NormalVector[2], 2));
                if (norm != 0)
                {
                    NormalVector[0] /= (float)norm;
                    NormalVector[1] /= (float)norm;
                    NormalVector[2] /= (float)norm;
                }
                iter.NormalVector = NormalVector;

                if (ShowNormals)
                {
                    Cl3DModel.Cl3DModelPointIterator point = p_Model.AddPointToModel(iter.X - (float)NormalVector[0]*3, iter.Y - (float)NormalVector[1]*3, iter.Z - (float)NormalVector[2]*3);
                    iter.AddNeighbor(point);
                    NormalsAdded.Add(point);
                }

            } while (iter.MoveToNext());
        }
        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;
                    }
                }
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                Dictionary<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>> modelNeighbors = new Dictionary<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>>();
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    string line;
                    bool Landmarks = false;
                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Length == 0)
                            continue;
                        if (line[0].Equals('@'))
                            continue;

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

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

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

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

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

                            Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.AddPointToModel(X, Y, Z, XImage, YImage, PointId);
                            List<uint> neighbors = new List<uint>();
                            for (int i = 9; i < splitedLine.Length - 1; i++)
                            {
                                neighbors.Add(UInt32.Parse(splitedLine[i], System.Globalization.CultureInfo.InvariantCulture));
                            }
                            modelNeighbors.Add(PointId, new KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>(iter, neighbors));
                        }
                    }
                }
                foreach(KeyValuePair<uint, KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>>> onePoint in modelNeighbors)
                {
                    foreach(uint neighboorNo in onePoint.Value.Value)
                    {
                        KeyValuePair<Cl3DModel.Cl3DModelPointIterator, List<uint>> list;
                        if(modelNeighbors.TryGetValue(neighboorNo, out list))
                            onePoint.Value.Key.AddNeighbor(list.Key);
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            try
            {
                Dictionary<string, Cl3DModel.Cl3DModelPointIterator> Points = new Dictionary<string, Cl3DModel.Cl3DModelPointIterator>();
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    string line = "";
                    while ((line = FileStream.ReadLine()) != null)
                    {
                        if (line.Contains("    [POLYGON [PLANE"))
                        {
                            Cl3DModel.Cl3DModelPointIterator[] polygon = new Cl3DModel.Cl3DModelPointIterator[3];
                            for (int i = 0; i < 3; i++)
                            {
                                if ((line = FileStream.ReadLine()) != null)
                                {
                                    string[] param = line.Replace('[',' ').Replace(']',' ').Split(' ');
                                    double H = Double.Parse(param[3]);
                                    double K = Double.Parse(param[7]);

                                    if ((line = FileStream.ReadLine()) != null)
                                    {
                                        param = line.Replace('[', ' ').Replace(']', ' ').Replace('"', ' ').Split(' ');
                                        float U = Single.Parse(param[3]);
                                        float V = Single.Parse(param[4]);

                                        float X = 0;
                                        float Y = 0;
                                        float Z = 0;

                                        string ID = "";
                                        if(line.Contains("[NORMAL"))
                                        {
                                            X = Single.Parse(param[9]);
                                            Y = Single.Parse(param[10]);
                                            Z = Single.Parse(param[11]);
                                            ID = param[9]+param[10]+param[11];
                                        }
                                        else
                                        {
                                            X = Single.Parse(param[7]);
                                            Y = Single.Parse(param[8]);
                                            Z = Single.Parse(param[9]);
                                            ID = param[7] + param[8] + param[9];
                                        }

                                        Cl3DModel.Cl3DModelPointIterator it = null;
                                        if (!Points.TryGetValue(ID, out it))
                                        {
                                            it = p_mModel3D.AddPointToModel(X, Y, Z);
                                            it.U = U;
                                            it.V = V;
                                            it.AddSpecificValue("GroundK", K);
                                            it.AddSpecificValue("GroundH", H);

                                            Points.Add(ID, it);
                                        }

                                        polygon[i] = it;
                                    }
                                    else
                                        throw new Exception("Something wrong 2");

                                }
                                else
                                    throw new Exception("Something wrong 1");
                            }
                            polygon[0].AddNeighbor(polygon[1]);
                            polygon[0].AddNeighbor(polygon[2]);
                            polygon[1].AddNeighbor(polygon[2]);

                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            Cl3DModel.Cl3DModelPointIterator MaxPoint = null;

                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    int iTableWidth = 0;
                    int iTableHeight = 0;
                    bool endOfHeader = false;

                    string line = "";
                    while ((line = FileStream.ReadLine()) != null) // Search for ROWS
                    {
                        if(line.Equals("|"))
                        {
                            endOfHeader = true;
                            break;
                        }
                    }

                    if(!endOfHeader)
                        throw new Exception("Wrong header");

                    string precision = "";
                    string format = "";
                    string width = "";
                    string height = "";
                    string sX = "";
                    string sY = "";
                    string sZ = "";
                    string sValidPixels = "";

                    if ((precision = FileStream.ReadLine()) == null)
                        throw new Exception("Wrong file format, file is to short, cannot get precision");

                    if ((format = FileStream.ReadLine()) == null)
                        throw new Exception("Wrong file format, file is to short, cannot get format");

                    if ((width = FileStream.ReadLine()) == null)
                        throw new Exception("Wrong file format, file is to short, cannot get width");

                    if ((height = FileStream.ReadLine()) == null)
                        throw new Exception("Wrong file format, file is to short, cannot get height");

                    iTableWidth = Int32.Parse(width);
                    iTableHeight = Int32.Parse(height);

                    string tmp = "";
                    for(int i = 0; i< iTableHeight; i++)
                    {
                        if (((tmp = FileStream.ReadLine()) == null))
                            throw new Exception("Wrong file format, file is to short, cannot get sX");
                        sX += tmp;
                    }

                    for (int i = 0; i < iTableHeight; i++)
                    {
                        if (((tmp = FileStream.ReadLine()) == null))
                            throw new Exception("Wrong file format, file is to short, cannot get sY");
                        sY += tmp;
                    }

                    for (int i = 0; i < iTableHeight; i++)
                    {
                        if (((tmp = FileStream.ReadLine()) == null))
                            throw new Exception("Wrong file format, file is to short, cannot get sZ");
                        sZ += tmp;
                    }

                    for (int i = 0; i < iTableHeight; i++)
                    {
                        if (((tmp = FileStream.ReadLine()) == null))
                            throw new Exception("Wrong file format, file is to short, cannot get sValidPixels");
                        sValidPixels += tmp;
                    }

                    FileStream.Close();

                    string[] sArrayPixels = sValidPixels.Remove(sValidPixels.Length - 1).Split(' ');
                    string[] sArrayX = sX.Remove(sX.Length - 1).Split(' ');
                    string[] sArrayY = sY.Remove(sY.Length - 1).Split(' ');
                    string[] sArrayZ = sZ.Remove(sZ.Length - 1).Split(' ');

                    float vectorLength = iTableWidth * iTableHeight;

                    if (sArrayX.Length != vectorLength ||
                        sArrayY.Length != vectorLength ||
                        sArrayZ.Length != vectorLength ||
                        sArrayPixels.Length != vectorLength)
                        throw new Exception("Arrays length are different");

                    int ax = 0;
                    int ay = 0;
                    Cl3DModel.Cl3DModelPointIterator[,] tabOfElements = new Cl3DModel.Cl3DModelPointIterator[iTableWidth, iTableHeight];
                    //p_mModel3D.ResetModel();
                    for (int i = 0; i < sArrayPixels.Length; i++)
                    {
                        if (ax == iTableWidth)
                        {
                            ax = 0;
                            ay++;
                        }

                        if (ax >= iTableWidth || ay >= iTableHeight)
                            throw new Exception("One of acces operators is bigger than should be");

                        if (sArrayPixels[i].Equals("0"))
                        {
                            string Xstring = sArrayX[i];
                            string Ystring = sArrayY[i];
                            string Zstring = sArrayZ[i];

                            float x = System.Single.Parse(Xstring, System.Globalization.CultureInfo.InvariantCulture);
                            float y = System.Single.Parse(Ystring, System.Globalization.CultureInfo.InvariantCulture);
                            float z = System.Single.Parse(Zstring, System.Globalization.CultureInfo.InvariantCulture);

                            tabOfElements[ax,ay] = p_mModel3D.AddPointToModel(x, y, z, ax, ay);
                            if (MaxPoint == null)
                                MaxPoint = tabOfElements[ax, ay];
                            else if (tabOfElements[ax, ay].Z > MaxPoint.Z)
                                MaxPoint = tabOfElements[ax, ay];
                        }
                        ax++;
                    }
                    float minusX = MaxPoint.X;
                    float minusY = MaxPoint.Y;
                    float minusZ = MaxPoint.Z;
                    for (int x = 0; x < iTableWidth; x++)
                    {
                        for (int y = 0; y < iTableHeight; y++)
                        {
                            if (tabOfElements[x, y] == null)
                                continue;

                            if (x - 1 >= 0 && y + 1 < iTableHeight && tabOfElements[x - 1, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x - 1, y + 1]);

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

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

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

                            if (x + 1 < iTableWidth && y - 1 >= 0 && tabOfElements[x + 1, y - 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y - 1]);

                            if (x + 1 < iTableWidth && tabOfElements[x + 1, y] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y]);

                            if (x + 1 < iTableWidth && y + 1 < iTableHeight && tabOfElements[x + 1, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y + 1]);

                            if (y + 1 < iTableHeight && tabOfElements[x, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x, y + 1]);
                        }
                    }
                }
        }
        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;
            }
        }
        public override void Read(Cl3DModel p_mModel3D, string p_sFilePath)
        {
            Cl3DModel.Cl3DModelPointIterator MaxPoint = null;
            try
            {
                using (StreamReader FileStream = File.OpenText(p_sFilePath))
                {
                    int iTableWidth = 0;
                    int iTableHeight = 0;

                    #region HeaderParse

                    String header = "";
                    if ((header = FileStream.ReadLine()) != null) // Search for ROWS
                    {
                        string[] val = header.Split(' ');
                        if (val.Length != 2)
                            throw new Exception("Wrong file format");

                        if (!val[1].Equals("rows"))
                            throw new Exception("Wrong file format, cannot find 'rows'");

                        iTableHeight = Int32.Parse(val[0]);
                    }
                    else
                        throw new Exception("Wrong file format, file is to short");

                    if ((header = FileStream.ReadLine()) != null) // Search for COLUMNS
                    {
                        string[] val = header.Split(' ');
                        if (val.Length != 2)
                            throw new Exception("Wrong file format");

                        if (!val[1].Equals("columns"))
                            throw new Exception("Wrong file format, cannot find 'rows'");

                        iTableWidth = Int32.Parse(val[0]);
                    }
                    else
                        throw new Exception("Wrong file format, file is to short");

                    if ((header = FileStream.ReadLine()) != null)// Search for PIXELS
                    {
                        if (!header.StartsWith("pixels (flag X Y Z):"))
                            throw new Exception("Wrong file format, cannot find 'pixels (flag X Y Z):', only this flags are available");
                    }
                    else
                        throw new Exception("Wrong file format, file is to short");
                    #endregion

                    string sValidPixels = "";
                    string sX = "";
                    string sY = "";
                    string sZ = "";
                    if ((sValidPixels = FileStream.ReadLine()) == null)// Search for sValidPixels
                        throw new Exception("Wrong file format, file is to short, cannot get Valid Pixels line");

                    if ((sX = FileStream.ReadLine()) == null)// Search for X
                        throw new Exception("Wrong file format, file is to short, cannot get X line");

                    if ((sY = FileStream.ReadLine()) == null)// Search for Y
                        throw new Exception("Wrong file format, file is to short, cannot get Y line");

                    if ((sZ = FileStream.ReadLine()) == null)// Search for Z
                        throw new Exception("Wrong file format, file is to short, cannot get Z line");

                    FileStream.Close();

                    string[] sArrayPixels = sValidPixels.Remove(sValidPixels.Length - 1).Split(' ');
                    string[] sArrayX = sX.Remove(sX.Length - 1).Split(' ');
                    string[] sArrayY = sY.Remove(sY.Length - 1).Split(' ');
                    string[] sArrayZ = sZ.Remove(sZ.Length - 1).Split(' ');

                    float vectorLength = iTableWidth * iTableHeight;

                    if (sArrayX.Length != vectorLength ||
                        sArrayY.Length != vectorLength ||
                        sArrayZ.Length != vectorLength ||
                        sArrayPixels.Length != vectorLength)
                        throw new Exception("Arrays length are different");

                    int ax = 0;
                    int ay = 0;
                    Cl3DModel.Cl3DModelPointIterator[,] tabOfElements = new Cl3DModel.Cl3DModelPointIterator[iTableWidth, iTableHeight];
                    //p_mModel3D.ResetModel();
                    for (int i = 0; i < sArrayPixels.Length; i++)
                    {
                        if (ax == iTableWidth)
                        {
                            ax = 0;
                            ay++;
                        }

                        if (ax >= iTableWidth || ay >= iTableHeight)
                            throw new Exception("One of acces operators is bigger than should be");

                        if (sArrayPixels[i].Equals("1"))
                        {
                            string Xstring = sArrayX[i];//.Replace(".", ",");
                            string Ystring = sArrayY[i];//.Replace(".", ",");
                            string Zstring = sArrayZ[i];//.Replace(".", ",");

                            float x = System.Single.Parse(Xstring, System.Globalization.CultureInfo.InvariantCulture);
                            float y = System.Single.Parse(Ystring, System.Globalization.CultureInfo.InvariantCulture);
                            float z = System.Single.Parse(Zstring, System.Globalization.CultureInfo.InvariantCulture);

                            tabOfElements[ax,ay] = p_mModel3D.AddPointToModel(x, y, z, ax, ay);
                            if (MaxPoint == null)
                                MaxPoint = tabOfElements[ax, ay];
                            else if (tabOfElements[ax, ay].Z > MaxPoint.Z)
                                MaxPoint = tabOfElements[ax, ay];
                        }
                        ax++;
                    }
                    float minusX = MaxPoint.X;
                    float minusY = MaxPoint.Y;
                    float minusZ = MaxPoint.Z;
                    for (int x = 0; x < iTableWidth; x++)
                    {
                        for (int y = 0; y < iTableHeight; y++)
                        {
                            if (tabOfElements[x, y] == null)
                                continue;

                            if (x - 1 >= 0 && y + 1 < iTableHeight && tabOfElements[x - 1, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x - 1, y + 1]);

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

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

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

                            if (x + 1 < iTableWidth && y - 1 >= 0 && tabOfElements[x + 1, y - 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y - 1]);

                            if (x + 1 < iTableWidth && tabOfElements[x + 1, y] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y]);

                            if (x + 1 < iTableWidth && y + 1 < iTableHeight && tabOfElements[x + 1, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x + 1, y + 1]);

                            if (y + 1 < iTableHeight && tabOfElements[x, y + 1] != null)
                                tabOfElements[x, y].AddNeighbor(tabOfElements[x, y + 1]);
                        }
                    }
                }
            }
            catch (Exception)
            {
                p_mModel3D.ResetModel();
                throw;
            }
        }