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