Updated .L files to assign properly the function 'yywrap()' for Flex 2.6.0 and newer.
[foam-extend-3.2.git] / src / meshTools / triSurface / triSurface / interfaces / STL / readSTLASCII.L
blob941792c20d0bf5f7be98e51e92016e585c05c58c
1 /*--------------------------------*- C++ -*----------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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 \*---------------------------------------------------------------------------*/
28 #undef yyFlexLexer
30  /* ------------------------------------------------------------------------ *\
31    ------ local definitions
32  \* ------------------------------------------------------------------------ */
34 #include "IFstream.H"
35 #include "triSurface.H"
36 #include "STLpoint.H"
37 #include "OSspecific.H"
39 using namespace Foam;
41 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
42 //! @cond dummy
43 int yyFlexLexer::yylex()
45     FatalErrorIn("yyFlexLexer::yylex()")
46         << "Should not have called this function"
47         << abort(FatalError);
48     return 0;
50 //! @endcond dummy
52 // Dummy yywrap to keep yylex happy at compile time.
53 // It is called by yylex but is not used as the mechanism to change file.
54 // See <<EOF>>
55 //! @cond dummy
56 #if YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 34
57 extern "C" int yywrap()
58 #else
59 int yyFlexLexer::yywrap()
60 #endif
62     return 1;
64 //! @endcond dummy
67 class STLLexer
69     public yyFlexLexer
71     // Private data
73         label nTriangles_;
74         short region_;       // current region
75         short maxRegion_;    // max region
77         label lineNo_;
78         word startError_;
80         DynamicList<STLpoint> STLpoints_;
81         //DynamicList<STLpoint> STLnormals_;
82         DynamicList<label> STLlabels_;
83         HashTable<label, word> STLsolidNames_;
86 public:
88     // Constructors
90         //- From input stream and the approximate number of vertices in the STL
91     STLLexer(std::istream* is, const label approxNpoints);
94     // Member Functions
96         //- The lexer function itself
97         int lex();
99     // Access
101         label nTriangles() const
102         {
103             return nTriangles_;
104         }
106         DynamicList<STLpoint>& STLpoints()
107         {
108             return STLpoints_;
109         }
111         //DynamicList<STLpoint>& STLnormals()
112         //{
113         //    return STLnormals_;
114         //}
116         DynamicList<label>& STLlabels()
117         {
118             return STLlabels_;
119         }
121         const HashTable<label, word>& STLsolidNames() const
122         {
123             return STLsolidNames_;
124         }
128 STLLexer::STLLexer(std::istream* is, const label approxNpoints)
130     yyFlexLexer(is),
132     nTriangles_(0),
133     region_(-1),
134     maxRegion_(0),
136     lineNo_(1),
138     STLpoints_(approxNpoints),
139     //STLnormals_(approxNpoints),
140     STLlabels_(approxNpoints)
144  /* ------------------------------------------------------------------------ *\
145    ------ cppLexer::yylex()
146  \* ------------------------------------------------------------------------ */
148 #define YY_DECL int STLLexer::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 solidName(Foam::string::validate<word>(YYText()));
253         if (STLsolidNames_.found(solidName))
254         {
255             region_ = STLsolidNames_[solidName];
256         }
257         else
258         {
259             region_ = maxRegion_++;
260             STLsolidNames_.insert(solidName, region_);
261         }
262         BEGIN(INITIAL);
263     }
265 <readSolidName>{space}\n {
266         word solidName("solid");
267         if (STLsolidNames_.found(solidName))
268         {
269             region_ = STLsolidNames_[solidName];
270         }
271         else
272         {
273             region_ = maxRegion_++;
274             STLsolidNames_.insert(solidName, region_);
275         }
277         lineNo_++;
279         BEGIN(INITIAL);
280     }
282 {color} {
283     }
285 {facet} {
286         BEGIN(readFacet);
287     }
289 <readFacet>{normal} {
290         BEGIN(readNormal);
291     }
293 <readNormal>{point} {
294         /*
295         normal.x() = strtof(YYText(), &endPtr);
296         normal.y() = strtof(endPtr, &endPtr);
297         normal.z() = strtof(endPtr, &endPtr);
298         STLnormals_.append(normal);
299         */
300         BEGIN(readFacet);
301     }
303 <readFacet>{outerloop} {
304         BEGIN(readVertices);
305     }
307 <readVertices>{vertex} {
308         BEGIN(readVertex);
309     }
311 <readVertex>{space}{signedInteger}{space} {
312         vertex[cmpt++] = atol(YYText());
314         if (cmpt == 3)
315         {
316             cmpt = 0;
317             STLpoints_.append(vertex);
318             BEGIN(readVertices);
319         }
320     }
322 <readVertex>{space}{float}{space} {
323         vertex[cmpt++] = atof(YYText());
325         if (cmpt == 3)
326         {
327             cmpt = 0;
328             STLpoints_.append(vertex);
329             BEGIN(readVertices);
330         }
331     }
333 <readVertices>{endloop} {
334         BEGIN(readFacet);
335     }
337 <readFacet>{endfacet} {
338         nTriangles_++;
339         STLlabels_.append(region_);
340         BEGIN(INITIAL);
341     }
343 {endsolid} {
344     }
347  /* ------------------ Ignore remaining space and \n s. -------------------- */
349 <*>{space} {}
350 <*>\n      { lineNo_++; }
353  /* ------------------- Any other characters are errors -------------------- */
355 <*>. {
356         startError_ = YYText();
357         yy_push_state(stlerror);
358     }
361  /* ---------------------------- Error handler ----------------------------- */
363 <stlerror>.* {
364         yy_pop_state();
365         FatalErrorIn
366         (
367             "triSurface::readSTLASCII(const fileName& STLfileName)"
368         )   << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
369             << "    expected " << stateExpects[YY_START]
370             << " but found '" << startError_.c_str() << YYText() << "'"
371             << exit(FatalError);
372     }
375  /*  ------------------------ On EOF terminate ----------------------------  */
377 <<EOF>> {
378             yyterminate();
379     }
383 #include <fstream>
385 bool triSurface::readSTLASCII(const fileName& STLfileName)
387     IFstream STLstream(STLfileName);
389     if (!STLstream)
390     {
391         FatalErrorIn
392         (
393             "triSurface::readSTLASCII(const fileName&)"
394         )   << "file " << STLfileName << " not found"
395             << exit(FatalError);
396     }
398     // Create the lexer obtaining the approximate number of vertices in the STL
399     // from the file size
400     STLLexer lexer(&STLstream.stdStream(), Foam::fileSize(STLfileName)/400);
401     while(lexer.lex() != 0)
402     {}
404     DynamicList<STLpoint>& STLpoints = lexer.STLpoints();
406     /*
407     DynamicList<STLpoint>& STLnormals = lexer.STLnormals();
409     if (STLpoints.size() != 3*STLnormals.size())
410     {
411         FatalErrorIn
412         (
413             "triSurface::readSTLASCII(const fileName& STLfileName)"
414         )   << "in file " << STLfileName << endl
415             << "Problem: read " << STLnormals.size() << " normals"
416             << " but " << STLpoints.size() << " points"
417             << exit(FatalError);
418     }
419     */
421     pointField rawPoints(STLpoints.size());
423     forAll(rawPoints, i)
424     {
425         rawPoints[i] = STLpoints[i];
426     }
428     STLpoints.clear();
430     setSize(lexer.nTriangles());
431     DynamicList<label>& STLlabels = lexer.STLlabels();
433     label pointi = 0;
434     forAll(*this, i)
435     {
436         operator[](i)[0] = pointi++;
437         operator[](i)[1] = pointi++;
438         operator[](i)[2] = pointi++;
439         operator[](i).region() = STLlabels[i];
440     }
442     STLlabels.clear();
444     // Stitch all points within SMALL meters.
445     stitchTriangles(rawPoints);
447     // Convert solidNames into regionNames
448     patches_.setSize(lexer.STLsolidNames().size());
450     for
451     (
452         HashTable<label, word>::const_iterator iter =
453             lexer.STLsolidNames().begin();
454         iter != lexer.STLsolidNames().end();
455         ++iter
456     )
457     {
458         patches_[iter()].name() = iter.key();
459     }
461     // Fill in the missing information in the patches
462     setDefaultPatches();
464     return true;
468  /* ------------------------------------------------------------------------ *\
469     ------ End of STLToFoam.L
470  \* ------------------------------------------------------------------------ */