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