Example #1
0
        private void ParserPlyModel()
        {
            using (BufferedStream sr = new BufferedStream(File.OpenRead(this.path)))
            {
                int             byteCount;
                PlyObjectHeader headerObj = this.GetPlyObjectHeader(sr, out byteCount);
                this.triangles = new Triangle[headerObj.Elements["face"].Count];
                sr.Position    = byteCount;
                switch (headerObj.Format)
                {
                case PlyFormat.ascii:
                    this.ParserASCII(headerObj, sr);
                    break;

                case PlyFormat.binary_big_endian:
                    using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.BigEndian))
                    {
                        this.ParserBinary(headerObj, br);
                    }
                    break;

                case PlyFormat.binary_little_endian:
                    using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.LittleEndian))
                    {
                        this.ParserBinary(headerObj, br);
                    }
                    break;

                default:
                    throw new FormatException("Invalid File format!");
                    break;
                }
            }
        }
Example #2
0
        private PlyObjectHeader GetPlyObjectHeader(Stream sr, out int byteCount)
        {
            PlyObjectHeader headerObj = new PlyObjectHeader();
            int             lineByteCount;
            string          line = ExtensionsMethods.ReadLine(sr, out lineByteCount);

            byteCount = lineByteCount;
            if (line.ToLower() != "ply")
            {
                throw new ArgumentException("Invalid file format. PLY indentifier expected in header file.");
            }
            String[] lineSplits;
            while (line.ToLower() != "end_header")
            {
                line       = ExtensionsMethods.ReadLine(sr, out lineByteCount);
                byteCount += lineByteCount;
                lineSplits = line.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                switch (lineSplits[0])
                {
                case "format":
                    lineSplits       = lineSplits[1].Split(' ');
                    headerObj.Format = (PlyFormat)Enum.Parse(typeof(PlyFormat), lineSplits[0]);
                    NumberFormatInfo nfi = new NumberFormatInfo();
                    nfi.NumberDecimalSeparator = ".";
                    nfi.NumberGroupSeparator   = ",";
                    headerObj.Vesion           = float.Parse(lineSplits[1], nfi);
                    break;

                case "comment":
                    headerObj.Comments.Add(lineSplits[1]);
                    break;

                case "element":
                    lineSplits = lineSplits[1].Split(' ');
                    ElementDescription element = new ElementDescription(lineSplits[0].ToLower(),
                                                                        Convert.ToInt32(
                                                                            lineSplits[lineSplits.Length - 1]));
                    headerObj.Elements.Add(element);
                    break;

                case "property":
                    lineSplits = lineSplits[1].Split(' ');
                    PropertyType        pType    = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[0]);
                    String              pName    = lineSplits[lineSplits.Length - 1];
                    PropertyDescription property = new PropertyDescription(pType, pName);
                    if (pType == PropertyType.list)
                    {
                        property.CountType  = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[1]);
                        property.TypeOfList = (PropertyType)Enum.Parse(typeof(PropertyType), lineSplits[2]);
                    }
                    headerObj.Elements[headerObj.Elements.Count - 1].Properties.Add(property);
                    break;
                }
            }
            return(headerObj);
        }
