Exemplo n.º 1
0
        public static Supported3DFiles CheckFileType(ModelFileData fileData)
        {
            byte[] byteBuffer = new byte[100];

            if (fileData.HasBytes())
            {
                // Has enough bytes?
                if (!fileData.ReadBytes(byteBuffer, 0, 0, byteBuffer.Length))
                {
                    return(Supported3DFiles.Unsuportted);
                }

                // Check if some evil being renamed some PNG file to one of the supported formats.
                if (byteBuffer[0] == 137 && byteBuffer[1] == 80 && byteBuffer[2] == 78 && byteBuffer[3] == 71 && byteBuffer[4] == 13 && byteBuffer[5] == 10 && byteBuffer[6] == 26 && byteBuffer[7] == 10)
                {
                    return(Supported3DFiles.Unsuportted);
                }

                // Or maybe a JPG.
                if (byteBuffer[0] == 0xFF && byteBuffer[1] == 0xD8 && byteBuffer[2] == 0xFF)
                {
                    return(Supported3DFiles.Unsuportted);
                }
            }

            if (fileData.FileName.EndsWith(".stl", StringComparison.InvariantCultureIgnoreCase))
            {
                if (!fileData.HasBytes())
                {
                    return(Supported3DFiles.STL_Binary); // Return default STL format.
                }
                // If doesnt start with "solid", its always binary.
                if (!(Encoding.ASCII.GetString(byteBuffer, 0, 5) == "solid"))
                {
                    return(Supported3DFiles.STL_Binary);
                }

                // EXCEPT, that some binary files also start with solid, so check the header and wish bad omen to whoever created such files.
                string header = Encoding.ASCII.GetString(byteBuffer, 0, 100);
                for (int i = 0; i < header.Length; i++)
                {
                    if (Char.IsControl(header[i]) && header[i] != '\r' && header[i] != '\n')
                    {
                        return(Supported3DFiles.STL_Binary);
                    }
                }
                return(Supported3DFiles.STL_ASCII);
            }
            else if (fileData.FileName.EndsWith(".obj", StringComparison.InvariantCultureIgnoreCase))
            {
                return(Supported3DFiles.OBJ);
            }
            if (fileData.FileName.EndsWith(".3mf", StringComparison.InvariantCultureIgnoreCase))
            {
                return(Supported3DFiles._3MF);
            }
            else
            {
                return(Supported3DFiles.Unsuportted);
            }
        }
Exemplo n.º 2
0
        static Mesh3D ParseSTLBinary(ModelFileData fileData)
        {
            // STL Binary Format: https://en.wikipedia.org/wiki/STL_(file_format)#Binary_STL

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

            byte[] byteBuffer      = new byte[4 * 9];
            int    index           = 80;
            int    byteBufferIndex = 0;

            fileData.ReadBytes(byteBuffer, index, 0, 4);
            int triangleAmount = (int)System.BitConverter.ToUInt32(byteBuffer, 0); index += 4;

            if (triangleAmount <= 0 || fileData.BytesLength < 80 + triangleAmount * 50)
            {
                return(null);
            }

            try
            {
                if (triangleAmount <= 0 || triangleAmount > 10000000)
                {
                    throw new Exception("The STLBinary file has too many triangles.");
                }

                SegmentedArray <int>            triangles = new SegmentedArray <int>(triangleAmount * 3);
                SegmentedArray <Mesh3D.Vertexh> vertices  = new SegmentedArray <Mesh3D.Vertexh>(triangleAmount * 3);

                for (int i = 0; i < triangles.Length;)
                {
                    // Skip reading the facet normal (why STL come with normals???).
                    index += 4 * 3;

                    // Triangle vertices
                    {
                        fileData.ReadBytes(byteBuffer, index, 0, byteBuffer.Length); byteBufferIndex = 0;
                        index += 4 * 9;

                        vertices[i] = new Mesh3D.Vertexh(
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4)
                            );
                        triangles[i] = i++;

                        vertices[i] = new Mesh3D.Vertexh(
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4)
                            );
                        triangles[i] = i++;

                        vertices[i] = new Mesh3D.Vertexh(
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4),
                            (Half)System.BitConverter.ToSingle(byteBuffer, byteBufferIndex += 4)
                            );
                        triangles[i] = i++;
                    }

                    // Skip the remaining bytes.
                    index += 2;
                }

                return(new Mesh3D(vertices, triangles));
            }
            catch (Exception ex)
            {
                logger.Trace(ex, "Exception when processing file: {FileName}, {FileSizeKB}, {FileType}", fileData.FileName, fileData.FileSizeKB, fileData.FileType.ToString());
                return(null);
            }
        }