00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <MeshFormatReader.hpp>
00021
00022 #include <Stringify.hpp>
00023
00024 #include <set>
00025 #include <sstream>
00026
00027 void MeshFormatReader::__skipComments() {
00028 char checkComment[2];
00029 while (fscanf(__ifh,"%1s",checkComment) > 0) {
00030 if (checkComment[0] == '#') {
00031 char c;
00032 do {
00033 c = fgetc(__ifh);
00034 } while(c != '\n');
00035 } else {
00036 ungetc(checkComment[0],__ifh);
00037 }
00038 return;
00039 }
00040 }
00041
00042 MeshFormatReader::Keyword MeshFormatReader::__nextKeyword()
00043 {
00044 MeshFormatReader::Keyword kw;
00045
00046 __skipComments();
00047 char pKeyword[256];
00048 int retval = fscanf(__ifh,"%255s",pKeyword);
00049 const std::string aKeyword = pKeyword;
00050
00051 if (retval < 0) {
00052 kw.second = EndOfFile;
00053 return kw;
00054 } else if (retval == 0) {
00055 kw.second = Unknown;
00056 return kw;
00057 }
00058
00059 KeywordList::iterator i = __keywordList.find(aKeyword.c_str());
00060
00061 if (i != __keywordList.end()) {
00062 kw.first = (*i).first;
00063 kw.second = (*i).second;
00064 return kw;
00065 }
00066 throw ErrorHandler(__FILE__,__LINE__,
00067 "reading file '"+__fileName
00068 +"': keyword '"+aKeyword+"' unknown",
00069 ErrorHandler::normal);
00070
00071 kw.first = aKeyword;
00072 kw.second = Unknown;
00073 return kw;
00074 }
00075
00076 void MeshFormatReader::__checkVertex(const size_t& n)
00077 {
00078 if ((n == 0) or (n > (*__vertices).numberOfVertices())) {
00079 throw MeshFormatReader::VertexError();
00080 }
00081 }
00082
00083 size_t MeshFormatReader::__getVertexNumber()
00084 {
00085 size_t n = this->__getInteger();
00086 this->__checkVertex(n);
00087
00088 return n;
00089 }
00090
00091
00092 void MeshFormatReader::
00093 __writeReferences(const std::set<size_t>& references,
00094 std::string objectName)
00095 {
00096 ffout(3) << " " << objectName << " references: ";
00097 for (std::set<size_t>::const_iterator i = references.begin();
00098 i != references.end(); ++i) {
00099 if (i != references.begin()) ffout(3) << ',';
00100 ffout(3) << *i;
00101 }
00102 ffout(3) << '\n';
00103 }
00104
00105 void MeshFormatReader::__readVertices()
00106 {
00107 std::set<size_t> references;
00108 VerticesSet& V = *__vertices;
00109 for (size_t i=0; i<V.numberOfVertices(); ++i) {
00110 const double x = __getReal();
00111 const double y = __getReal();
00112 const double z = __getReal();
00113 const size_t ref = __getInteger();
00114 references.insert(ref);
00115 V[i] = Vertex(x,y,z, ref);
00116 }
00117
00118 this->__writeReferences(references, "Vertices");
00119 }
00120
00121 void MeshFormatReader::__readElements()
00122 {
00123 std::string elementType;
00124 Keyword kw = __nextKeyword();
00125 while (kw.second != EndOfFile) {
00126 switch (kw.second) {
00127 case Vertices: {
00128 throw ErrorHandler(__FILE__,__LINE__,
00129 "reading file '"+__fileName
00130 +"': vertices defined twice",
00131 ErrorHandler::normal);
00132 break;
00133 }
00134 case Hexahedra: {
00135 __skipComments();
00136 size_t numberOfHexahedra = __getInteger();
00137 __skipComments();
00138
00139 __hexahedra = new Vector<Hexahedron>(numberOfHexahedra);
00140
00141 ffout(3) << "- Number of hexahedra: " << numberOfHexahedra << '\n';
00142 this->__readHexahedra();
00143
00144 break;
00145 }
00146 case Tetrahedra: {
00147 __skipComments();
00148 size_t numberOfTetrahedra = __getInteger();
00149 __skipComments();
00150
00151 __tetrahedra = new Vector<Tetrahedron>(numberOfTetrahedra);
00152
00153 ffout(3) << "- Number of tetrahedra: " << numberOfTetrahedra << '\n';
00154 this->__readTetrahedra();
00155
00156 break;
00157 }
00158 case Triangles: {
00159 __skipComments();
00160 size_t numberOfTriangles = __getInteger();
00161 __skipComments();
00162
00163 __triangles = new Vector<Triangle>(numberOfTriangles);
00164
00165 ffout(3) << "- Number of triangles: " << numberOfTriangles << '\n';
00166 this->__readTriangles();
00167
00168 break;
00169 }
00170 case Quadrilaterals: {
00171 __skipComments();
00172 size_t numberOfQuadrilaterals = __getInteger();
00173 __skipComments();
00174
00175 __quadrilaterals = new Vector<Quadrangle>(numberOfQuadrilaterals);
00176
00177 ffout(3) << "- Number of quadrilaterals: "
00178 << numberOfQuadrilaterals << '\n';
00179 this->__readQuadrilaterals();
00180
00181 break;
00182 }
00183 case Corners: {
00184 __skipComments();
00185 size_t numberOfCorners = __getInteger();
00186 __skipComments();
00187 for (size_t j=0; j<numberOfCorners; ++j) {
00188 __getInteger();
00189 }
00190
00191 fferr(3) << " warning: while reading \"" << __fileName
00192 << "\": skipping Corners\n";
00193 break;
00194 }
00195 case Edges: {
00196 __skipComments();
00197 size_t numberOfEdges = __getInteger();
00198 __skipComments();
00199 for (size_t j=0; j<numberOfEdges; ++j) {
00200 __getInteger();
00201 __getInteger();
00202 __getInteger();
00203 }
00204
00205 fferr(3) << " warning: while reading \"" << __fileName
00206 << "\": skipping Edges\n";
00207 break;
00208 }
00209 case Ridges: {
00210 __skipComments();
00211 size_t numberOfRidges = __getInteger();
00212 __skipComments();
00213 for (size_t j=0; j<numberOfRidges; ++j) {
00214 __getInteger();
00215 }
00216
00217 fferr(3) << " warning: while reading \"" << __fileName
00218 << "\": skipping Ridges\n";
00219 break;
00220 }
00221 default: {
00222 std::stringstream errorMsg;
00223 errorMsg << "reading file '" << __fileName
00224 << "' unknown keyword: " << kw.first << std::ends;
00225 throw ErrorHandler(__FILE__,__LINE__,
00226 errorMsg.str(),
00227 ErrorHandler::normal);
00228
00229 }
00230 }
00231 kw = __nextKeyword();
00232 }
00233 }
00234
00235
00236 void MeshFormatReader::__readHexahedra()
00237 {
00238 VerticesSet& V = *__vertices;
00239 Vector<Hexahedron>& H = *__hexahedra;
00240 std::set<size_t> references;
00241
00242 size_t i=0;
00243 try {
00244 for (; i<H.size(); ++i) {
00245 const size_t a = __getVertexNumber() - 1;
00246 const size_t b = __getVertexNumber() - 1;
00247 const size_t c = __getVertexNumber() - 1;
00248 const size_t d = __getVertexNumber() - 1;
00249 const size_t e = __getVertexNumber() - 1;
00250 const size_t f = __getVertexNumber() - 1;
00251 const size_t g = __getVertexNumber() - 1;
00252 const size_t h = __getVertexNumber() - 1;
00253
00254 const size_t ref = __getInteger();
00255 references.insert(ref);
00256
00257 H[i] = Hexahedron(V[a],V[b],V[c],V[d],V[e],V[f],V[g],V[h], ref);
00258 }
00259 }
00260 catch (MeshFormatReader::VertexError e) {
00261 throw MeshReader::Error("invalid vertex number reading hexahedron "+stringify(i));
00262 }
00263
00264 this->__writeReferences(references, "Hexahedra");
00265 }
00266
00267 void MeshFormatReader::__readQuadrilaterals()
00268 {
00269 VerticesSet& V = *__vertices;
00270 Vector<Quadrangle>& Q = *__quadrilaterals;
00271
00272 std::set<size_t> references;
00273 size_t i;
00274 try {
00275 for (i=0; i < Q.size(); ++i) {
00276 const size_t a = __getVertexNumber() - 1;
00277 const size_t b = __getVertexNumber() - 1;
00278 const size_t c = __getVertexNumber() - 1;
00279 const size_t d = __getVertexNumber() - 1;
00280
00281 const size_t ref = __getInteger();
00282 references.insert(ref);
00283
00284 Q[i] = Quadrangle(V[a], V[b], V[c], V[d], ref);
00285 }
00286 }
00287 catch (MeshFormatReader::VertexError e) {
00288 throw MeshReader::Error("invalid vertex number reading quadrilateral "+stringify(i));
00289 }
00290
00291 this->__writeReferences(references, "Quadrilaterals");
00292 }
00293
00294
00295 void MeshFormatReader::__readTetrahedra()
00296 {
00297 VerticesSet& V = *__vertices;
00298 Vector<Tetrahedron>& T = *__tetrahedra;
00299
00300 std::set<size_t> references;
00301 size_t i;
00302 try {
00303 for (i=0; i<T.size(); ++i) {
00304 const size_t a = __getVertexNumber() - 1;
00305 const size_t b = __getVertexNumber() - 1;
00306 const size_t c = __getVertexNumber() - 1;
00307 const size_t d = __getVertexNumber() - 1;
00308
00309 const size_t ref = __getInteger();
00310 references.insert(ref);
00311
00312 T[i] = Tetrahedron(V[a],V[b],V[c],V[d], ref);
00313 }
00314 }
00315 catch (MeshFormatReader::VertexError e) {
00316 throw MeshReader::Error("invalid vertex number reading tetrahedron "+stringify(i));
00317 }
00318
00319 this->__writeReferences(references, "Tetrahedra");
00320 }
00321
00322 void MeshFormatReader::__readTriangles()
00323 {
00324 VerticesSet& V = *__vertices;
00325 Vector<Triangle>& T = *__triangles;
00326
00327 std::set<size_t> references;
00328 size_t i;
00329 try {
00330 for (i=0; i<T.size(); ++i) {
00331 const size_t a = __getVertexNumber() - 1;
00332 const size_t b = __getVertexNumber() - 1;
00333 const size_t c = __getVertexNumber() - 1;
00334
00335 const size_t ref = __getInteger();
00336 references.insert(ref);
00337
00338 T[i] = Triangle(V[a],V[b],V[c], ref);
00339 }
00340 }
00341 catch (MeshFormatReader::VertexError e) {
00342 throw MeshReader::Error("invalid vertex number reading triangle "+stringify(i));
00343 }
00344
00345 this->__writeReferences(references, "Triangles");
00346 }
00347
00348 MeshFormatReader::MeshFormatReader(const std::string & s)
00349 : MeshReader(s)
00350 {
00351 __keywordList["MeshVersionFormatted"]=MeshVersionFormatted;
00352 __keywordList["Dimension"]=MeshDimension;
00353 __keywordList["Vertices"]=Vertices;
00354 __keywordList["Triangles"]=Triangles;
00355 __keywordList["Quadrilaterals"]=Quadrilaterals;
00356 __keywordList["Tetrahedra"]=Tetrahedra;
00357 __keywordList["Hexahedra"]=Hexahedra;
00358 __keywordList["Normals"]=Normals;
00359 __keywordList["Tangents"]=Tangents;
00360 __keywordList["Corners"]=Corners;
00361 __keywordList["Edges"]=Edges;
00362 __keywordList["Ridges"]=Ridges;
00363 __keywordList["End"]=EndOfFile;
00364
00365 size_t integer;
00366
00367 ffout(3) << "\n";
00368 ffout(3) << "Reading file " << s << '\n';
00369 MeshFormatReader::Keyword kw;
00370
00371 kw = this->__nextKeyword();
00372 if (kw.second != MeshVersionFormatted) {
00373 std::stringstream errorMsg;
00374 errorMsg << "reading file '" << __fileName
00375 << "' expecting 'MeshVersionFormatted'" << std::ends;
00376 throw ErrorHandler(__FILE__,__LINE__,
00377 errorMsg.str(),
00378 ErrorHandler::normal);
00379 }
00380 __skipComments();
00381 integer = __getInteger();
00382
00383 ffout(3) << "- MeshVersionFormatted: " << integer << '\n';
00384
00385 kw = this->__nextKeyword();
00386 if (kw.second != MeshDimension) {
00387 std::stringstream errorMsg;
00388 errorMsg << "reading file '" << __fileName
00389 << "' expecting 'Dimension'" << std::ends;
00390 throw ErrorHandler(__FILE__,__LINE__,
00391 errorMsg.str(),
00392 ErrorHandler::normal);
00393 }
00394 __skipComments();
00395 integer = __getInteger();
00396
00397 ffout(3) << "- Dimension: " << integer << '\n';
00398
00399 if (integer != 3) {
00400 std::stringstream errorMsg;
00401 errorMsg << "reading file '" << __fileName
00402 << "' only 3D meshes can be read" << std::ends;
00403 throw ErrorHandler(__FILE__,__LINE__,
00404 errorMsg.str(),
00405 ErrorHandler::normal);
00406 }
00407
00408 kw = this->__nextKeyword();
00409 if (kw.second != Vertices) {
00410 std::stringstream errorMsg;
00411 errorMsg << "reading file '" << __fileName
00412 << "' expecting vertices list" << std::ends;
00413 throw ErrorHandler(__FILE__,__LINE__,
00414 errorMsg.str(),
00415 ErrorHandler::normal);
00416 }
00417 __skipComments();
00418 integer = __getInteger();
00419 __skipComments();
00420
00421 ffout(3) << "- Number of vertices: " << integer << '\n';
00422
00423 __vertices = new VerticesSet(integer);
00424
00425 this->__readVertices();
00426
00427 this->__readElements();
00428
00429 this->__createMesh();
00430 }