Example #3
0
        private void ParserASCII(PlyObjectHeader header, String content)
        {
            StringReader sr = new StringReader(content);


            Point3D[]         vertices         = new Point3D[header.Elements["vertex"].Count];
            PointerToVertex[] pointersToVertex = new PointerToVertex[header.Elements["face"].Count];
            //int headerLength = header.Count + 1;
            //while (sr.ReadLine().ToLower() != "end_header") { } //Pass header...
            NumberFormatInfo nfi = new NumberFormatInfo();

            nfi.NumberDecimalSeparator = ".";
            nfi.NumberGroupSeparator   = ",";
            String[] str;

            //for number of vertices readed in header do...
            for (int i = 0; i < vertices.Length; i++)
            {
                str         = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                vertices[i] = new Point3D(float.Parse(str[0], nfi), float.Parse(str[1], nfi), float.Parse(str[2], nfi));
                //Adjusting BoundBox...
                this.BoundBox.Include(vertices[i]);
                //Reporting progress
                int percent = (int)(((float)i / vertices.Length) * 100.0f);
                if ((percent % 20) == 0)
                {
                    this.OnElementLoaded(percent, ElementMesh.Vertex);
                }
            }

            for (int i = 0; i < this.triangles.Length; i++)
            {
                str = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                pointersToVertex[i] = new PointerToVertex(Int32.Parse(str[1], nfi), Int32.Parse(str[2], nfi),
                                                          Int32.Parse(str[3], nfi));
                this.triangles[i] = new Triangle(vertices[pointersToVertex[i].Vertex1],
                                                 vertices[pointersToVertex[i].Vertex2],
                                                 vertices[pointersToVertex[i].Vertex3]);
                int percent = (int)(((float)i / this.triangles.Length) * 100.0f);
                if ((percent % 20) == 0)
                {
                    this.OnElementLoaded(percent, ElementMesh.Triangle);
                }
            }
            //System.Windows.Forms.MessageBox.Show("Degenerate Triangles: " + RemoveDegenerateTriangles(ref pointersToVertex));
            //RemoveUnusedVertices(ref vertices, pointersToVertex);

            this.ProcessNormalsPerVertex(pointersToVertex, vertices.Length);

            vertices         = null;
            pointersToVertex = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
Example #4
0
        private void ParserASCII(PlyObjectHeader header, Stream sr)
        {
            Point3D[]         vertices         = new Point3D[header.Elements["vertex"].Count];;
            PointerToVertex[] pointersToVertex = new PointerToVertex[header.Elements["face"].Count];
            //int headerLength = header.Count + 1;
            //while (sr.ReadLine().ToLower() != "end_header") { } //Pass header...
            NumberFormatInfo nfi = new NumberFormatInfo();

            nfi.NumberDecimalSeparator = ".";
            nfi.NumberGroupSeparator   = ",";
            //Initialize bound box calculation
            Point3D pmin, pmax;

            pmin          = pmax = Point3D.Zero;
            this.boundBox = new BoundBox();
            String[] str;
            //for number of vertices readed in header do...
            for (int i = 0; i < vertices.Length; i++)
            {
                str         = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                vertices[i] = new Point3D(float.Parse(str[0], nfi), float.Parse(str[1], nfi),
                                          float.Parse(str[2], nfi));
                //Adjusting BoundBox...
                this.boundBox.Include(vertices[i]);
                //Reporting progress
                int percent = (int)(((float)i / vertices.Length) * 100.0f);
                if ((percent % 20) == 0)
                {
                    this.OnElementLoaded(percent, ElementMesh.Vertex);
                }
            }
            for (int i = 0; i < this.triangles.Length; i++)
            {
                str = sr.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                pointersToVertex[i] = new PointerToVertex(Int32.Parse(str[1], nfi), Int32.Parse(str[2], nfi),
                                                          Int32.Parse(str[3], nfi));
                this.triangles[i] = new Triangle(vertices[pointersToVertex[i].Vertex1],
                                                 vertices[pointersToVertex[i].Vertex2],
                                                 vertices[pointersToVertex[i].Vertex3]);
                int percent = (int)(((float)i / this.triangles.Length) * 100.0f);
                if ((percent % 20) == 0)
                {
                    this.OnElementLoaded(percent, ElementMesh.Triangle);
                }
            }
            this.ProcessNormalsPerVertex(pointersToVertex, vertices.Length);
            vertices         = null;
            pointersToVertex = null;
            GC.Collect();
        }
Example #5
0
        private void ParserPlyModel()
        {
            using (BufferedStream sr = new BufferedStream(File.OpenRead(this.path))) {
                int             byteCount;
                PlyObjectHeader headerObj = this.GetPlyObjectHeader(sr, out byteCount);
                this.triangles = new Triangle[headerObj.Elements["face"].Count];
                sr.Position    = byteCount;
                switch (headerObj.Format)
                {
                case PlyFormat.ascii:
                    FileInfo info = new FileInfo(this.path);
                    byte[]   file = new byte[info.Length];
                    sr.Read(file, 0, file.Length);
                    string content = Encoding.ASCII.GetString(file);
                    this.ParserASCII(headerObj, content);
                    file    = null;
                    content = null;
                    GC.Collect();
                    GC.WaitForPendingFinalizers();

                    //antes = DateTime.Now;
                    //this.ParserASCII(headerObj, sr);
                    //TimeSpan depoisNovo = antes - DateTime.Now;
                    //System.Windows.Forms.MessageBox.Show("Tempo Novo: " + depoisNovo);


                    break;

                case PlyFormat.binary_big_endian:
                    using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.BigEndian)) {
                        this.ParserBinary(headerObj, br);
                    }
                    break;

                case PlyFormat.binary_little_endian:
                    using (EndianessBinaryReader br = new EndianessBinaryReader(sr, Endianess.LittleEndian)) {
                        this.ParserBinary(headerObj, br);
                    }
                    break;

                default:
                    throw new FormatException("Invalid File format!");
                }
            }
        }
