protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            int maxX = (int)iter.X;
            int minX = (int)iter.X;
            int maxY = (int)iter.Y;
            int minY = (int)iter.Y;

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

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

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

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

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

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

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

                        float MeanU = 0;
                        float MeanV = 0;

                        float MeanRangeX = 0;
                        float MeanRangeY = 0;

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

                        Cl3DModel.Cl3DModelPointIterator MaxPoint = null;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

               } while (iter.MoveToNext());

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

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

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

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

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

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

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

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

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

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

                        SampledModel[i, j] = pt;

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

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

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

                    }
                }
            }
        }