/// <summary>
        /// Reads a binary STL file filtered by a provided filter.
        /// </summary>
        /// <param name="file">The mesh file.</param>
        /// <param name="filter">The provided filtered.</param>
        /// <returns>The DMTModel that obeys to the filter condition.</returns>
        public List <DMTModel> ReadFile(File file, IDMTModelFilter filter)
        {
            if (file.Exists == false)
            {
                throw new DMTFileException(DMTFileError.FileDoesNotExist);
            }

            var blocksIn  = new List <DMTTriangleBlock>();
            var blocksOut = new List <DMTTriangleBlock>();
            var blockIn   = new DMTTriangleBlock();
            var blockOut  = new DMTTriangleBlock();
            var objReader = new BinaryFileReader(file);

            try
            {
                //Read first 80 characters (bytes) and ignore them
                objReader.ReadBytes(80);

                //Read the next 4 bytes to get an unsigned integer of number of triangles
                var intNoOfFacets = objReader.ReadUInteger();

                //Now keep reading until the end of the file
                var mapPointVertexIndexBlockIn  = new Dictionary <Point, int>();
                var mapPointVertexIndexBlockOut = new Dictionary <Point, int>();
                var point1Index = -1;
                var point2Index = -1;
                var point3Index = -1;
                for (uint intCounter = 0; intCounter <= intNoOfFacets - 1; intCounter++)
                {
                    //Read 3 32bit floating point numbers - triangle normal
                    // We do not keep the normals in memory, they take too much space
                    objReader.ReadSingle();
                    objReader.ReadSingle();
                    objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 1 X/Y/Z
                    var objPoint1 = new Point();
                    objPoint1.X = objReader.ReadSingle();
                    objPoint1.Y = objReader.ReadSingle();
                    objPoint1.Z = objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 2 X/Y/Z
                    var objPoint2 = new Point();
                    objPoint2.X = objReader.ReadSingle();
                    objPoint2.Y = objReader.ReadSingle();
                    objPoint2.Z = objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 3 X/Y/Z
                    var objPoint3 = new Point();
                    objPoint3.X = objReader.ReadSingle();
                    objPoint3.Y = objReader.ReadSingle();
                    objPoint3.Z = objReader.ReadSingle();

                    if (filter.CanAddTriangle(objPoint1, objPoint2, objPoint3))
                    {
                        AddTriangle(mapPointVertexIndexBlockIn, blockIn, objPoint1, objPoint2, objPoint3);
                    }
                    else
                    {
                        AddTriangle(mapPointVertexIndexBlockOut, blockOut, objPoint1, objPoint2, objPoint3);
                    }

                    //Read 16 bit number
                    objReader.ReadUInt16();
                }

                blockIn.DoVerticesHaveNormals  = false;
                blockOut.DoVerticesHaveNormals = false;
                blocksIn.Add(blockIn);
                blocksOut.Add(blockOut);

                var modelWithinFilter  = new DMTModel();
                var modelOutsideFilter = new DMTModel();
                modelWithinFilter.TriangleBlocks.AddRange(blocksIn);
                modelOutsideFilter.TriangleBlocks.AddRange(blocksOut);
                var result = new List <DMTModel>();
                result.Add(modelWithinFilter);
                result.Add(modelOutsideFilter);
                return(result);
            }
            finally
            {
                objReader.Close();
            }
        }
        /// <summary>
        /// Reads an ASCII STL file filtered by a provided filter.
        /// </summary>
        /// <param name="file">The mesh file.</param>
        /// <param name="filter">The provided filtered.</param>
        /// <returns>The DMTModel that obeys to the filter condition.</returns>
        public List <DMTModel> ReadFile(File file, IDMTModelFilter filter)
        {
            if (file.Exists == false)
            {
                throw new DMTFileException(DMTFileError.FileDoesNotExist);
            }

            var blocksIn  = new List <DMTTriangleBlock>();
            var blocksOut = new List <DMTTriangleBlock>();
            var blockIn   = new DMTTriangleBlock();
            var blockOut  = new DMTTriangleBlock();
            var vertices  = new List <Point>();

            foreach (var strLine in file.ReadTextLines())
            {
                if (strLine.Trim().StartsWith("vertex "))
                {
                    //Add position
                    var    strCoords  = strLine.Trim().Split(' ');
                    var    intCounter = 0;
                    double x          = 0;
                    double y          = 0;
                    double z          = 0;
                    foreach (var strCoord in strCoords)
                    {
                        if (Information.IsNumeric(strCoord))
                        {
                            if (intCounter == 0)
                            {
                                x = Convert.ToDouble(strCoord);
                            }
                            else if (intCounter == 1)
                            {
                                y = Convert.ToDouble(strCoord);
                            }
                            else
                            {
                                z = Convert.ToDouble(strCoord);
                            }
                            intCounter += 1;
                        }
                    }

                    vertices.Add(new Point(x, y, z));
                }
                else if (strLine.Trim().StartsWith("endloop"))
                {
                    if (filter.CanAddTriangle(vertices.ElementAt(0), vertices.ElementAt(1), vertices.ElementAt(2)))
                    {
                        blockIn.AddTriangle(vertices.ElementAt(0), vertices.ElementAt(1), vertices.ElementAt(2));
                    }
                    else
                    {
                        blockOut.AddTriangle(vertices.ElementAt(0), vertices.ElementAt(1), vertices.ElementAt(2));
                    }

                    vertices.Clear();
                }
            }

            blocksIn.Add(blockIn);
            blocksOut.Add(blockOut);

            var modelWithinFilter  = new DMTModel();
            var modelOutsideFilter = new DMTModel();

            modelWithinFilter.TriangleBlocks.AddRange(blocksIn);
            modelOutsideFilter.TriangleBlocks.AddRange(blocksOut);
            var result = new List <DMTModel>();

            result.Add(modelWithinFilter);
            result.Add(modelOutsideFilter);
            return(result);
        }