Example #6
0
        private void ParserBinary(PlyObjectHeader header, BinaryReader ebr)
        {
            Point3D[]         vertices         = new Point3D[header.Elements["vertex"].Count];
            PointerToVertex[] pointersToVertex = new PointerToVertex[header.Elements["face"].Count];
            for (int i = 0; i < header.Elements.Count; i++)
            {
                ElementDescription element = header.Elements[i];
                for (int e = 0; e < element.Count; e++)
                {
                    for (int p = 0; p < element.Properties.Count; p++)
                    {
                        PropertyDescription property = element.Properties[p];
                        if (property.IsList)
                        {
                            int listCount = 0;
                            if (property.CountType == PropertyType.uchar || property.CountType == PropertyType.uint8)
                            {
                                listCount = ebr.ReadByte();
                            }
                            else
                            {
                                throw new ArgumentException(
                                          "The type expected for List Count is 'uchar'. Type in file: '" + property.CountType +
                                          "'");
                            }

                            if (property.TypeOfList == PropertyType.@int || property.TypeOfList == PropertyType.int32)
                            {
                                if (element.Name == "face")
                                {
                                    for (int j = 0; j < listCount; j += 3)
                                    {
                                        pointersToVertex[e].Vertex1 = ebr.ReadInt32();
                                        pointersToVertex[e].Vertex2 = ebr.ReadInt32();
                                        pointersToVertex[e].Vertex3 = ebr.ReadInt32();

                                        this.triangles[e] = new Triangle(vertices[pointersToVertex[e].Vertex1],
                                                                         vertices[pointersToVertex[e].Vertex2],
                                                                         vertices[pointersToVertex[e].Vertex3]);


                                        int percent = (int)(((float)e / this.triangles.Length) * 100.0f);
                                        if ((percent % 20) == 0)
                                        {
                                            this.OnElementLoaded(percent, ElementMesh.Triangle);
                                        }
                                    }
                                }
                                else if (element.Name == "vertex")
                                {
                                    #region Ignore other properties for vertex

                                    //for (int j = 0; j < listCount; j += 3)
                                    //{
                                    //    ebr.ReadInt32();
                                    //    ebr.ReadInt32();
                                    //    ebr.ReadInt32();
                                    //}

                                    #endregion

                                    ebr.ReadBytes(element.Properties.SumTypesLength);
                                    break;
                                }
                            }
                            else
                            {
                                throw new ArgumentException(
                                          "The type expected for List elements is 'int'. Type in file: '" +
                                          property.TypeOfList + "'");
                            }
                        }
                        else
                        {
                            if (element.Name == "face")
                            {
                                ebr.ReadBytes(element.Properties.SumTypesLength);
                                break;
                            }
                            else if (element.Name == "vertex")
                            {
                                if (property.Name.ToLowerInvariant() == "x")
                                {
                                    vertices[e].X = ebr.ReadSingle();
                                    vertices[e].Y = ebr.ReadSingle();
                                    vertices[e].Z = ebr.ReadSingle();
                                    p            += (2 + element.Properties.Count - p);
                                    ebr.ReadBytes(element.Properties.SumTypesLength - 12);
                                    //Adjusting BoundBox...
                                    this.BoundBox.Include(vertices[e]);
                                    //Reporting progress
                                    int percent = (int)(((float)e / vertices.Length) * 100.0f);
                                    if ((percent % 20) == 0)
                                    {
                                        this.OnElementLoaded(percent, ElementMesh.Vertex);
                                    }
                                }

                                #region Antigo

                                //switch (property.Type)
                                //{
                                //    case PropertyType.@char:
                                //    case PropertyType.int8:
                                //        ebr.ReadSByte();
                                //        break;
                                //    case PropertyType.uchar:
                                //    case PropertyType.uint8:
                                //        ebr.ReadByte();
                                //        break;
                                //    case PropertyType.@short:
                                //    case PropertyType.int16:
                                //        ebr.ReadInt16();
                                //        break;
                                //    case PropertyType.@ushort:
                                //    case PropertyType.uint16:
                                //        ebr.ReadUInt16();
                                //        break;
                                //    case PropertyType.@int:
                                //    case PropertyType.int32:
                                //        ebr.ReadInt32();
                                //        break;
                                //    case PropertyType.@uint:
                                //    case PropertyType.uint32:
                                //        ebr.ReadUInt32();
                                //        break;
                                //    case PropertyType.@float:
                                //    case PropertyType.float32:
                                //        vertices[e].X = ebr.ReadSingle();
                                //        vertices[e].Y = ebr.ReadSingle();
                                //        vertices[e].Z = ebr.ReadSingle();
                                //        p += 2;
                                //        //Adjusting BoundBox...
                                //        this.BoundBox.Include(vertices[e]);
                                //        //Reporting progress
                                //        int percent = (int)(((float)e / vertices.Length) * 100.0f);
                                //        if ((percent % 20) == 0)
                                //        {
                                //            this.OnElementLoaded(percent, ElementMesh.Vertex);
                                //        }
                                //        break;
                                //    case PropertyType.@double:
                                //    case PropertyType.float64:
                                //        ebr.ReadDouble();
                                //        break;
                                //    default:
                                //        break;
                                //}

                                #endregion
                            }
                        }
                    }
                }
            }
            this.ProcessNormalsPerVertex(pointersToVertex, vertices.Length);
            vertices         = null;
            pointersToVertex = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
Example #7
0
        private void ParserBinary(PlyObjectHeader header, BinaryReader ebr)
        {
            Point3D[]         vertices         = new Point3D[header.Elements["vertex"].Count];;
            PointerToVertex[] pointersToVertex = new PointerToVertex[header.Elements["face"].Count];
            //Initialize bound box calculation
            Point3D pmin, pmax;

            pmin          = pmax = Point3D.Zero;
            this.boundBox = new BoundBox();
            for (int i = 0; i < header.Elements.Count; i++)
            {
                ElementDescription element = header.Elements[i];
                for (int e = 0; e < element.Count; e++)
                {
                    for (int p = 0; p < element.Properties.Count; p++)
                    {
                        PropertyDescription property = element.Properties[p];

                        if (property.IsList)
                        {
                            int listCount = 0;
                            if (property.CountType == PropertyType.uchar || property.CountType == PropertyType.uint8)
                            {
                                listCount = ebr.ReadByte();
                            }
                            else
                            {
                                throw new ArgumentException("The type expected for List Count is 'uchar'. Type in file: '" + property.CountType + "'");
                            }

                            if (property.TypeOfList == PropertyType.@int || property.TypeOfList == PropertyType.int32)
                            {
                                if (element.Name == "face")
                                {
                                    for (int j = 0; j < listCount; j += 3)
                                    {
                                        pointersToVertex[e].Vertex1 = ebr.ReadInt32();
                                        pointersToVertex[e].Vertex2 = ebr.ReadInt32();
                                        pointersToVertex[e].Vertex3 = ebr.ReadInt32();

                                        this.triangles[e] = new Triangle(vertices[pointersToVertex[e].Vertex1],
                                                                         vertices[pointersToVertex[e].Vertex2],
                                                                         vertices[pointersToVertex[e].Vertex3]);

                                        int percent = (int)(((float)e / this.triangles.Length) * 100.0f);
                                        if ((percent % 20) == 0)
                                        {
                                            this.OnElementLoaded(percent, ElementMesh.Triangle);
                                        }
                                    }
                                }
                                else if (element.Name == "vertex")
                                {
                                    #region Ignore other properties for vertex
                                    for (int j = 0; j < listCount; j += 3)
                                    {
                                        ebr.ReadInt32();
                                        ebr.ReadInt32();
                                        ebr.ReadInt32();
                                    }
                                    #endregion
                                }
                            }
                            else
                            {
                                throw new ArgumentException("The type expected for List elements is 'int'. Type in file: '" + property.TypeOfList + "'");
                            }
                        }
                        else
                        {
                            if (element.Name == "face")
                            {
                                #region Ignore other properties for face
                                switch (property.Type)
                                {
                                case PropertyType.@char:
                                case PropertyType.int8:
                                    ebr.ReadSByte();
                                    break;

                                case PropertyType.uchar:
                                case PropertyType.uint8:
                                    ebr.ReadByte();
                                    break;

                                case PropertyType.@short:
                                case PropertyType.int16:
                                    ebr.ReadInt16();
                                    break;

                                case PropertyType.@ushort:
                                case PropertyType.uint16:
                                    ebr.ReadUInt16();
                                    break;

                                case PropertyType.@int:
                                case PropertyType.int32:
                                    ebr.ReadInt32();
                                    break;

                                case PropertyType.@uint:
                                case PropertyType.uint32:
                                    ebr.ReadUInt32();
                                    break;

                                case PropertyType.@float:
                                case PropertyType.float32:
                                    ebr.ReadSingle();
                                    break;

                                case PropertyType.@double:
                                case PropertyType.float64:
                                    ebr.ReadDouble();
                                    break;

                                default:
                                    break;
                                }
                                #endregion
                            }
                            else if (element.Name == "vertex")
                            {
                                switch (property.Type)
                                {
                                case PropertyType.@char:
                                case PropertyType.int8:
                                    ebr.ReadSByte();
                                    break;

                                case PropertyType.uchar:
                                case PropertyType.uint8:
                                    ebr.ReadByte();
                                    break;

                                case PropertyType.@short:
                                case PropertyType.int16:
                                    ebr.ReadInt16();
                                    break;

                                case PropertyType.@ushort:
                                case PropertyType.uint16:
                                    ebr.ReadUInt16();
                                    break;

                                case PropertyType.@int:
                                case PropertyType.int32:
                                    ebr.ReadInt32();
                                    break;

                                case PropertyType.@uint:
                                case PropertyType.uint32:
                                    ebr.ReadUInt32();
                                    break;

                                case PropertyType.@float:
                                case PropertyType.float32:
                                    vertices[e].X = ebr.ReadSingle();
                                    vertices[e].Y = ebr.ReadSingle();
                                    vertices[e].Z = ebr.ReadSingle();
                                    p            += 2;
                                    //Adjusting BoundBox...
                                    this.boundBox.Include(vertices[e]);
                                    //Reporting progress
                                    int percent = (int)(((float)e / vertices.Length) * 100.0f);
                                    if ((percent % 20) == 0)
                                    {
                                        this.OnElementLoaded(percent, ElementMesh.Vertex);
                                    }
                                    break;

                                case PropertyType.@double:
                                case PropertyType.float64:
                                    ebr.ReadDouble();
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            this.ProcessNormalsPerVertex(pointersToVertex, vertices.Length);
            vertices         = null;
            pointersToVertex = null;
            GC.Collect();
        }