Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/IO/STLTxtMeshReader.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief ASCII STL (STereoLithography) reader class definition
9 : : \details ASCII STL (STereoLithography) reader class definition.
10 : : */
11 : : // *****************************************************************************
12 : :
13 : : #include "STLMesh.hpp"
14 : : #include "STLTxtMeshReader.hpp"
15 : :
16 : : using tk::STLTxtMeshReader;
17 : :
18 : 0 : STLTxtMeshReader::STLTxtMeshReader( const std::string& filename, STLMesh& mesh )
19 : 0 : : Reader( filename ), m_mesh( mesh )
20 : : // *****************************************************************************
21 : : // Constructor
22 : : //! \param[in] filename File to read STL data from
23 : : //! \param[inout] mesh STLMesh object to store STL mesh
24 : : // *****************************************************************************
25 : : {
26 : : // Set mesh name as filename modulo extension
27 [ - - ][ - - ]: 0 : mesh.setName( filename.substr( 0, filename.find_last_of(".") ) );
28 : 0 : }
29 : :
30 : : void
31 : 0 : STLTxtMeshReader::readMesh()
32 : : // *****************************************************************************
33 : : // Read ASCII STL mesh
34 : : // *****************************************************************************
35 : : {
36 : : // Count up number of vertices in STL mesh
37 : 0 : auto nnodes = readFacets( COUNT );
38 [ - - ][ - - ]: 0 : Assert( nnodes%3 == 0, "Number of nodes in STL file must be divisible by 3");
[ - - ][ - - ]
39 : :
40 : : // Allocate memory to store coordinates and face list
41 : 0 : m_mesh.alloc( nnodes );
42 : :
43 : : // Read and store mesh
44 : 0 : readFacets( STORE, m_mesh.getx(), m_mesh.gety(), m_mesh.getz() );
45 : 0 : }
46 : :
47 : : std::size_t
48 : 0 : STLTxtMeshReader::readFacets( const bool store,
49 : : tk::real* const x,
50 : : tk::real* const y,
51 : : tk::real* const z )
52 : : // *****************************************************************************
53 : : // Read ASCII STL mesh
54 : : // \param[in] store Whether to store the facets or not (i.e., only count)
55 : : // \param[in] x Vertex x coordinates
56 : : // \param[in] y Vertex y coordinates
57 : : // \param[in] z Vertex z coordinates
58 : : // \return Number of vertices counted
59 : : // *****************************************************************************
60 : : {
61 : : #ifdef STRICT_GNUC
62 : : #pragma GCC diagnostic push
63 : : #pragma GCC diagnostic ignored "-Winline"
64 : : #endif
65 : : // Define possible keywords in ASCI STL file: objects and their correct
66 : : // string values (for error checking)
67 [ - - ][ - - ]: 0 : STLKeyword solid("solid"), facet("facet"), normal("normal"), outer("outer"),
[ - - ][ - - ]
68 [ - - ][ - - ]: 0 : loop("loop"), vertex("vertex"), endloop("endloop"),
[ - - ]
69 [ - - ]: 0 : endfacet("endfacet");
70 : : #ifdef STRICT_GNUC
71 : : #pragma GCC diagnostic pop
72 : : #endif
73 : :
74 : : // Read in solids with their facets until eof
75 : 0 : std::size_t num = 0;
76 [ - - ][ - - ]: 0 : while ( !m_inFile.eof() ) {
77 : : // Start reading new solid
78 : 0 : std::string solidname;
79 [ - - ][ - - ]: 0 : m_inFile >> solid >> solidname;
80 : :
81 : : // Read and store facets
82 : 0 : bool newfacet = true;
83 [ - - ]: 0 : while (newfacet) {
84 : : // Coordinates of normal, triangle vertex A, B, and C
85 : : tk::real nx, ny, nz, Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz;
86 : :
87 : : // Read in normal (and throw it away as it is redundant)
88 [ - - ][ - - ]: 0 : m_inFile >> facet >> normal >> nx >> ny >> nz;
[ - - ][ - - ]
[ - - ]
89 : :
90 : : // Read in and store off triangle
91 [ - - ][ - - ]: 0 : m_inFile >> outer >> loop;
92 [ - - ][ - - ]: 0 : m_inFile >> vertex >> Ax >> Ay >> Az;
[ - - ][ - - ]
93 [ - - ][ - - ]: 0 : m_inFile >> vertex >> Bx >> By >> Bz;
[ - - ][ - - ]
94 [ - - ][ - - ]: 0 : m_inFile >> vertex >> Cx >> Cy >> Cz;
[ - - ][ - - ]
95 [ - - ][ - - ]: 0 : m_inFile >> endloop >> endfacet;
96 : :
97 : : // Store coordinates of facet if requested
98 [ - - ]: 0 : if (store) {
99 : 0 : x[num] = Ax;
100 : 0 : y[num] = Ay;
101 : 0 : z[num] = Az;
102 : 0 : ++num;
103 : 0 : x[num] = Bx;
104 : 0 : y[num] = By;
105 : 0 : z[num] = Bz;
106 : 0 : ++num;
107 : 0 : x[num] = Cx;
108 : 0 : y[num] = Cy;
109 : 0 : z[num] = Cz;
110 : 0 : ++num;
111 : : } else {
112 : 0 : num += 3; // only increase number of vertices
113 : : }
114 : :
115 : : // Read in next keyword
116 [ - - ]: 0 : std::streampos back = m_inFile.tellg(); // save file position
117 : 0 : std::string kw; // not an STLKeyword: no error checking
118 [ - - ]: 0 : m_inFile >> kw;
119 [ - - ]: 0 : if (kw == "facet") {
120 [ - - ]: 0 : m_inFile.seekg(back); // seek back
121 : 0 : newfacet = true; // there is more to this solid
122 [ - - ]: 0 : } else if (kw == "endsolid") {
123 [ - - ]: 0 : m_inFile >> solidname; // read in solidname last time
124 : 0 : newfacet = false; // solid finished, try to read next one
125 [ - - ]: 0 : back = m_inFile.tellg();
126 [ - - ]: 0 : m_inFile >> kw; // try to read on
127 [ - - ][ - - ]: 0 : if (!m_inFile.eof()) m_inFile.seekg(back);
[ - - ]
128 : : } else {
129 [ - - ][ - - ]: 0 : Throw( "Corruption in ASCII STL file while parsing keyword '" + kw +
[ - - ][ - - ]
130 : : "': keyword 'endfacet' must be followed by either 'facet' or "
131 : : "'endsolid'" );
132 : : }
133 : : } // while (newfacet)
134 : : } // while (newsolid)
135 : :
136 : : // Seek to beginning of file
137 [ - - ]: 0 : m_inFile.seekg(0, std::ios::beg);
138 : :
139 : : // Return number of vertices
140 : 0 : return num;
141 : : }
|