Esempio n. 1
0
        static Mesh3D ParseSTLASCII(ModelFileData fileData)
        {
            // STL ASCII Format: https://en.wikipedia.org/wiki/STL_(file_format)#Binary_STL

            if (!fileData.HasBytes())
            {
                return(null);
            }

            List <Mesh3D.Vertexh> vertices = new List <Mesh3D.Vertexh>();

            try
            {
                Stream fileDataStream = fileData.GetStream();
                fileDataStream.Position = 0;
                StreamReader reader = new StreamReader(fileDataStream);
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine().TrimStart();
                    if (!line.StartsWith("vertex"))
                    {
                        continue;
                    }

                    for (int i = 0; i < 3; i++)
                    {
                        var matches = Regex.Matches(line, FloatStringPattern);
                        vertices.Add(new Mesh3D.Vertexh(
                                         Half.Parse(matches[0].Value),
                                         Half.Parse(matches[1].Value),
                                         Half.Parse(matches[2].Value)
                                         ));
                        line = reader.ReadLine().TrimStart();
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Trace(ex, "Exception when processing file: {FileName}, {FileSizeKB}, {FileType}", fileData.FileName, fileData.FileSizeKB, fileData.FileType.ToString());
                return(null);
            }

            SegmentedArray <Mesh3D.Vertexh> verticesArray  = new SegmentedArray <Mesh3D.Vertexh>(vertices.Count);
            SegmentedArray <int>            trianglesArray = new SegmentedArray <int>(vertices.Count);

            for (int i = 0; i < vertices.Count; i++)
            {
                verticesArray[i]  = vertices[i];
                trianglesArray[i] = i;
            }
            return(new Mesh3D(verticesArray, trianglesArray));
        }
Esempio n. 2
0
        static Mesh3D ParseWavefront(ModelFileData fileData)
        {
            // Wavefront OBJ Format: https://en.wikipedia.org/wiki/Wavefront_.obj_file
            if (!fileData.HasBytes())
            {
                return(null);
            }

            List <Mesh3D.Vertexh> vertices  = new List <Mesh3D.Vertexh>();
            List <int>            triangles = new List <int>();

            try
            {
                Stream fileDataStream = fileData.GetStream();
                fileDataStream.Position = 0;
                StreamReader reader = new StreamReader(fileDataStream);
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine().TrimStart();
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    if (line.StartsWith("v "))
                    {
                        var matches = Regex.Matches(line, FloatStringPattern);
                        if (matches.Count >= 6)
                        {   // Dodge the vertex color (or is it supposed to come after x y z? Wikipedia is not clear about it).
                            vertices.Add(new Mesh3D.Vertexh(
                                             Half.Parse(matches[0].Value),
                                             Half.Parse(matches[2].Value),
                                             Half.Parse(matches[4].Value)
                                             ));
                        }
                        else
                        {
                            vertices.Add(new Mesh3D.Vertexh(
                                             Half.Parse(matches[0].Value),
                                             Half.Parse(matches[1].Value),
                                             Half.Parse(matches[2].Value)
                                             ));
                        }
                    }
                    else if (line.StartsWith("f"))
                    {
                        IEnumerable <string> faceIndexes = line.Split(' ').Where(s => s != "f" && !string.IsNullOrWhiteSpace(s));

                        int index0 = triangles.Count; // First index added for this line.
                        for (int i = 0; i < faceIndexes.Count(); i++)
                        {
                            int.TryParse(faceIndexes.ElementAt(i).Split('/').First(), out int parsedIndex);

                            // Handle the face as a triangle fan to support faces with more than 3 vertex (idea from https://notes.underscorediscovery.com/obj-parser-easy-parse-time-triangulation/).
                            if (i >= 3)
                            {
                                triangles.Add(triangles[index0]);
                                triangles.Add(triangles[triangles.Count - 2]);
                            }
                            triangles.Add(parsedIndex - 1); // -1 because our array starts at 0 while the OBJ starts at 1.
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Trace(ex, "Exception when processing file: {FileName}, {FileSizeKB}, {FileType}", fileData.FileName, fileData.FileSizeKB, fileData.FileType.ToString());
                return(null);
            }

            SegmentedArray <Mesh3D.Vertexh> verticesArray  = new SegmentedArray <Mesh3D.Vertexh>(vertices.Count);
            SegmentedArray <int>            trianglesArray = new SegmentedArray <int>(triangles.Count);

            for (int i = 0; i < vertices.Count; i++)
            {
                verticesArray[i] = vertices[i];
            }

            for (int i = 0; i < triangles.Count; i++)
            {
                trianglesArray[i] = triangles[i];
            }

            return(new Mesh3D(verticesArray, trianglesArray));
        }