示例#3
0
        /// <summary>
        /// Reads a DMT file filtered by a provided filter.
        /// </summary>
        /// <param name="file">The mesh file.</param>
        /// <param name="filter">The provided filtered.</param>
        /// <returns>The DMTModel that obeys to the filter condition.</returns>
        public List <DMTModel> ReadFile(File file, IDMTModelFilter filter)
        {
            var blocksIn     = new List <DMTTriangleBlock>();
            var blocksOut    = new List <DMTTriangleBlock>();
            var binaryReader = new BinaryFileReader(file);

            try
            {
                if (file.Exists == false)
                {
                    throw new DMTFileException(DMTFileError.FileDoesNotExist);
                }

                // Read the file header. It is terminated with a 0 (null) and or has a
                // maximum of 256 bytes
                string header = null;
                header = binaryReader.ReadStringUntil(0, 256);

                // Read the file version number. Should be 1000 as this is the only format currently supported
                var version = binaryReader.ReadUShort();
                if (version != 1000)
                {
                    //Close the reader and return fail
                    binaryReader.Close();
                    throw new DMTFileException(DMTFileError.UnsupportedFileFormat);
                }

                // Read the file flags
                // The bits of this integer are used as flags to detail file specific features.
                //   1.  If this bit is set then the vertex data are stored as floats, else doubles.
                //   2.  If this bit is set then the file contains triangles which are known to have been written in units of MMs.
                //       If the flag is unset then the units used are unknown. This change was introduced by api#25 and dicc34143
                //
                //   New files (Since TVD release 2000111) MUST be written in MM. The code in dmkdmt always sets the flag and
                //   the write_node() API ensures that you know about the requirement.
                uint fileFlags = 0;
                fileFlags = binaryReader.ReadUInteger();
                var pointsAreFloats = (fileFlags & 1) == 1;

                // Read the number of triangle blocks in the file. Should not be zero
                uint noOfBlocks = 0;
                noOfBlocks = binaryReader.ReadUInteger();
                if (noOfBlocks == 0)
                {
                    binaryReader.Close();
                    throw new DMTFileException(DMTFileError.NoTriangleBlocks);
                }

                // Read the number of vertices in the file. Should not be zero
                uint totalTriangleVertices = 0;
                totalTriangleVertices = binaryReader.ReadUInteger();
                if (totalTriangleVertices == 0)
                {
                    binaryReader.Close();
                    throw new DMTFileException(DMTFileError.NoVertices);
                }

                // Read the number of triangles in the file. Should not be zero
                uint totalTriangles = 0;
                totalTriangles = binaryReader.ReadUInteger();
                if (totalTriangles == 0)
                {
                    binaryReader.Close();
                    throw new DMTFileException(DMTFileError.NoTriangles);
                }

                // Read the blocks
                for (var blockNo = 0; blockNo <= noOfBlocks - 1; blockNo++)
                {
                    var blockIn       = new DMTTriangleBlock();
                    var blockOut      = new DMTTriangleBlock();
                    var vertices      = new List <Point>();
                    var vertexNormals = new List <Vector>();
                    var oldIndexToNewIndexMapBlockIn  = new Dictionary <int, int>();
                    var oldIndexToNewIndexMapBlockOut = new Dictionary <int, int>();

                    // Read the block flags
                    uint blockFlags = 0;
                    blockFlags = binaryReader.ReadUInteger();
                    var verticesHaveNormals = false;
                    verticesHaveNormals            = (blockFlags & 1) == 1;
                    blockIn.DoVerticesHaveNormals  = verticesHaveNormals;
                    blockOut.DoVerticesHaveNormals = verticesHaveNormals;

                    uint noOfTriangleVertices = 0;
                    noOfTriangleVertices = binaryReader.ReadUInteger();
                    uint noOfTriangles = 0;
                    noOfTriangles = binaryReader.ReadUInteger();

                    // Read the vertices
                    var x  = default(MM);
                    var y  = default(MM);
                    var z  = default(MM);
                    var nx = default(MM);
                    var ny = default(MM);
                    var nz = default(MM);

                    for (var intNodeNo = 0; intNodeNo <= noOfTriangleVertices - 1; intNodeNo++)
                    {
                        // Read the XYZ values
                        if (pointsAreFloats)
                        {
                            x = binaryReader.ReadSingle();
                            y = binaryReader.ReadSingle();
                            z = binaryReader.ReadSingle();
                        }
                        else
                        {
                            x = binaryReader.ReadDouble();
                            y = binaryReader.ReadDouble();
                            z = binaryReader.ReadDouble();
                        }

                        // Continue reading
                        if (verticesHaveNormals)
                        {
                            if (pointsAreFloats)
                            {
                                nx = binaryReader.ReadSingle();
                                ny = binaryReader.ReadSingle();
                                nz = binaryReader.ReadSingle();
                            }
                            else
                            {
                                nx = binaryReader.ReadDouble();
                                ny = binaryReader.ReadDouble();
                                nz = binaryReader.ReadDouble();
                            }
                        }

                        // Store the vertex
                        vertices.Add(new Point(x, y, z));
                        if (verticesHaveNormals)
                        {
                            vertexNormals.Add(new Vector(nx, ny, nz));
                        }
                    }

                    // What size are the pointers?
                    // They will use 32 bit Unsigned Integers if 16 bit Unsigned Integer is not enough
                    var use32bitPointers = noOfTriangleVertices > ushort.MaxValue;

                    // Read the triangles
                    var vertex1Index = 0;
                    var vertex2Index = 0;
                    var vertex3Index = 0;

                    for (var triangleNo = 0; triangleNo <= noOfTriangles - 1; triangleNo++)
                    {
                        if (use32bitPointers)
                        {
                            vertex1Index = binaryReader.ReadInteger();
                            vertex2Index = binaryReader.ReadInteger();
                            vertex3Index = binaryReader.ReadInteger();
                        }
                        else
                        {
                            vertex1Index = binaryReader.ReadUShort();
                            vertex2Index = binaryReader.ReadUShort();
                            vertex3Index = binaryReader.ReadUShort();
                        }

                        if (filter.CanAddTriangle(vertices[vertex1Index], vertices[vertex2Index], vertices[vertex3Index]))
                        {
                            AddTriangle(oldIndexToNewIndexMapBlockIn,
                                        blockIn,
                                        verticesHaveNormals,
                                        vertices,
                                        vertexNormals,
                                        vertex1Index,
                                        vertex2Index,
                                        vertex3Index);
                        }
                        else
                        {
                            AddTriangle(oldIndexToNewIndexMapBlockOut,
                                        blockOut,
                                        verticesHaveNormals,
                                        vertices,
                                        vertexNormals,
                                        vertex1Index,
                                        vertex2Index,
                                        vertex3Index);
                        }
                    }

                    // Check that the version number is ok
                    if (binaryReader.ReadUShort() != version)
                    {
                        throw new DMTFileException(DMTFileError.BlockVersionDoesNotMatchFileVersion);
                    }

                    blocksIn.Add(blockIn);
                    blocksOut.Add(blockOut);
                }

                var modelWithinFilter  = new DMTModel();
                var modelOutsideFilter = new DMTModel();
                modelWithinFilter.TriangleBlocks.AddRange(blocksIn);
                modelOutsideFilter.TriangleBlocks.AddRange(blocksOut);
                var result = new List <DMTModel>();
                result.Add(modelWithinFilter);
                result.Add(modelOutsideFilter);
                return(result);
            }
            finally
            {
                // Close the binary reader
                if (binaryReader != null)
                {
                    binaryReader.Close();
                }
            }
        }