1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. 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_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}+
159 signedInteger [-+]?{integer}
161 word ([[:alnum:]]|[[:punct:]])*
162 string {word}({some_space}{word})*
164 exponent_part [eE][-+]?{digit}+
165 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
167 floatNum (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
173 solid {space}("solid"|"SOLID"){space}
174 color {space}("color"|"COLOR"){some_space}{floatNum}{some_space}{floatNum}{some_space}{floatNum}{space}
175 facet {space}("facet"|"FACET"){space}
176 normal {space}("normal"|"NORMAL"){space}
177 point {space}{x}{some_space}{y}{some_space}{z}{space}
178 outerloop {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
179 vertex {space}("vertex"|"VERTEX"){space}
180 endloop {space}("endloop"|"ENDLOOP"){space}
181 endfacet {space}("endfacet"|"ENDFACET"){space}
182 endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
185 /* ------------------------------------------------------------------------ *\
186 ----- Exclusive start states -----
187 \* ------------------------------------------------------------------------ */
201 // End of read character pointer returned by strtof
206 label cmpt = 0; // component index used for reading vertex
208 static const char* stateNames[7] =
211 "reading solid name",
219 static const char* stateExpects[7] =
221 "'solid', 'color', 'facet' or 'endsolid'",
223 "'normal', 'outer loop' or 'endfacet'",
224 "<float> <float> <float>",
225 "'vertex' or 'endloop'",
226 "<float> <float> <float>",
232 /* ------------------------------------------------------------------------ *\
233 ------ Start Lexing ------
234 \* ------------------------------------------------------------------------ */
236 /* ------ Reading control header ------ */
239 BEGIN(readSolidName);
242 <readSolidName>{string} {
243 word name(Foam::string::validate<word>(YYText()));
245 HashTable<label>::const_iterator fnd = lookup_.find(name);
246 if (fnd != lookup_.end())
248 if (groupID_ != fnd())
250 // group appeared out of order
257 groupID_ = sizes_.size();
258 lookup_.insert(name, groupID_);
265 <readSolidName>{space}\n {
268 HashTable<label>::const_iterator fnd = lookup_.find(name);
269 if (fnd != lookup_.end())
271 if (groupID_ != fnd())
273 // group appeared out of order
280 groupID_ = sizes_.size();
281 lookup_.insert(name, groupID_);
297 <readFacet>{normal} {
301 <readNormal>{point} {
303 skip reading normals:
304 normal.x() = strtof(YYText(), &endPtr);
305 normal.y() = strtof(endPtr, &endPtr);
306 normal.z() = strtof(endPtr, &endPtr);
307 normals_.append(normal);
312 <readFacet>{outerloop} {
316 <readVertices>{vertex} {
320 <readVertex>{space}{signedInteger}{space} {
321 vertex[cmpt++] = atol(YYText());
326 points_.append(vertex);
331 <readVertex>{space}{floatNum}{space} {
332 vertex[cmpt++] = atof(YYText());
337 points_.append(vertex);
342 <readVertices>{endloop} {
346 <readFacet>{endfacet} {
347 facets_.append(groupID_);
356 /* ------------------ Ignore remaining space and \n s. -------------------- */
362 /* ------------------- Any other characters are errors -------------------- */
365 startError_ = YYText();
366 yy_push_state(stlError);
370 /* ---------------------------- Error handler ----------------------------- */
376 "fileFormats::STLsurfaceFormatCore::readASCII(const fileName&)"
377 ) << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
378 << " expected " << stateExpects[YY_START]
379 << " but found '" << startError_.c_str() << YYText() << "'"
384 /* ------------------------ On EOF terminate ---------------------------- */
395 bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
398 const off_t dataFileSize
401 // Create the lexer with the approximate number of vertices in the STL
402 // from the file size
403 STLASCIILexer lexer(&is, dataFileSize/400);
404 while (lexer.lex() != 0) {}
406 sorted_ = lexer.sorted();
408 // transfer to normal lists
409 points_.transfer(lexer.points());
410 zoneIds_.transfer(lexer.facets());
411 names_.transfer(lexer.names());
412 sizes_.transfer(lexer.sizes());
417 /* ------------------------------------------------------------------------ *\
418 ------ End of STLfileFormatASCII.L
419 \* ------------------------------------------------------------------------ */