1 /*--------------------------------*- C++ -*----------------------------------*\
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 -------------------------------------------------------------------------------
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 \*---------------------------------------------------------------------------*/
30 /* ------------------------------------------------------------------------ *\
31 ------ local definitions
32 \* ------------------------------------------------------------------------ */
35 #include "triSurface.H"
37 #include "OSspecific.H"
41 // Dummy yyFlexLexer::yylex() to keep the linker happy. It is not called
43 int yyFlexLexer::yylex()
45 FatalErrorIn("yyFlexLexer::yylex()")
46 << "Should not have called this function"
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.
56 #if YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 34
57 extern "C" int yywrap()
59 int yyFlexLexer::yywrap()
74 short region_; // current region
75 short maxRegion_; // max region
80 DynamicList<STLpoint> STLpoints_;
81 //DynamicList<STLpoint> STLnormals_;
82 DynamicList<label> STLlabels_;
83 HashTable<label, word> STLsolidNames_;
90 //- From input stream and the approximate number of vertices in the STL
91 STLLexer(std::istream* is, const label approxNpoints);
96 //- The lexer function itself
101 label nTriangles() const
106 DynamicList<STLpoint>& STLpoints()
111 //DynamicList<STLpoint>& STLnormals()
113 // return STLnormals_;
116 DynamicList<label>& STLlabels()
121 const HashTable<label, word>& STLsolidNames() const
123 return STLsolidNames_;
128 STLLexer::STLLexer(std::istream* is, const label approxNpoints)
138 STLpoints_(approxNpoints),
139 //STLnormals_(approxNpoints),
140 STLlabels_(approxNpoints)
144 /* ------------------------------------------------------------------------ *\
145 ------ cppLexer::yylex()
146 \* ------------------------------------------------------------------------ */
148 #define YY_DECL int STLLexer::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 solidName(Foam::string::validate<word>(YYText()));
253 if (STLsolidNames_.found(solidName))
255 region_ = STLsolidNames_[solidName];
259 region_ = maxRegion_++;
260 STLsolidNames_.insert(solidName, region_);
265 <readSolidName>{space}\n {
266 word solidName("solid");
267 if (STLsolidNames_.found(solidName))
269 region_ = STLsolidNames_[solidName];
273 region_ = maxRegion_++;
274 STLsolidNames_.insert(solidName, region_);
289 <readFacet>{normal} {
293 <readNormal>{point} {
295 normal.x() = strtof(YYText(), &endPtr);
296 normal.y() = strtof(endPtr, &endPtr);
297 normal.z() = strtof(endPtr, &endPtr);
298 STLnormals_.append(normal);
303 <readFacet>{outerloop} {
307 <readVertices>{vertex} {
311 <readVertex>{space}{signedInteger}{space} {
312 vertex[cmpt++] = atol(YYText());
317 STLpoints_.append(vertex);
322 <readVertex>{space}{float}{space} {
323 vertex[cmpt++] = atof(YYText());
328 STLpoints_.append(vertex);
333 <readVertices>{endloop} {
337 <readFacet>{endfacet} {
339 STLlabels_.append(region_);
347 /* ------------------ Ignore remaining space and \n s. -------------------- */
353 /* ------------------- Any other characters are errors -------------------- */
356 startError_ = YYText();
357 yy_push_state(stlerror);
361 /* ---------------------------- Error handler ----------------------------- */
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() << "'"
375 /* ------------------------ On EOF terminate ---------------------------- */
385 bool triSurface::readSTLASCII(const fileName& STLfileName)
387 IFstream STLstream(STLfileName);
393 "triSurface::readSTLASCII(const fileName&)"
394 ) << "file " << STLfileName << " not found"
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)
404 DynamicList<STLpoint>& STLpoints = lexer.STLpoints();
407 DynamicList<STLpoint>& STLnormals = lexer.STLnormals();
409 if (STLpoints.size() != 3*STLnormals.size())
413 "triSurface::readSTLASCII(const fileName& STLfileName)"
414 ) << "in file " << STLfileName << endl
415 << "Problem: read " << STLnormals.size() << " normals"
416 << " but " << STLpoints.size() << " points"
421 pointField rawPoints(STLpoints.size());
425 rawPoints[i] = STLpoints[i];
430 setSize(lexer.nTriangles());
431 DynamicList<label>& STLlabels = lexer.STLlabels();
436 operator[](i)[0] = pointi++;
437 operator[](i)[1] = pointi++;
438 operator[](i)[2] = pointi++;
439 operator[](i).region() = STLlabels[i];
444 // Stitch all points within SMALL meters.
445 stitchTriangles(rawPoints);
447 // Convert solidNames into regionNames
448 patches_.setSize(lexer.STLsolidNames().size());
452 HashTable<label, word>::const_iterator iter =
453 lexer.STLsolidNames().begin();
454 iter != lexer.STLsolidNames().end();
458 patches_[iter()].name() = iter.key();
461 // Fill in the missing information in the patches
468 /* ------------------------------------------------------------------------ *\
469 ------ End of STLToFoam.L
470 \* ------------------------------------------------------------------------ */