1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
30 /* ------------------------------------------------------------------------ *\
31 ------ local definitions
32 \* ------------------------------------------------------------------------ */
34 #include "STLsurfaceFormatCore.H"
38 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
40 int yyFlexLexer::yylex()
42 FatalErrorIn("yyFlexLexer::yylex()")
43 << "Should not have called this function"
49 // Dummy yywrap to keep yylex happy at compile time.
50 // It is called by yylex but is not used as the mechanism to change file.
53 #if YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 34
54 extern "C" int yywrap()
56 int yyFlexLexer::yywrap()
64 //- A lexer for parsing STL ASCII files.
65 // Returns DynamicList(s) of points and facets (zoneIds).
66 // The facets are within a solid/endsolid grouping
74 label groupID_; // current solid group
78 DynamicList<point> points_;
79 DynamicList<label> facets_;
80 DynamicList<word> names_;
81 DynamicList<label> sizes_;
82 HashTable<label> lookup_;
88 //- From input stream and the approximate number of vertices in the STL
89 STLASCIILexer(istream* is, const label approxNpoints);
94 //- The lexer function itself
99 //- Do all the solid groups appear in order
105 //- A list of points corresponding to a pointField
106 DynamicList<point>& points()
111 //- A list of facet IDs (group IDs)
112 // corresponds to the number of triangles
113 DynamicList<label>& facets()
119 DynamicList<word>& names()
125 DynamicList<label>& sizes()
132 STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
138 points_(approxNpoints),
139 facets_(approxNpoints)
143 /* ------------------------------------------------------------------------ *\
144 ------ cppLexer::yylex()
145 \* ------------------------------------------------------------------------ */
147 #define YY_DECL int STLASCIILexer::lex()
153 some_space {one_space}+
160 hex_digit [0-9a-fA-F]
162 identifier {alpha}({alpha}|{digit})*
164 label [1-9]{dec_digit}*
166 signedInteger [-+]?{integer}
168 word ([[:alnum:]]|[[:punct:]])*
169 string {word}({some_space}{word})*
171 exponent_part [eE][-+]?{digit}+
172 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
174 double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
181 solid {space}("solid"|"SOLID"){space}
182 color {space}("color"|"COLOR"){some_space}{float}{some_space}{float}{some_space}{float}{space}
183 facet {space}("facet"|"FACET"){space}
184 normal {space}("normal"|"NORMAL"){space}
185 point {space}{x}{some_space}{y}{some_space}{z}{space}
186 outerloop {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
187 vertex {space}("vertex"|"VERTEX"){space}
188 endloop {space}("endloop"|"ENDLOOP"){space}
189 endfacet {space}("endfacet"|"ENDFACET"){space}
190 endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
193 /* ------------------------------------------------------------------------ *\
194 ----- Exclusive start states -----
195 \* ------------------------------------------------------------------------ */
209 // End of read character pointer returned by strtof
214 label cmpt = 0; // component index used for reading vertex
216 static const char* stateNames[7] =
219 "reading solid name",
227 static const char* stateExpects[7] =
229 "'solid', 'color', 'facet' or 'endsolid'",
231 "'normal', 'outer loop' or 'endfacet'",
232 "<float> <float> <float>",
233 "'vertex' or 'endloop'",
234 "<float> <float> <float>",
240 /* ------------------------------------------------------------------------ *\
241 ------ Start Lexing ------
242 \* ------------------------------------------------------------------------ */
244 /* ------ Reading control header ------ */
247 BEGIN(readSolidName);
250 <readSolidName>{string} {
251 word name(Foam::string::validate<word>(YYText()));
253 HashTable<label>::const_iterator fnd = lookup_.find(name);
254 if (fnd != lookup_.end())
256 if (groupID_ != fnd())
258 // group appeared out of order
265 groupID_ = sizes_.size();
266 lookup_.insert(name, groupID_);
273 <readSolidName>{space}\n {
276 HashTable<label>::const_iterator fnd = lookup_.find(name);
277 if (fnd != lookup_.end())
279 if (groupID_ != fnd())
281 // group appeared out of order
288 groupID_ = sizes_.size();
289 lookup_.insert(name, groupID_);
305 <readFacet>{normal} {
309 <readNormal>{point} {
311 skip reading normals:
312 normal.x() = strtof(YYText(), &endPtr);
313 normal.y() = strtof(endPtr, &endPtr);
314 normal.z() = strtof(endPtr, &endPtr);
315 normals_.append(normal);
320 <readFacet>{outerloop} {
324 <readVertices>{vertex} {
328 <readVertex>{space}{signedInteger}{space} {
329 vertex[cmpt++] = atol(YYText());
334 points_.append(vertex);
339 <readVertex>{space}{float}{space} {
340 vertex[cmpt++] = atof(YYText());
345 points_.append(vertex);
350 <readVertices>{endloop} {
354 <readFacet>{endfacet} {
355 facets_.append(groupID_);
364 /* ------------------ Ignore remaining space and \n s. -------------------- */
370 /* ------------------- Any other characters are errors -------------------- */
373 startError_ = YYText();
374 yy_push_state(stlError);
378 /* ---------------------------- Error handler ----------------------------- */
384 "fileFormats::STLsurfaceFormatCore::readASCII(const fileName&)"
385 ) << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
386 << " expected " << stateExpects[YY_START]
387 << " but found '" << startError_.c_str() << YYText() << "'"
392 /* ------------------------ On EOF terminate ---------------------------- */
403 bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
406 const off_t dataFileSize
409 // Create the lexer with the approximate number of vertices in the STL
410 // from the file size
411 STLASCIILexer lexer(&is, dataFileSize/400);
412 while (lexer.lex() != 0) {}
414 sorted_ = lexer.sorted();
416 // transfer to normal lists
417 points_.transfer(lexer.points());
418 zoneIds_.transfer(lexer.facets());
419 names_.transfer(lexer.names());
420 sizes_.transfer(lexer.sizes());
425 /* ------------------------------------------------------------------------ *\
426 ------ End of STLfileFormatASCII.L
427 \* ------------------------------------------------------------------------ */