00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <cassert>
00029 #include <sstream>
00030 #include <iostream>
00031
00032 #include "TrianglesMeshReader.hpp"
00033 #include "Exception.hpp"
00034
00035 static const char* NODES_FILE_EXTENSION = ".node";
00036 static const char* ELEMENTS_FILE_EXTENSION = ".ele";
00037 static const char* FACES_FILE_EXTENSION = ".face";
00038 static const char* EDGES_FILE_EXTENSION = ".edge";
00039 static const char* NCL_FILE_EXTENSION = ".ncl";
00040 static const char* CABLE_FILE_EXTENSION = ".cable";
00041
00043
00045
00046 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00047 TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::TrianglesMeshReader(std::string pathBaseName,
00048 unsigned orderOfElements,
00049 unsigned orderOfBoundaryElements,
00050 bool readContainingElementForBoundaryElements)
00051 : mFilesBaseName(pathBaseName),
00052 mNodeItemWidth(0),
00053 mElementItemWidth(0),
00054 mFaceItemWidth(0),
00055 mNumNodes(0),
00056 mNumElements(0),
00057 mNumFaces(0),
00058 mNumCableElements(0),
00059 mNodesRead(0),
00060 mElementsRead(0),
00061 mCableElementsRead(0),
00062 mFacesRead(0),
00063 mBoundaryFacesRead(0),
00064 mNumNodeAttributes(0),
00065 mNumElementAttributes(0),
00066 mNumFaceAttributes(0),
00067 mNumCableElementAttributes(0),
00068 mOrderOfElements(orderOfElements),
00069 mOrderOfBoundaryElements(orderOfBoundaryElements),
00070 mEofException(false),
00071 mReadContainingElementOfBoundaryElement(readContainingElementForBoundaryElements),
00072 mFilesAreBinary(false),
00073 mMeshIsHexahedral(false),
00074 mNodeFileReadBuffer(NULL),
00075 mElementFileReadBuffer(NULL),
00076 mFaceFileReadBuffer(NULL),
00077 mNodePermutationDefined(false)
00078 {
00079
00080 assert(orderOfElements==1 || orderOfElements==2);
00081 if ( mOrderOfBoundaryElements == 2 && mReadContainingElementOfBoundaryElement)
00082 {
00083 EXCEPTION("Boundary element file should not have containing element info if it is quadratic");
00084 }
00085 if (mOrderOfElements==1)
00086 {
00087 mNodesPerElement = ELEMENT_DIM+1;
00088 }
00089 else
00090 {
00091 #define COVERAGE_IGNORE
00092 assert(SPACE_DIM==ELEMENT_DIM);
00093 #undef COVERAGE_IGNORE
00094 mNodesPerElement = (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2;
00095 }
00096
00097 if (mOrderOfBoundaryElements==1)
00098 {
00099 mNodesPerBoundaryElement = ELEMENT_DIM;
00100 }
00101 else
00102 {
00103 #define COVERAGE_IGNORE
00104 assert(SPACE_DIM==ELEMENT_DIM);
00105 #undef COVERAGE_IGNORE
00106 mNodesPerBoundaryElement = ELEMENT_DIM*(ELEMENT_DIM+1)/2;
00107 }
00108
00109 mIndexFromZero = false;
00110
00111 OpenFiles();
00112 ReadHeaders();
00113 }
00114
00115 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00116 TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::~TrianglesMeshReader()
00117 {
00118 delete[] mNodeFileReadBuffer;
00119 delete[] mElementFileReadBuffer;
00120 delete[] mFaceFileReadBuffer;
00121 }
00122
00123 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00124 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00125 {
00126 return mNumElements;
00127 }
00128
00129 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00130 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00131 {
00132 return mNumNodes;
00133 }
00134
00135 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00136 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00137 {
00138 return mNumFaces;
00139 }
00140
00141 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00142 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElements() const
00143 {
00144 return mNumCableElements;
00145 }
00146
00147
00148 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00149 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00150 {
00151 return mNumElementAttributes;
00152 }
00153
00154 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00155 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaceAttributes() const
00156 {
00157 return mNumFaceAttributes;
00158 }
00159
00160 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00161 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElementAttributes() const
00162 {
00163 return mNumCableElementAttributes;
00164 }
00165
00166
00167 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::Reset()
00169 {
00170 CloseFiles();
00171
00172 mNodesRead = 0;
00173 mElementsRead = 0;
00174 mFacesRead = 0;
00175 mBoundaryFacesRead = 0;
00176 mCableElementsRead = 0;
00177 mEofException = false;
00178
00179 OpenFiles();
00180 ReadHeaders();
00181 }
00182
00183 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00184 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00185 {
00186 std::vector<double> ret_coords(SPACE_DIM);
00187
00188 mNodeAttributes.clear();
00189 GetNextItemFromStream(mNodesFile, mNodesRead, ret_coords, mNumNodeAttributes, mNodeAttributes);
00190
00191 mNodesRead++;
00192 return ret_coords;
00193 }
00194
00195 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00196 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementData()
00197 {
00198 ElementData element_data;
00199 element_data.NodeIndices.resize(mNodesPerElement);
00200 element_data.AttributeValue = 0;
00201
00202 std::vector<unsigned> element_attributes;
00203 GetNextItemFromStream(mElementsFile, mElementsRead, element_data.NodeIndices, mNumElementAttributes, element_attributes);
00204 if (mNumElementAttributes > 0)
00205 {
00206 element_data.AttributeValue = (unsigned) element_attributes[0];
00207 }
00208
00209 EnsureIndexingFromZero(element_data.NodeIndices);
00210
00211 mElementsRead++;
00212
00213 if (mNodePermutationDefined)
00214 {
00215 for (std::vector<unsigned>::iterator node_it = element_data.NodeIndices.begin();
00216 node_it != element_data.NodeIndices.end();
00217 ++ node_it)
00218 {
00219 assert(*node_it < mPermutationVector.size());
00220 *node_it = mPermutationVector[*node_it];
00221 }
00222 }
00223
00224 return element_data;
00225 }
00226
00227 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00228 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextCableElementData()
00229 {
00230 ElementData element_data;
00231 element_data.NodeIndices.resize(2u);
00232 element_data.AttributeValue = 0;
00233
00234 std::vector<double> cable_element_attributes;
00235 GetNextItemFromStream(mCableElementsFile, mCableElementsRead, element_data.NodeIndices, mNumCableElementAttributes, cable_element_attributes);
00236 if (mNumCableElementAttributes > 0)
00237 {
00238 element_data.AttributeValue = cable_element_attributes[0];
00239 }
00240
00241 EnsureIndexingFromZero(element_data.NodeIndices);
00242
00243 mCableElementsRead++;
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 return element_data;
00258 }
00259
00260 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00261 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextFaceData()
00262 {
00263 ElementData face_data;
00264 std::vector<unsigned> ret_indices;
00265
00266
00267 if (ELEMENT_DIM == 1)
00268 {
00269 ret_indices.push_back( mOneDimBoundary[mBoundaryFacesRead] );
00270 }
00271 else
00272 {
00273 ret_indices.resize(mNodesPerBoundaryElement);
00274
00275 assert(ELEMENT_DIM != 0);
00276 do
00277 {
00278 face_data.AttributeValue = 1u;
00279
00280 std::vector<unsigned> face_attributes;
00281 if (mReadContainingElementOfBoundaryElement)
00282 {
00283 assert(mNumFaceAttributes == 0);
00284 GetNextItemFromStream(mFacesFile, mFacesRead, ret_indices, 1,
00285 face_attributes);
00286
00287 if (face_attributes.size() > 0)
00288 {
00289 face_data.ContainingElement = (unsigned) face_attributes[0];
00290 }
00291
00292 }
00293 else
00294 {
00295 GetNextItemFromStream(mFacesFile, mFacesRead, ret_indices, mNumFaceAttributes,
00296 face_attributes);
00297
00298 if (mNumFaceAttributes > 0)
00299 {
00300 face_data.AttributeValue = (unsigned) face_attributes[0];
00301 }
00302 }
00303
00304 EnsureIndexingFromZero(ret_indices);
00305
00306 mFacesRead++;
00307 }
00308 while (ELEMENT_DIM==2 && face_data.AttributeValue==0);
00309 }
00310
00311 mBoundaryFacesRead++;
00312
00313 if (mNodePermutationDefined)
00314 {
00315 for (std::vector<unsigned>::iterator node_it = ret_indices.begin();
00316 node_it != ret_indices.end();
00317 ++ node_it)
00318 {
00319 assert(*node_it < mPermutationVector.size());
00320 *node_it = mPermutationVector[*node_it];
00321 }
00322 }
00323
00324 face_data.NodeIndices = ret_indices;
00325
00326 return face_data;
00327 }
00328
00329 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00330 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index)
00331 {
00332 if (!mFilesAreBinary)
00333 {
00334 EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00335 }
00336 if (index >= mNumNodes)
00337 {
00338 EXCEPTION("Node does not exist - not enough nodes.");
00339 }
00340
00341 if (mNodePermutationDefined)
00342 {
00343 assert(index<mInversePermutationVector.size());
00344 index = mInversePermutationVector[index];
00345 }
00346
00347
00348 mNodesFile.seekg(mNodeFileDataStart + mNodeItemWidth*index, std::ios_base::beg);
00349
00350
00351 return GetNextNode();
00352 }
00353
00354 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00355 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementData(unsigned index)
00356 {
00357 if (!mFilesAreBinary)
00358 {
00359 EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00360 }
00361 if (index >=mNumElements)
00362 {
00363 EXCEPTION("Element " << index << " does not exist - not enough elements (only " << mNumElements << ").");
00364 }
00365
00366
00367 mElementsFile.seekg(mElementFileDataStart + mElementItemWidth*index, std::ios_base::beg);
00368
00369
00370 return GetNextElementData();
00371 }
00372
00373 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00374 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetFaceData(unsigned index)
00375 {
00376 if (!mFilesAreBinary)
00377 {
00378 EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00379 }
00380 if (index >=mNumFaces)
00381 {
00382 EXCEPTION("Face does not exist - not enough faces.");
00383 }
00384
00385
00386 mFacesFile.seekg(mFaceFileDataStart + mFaceItemWidth*index, std::ios_base::beg);
00387
00388
00389 return GetNextFaceData();
00390 }
00391
00392 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00393 std::vector<unsigned> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetContainingElementIndices(unsigned index)
00394 {
00395 if (!mFilesAreBinary)
00396 {
00397 EXCEPTION("NCL file functionality is only implemented in mesh readers for binary mesh files.");
00398 }
00399
00400 if (!mNclFileAvailable)
00401 {
00402 EXCEPTION("No NCL file available for this mesh.");
00403 }
00404 if (index >= mNumNodes)
00405 {
00406 EXCEPTION("Connectivity list does not exist - not enough nodes.");
00407 }
00408
00409 if (mNodePermutationDefined)
00410 {
00411 assert(index < mInversePermutationVector.size());
00412 index = mInversePermutationVector[index];
00413 }
00414
00415
00416 mNclFile.seekg(mNclFileDataStart + mNclItemWidth*index, std::ios_base::beg);
00417
00418
00419 std::vector<unsigned> containing_element_indices;
00420 containing_element_indices.resize(mMaxContainingElements);
00421
00422 std::vector<unsigned> dummy;
00423 GetNextItemFromStream(mNclFile, index, containing_element_indices, 0, dummy);
00424
00425 EnsureIndexingFromZero(containing_element_indices);
00426
00427 unsigned num_containing_elements = mMaxContainingElements;
00428 while ( containing_element_indices[num_containing_elements-1] == UINT_MAX )
00429 {
00430 num_containing_elements--;
00431 }
00432
00433 containing_element_indices.resize(num_containing_elements);
00434
00435 return containing_element_indices;
00436 }
00437
00438 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00439 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFiles()
00440 {
00441 OpenNodeFile();
00442 OpenElementsFile();
00443 OpenFacesFile();
00444 OpenNclFile();
00445 OpenCableElementsFile();
00446 }
00447
00448 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00449 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenNodeFile()
00450 {
00451
00452 std::string file_name = mFilesBaseName + NODES_FILE_EXTENSION;
00453 mNodesFile.open(file_name.c_str());
00454 if (!mNodesFile.is_open())
00455 {
00456 EXCEPTION("Could not open data file: " + file_name);
00457 }
00458 }
00459
00460 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00461 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenElementsFile()
00462 {
00463
00464 std::string file_name;
00465 if (ELEMENT_DIM == SPACE_DIM)
00466 {
00467 file_name = mFilesBaseName + ELEMENTS_FILE_EXTENSION;
00468 }
00469 else
00470 {
00471 if (ELEMENT_DIM == 1)
00472 {
00473 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00474 }
00475 else if (ELEMENT_DIM == 2)
00476 {
00477 file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00478 }
00479 else
00480 {
00481 EXCEPTION("Can't have a zero-dimensional mesh in a one-dimensional space");
00482 }
00483 }
00484
00485 mElementsFile.open(file_name.c_str());
00486 if (!mElementsFile.is_open())
00487 {
00488 EXCEPTION("Could not open data file: " + file_name);
00489 }
00490 }
00491
00492 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00493 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFacesFile()
00494 {
00495
00496 std::string file_name;
00497 if (ELEMENT_DIM == 3)
00498 {
00499 file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00500 }
00501 else if (ELEMENT_DIM == 2)
00502 {
00503 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00504 }
00505 else
00506 {
00507
00508 return;
00509 }
00510
00511 mFacesFile.open(file_name.c_str());
00512 if (!mFacesFile.is_open())
00513 {
00514 EXCEPTION("Could not open data file: " + file_name);
00515 }
00516 }
00517
00518 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00519 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenNclFile()
00520 {
00521 std::string file_name = mFilesBaseName + NCL_FILE_EXTENSION;
00522 mNclFile.open(file_name.c_str());
00523
00524 mNclFileAvailable = mNclFile.is_open();
00525 }
00526
00527 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00528 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenCableElementsFile()
00529 {
00530 std::string file_name = mFilesBaseName + CABLE_FILE_EXTENSION;
00531 mCableElementsFile.open(file_name.c_str());
00532 if (!mCableElementsFile.is_open())
00533 {
00534 mNumCableElements = 0u;
00535 mNumCableElementAttributes = 0u;
00536 }
00537 }
00538
00539 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00540 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeAttributes()
00541 {
00542 return mNodeAttributes;
00543 }
00544
00545 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00546 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadHeaders()
00547 {
00548
00549
00550
00551 std::string buffer;
00552 GetNextLineFromStream(mNodesFile, buffer);
00553 std::stringstream node_header_line(buffer);
00554 unsigned dimension;
00555 node_header_line >> mNumNodes >> dimension >> mNumNodeAttributes >> mMaxNodeBdyMarker;
00556 if (SPACE_DIM != dimension)
00557 {
00558 EXCEPTION("SPACE_DIM != dimension read from file ");
00559 }
00560
00561
00562 std::string extras;
00563 node_header_line >> extras;
00564 if (extras == "BIN")
00565 {
00566 mFilesAreBinary = true;
00567 mNodeFileDataStart = mNodesFile.tellg();
00568 mNodeItemWidth = SPACE_DIM * sizeof(double);
00569
00570
00571 mIndexFromZero = true;
00572 }
00573 else
00574 {
00575
00576 assert(!mNclFileAvailable);
00577
00578
00579 GetNextLineFromStream(mNodesFile, buffer);
00580 std::stringstream node_first_line(buffer);
00581 unsigned first_index;
00582 node_first_line >> first_index;
00583 assert(first_index == 0 || first_index == 1);
00584 mIndexFromZero = (first_index == 0);
00585
00586
00587 mNodesFile.close();
00588 OpenNodeFile();
00589 GetNextLineFromStream(mNodesFile, buffer);
00590 }
00591
00592
00593
00594
00595 GetNextLineFromStream(mElementsFile, buffer);
00596 std::stringstream element_header_line(buffer);
00597
00598 unsigned extra_attributes = 0;
00599
00600 if (ELEMENT_DIM == SPACE_DIM)
00601 {
00602 element_header_line >> mNumElements >> mNumElementNodes >> mNumElementAttributes;
00603
00604 extra_attributes = mNumElementAttributes;
00605
00606
00607 std::string element_extras;
00608 element_header_line >> element_extras;
00609 if (element_extras == "BIN")
00610 {
00611
00612 assert (mFilesAreBinary);
00613 }
00614 else if (element_extras == "HEX")
00615 {
00616 mMeshIsHexahedral = true;
00617 if ( ELEMENT_DIM == 2 )
00618 {
00619 mNodesPerElement = 4;
00620 mNodesPerBoundaryElement = 2;
00621 }
00622 if ( ELEMENT_DIM == 3 )
00623 {
00624 mNodesPerElement = 8;
00625 mNodesPerBoundaryElement = 4;
00626 }
00627 }
00628 else
00629 {
00630 assert (element_extras == "");
00631 }
00632
00633
00634 if (mNumElements != 0)
00635 {
00636 if (mNumElementNodes != mNodesPerElement)
00637 {
00638 EXCEPTION("Number of nodes per elem, " << mNumElementNodes << ", does not match "
00639 << "expected number, " << mNodesPerElement << " (which is calculated given "
00640 << "the order of elements chosen, " << mOrderOfElements << " (1=linear, 2=quadratics)");
00641 }
00642 }
00643 }
00644 else
00645 {
00646 element_header_line >> mNumElements >> mNumFaceAttributes;
00647
00648 extra_attributes = mNumFaceAttributes;
00649
00650
00651 std::string element_extras;
00652 element_header_line >> element_extras;
00653 if (element_extras == "BIN")
00654 {
00655
00656 assert (mFilesAreBinary);
00657 }
00658
00659 mNodesPerElement = ELEMENT_DIM+1;
00660 }
00661
00662
00663 if (mFilesAreBinary)
00664 {
00665 mElementFileDataStart = mElementsFile.tellg();
00666 mElementItemWidth = (mNodesPerElement + extra_attributes) * sizeof(unsigned);
00667 }
00668
00669
00670
00671
00672
00673 if (mNumElements != 0)
00674 {
00675 if (ELEMENT_DIM == 1)
00676 {
00677 GetOneDimBoundary();
00678 mNumFaces = mOneDimBoundary.size();
00679 }
00680 else
00681 {
00682 GetNextLineFromStream(mFacesFile, buffer);
00683 std::stringstream face_header_line(buffer);
00684
00685 face_header_line >> mNumFaces >> mNumFaceAttributes;
00686 assert(mNumFaceAttributes==0 || mNumFaceAttributes==1);
00687
00688
00689
00690
00691
00692
00693 std::string face_extras;
00694 face_header_line >> face_extras;
00695 assert (mFilesAreBinary == (face_extras == "BIN"));
00696 if ((mNumFaceAttributes==1))
00697 {
00698 unsigned num_boundary_faces = 0;
00699 bool end_of_file=false;
00700 while (!end_of_file)
00701 {
00702 try
00703 {
00704 GetNextFaceData();
00705 num_boundary_faces++;
00706 }
00707 catch(Exception& e)
00708 {
00709 if (mEofException)
00710 {
00711 end_of_file = true;
00712 }
00713 else
00714 {
00715 throw e;
00716 }
00717 }
00718 }
00719 mNumFaces = num_boundary_faces;
00720
00723
00724
00725
00726
00727
00728
00729 mFacesFile.close();
00730 mFacesFile.clear();
00731 OpenFacesFile();
00732 GetNextLineFromStream(mFacesFile, buffer);
00733 mFacesRead = 0;
00734 mBoundaryFacesRead = 0;
00735 }
00736 }
00737 }
00738
00739 if (mFilesAreBinary)
00740 {
00741 mFaceFileDataStart = mFacesFile.tellg();
00742 mFaceItemWidth = (ELEMENT_DIM + mNumFaceAttributes) * sizeof(unsigned);
00743 }
00744
00745
00746
00747
00748 if (mNclFileAvailable)
00749 {
00750 GetNextLineFromStream(mNclFile, buffer);
00751 std::stringstream ncl_header_line(buffer);
00752 unsigned num_nodes_in_file;
00753 ncl_header_line >> num_nodes_in_file >> mMaxContainingElements;
00754
00755 if ( mNumNodes != num_nodes_in_file )
00756 {
00757 EXCEPTION("NCL file does not contain the correct number of nodes for mesh");
00758 }
00759
00760 mNclFileDataStart = mNclFile.tellg();
00761 mNclItemWidth = mMaxContainingElements * sizeof(unsigned);
00762 }
00763
00764
00765
00766
00767 if (mCableElementsFile.is_open())
00768 {
00769 GetNextLineFromStream(mCableElementsFile, buffer);
00770 std::stringstream cable_header_line(buffer);
00771 unsigned num_nodes_per_cable_element;
00772 cable_header_line >> mNumCableElements >> num_nodes_per_cable_element >> mNumCableElementAttributes;
00773 assert(num_nodes_per_cable_element == 2u);
00774 mCableElementsRead = 0u;
00775 }
00776 }
00777
00778 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00779 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::CloseFiles()
00780 {
00781 mNodesFile.close();
00782 mElementsFile.close();
00783 mFacesFile.close();
00784 mNclFile.close();
00785 mCableElementsFile.close();
00786 }
00787
00788 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00789 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& rFileStream, std::string& rRawLine)
00790 {
00791 bool line_is_blank;
00792 mEofException = false;
00793 do
00794 {
00795 getline(rFileStream, rRawLine);
00796 if (rFileStream.eof())
00797 {
00798 mEofException = true;
00799 EXCEPTION("File contains incomplete data: unexpected end of file.");
00800 }
00801
00802
00803 rRawLine = rRawLine.substr(0, rRawLine.find('#',0));
00804
00805 line_is_blank = (rRawLine.find_first_not_of(" \t",0) == std::string::npos);
00806 }
00807 while (line_is_blank);
00808 }
00809
00810 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00811 template<class T_DATA, class T_ATTR>
00812 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextItemFromStream(std::ifstream& rFileStream, unsigned expectedItemNumber,
00813 std::vector<T_DATA>& rDataPacket, const unsigned& rNumAttributes, std::vector<T_ATTR>& rAttributes)
00814 {
00815 if (mFilesAreBinary)
00816 {
00817 rFileStream.read((char*)&rDataPacket[0], rDataPacket.size()*sizeof(T_DATA));
00818 if (rNumAttributes > 0)
00819 {
00820 for (unsigned i = 0; i < rNumAttributes; i++)
00821 {
00822 T_ATTR attribute;
00823 rFileStream.read((char*) &attribute, sizeof(T_ATTR));
00824 rAttributes.push_back(attribute);
00825 }
00826 }
00827 }
00828 else
00829 {
00830 std::string buffer;
00831 GetNextLineFromStream(rFileStream,buffer);
00832 std::stringstream buffer_stream(buffer);
00833
00834 unsigned item_index;
00835 buffer_stream >> item_index;
00836
00837
00838 expectedItemNumber += mIndexFromZero ? 0 : 1;
00839
00840 if (item_index != expectedItemNumber)
00841 {
00842 if (!mIndexFromZero)
00843 {
00844
00845 expectedItemNumber--;
00846 }
00847 EXCEPTION("Data for item " << expectedItemNumber << " missing");
00848 }
00849
00850 for (unsigned i=0; i<rDataPacket.size(); i++)
00851 {
00852 buffer_stream >> rDataPacket[i];
00853 }
00854
00855 if (rNumAttributes > 0)
00856 {
00857 for (unsigned i = 0; i < rNumAttributes; i++)
00858 {
00859 T_ATTR attribute;
00860 buffer_stream >> attribute;
00861 if (buffer_stream.fail())
00862 {
00863 EXCEPTION("Error in reading attributes in one of the files in " << mFilesBaseName);
00864 }
00865 rAttributes.push_back(attribute);
00866 }
00867 }
00868 }
00869 }
00870
00871 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00872 std::string TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName()
00873 {
00874 return mFilesBaseName;
00875 }
00876
00877 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00878 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOneDimBoundary()
00879 {
00880 assert(ELEMENT_DIM == 1);
00881 mNumFaceAttributes = 0;
00882 if (!mOneDimBoundary.empty())
00883 {
00884
00885 return;
00886 }
00887 std::vector<unsigned> node_indices(2);
00888 std::vector<unsigned> dummy_attribute;
00889
00890
00891 std::vector<unsigned> node_count(mNumNodes);
00892 for (unsigned element_index=0; element_index<mNumElements;element_index++)
00893 {
00894 GetNextItemFromStream(mElementsFile, element_index, node_indices, mNumElementAttributes, dummy_attribute);
00895 if (!mIndexFromZero)
00896 {
00897
00898 node_indices[0]--;
00899 node_indices[1]--;
00900 }
00901 node_count[node_indices[0]]++;
00902 node_count[node_indices[1]]++;
00903 }
00904
00905
00906 for (unsigned node_index=0; node_index<mNumNodes;node_index++)
00907 {
00908 if (node_count[node_index] == 1u)
00909 {
00910 mOneDimBoundary.push_back(node_index);
00911 }
00912 }
00913
00914
00915 mElementsFile.close();
00916 mElementsFile.clear();
00917 OpenElementsFile();
00918 std::string buffer;
00919 GetNextLineFromStream(mElementsFile, buffer);
00920 }
00921
00922 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00923 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::EnsureIndexingFromZero(std::vector<unsigned>& rNodeIndices)
00924 {
00925 if (!mIndexFromZero)
00926 {
00927 for (unsigned i=0; i<rNodeIndices.size(); i++)
00928 {
00929 rNodeIndices[i]--;
00930 }
00931 }
00932 }
00933
00934 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00935 bool TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::IsFileFormatBinary()
00936 {
00937 return mFilesAreBinary;
00938 }
00939
00940 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00941 bool TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::HasNclFile()
00942 {
00943 return mNclFileAvailable;
00944 }
00945
00946 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00947 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::SetReadBufferSize(unsigned bufferSize)
00948 {
00949 mNodeFileReadBuffer = new char[bufferSize];
00950 mElementFileReadBuffer = new char[bufferSize];
00951 mFaceFileReadBuffer = new char[bufferSize];
00952
00953 mNodesFile.rdbuf()->pubsetbuf(mNodeFileReadBuffer, bufferSize);
00954 mElementsFile.rdbuf()->pubsetbuf(mElementFileReadBuffer, bufferSize);
00955 mFacesFile.rdbuf()->pubsetbuf(mFaceFileReadBuffer, bufferSize);
00956 }
00957
00958 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00959 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::SetNodePermutation(std::vector<unsigned>& rPermutationVector)
00960 {
00961 if ( !mFilesAreBinary )
00962 {
00963
00964 EXCEPTION("Permuted read can only be used with binary files since it requires random access to the node file.");
00965 }
00966
00967 mNodePermutationDefined = true;
00968 mPermutationVector = rPermutationVector;
00969 mInversePermutationVector.resize(mPermutationVector.size());
00970 for (unsigned index=0; index<mPermutationVector.size(); index++)
00971 {
00972 mInversePermutationVector[mPermutationVector[index]]=index;
00973 }
00974 }
00975
00977
00979
00980 template class TrianglesMeshReader<0,1>;
00981 template class TrianglesMeshReader<1,1>;
00982 template class TrianglesMeshReader<1,2>;
00983 template class TrianglesMeshReader<1,3>;
00984 template class TrianglesMeshReader<2,2>;
00985 template class TrianglesMeshReader<2,3>;
00986 template class TrianglesMeshReader<3,3>;
00987
00992 template void TrianglesMeshReader<0,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
00993 template void TrianglesMeshReader<0,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
00994 template void TrianglesMeshReader<1,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
00995 template void TrianglesMeshReader<1,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
00996 template void TrianglesMeshReader<1,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
00997 template void TrianglesMeshReader<1,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
00998 template void TrianglesMeshReader<1,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
00999 template void TrianglesMeshReader<1,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
01000 template void TrianglesMeshReader<2,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
01001 template void TrianglesMeshReader<2,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
01002 template void TrianglesMeshReader<2,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
01003 template void TrianglesMeshReader<2,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);
01004 template void TrianglesMeshReader<3,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, std::vector<unsigned>&);
01005 template void TrianglesMeshReader<3,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double> &, const unsigned&, std::vector<double>&);