1 /*--------------------------------*- C++ -*----------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
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 \* ------------------------------------------------------------------------ */
36 #include "triSurface.H"
38 #include "OSspecific.H"
42 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
44 int yyFlexLexer::yylex()
46 FatalErrorIn("yyFlexLexer::yylex()")
47 << "Should not have called this function"
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.
57 #if YY_FLEX_SUBMINOR_VERSION < 34
58 extern "C" int yywrap()
60 int yyFlexLexer::yywrap()
75 short region_; // current region
76 short maxRegion_; // max region
81 DynamicList<STLpoint> STLpoints_;
82 //DynamicList<STLpoint> STLnormals_;
83 DynamicList<label> STLlabels_;
84 HashTable<label, word> STLsolidNames_;
91 //- From input stream and the approximate number of vertices in the STL
92 STLLexer(istream* is, const label approxNpoints);
97 //- The lexer function itself
102 label nTriangles() const
107 DynamicList<STLpoint>& STLpoints()
112 //DynamicList<STLpoint>& STLnormals()
114 // return STLnormals_;
117 DynamicList<label>& STLlabels()
122 const HashTable<label, word>& STLsolidNames() const
124 return STLsolidNames_;
129 STLLexer::STLLexer(istream* is, const label approxNpoints)
139 STLpoints_(approxNpoints),
140 //STLnormals_(approxNpoints),
141 STLlabels_(approxNpoints)
145 /* ------------------------------------------------------------------------ *\
146 ------ cppLexer::yylex()
147 \* ------------------------------------------------------------------------ */
149 #define YY_DECL int STLLexer::lex()
155 some_space {one_space}+
162 hex_digit [0-9a-fA-F]
164 identifier {alpha}({alpha}|{digit})*
166 label [1-9]{dec_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}))
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 \* ------------------------------------------------------------------------ */
211 // End of read character pointer returned by strtof
216 label cmpt = 0; // component index used for reading vertex
218 static const char* stateNames[7] =
221 "reading solid name",
229 static const char* stateExpects[7] =
231 "'solid', 'color', 'facet' or 'endsolid'",
233 "'normal', 'outer loop' or 'endfacet'",
234 "<float> <float> <float>",
235 "'vertex' or 'endloop'",
236 "<float> <float> <float>",
242 /* ------------------------------------------------------------------------ *\
243 ------ Start Lexing ------
244 \* ------------------------------------------------------------------------ */
246 /* ------ Reading control header ------ */
249 BEGIN(readSolidName);
252 <readSolidName>{string} {
253 word solidName(Foam::string::validate<word>(YYText()));
254 if (STLsolidNames_.found(solidName))
256 region_ = STLsolidNames_[solidName];
260 region_ = maxRegion_++;
261 STLsolidNames_.insert(solidName, region_);
266 <readSolidName>{space}\n {
267 word solidName("solid");
268 if (STLsolidNames_.found(solidName))
270 region_ = STLsolidNames_[solidName];
274 region_ = maxRegion_++;
275 STLsolidNames_.insert(solidName, region_);
290 <readFacet>{normal} {
294 <readNormal>{point} {
296 normal.x() = strtof(YYText(), &endPtr);
297 normal.y() = strtof(endPtr, &endPtr);
298 normal.z() = strtof(endPtr, &endPtr);
299 STLnormals_.append(normal);
304 <readFacet>{outerloop} {
308 <readVertices>{vertex} {
312 <readVertex>{space}{signedInteger}{space} {
313 vertex[cmpt++] = atol(YYText());
318 STLpoints_.append(vertex);
323 <readVertex>{space}{float}{space} {
324 vertex[cmpt++] = atof(YYText());
329 STLpoints_.append(vertex);
334 <readVertices>{endloop} {
338 <readFacet>{endfacet} {
340 STLlabels_.append(region_);
348 /* ------------------ Ignore remaining space and \n s. -------------------- */
354 /* ------------------- Any other characters are errors -------------------- */
357 startError_ = YYText();
358 yy_push_state(stlerror);
362 /* ---------------------------- Error handler ----------------------------- */
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() << "'"
376 /* ------------------------ On EOF terminate ---------------------------- */
386 bool triSurface::readSTLASCII(const fileName& STLfileName)
388 IFstream STLstream(STLfileName);
394 "triSurface::readSTLASCII(const fileName&)"
395 ) << "file " << STLfileName << " not found"
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)
405 DynamicList<STLpoint>& STLpoints = lexer.STLpoints();
408 DynamicList<STLpoint>& STLnormals = lexer.STLnormals();
410 if (STLpoints.size() != 3*STLnormals.size())
414 "triSurface::readSTLASCII(const fileName& STLfileName)"
415 ) << "in file " << STLfileName << endl
416 << "Problem: read " << STLnormals.size() << " normals"
417 << " but " << STLpoints.size() << " points"
422 pointField rawPoints(STLpoints.size());
426 rawPoints[i] = STLpoints[i];
431 setSize(lexer.nTriangles());
432 DynamicList<label>& STLlabels = lexer.STLlabels();
437 operator[](i)[0] = pointi++;
438 operator[](i)[1] = pointi++;
439 operator[](i)[2] = pointi++;
440 operator[](i).region() = STLlabels[i];
445 // Stitch all points within SMALL meters.
446 stitchTriangles(rawPoints);
448 // Convert solidNames into regionNames
449 patches_.setSize(lexer.STLsolidNames().size());
453 HashTable<label, word>::const_iterator iter =
454 lexer.STLsolidNames().begin();
455 iter != lexer.STLsolidNames().end();
459 patches_[iter()].name() = iter.key();
462 // Fill in the missing information in the patches
469 /* ------------------------------------------------------------------------ *\
470 ------ End of STLToFoam.L
471 \* ------------------------------------------------------------------------ */