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