initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / surfMesh / surfaceFormats / stl / STLsurfaceFormatASCII.L
blob4bf7880c25d3a7724607355101d3f4aa440c3ba2
1 /*--------------------------------*- C++ -*----------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 \*---------------------------------------------------------------------------*/
29 #undef yyFlexLexer
31  /* ------------------------------------------------------------------------ *\
32    ------ local definitions
33  \* ------------------------------------------------------------------------ */
35 #include "STLsurfaceFormatCore.H"
37 using namespace Foam;
39 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
40 //! @cond dummy
41 int yyFlexLexer::yylex()
43     FatalErrorIn("yyFlexLexer::yylex()")
44         << "Should not have called this function"
45         << abort(FatalError);
46     return 0;
48 //! @endcond dummy
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.
52 // See <<EOF>>
53 //! @cond dummy
54 #if YY_FLEX_SUBMINOR_VERSION < 34
55 extern "C" int yywrap()
56 #else
57 int yyFlexLexer::yywrap()
58 #endif
60     return 1;
62 //! @endcond dummy
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
68 class STLASCIILexer
70     public yyFlexLexer
72     // Private data
74         bool  sorted_;
75         label groupID_;      // current solid group
76         label lineNo_;
77         word  startError_;
79         DynamicList<point> points_;
80         DynamicList<label> facets_;
81         DynamicList<word>  names_;
82         DynamicList<label> sizes_;
83         HashTable<label>   lookup_;
85 public:
87     // Constructors
89         //- From input stream and the approximate number of vertices in the STL
90         STLASCIILexer(istream* is, const label approxNpoints);
93     // Member Functions
95         //- The lexer function itself
96         int lex();
98     // Access
100         //- Do all the solid groups appear in order
101         bool sorted() const
102         {
103             return sorted_;
104         }
106         //- A list of points corresponding to a pointField
107         DynamicList<point>& points()
108         {
109             return points_;
110         }
112         //- A list of facet IDs (group IDs)
113         //  corresponds to the number of triangles
114         DynamicList<label>& facets()
115         {
116             return facets_;
117         }
119         //- Names
120         DynamicList<word>& names()
121         {
122             return names_;
123         }
125         //- Sizes
126         DynamicList<label>& sizes()
127         {
128             return sizes_;
129         }
133 STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
135     yyFlexLexer(is),
136     sorted_(true),
137     groupID_(-1),
138     lineNo_(1),
139     points_(approxNpoints),
140     facets_(approxNpoints)
144  /* ------------------------------------------------------------------------ *\
145    ------ cppLexer::yylex()
146  \* ------------------------------------------------------------------------ */
148 #define YY_DECL int STLASCIILexer::lex()
152 one_space             [ \t\f\r]
153 space                 {one_space}*
154 some_space            {one_space}+
155 cspace                ","{space}
157 alpha                 [_A-Za-z]
158 digit                 [0-9]
159 dec_digit             [0-9]
160 octal_digit           [0-7]
161 hex_digit             [0-9a-fA-F]
163 identifier            {alpha}({alpha}|{digit})*
164 integer               {dec_digit}+
165 label                 [1-9]{dec_digit}*
166 zeroLabel             {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}))
176 float                 {double}
178 x                     {float}
179 y                     {float}
180 z                     {float}
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  \* ------------------------------------------------------------------------ */
198 %option stack
200 %x readSolidName
201 %x readFacet
202 %x readNormal
203 %x readVertices
204 %x readVertex
205 %x stlError
210     // End of read character pointer returned by strtof
211     // char* endPtr;
213     STLpoint normal;
214     STLpoint vertex;
215     label cmpt = 0;   // component index used for reading vertex
217     static const char* stateNames[7] =
218     {
219         "reading solid",
220         "reading solid name",
221         "reading facet",
222         "reading normal",
223         "reading vertices",
224         "reading vertex",
225         "error"
226     };
228     static const char* stateExpects[7] =
229     {
230         "'solid', 'color', 'facet' or 'endsolid'",
231         "<string>",
232         "'normal', 'outer loop' or 'endfacet'",
233         "<float> <float> <float>",
234         "'vertex' or 'endloop'",
235         "<float> <float> <float>",
236         ""
237     };
241  /* ------------------------------------------------------------------------ *\
242                             ------ Start Lexing ------
243  \* ------------------------------------------------------------------------ */
245  /*                      ------ Reading control header ------                */
247 {solid} {
248         BEGIN(readSolidName);
249     }
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())
256         {
257             if (groupID_ != fnd())
258             {
259                 // group appeared out of order
260                 sorted_ = false;
261             }
262             groupID_ = fnd();
263         }
264         else
265         {
266             groupID_ = sizes_.size();
267             lookup_.insert(name, groupID_);
268             names_.append(name);
269             sizes_.append(0);
270         }
271         BEGIN(INITIAL);
272     }
274 <readSolidName>{space}\n {
275         word name("solid");
277         HashTable<label>::const_iterator fnd = lookup_.find(name);
278         if (fnd != lookup_.end())
279         {
280             if (groupID_ != fnd())
281             {
282                 // group appeared out of order
283                 sorted_ = false;
284             }
285             groupID_ = fnd();
286         }
287         else
288         {
289             groupID_ = sizes_.size();
290             lookup_.insert(name, groupID_);
291             names_.append(name);
292             sizes_.append(0);
293         }
295         lineNo_++;
296         BEGIN(INITIAL);
297     }
299 {color} {
300     }
302 {facet} {
303         BEGIN(readFacet);
304     }
306 <readFacet>{normal} {
307         BEGIN(readNormal);
308     }
310 <readNormal>{point} {
311         /*
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);
317          */
318         BEGIN(readFacet);
319     }
321 <readFacet>{outerloop} {
322         BEGIN(readVertices);
323     }
325 <readVertices>{vertex} {
326         BEGIN(readVertex);
327     }
329 <readVertex>{space}{signedInteger}{space} {
330         vertex[cmpt++] = atol(YYText());
332         if (cmpt == 3)
333         {
334             cmpt = 0;
335             points_.append(vertex);
336             BEGIN(readVertices);
337         }
338     }
340 <readVertex>{space}{float}{space} {
341         vertex[cmpt++] = atof(YYText());
343         if (cmpt == 3)
344         {
345             cmpt = 0;
346             points_.append(vertex);
347             BEGIN(readVertices);
348         }
349     }
351 <readVertices>{endloop} {
352         BEGIN(readFacet);
353     }
355 <readFacet>{endfacet} {
356         facets_.append(groupID_);
357         sizes_[groupID_]++;
358         BEGIN(INITIAL);
359     }
361 {endsolid} {
362     }
365  /* ------------------ Ignore remaining space and \n s. -------------------- */
367 <*>{space} {}
368 <*>\n      { lineNo_++; }
371  /* ------------------- Any other characters are errors -------------------- */
373 <*>. {
374         startError_ = YYText();
375         yy_push_state(stlError);
376     }
379  /* ---------------------------- Error handler ----------------------------- */
381 <stlError>.* {
382         yy_pop_state();
383         FatalErrorIn
384         (
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() << "'"
389             << exit(FatalError);
390     }
393  /*  ------------------------ On EOF terminate ----------------------------  */
395 <<EOF>> {
396             yyterminate();
397     }
402 // member function
404 bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
406     istream& is,
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());
423     return true;
426  /* ------------------------------------------------------------------------ *\
427     ------ End of STLfileFormatASCII.L
428  \* ------------------------------------------------------------------------ */