1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
31 /* ------------------------------------------------------------------------ *\
32 ------ local definitions
33 \* ------------------------------------------------------------------------ */
35 #include "STLsurfaceFormatCore.H"
39 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
41 int yyFlexLexer::yylex()
43 FatalErrorIn("yyFlexLexer::yylex()")
44 << "Should not have called this function"
50 // Dummy yywrap to keep yylex happy at compile time.
51 // It is called by yylex but is not used as the mechanism to change file.
54 #if YY_FLEX_SUBMINOR_VERSION < 34
55 extern "C" int yywrap()
57 int yyFlexLexer::yywrap()
65 //- A lexer for parsing STL ASCII files.
66 // Returns DynamicList(s) of points and facets (zoneIds).
67 // The facets are within a solid/endsolid grouping
75 label groupID_; // current solid group
79 DynamicList<point> points_;
80 DynamicList<label> facets_;
81 DynamicList<word> names_;
82 DynamicList<label> sizes_;
83 HashTable<label> lookup_;
89 //- From input stream and the approximate number of vertices in the STL
90 STLASCIILexer(istream* is, const label approxNpoints);
95 //- The lexer function itself
100 //- Do all the solid groups appear in order
106 //- A list of points corresponding to a pointField
107 DynamicList<point>& points()
112 //- A list of facet IDs (group IDs)
113 // corresponds to the number of triangles
114 DynamicList<label>& facets()
120 DynamicList<word>& names()
126 DynamicList<label>& sizes()
133 STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
139 points_(approxNpoints),
140 facets_(approxNpoints)
144 /* ------------------------------------------------------------------------ *\
145 ------ cppLexer::yylex()
146 \* ------------------------------------------------------------------------ */
148 #define YY_DECL int STLASCIILexer::lex()
154 some_space {one_space}+
161 hex_digit [0-9a-fA-F]
163 identifier {alpha}({alpha}|{digit})*
165 label [1-9]{dec_digit}*
167 signedInteger [-+]?{integer}
169 word ([[:alnum:]]|[[:punct:]])*
170 string {word}({some_space}{word})*
172 exponent_part [eE][-+]?{digit}+
173 fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
175 double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
182 solid {space}("solid"|"SOLID"){space}
183 color {space}("color"|"COLOR"){some_space}{float}{some_space}{float}{some_space}{float}{space}
184 facet {space}("facet"|"FACET"){space}
185 normal {space}("normal"|"NORMAL"){space}
186 point {space}{x}{some_space}{y}{some_space}{z}{space}
187 outerloop {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
188 vertex {space}("vertex"|"VERTEX"){space}
189 endloop {space}("endloop"|"ENDLOOP"){space}
190 endfacet {space}("endfacet"|"ENDFACET"){space}
191 endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
194 /* ------------------------------------------------------------------------ *\
195 ----- Exclusive start states -----
196 \* ------------------------------------------------------------------------ */
210 // End of read character pointer returned by strtof
215 label cmpt = 0; // component index used for reading vertex
217 static const char* stateNames[7] =
220 "reading solid name",
228 static const char* stateExpects[7] =
230 "'solid', 'color', 'facet' or 'endsolid'",
232 "'normal', 'outer loop' or 'endfacet'",
233 "<float> <float> <float>",
234 "'vertex' or 'endloop'",
235 "<float> <float> <float>",
241 /* ------------------------------------------------------------------------ *\
242 ------ Start Lexing ------
243 \* ------------------------------------------------------------------------ */
245 /* ------ Reading control header ------ */
248 BEGIN(readSolidName);
251 <readSolidName>{string} {
252 word name(Foam::string::validate<word>(YYText()));
254 HashTable<label>::const_iterator fnd = lookup_.find(name);
255 if (fnd != lookup_.end())
257 if (groupID_ != fnd())
259 // group appeared out of order
266 groupID_ = sizes_.size();
267 lookup_.insert(name, groupID_);
274 <readSolidName>{space}\n {
277 HashTable<label>::const_iterator fnd = lookup_.find(name);
278 if (fnd != lookup_.end())
280 if (groupID_ != fnd())
282 // group appeared out of order
289 groupID_ = sizes_.size();
290 lookup_.insert(name, groupID_);
306 <readFacet>{normal} {
310 <readNormal>{point} {
312 skip reading normals:
313 normal.x() = strtof(YYText(), &endPtr);
314 normal.y() = strtof(endPtr, &endPtr);
315 normal.z() = strtof(endPtr, &endPtr);
316 normals_.append(normal);
321 <readFacet>{outerloop} {
325 <readVertices>{vertex} {
329 <readVertex>{space}{signedInteger}{space} {
330 vertex[cmpt++] = atol(YYText());
335 points_.append(vertex);
340 <readVertex>{space}{float}{space} {
341 vertex[cmpt++] = atof(YYText());
346 points_.append(vertex);
351 <readVertices>{endloop} {
355 <readFacet>{endfacet} {
356 facets_.append(groupID_);
365 /* ------------------ Ignore remaining space and \n s. -------------------- */
371 /* ------------------- Any other characters are errors -------------------- */
374 startError_ = YYText();
375 yy_push_state(stlError);
379 /* ---------------------------- Error handler ----------------------------- */
385 "fileFormats::STLsurfaceFormatCore::readASCII(const fileName&)"
386 ) << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
387 << " expected " << stateExpects[YY_START]
388 << " but found '" << startError_.c_str() << YYText() << "'"
393 /* ------------------------ On EOF terminate ---------------------------- */
404 bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
407 const off_t dataFileSize
410 // Create the lexer with the approximate number of vertices in the STL
411 // from the file size
412 STLASCIILexer lexer(&is, dataFileSize/400);
413 while (lexer.lex() != 0) {}
415 sorted_ = lexer.sorted();
417 // transfer to normal lists
418 points_.transfer(lexer.points());
419 zoneIds_.transfer(lexer.facets());
420 names_.transfer(lexer.names());
421 sizes_.transfer(lexer.sizes());
426 /* ------------------------------------------------------------------------ *\
427 ------ End of STLfileFormatASCII.L
428 \* ------------------------------------------------------------------------ */