initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / triSurface / triSurface / interfaces / STL / readSTLASCII.L
blob208aa13d1619dc85175233845aa14dbd46a85eed
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 "IFstream.H"
36 #include "triSurface.H"
37 #include "STLpoint.H"
38 #include "OSspecific.H"
40 using namespace Foam;
42 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
43 //! @cond dummy
44 int yyFlexLexer::yylex()
46     FatalErrorIn("yyFlexLexer::yylex()")
47         << "Should not have called this function"
48         << abort(FatalError);
49     return 0;
51 //! @endcond dummy
53 // Dummy yywrap to keep yylex happy at compile time.
54 // It is called by yylex but is not used as the mechanism to change file.
55 // See <<EOF>>
56 //! @cond dummy
57 #if YY_FLEX_SUBMINOR_VERSION < 34
58 extern "C" int yywrap()
59 #else
60 int yyFlexLexer::yywrap()
61 #endif
63     return 1;
65 //! @endcond dummy
68 class STLLexer
70     public yyFlexLexer
72     // Private data
74         label nTriangles_;
75         short region_;       // current region
76         short maxRegion_;    // max region
78         label lineNo_;
79         word startError_;
81         DynamicList<STLpoint> STLpoints_;
82         //DynamicList<STLpoint> STLnormals_;
83         DynamicList<label> STLlabels_;
84         HashTable<label, word> STLsolidNames_;
87 public:
89     // Constructors
91         //- From input stream and the approximate number of vertices in the STL
92         STLLexer(istream* is, const label approxNpoints);
95     // Member Functions
97         //- The lexer function itself
98         int lex();
100     // Access
102         label nTriangles() const
103         {
104             return nTriangles_;
105         }
107         DynamicList<STLpoint>& STLpoints()
108         {
109             return STLpoints_;
110         }
112         //DynamicList<STLpoint>& STLnormals()
113         //{
114         //    return STLnormals_;
115         //}
117         DynamicList<label>& STLlabels()
118         {
119             return STLlabels_;
120         }
122         const HashTable<label, word>& STLsolidNames() const
123         {
124             return STLsolidNames_;
125         }
129 STLLexer::STLLexer(istream* is, const label approxNpoints)
131     yyFlexLexer(is),
133     nTriangles_(0),
134     region_(-1),
135     maxRegion_(0),
137     lineNo_(1),
139     STLpoints_(approxNpoints),
140     //STLnormals_(approxNpoints),
141     STLlabels_(approxNpoints)
145  /* ------------------------------------------------------------------------ *\
146    ------ cppLexer::yylex()
147  \* ------------------------------------------------------------------------ */
149 #define YY_DECL int STLLexer::lex()
153 one_space             [ \t\f\r]
154 space                 {one_space}*
155 some_space            {one_space}+
156 cspace                ","{space}
158 alpha                 [_A-Za-z]
159 digit                 [0-9]
160 dec_digit             [0-9]
161 octal_digit           [0-7]
162 hex_digit             [0-9a-fA-F]
164 identifier            {alpha}({alpha}|{digit})*
165 integer               {dec_digit}+
166 label                 [1-9]{dec_digit}*
167 zeroLabel             {digit}*
168 signedInteger         [-+]?{integer}
170 word                  ([[:alnum:]]|[[:punct:]])*
171 string                {word}({some_space}{word})*
173 exponent_part         [eE][-+]?{digit}+
174 fractional_constant   [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
176 double                (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
177 float                 {double}
179 x                     {float}
180 y                     {float}
181 z                     {float}
183 solid                 {space}("solid"|"SOLID"){space}
184 color                 {space}("color"|"COLOR"){some_space}{float}{some_space}{float}{some_space}{float}{space}
185 facet                 {space}("facet"|"FACET"){space}
186 normal                {space}("normal"|"NORMAL"){space}
187 point                 {space}{x}{some_space}{y}{some_space}{z}{space}
188 outerloop             {space}("outer"{some_space}"loop")|("OUTER"{some_space}"LOOP"){space}
189 vertex                {space}("vertex"|"VERTEX"){space}
190 endloop               {space}("endloop"|"ENDLOOP"){space}
191 endfacet              {space}("endfacet"|"ENDFACET"){space}
192 endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
195  /* ------------------------------------------------------------------------ *\
196                       -----  Exclusive start states -----
197  \* ------------------------------------------------------------------------ */
199 %option stack
201 %x readSolidName
202 %x readFacet
203 %x readNormal
204 %x readVertices
205 %x readVertex
206 %x stlerror
211     // End of read character pointer returned by strtof
212     char* endPtr;
214     STLpoint normal;
215     STLpoint vertex;
216     label cmpt = 0;   // component index used for reading vertex
218     static const char* stateNames[7] =
219     {
220         "reading solid",
221         "reading solid name",
222         "reading facet",
223         "reading normal",
224         "reading vertices",
225         "reading vertex",
226         "error"
227     };
229     static const char* stateExpects[7] =
230     {
231         "'solid', 'color', 'facet' or 'endsolid'",
232         "<string>",
233         "'normal', 'outer loop' or 'endfacet'",
234         "<float> <float> <float>",
235         "'vertex' or 'endloop'",
236         "<float> <float> <float>",
237         ""
238     };
242  /* ------------------------------------------------------------------------ *\
243                             ------ Start Lexing ------
244  \* ------------------------------------------------------------------------ */
246  /*                      ------ Reading control header ------                */
248 {solid} {
249         BEGIN(readSolidName);
250     }
252 <readSolidName>{string} {
253         word solidName(Foam::string::validate<word>(YYText()));
254         if (STLsolidNames_.found(solidName))
255         {
256             region_ = STLsolidNames_[solidName];
257         }
258         else
259         {
260             region_ = maxRegion_++;
261             STLsolidNames_.insert(solidName, region_);
262         }
263         BEGIN(INITIAL);
264     }
266 <readSolidName>{space}\n {
267         word solidName("solid");
268         if (STLsolidNames_.found(solidName))
269         {
270             region_ = STLsolidNames_[solidName];
271         }
272         else
273         {
274             region_ = maxRegion_++;
275             STLsolidNames_.insert(solidName, region_);
276         }
278         lineNo_++;
280         BEGIN(INITIAL);
281     }
283 {color} {
284     }
286 {facet} {
287         BEGIN(readFacet);
288     }
290 <readFacet>{normal} {
291         BEGIN(readNormal);
292     }
294 <readNormal>{point} {
295         /*
296         normal.x() = strtof(YYText(), &endPtr);
297         normal.y() = strtof(endPtr, &endPtr);
298         normal.z() = strtof(endPtr, &endPtr);
299         STLnormals_.append(normal);
300         */
301         BEGIN(readFacet);
302     }
304 <readFacet>{outerloop} {
305         BEGIN(readVertices);
306     }
308 <readVertices>{vertex} {
309         BEGIN(readVertex);
310     }
312 <readVertex>{space}{signedInteger}{space} {
313         vertex[cmpt++] = atol(YYText());
315         if (cmpt == 3)
316         {
317             cmpt = 0;
318             STLpoints_.append(vertex);
319             BEGIN(readVertices);
320         }
321     }
323 <readVertex>{space}{float}{space} {
324         vertex[cmpt++] = atof(YYText());
326         if (cmpt == 3)
327         {
328             cmpt = 0;
329             STLpoints_.append(vertex);
330             BEGIN(readVertices);
331         }
332     }
334 <readVertices>{endloop} {
335         BEGIN(readFacet);
336     }
338 <readFacet>{endfacet} {
339         nTriangles_++;
340         STLlabels_.append(region_);
341         BEGIN(INITIAL);
342     }
344 {endsolid} {
345     }
348  /* ------------------ Ignore remaining space and \n s. -------------------- */
350 <*>{space} {}
351 <*>\n      { lineNo_++; }
354  /* ------------------- Any other characters are errors -------------------- */
356 <*>. {
357         startError_ = YYText();
358         yy_push_state(stlerror);
359     }
362  /* ---------------------------- Error handler ----------------------------- */
364 <stlerror>.* {
365         yy_pop_state();
366         FatalErrorIn
367         (
368             "triSurface::readSTLASCII(const fileName& STLfileName)"
369         )   << "while " << stateNames[YY_START] << " on line " << lineNo_ << nl
370             << "    expected " << stateExpects[YY_START]
371             << " but found '" << startError_.c_str() << YYText() << "'"
372             << exit(FatalError);
373     }
376  /*  ------------------------ On EOF terminate ----------------------------  */
378 <<EOF>> {
379             yyterminate();
380     }
384 #include <fstream>
386 bool triSurface::readSTLASCII(const fileName& STLfileName)
388     IFstream STLstream(STLfileName);
390     if (!STLstream)
391     {
392         FatalErrorIn
393         (
394             "triSurface::readSTLASCII(const fileName&)"
395         )   << "file " << STLfileName << " not found"
396             << exit(FatalError);
397     }
399     // Create the lexer obtaining the approximate number of vertices in the STL
400     // from the file size
401     STLLexer lexer(&STLstream.stdStream(), Foam::fileSize(STLfileName)/400);
402     while(lexer.lex() != 0)
403     {}
405     DynamicList<STLpoint>& STLpoints = lexer.STLpoints();
407     /*
408     DynamicList<STLpoint>& STLnormals = lexer.STLnormals();
410     if (STLpoints.size() != 3*STLnormals.size())
411     {
412         FatalErrorIn
413         (
414             "triSurface::readSTLASCII(const fileName& STLfileName)"
415         )   << "in file " << STLfileName << endl
416             << "Problem: read " << STLnormals.size() << " normals"
417             << " but " << STLpoints.size() << " points"
418             << exit(FatalError);
419     }
420     */
422     pointField rawPoints(STLpoints.size());
424     forAll(rawPoints, i)
425     {
426         rawPoints[i] = STLpoints[i];
427     }
429     STLpoints.clear();
431     setSize(lexer.nTriangles());
432     DynamicList<label>& STLlabels = lexer.STLlabels();
434     label pointi = 0;
435     forAll(*this, i)
436     {
437         operator[](i)[0] = pointi++;
438         operator[](i)[1] = pointi++;
439         operator[](i)[2] = pointi++;
440         operator[](i).region() = STLlabels[i];
441     }
443     STLlabels.clear();
445     // Stitch all points within SMALL meters.
446     stitchTriangles(rawPoints);
448     // Convert solidNames into regionNames
449     patches_.setSize(lexer.STLsolidNames().size());
451     for
452     (
453         HashTable<label, word>::const_iterator iter =
454             lexer.STLsolidNames().begin();
455         iter != lexer.STLsolidNames().end();
456         ++iter
457     )
458     {
459         patches_[iter()].name() = iter.key();
460     }
462     // Fill in the missing information in the patches
463     setDefaultPatches();
465     return true;
469  /* ------------------------------------------------------------------------ *\
470     ------ End of STLToFoam.L
471  \* ------------------------------------------------------------------------ */