ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkVTKPolyDataMeshIO_h 00019 #define __itkVTKPolyDataMeshIO_h 00020 00021 #include "itkByteSwapper.h" 00022 #include "itkMetaDataObject.h" 00023 #include "itkMeshIOBase.h" 00024 #include "itkVectorContainer.h" 00025 00026 #include <fstream> 00027 #include <vector> 00028 00029 namespace itk 00030 { 00038 class ITK_EXPORT VTKPolyDataMeshIO:public MeshIOBase 00039 { 00040 public: 00042 typedef VTKPolyDataMeshIO Self; 00043 typedef MeshIOBase Superclass; 00044 typedef SmartPointer< Self > Pointer; 00045 typedef SmartPointer< const Self > ConstPointer; 00046 00047 typedef Superclass::SizeValueType SizeValueType; 00048 00049 typedef std::string StringType; 00050 typedef std::vector< StringType > StringVectorType; 00051 typedef std::stringstream StringStreamType; 00052 typedef std::vector< SizeValueType > PointIdVector; 00053 typedef VectorContainer< SizeValueType, PointIdVector > PolylinesContainerType; 00054 typedef PolylinesContainerType::Pointer PolylinesContainerPointer; 00055 00057 itkNewMacro(Self); 00058 00060 itkTypeMacro(VTKPolyDataMeshIO, MeshIOBase); 00061 00069 virtual bool CanReadFile(const char *FileNameToRead); 00070 00072 virtual void ReadMeshInformation(); 00073 00075 virtual void ReadPoints(void *buffer); 00076 00077 virtual void ReadCells(void *buffer); 00078 00079 virtual void ReadPointData(void *buffer); 00080 00081 virtual void ReadCellData(void *buffer); 00082 00083 /*-------- This part of the interfaces deals with writing data. ----- */ 00089 virtual bool CanWriteFile(const char *FileNameToWrite); 00090 00092 virtual void WriteMeshInformation(); 00093 00096 virtual void WritePoints(void *buffer); 00097 00098 virtual void WriteCells(void *buffer); 00099 00100 virtual void WritePointData(void *buffer); 00101 00102 virtual void WriteCellData(void *buffer); 00103 00104 virtual void Write(); 00105 protected: 00106 VTKPolyDataMeshIO(); 00107 virtual ~VTKPolyDataMeshIO() {} 00108 00109 void PrintSelf(std::ostream & os, Indent indent) const; 00110 00111 template< typename T > 00112 void UpdateCellInformation(T *buffer) 00113 { 00114 unsigned int numberOfVertices = 0; 00115 unsigned int numberOfVertexIndices = 0; 00116 unsigned int numberOfLines = 0; 00117 unsigned int numberOfLineIndices = 0; 00118 unsigned int numberOfPolygons = 0; 00119 unsigned int numberOfPolygonIndices = 0; 00120 00121 SizeValueType index = 0; 00122 00123 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 00124 { 00125 MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) ); 00126 unsigned int nn = static_cast< unsigned int >( buffer[index++] ); 00127 switch ( cellType ) 00128 { 00129 case VERTEX_CELL: 00130 numberOfVertices++; 00131 numberOfVertexIndices += nn + 1; 00132 break; 00133 case LINE_CELL: 00134 numberOfLines++; 00135 numberOfLineIndices += nn + 1; 00136 break; 00137 case TRIANGLE_CELL: 00138 numberOfPolygons++; 00139 numberOfPolygonIndices += nn + 1; 00140 break; 00141 case POLYGON_CELL: 00142 numberOfPolygons++; 00143 numberOfPolygonIndices += nn + 1; 00144 break; 00145 case QUADRILATERAL_CELL: 00146 numberOfPolygons++; 00147 numberOfPolygonIndices += nn + 1; 00148 break; 00149 default: 00150 itkExceptionMacro(<< "Currently we dont support this cell type"); 00151 } 00152 00153 index += nn; 00154 } 00155 00156 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00157 EncapsulateMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices); 00158 EncapsulateMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices); 00159 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines); 00160 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices); 00161 EncapsulateMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons); 00162 EncapsulateMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices); 00163 return; 00164 } 00165 00166 template< typename T > 00167 void ReadPointsBufferAsASCII(std::ifstream & inputFile, T *buffer) 00168 { 00169 std::string line; 00170 00171 while ( !inputFile.eof() ) 00172 { 00173 std::getline(inputFile, line, '\n'); 00174 00175 if ( line.find("POINTS") != std::string::npos ) 00176 { 00178 SizeValueType numberOfComponents = this->m_NumberOfPoints * this->m_PointDimension; 00179 for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ ) 00180 { 00181 inputFile >> buffer[ii]; 00182 } 00183 } 00184 } 00185 } 00186 00187 template< typename T > 00188 void ReadPointsBufferAsBINARY(std::ifstream & inputFile, T *buffer) 00189 { 00190 std::string line; 00191 00192 while ( !inputFile.eof() ) 00193 { 00194 std::getline(inputFile, line, '\n'); 00195 00196 if ( line.find("POINTS") != std::string::npos ) 00197 { 00199 SizeValueType numberOfComponents = this->m_NumberOfPoints * this->m_PointDimension; 00200 inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) ); 00201 if ( itk::ByteSwapper< T >::SystemIsLittleEndian() ) 00202 { 00203 itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents); 00204 } 00205 } 00206 } 00207 } 00209 00210 void ReadCellsBufferAsASCII(std::ifstream & inputFile, void *buffer); 00211 00212 void ReadCellsBufferAsBINARY(std::ifstream & inputFile, void *buffer); 00213 00214 template< typename T > 00215 void ReadPointDataBufferAsASCII(std::ifstream & inputFile, T *buffer) 00216 { 00217 StringType line; 00218 00219 while ( !inputFile.eof() ) 00220 { 00221 std::getline(inputFile, line, '\n'); 00222 if ( line.find("POINT_DATA") != std::string::npos ) 00223 { 00224 if ( !inputFile.eof() ) 00225 { 00226 std::getline(inputFile, line, '\n'); 00227 } 00228 else 00229 { 00230 itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA"); 00231 } 00232 00234 if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos ) 00235 { 00236 if ( !inputFile.eof() ) 00237 { 00238 std::getline(inputFile, line, '\n'); 00239 if ( line.find("LOOKUP_TABLE") == std::string::npos ) 00240 { 00241 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00242 } 00243 } 00244 else 00245 { 00246 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00247 } 00248 } 00250 00252 SizeValueType numberOfComponents = this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents; 00253 for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ ) 00254 { 00255 inputFile >> buffer[ii]; 00256 } 00257 } 00258 } 00259 } 00260 00261 template< typename T > 00262 void ReadPointDataBufferAsBINARY(std::ifstream & inputFile, T *buffer) 00263 { 00264 StringType line; 00265 00266 while ( !inputFile.eof() ) 00267 { 00268 std::getline(inputFile, line, '\n'); 00269 if ( line.find("POINT_DATA") != std::string::npos ) 00270 { 00271 if ( !inputFile.eof() ) 00272 { 00273 std::getline(inputFile, line, '\n'); 00274 } 00275 else 00276 { 00277 itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA"); 00278 } 00279 00281 if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos ) 00282 { 00283 if ( !inputFile.eof() ) 00284 { 00285 std::getline(inputFile, line, '\n'); 00286 if ( line.find("LOOKUP_TABLE") == std::string::npos ) 00287 { 00288 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00289 } 00290 } 00291 else 00292 { 00293 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00294 } 00295 } 00297 00299 SizeValueType numberOfComponents = this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents; 00300 inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) ); 00301 if ( itk::ByteSwapper< T >::SystemIsLittleEndian() ) 00302 { 00303 itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents); 00304 } 00305 } 00306 } 00307 } 00309 00310 template< typename T > 00311 void ReadCellDataBufferAsASCII(std::ifstream & inputFile, T *buffer) 00312 { 00313 StringType line; 00314 00315 while ( !inputFile.eof() ) 00316 { 00317 std::getline(inputFile, line, '\n'); 00318 if ( line.find("CELL_DATA") != std::string::npos ) 00319 { 00320 if ( !inputFile.eof() ) 00321 { 00322 std::getline(inputFile, line, '\n'); 00323 } 00324 else 00325 { 00326 itkExceptionMacro("UnExpected end of line while trying to read CELL_DATA"); 00327 } 00328 00330 if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos ) 00331 { 00332 if ( !inputFile.eof() ) 00333 { 00334 std::getline(inputFile, line, '\n'); 00335 if ( line.find("LOOKUP_TABLE") == std::string::npos ) 00336 { 00337 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00338 } 00339 } 00340 else 00341 { 00342 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00343 } 00344 } 00346 00348 SizeValueType numberOfComponents = this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents; 00349 for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ ) 00350 { 00351 inputFile >> buffer[ii]; 00352 } 00353 } 00354 } 00355 } 00356 00357 template< typename T > 00358 void ReadCellDataBufferAsBINARY(std::ifstream & inputFile, T *buffer) 00359 { 00360 StringType line; 00361 00362 while ( !inputFile.eof() ) 00363 { 00364 std::getline(inputFile, line, '\n'); 00365 if ( line.find("POINT_DATA") != std::string::npos ) 00366 { 00367 if ( !inputFile.eof() ) 00368 { 00369 std::getline(inputFile, line, '\n'); 00370 } 00371 else 00372 { 00373 itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA"); 00374 } 00375 00377 if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos ) 00378 { 00379 if ( !inputFile.eof() ) 00380 { 00381 std::getline(inputFile, line, '\n'); 00382 if ( line.find("LOOKUP_TABLE") == std::string::npos ) 00383 { 00384 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00385 } 00386 } 00387 else 00388 { 00389 itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE"); 00390 } 00391 } 00392 00394 SizeValueType numberOfComponents = this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents; 00395 inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) ); 00396 if ( itk::ByteSwapper< T >::SystemIsLittleEndian() ) 00397 { 00398 itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents); 00399 } 00400 } 00401 } 00402 } 00404 00405 template< typename T > 00406 void WritePointsBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & pointComponentType) 00407 { 00409 outputFile << "POINTS " << this->m_NumberOfPoints; 00410 00411 outputFile << pointComponentType << '\n'; 00412 for ( SizeValueType ii = 0; ii < this->m_NumberOfPoints; ii++ ) 00413 { 00414 for ( unsigned int jj = 0; jj < this->m_PointDimension - 1; jj++ ) 00415 { 00416 outputFile << buffer[ii * this->m_PointDimension + jj] << " "; 00417 } 00418 00419 outputFile << buffer[ii * this->m_PointDimension + this->m_PointDimension - 1] << '\n'; 00420 } 00421 00422 return; 00423 } 00424 00425 template< typename T > 00426 void WritePointsBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & pointComponentType) 00427 { 00429 outputFile << "POINTS " << this->m_NumberOfPoints; 00430 outputFile << pointComponentType << "\n"; 00431 itk::ByteSwapper< T >::SwapWriteRangeFromSystemToBigEndian(buffer, this->m_NumberOfPoints * this->m_PointDimension, &outputFile); 00432 outputFile << "\n"; 00433 00434 return; 00435 } 00436 00437 template< typename T > 00438 void WriteCellsBufferAsASCII(std::ofstream & outputFile, T *buffer) 00439 { 00440 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00441 unsigned int numberOfVertices = 0; 00442 unsigned int numberOfVertexIndices = 0; 00443 unsigned int numberOfLines = 0; 00444 unsigned int numberOfLineIndices = 0; 00445 unsigned int numberOfPolygons = 0; 00446 unsigned int numberOfPolygonIndices = 0; 00447 00449 SizeValueType index = 0; 00450 00451 ExposeMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices); 00452 if ( numberOfVertices ) 00453 { 00454 ExposeMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices); 00455 outputFile << "VERTICES " << numberOfVertices << " " << numberOfVertexIndices << '\n'; 00456 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 00457 { 00458 MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) ); 00459 unsigned int nn = static_cast< unsigned int >( buffer[index++] ); 00460 if ( cellType == VERTEX_CELL ) 00461 { 00462 outputFile << nn; 00463 for ( unsigned int jj = 0; jj < nn; jj++ ) 00464 { 00465 outputFile << " " << buffer[index++]; 00466 } 00467 outputFile << '\n'; 00468 } 00469 else 00470 { 00471 index += nn; 00472 } 00473 } 00474 } 00475 00477 index = 0; 00478 ExposeMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines); 00479 if ( numberOfLines ) 00480 { 00481 numberOfLineIndices = 0; 00482 SizeValueType numberOfPolylines = 0; 00483 PolylinesContainerPointer polylines = PolylinesContainerType::New(); 00484 PointIdVector pointIds; 00485 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 00486 { 00487 MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) ); 00488 unsigned int nn = static_cast< unsigned int >( buffer[index++] ); 00489 if ( cellType == LINE_CELL ) 00490 { 00491 if ( pointIds.size() >= nn ) 00492 { 00493 SizeValueType id = pointIds.back(); 00494 if ( id == static_cast< SizeValueType >( buffer[index] ) ) 00495 { 00496 pointIds.push_back( static_cast< SizeValueType >( buffer[index + 1] ) ); 00497 } 00498 else if ( id == static_cast< SizeValueType >( buffer[index + 1] ) ) 00499 { 00500 pointIds.push_back( static_cast< SizeValueType >( buffer[index] ) ); 00501 } 00502 else 00503 { 00504 polylines->InsertElement(numberOfPolylines++, pointIds); 00505 numberOfLineIndices += pointIds.size(); 00506 pointIds.clear(); 00508 00509 for ( unsigned int jj = 0; jj < nn; jj++ ) 00510 { 00511 pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) ); 00512 } 00513 } 00514 } 00515 else 00516 { 00517 for ( unsigned int jj = 0; jj < nn; jj++ ) 00518 { 00519 pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) ); 00520 } 00521 } 00522 } 00523 00524 index += nn; 00525 } 00526 polylines->InsertElement(numberOfPolylines++, pointIds); 00527 numberOfLineIndices += pointIds.size(); 00528 pointIds.clear(); 00529 00530 numberOfLines = polylines->Size(); 00531 numberOfLineIndices += numberOfLines; 00532 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines); 00533 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices); 00534 outputFile << "LINES " << numberOfLines << " " << numberOfLineIndices << '\n'; 00535 for ( SizeValueType ii = 0; ii < polylines->Size(); ++ii ) 00536 { 00537 unsigned int nn = polylines->ElementAt(ii).size(); 00538 outputFile << nn; 00539 for ( unsigned int jj = 0; jj < nn; ++jj ) 00540 { 00541 outputFile << " " << polylines->ElementAt(ii)[jj]; 00542 } 00543 outputFile << '\n'; 00544 } 00545 } 00546 00548 index = 0; 00549 ExposeMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons); 00550 if ( numberOfPolygons ) 00551 { 00552 ExposeMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices); 00553 outputFile << "POLYGONS " << numberOfPolygons << " " << numberOfPolygonIndices << '\n'; 00554 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 00555 { 00556 MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) ); 00557 unsigned int nn = static_cast< unsigned int >( buffer[index++] ); 00558 if ( cellType == POLYGON_CELL || 00559 cellType == TRIANGLE_CELL || 00560 cellType == QUADRILATERAL_CELL ) 00561 { 00562 outputFile << nn; 00563 for ( unsigned int jj = 0; jj < nn; jj++ ) 00564 { 00565 outputFile << " " << buffer[index++]; 00566 } 00567 outputFile << '\n'; 00568 } 00569 else 00570 { 00571 index += nn; 00572 } 00573 } 00574 } 00575 } 00577 00578 template< typename T > 00579 void WriteCellsBufferAsBINARY(std::ofstream & outputFile, T *buffer) 00580 { 00581 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00582 unsigned int numberOfVertices = 0; 00583 unsigned int numberOfVertexIndices = 0; 00584 unsigned int numberOfLines = 0; 00585 unsigned int numberOfLineIndices = 0; 00586 unsigned int numberOfPolygons = 0; 00587 unsigned int numberOfPolygonIndices = 0; 00588 00590 SizeValueType index = 0; 00591 00592 ExposeMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices); 00593 if ( numberOfVertices ) 00594 { 00595 ExposeMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices); 00596 outputFile << "VERTICES " << numberOfVertices << " " << numberOfVertexIndices << '\n'; 00597 unsigned int *data = new unsigned int[numberOfVertexIndices]; 00598 ReadCellsBuffer(buffer, data); 00599 itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfVertexIndices, &outputFile); 00600 outputFile << "\n"; 00601 delete[] data; 00602 } 00603 00605 index = 0; 00606 ExposeMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines); 00607 if ( numberOfLines ) 00608 { 00609 numberOfLineIndices = 0; 00610 SizeValueType numberOfPolylines = 0; 00611 PolylinesContainerPointer polylines = PolylinesContainerType::New(); 00612 PointIdVector pointIds; 00613 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 00614 { 00615 MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) ); 00616 unsigned int nn = static_cast< unsigned int >( buffer[index++] ); 00617 if ( cellType == LINE_CELL ) 00618 { 00619 if ( pointIds.size() >= nn ) 00620 { 00621 SizeValueType id = pointIds.back(); 00622 if ( id == static_cast< SizeValueType >( buffer[index] ) ) 00623 { 00624 pointIds.push_back( static_cast< SizeValueType >( buffer[index + 1] ) ); 00625 } 00626 else if ( id == static_cast< SizeValueType >( buffer[index + 1] ) ) 00627 { 00628 pointIds.push_back( static_cast< SizeValueType >( buffer[index] ) ); 00629 } 00630 else 00631 { 00632 polylines->InsertElement(numberOfPolylines++, pointIds); 00633 numberOfLineIndices += pointIds.size(); 00634 pointIds.clear(); 00636 00637 for ( unsigned int jj = 0; jj < nn; jj++ ) 00638 { 00639 pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) ); 00640 } 00641 } 00642 } 00643 else 00644 { 00645 for ( unsigned int jj = 0; jj < nn; jj++ ) 00646 { 00647 pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) ); 00648 } 00649 } 00650 } 00651 00652 index += nn; 00653 } 00654 polylines->InsertElement(numberOfPolylines++, pointIds); 00655 numberOfLineIndices += pointIds.size(); 00656 pointIds.clear(); 00657 00658 numberOfLines = polylines->Size(); 00659 numberOfLineIndices += numberOfLines; 00660 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines); 00661 EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices); 00662 00663 outputFile << "LINES " << numberOfLines << " " << numberOfLineIndices << '\n'; 00664 unsigned int *data = new unsigned int[numberOfLineIndices]; 00665 unsigned long outputIndex = 0; 00666 for ( SizeValueType ii = 0; ii < polylines->Size(); ++ii ) 00667 { 00668 unsigned int nn = polylines->ElementAt(ii).size(); 00669 data[outputIndex++] = nn; 00670 for ( unsigned int jj = 0; jj < nn; ++jj ) 00671 { 00672 data[outputIndex++] = polylines->ElementAt(ii)[jj]; 00673 } 00674 } 00675 00676 itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfLineIndices, &outputFile); 00677 outputFile << "\n"; 00678 delete[] data; 00679 } 00680 00682 index = 0; 00683 ExposeMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons); 00684 if ( numberOfPolygons ) 00685 { 00686 ExposeMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices); 00687 outputFile << "POLYGONS " << numberOfPolygons << " " << numberOfPolygonIndices << '\n'; 00688 unsigned int *data = new unsigned int[numberOfPolygonIndices]; 00689 ReadCellsBuffer(buffer, data); 00690 itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfPolygonIndices, &outputFile); 00691 outputFile << "\n"; 00692 delete[] data; 00693 } 00694 } 00696 00697 template< typename T > 00698 void WritePointDataBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & pointPixelComponentName) 00699 { 00700 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00701 StringType dataName; 00702 00703 outputFile << "POINT_DATA " << this->m_NumberOfPointPixels << '\n'; 00704 switch ( this->m_PointPixelType ) 00705 { 00706 case SCALAR: 00707 { 00708 outputFile << "SCALARS "; 00709 ExposeMetaData< StringType >(metaDic, "pointScalarDataName", dataName); 00710 outputFile << dataName << " "; 00711 break; 00712 } 00713 case OFFSET: 00714 case POINT: 00715 case COVARIANTVECTOR: 00716 case VECTOR: 00717 { 00718 outputFile << "VECTORS "; 00719 ExposeMetaData< StringType >(metaDic, "pointVectorDataName", dataName); 00720 outputFile << dataName << " "; 00721 break; 00722 } 00723 case SYMMETRICSECONDRANKTENSOR: 00724 case DIFFUSIONTENSOR3D: 00725 { 00726 outputFile << "TENSORS "; 00727 ExposeMetaData< StringType >(metaDic, "pointTensorDataName", dataName); 00728 outputFile << dataName << " "; 00729 break; 00730 } 00731 case ARRAY: 00732 case VARIABLELENGTHVECTOR: 00733 { 00734 outputFile << "COLOR_SCALARS "; 00735 ExposeMetaData< StringType >(metaDic, "pointColorScalarDataName", dataName); 00736 outputFile << dataName << " "; 00737 WriteColorScalarBufferAsASCII(outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels); 00738 return; 00739 } 00740 default: 00741 { 00742 itkExceptionMacro(<< "Unknown point pixel type"); 00743 } 00744 } 00745 00746 outputFile << pointPixelComponentName << '\n'; 00747 00748 if ( this->m_PointPixelType == SCALAR ) 00749 { 00750 outputFile << "LOOKUP_TABLE default" << '\n'; 00751 } 00752 00753 Indent indent(2); 00754 if ( this->m_PointPixelType == SYMMETRICSECONDRANKTENSOR ) 00755 { 00756 T *ptr = buffer; 00757 SizeValueType i = 0; 00758 const SizeValueType num = this->m_NumberOfPointPixelComponents * this->m_NumberOfPointPixels; 00759 if( this->m_NumberOfPointPixelComponents == 3 ) 00760 { 00761 T zero( itk::NumericTraits<T>::Zero ); 00762 T e12; 00763 while( i < num ) 00764 { 00765 // row 1 00766 outputFile << *ptr++ << indent; 00767 e12 = *ptr++; 00768 outputFile << e12 << indent; 00769 outputFile << zero << '\n'; 00770 // row 2 00771 outputFile << e12 << indent; 00772 outputFile << *ptr++ << indent; 00773 outputFile << zero << '\n'; 00774 // row 3 00775 outputFile << zero << indent << zero << indent << zero << "\n\n"; 00776 i += 3; 00777 } 00778 } 00779 else if( this->m_NumberOfPointPixelComponents == 3 ) 00780 { 00781 T e12; 00782 T e13; 00783 T e23; 00784 while( i < num ) 00785 { 00786 // row 1 00787 outputFile << *ptr++ << indent; 00788 e12 = *ptr++; 00789 outputFile << e12 << indent; 00790 e13 = *ptr++; 00791 outputFile << e13 << '\n'; 00792 // row 2 00793 outputFile << e12 << indent; 00794 outputFile << *ptr++ << indent; 00795 e23 = *ptr++; 00796 outputFile << e23 << '\n'; 00797 // row 3 00798 outputFile << e13 << indent; 00799 outputFile << e23 << indent; 00800 outputFile << *ptr++ << "\n\n"; 00801 i += 6; 00802 } 00803 } 00804 else 00805 { 00806 ::itk::ExceptionObject e_(__FILE__, __LINE__, 00807 "itk::ERROR: VTKImageIO2: Unsupported number of components in tensor.", 00808 ITK_LOCATION); 00809 throw e_; 00810 } 00811 } 00812 else // not tensor 00813 { 00814 unsigned int jj; 00815 for ( SizeValueType ii = 0; ii < this->m_NumberOfPointPixels; ii++ ) 00816 { 00817 for ( jj = 0; jj < this->m_NumberOfPointPixelComponents - 1; jj++ ) 00818 { 00819 outputFile << buffer[ii * this->m_NumberOfPointPixelComponents + jj] << indent; 00820 } 00821 outputFile << buffer[ii * this->m_NumberOfPointPixelComponents + jj]; 00822 outputFile << '\n'; 00823 } 00824 } 00825 00826 return; 00827 } 00828 00829 template< typename T > 00830 void WritePointDataBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & pointPixelComponentName) 00831 { 00832 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00833 StringType dataName; 00834 00835 outputFile << "POINT_DATA " << this->m_NumberOfPointPixels << "\n"; 00836 switch ( this->m_PointPixelType ) 00837 { 00838 case SCALAR: 00839 { 00840 outputFile << "SCALARS "; 00841 ExposeMetaData< StringType >(metaDic, "pointScalarDataName", dataName); 00842 outputFile << dataName << " "; 00843 break; 00844 } 00845 case OFFSET: 00846 case POINT: 00847 case COVARIANTVECTOR: 00848 case VECTOR: 00849 { 00850 outputFile << "VECTORS "; 00851 ExposeMetaData< StringType >(metaDic, "pointVectorDataName", dataName); 00852 outputFile << dataName << " "; 00853 break; 00854 } 00855 case SYMMETRICSECONDRANKTENSOR: 00856 case DIFFUSIONTENSOR3D: 00857 { 00858 outputFile << "TENSORS "; 00859 ExposeMetaData< StringType >(metaDic, "pointTensorDataName", dataName); 00860 outputFile << dataName << " "; 00861 break; 00862 } 00863 case ARRAY: 00864 case VARIABLELENGTHVECTOR: 00865 { 00866 outputFile << "COLOR_SCALARS "; 00867 ExposeMetaData< StringType >(metaDic, "pointColorScalarDataName", dataName); 00868 outputFile << dataName << " "; 00869 WriteColorScalarBufferAsBINARY(outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels); 00870 return; 00871 } 00872 default: 00873 { 00874 itkExceptionMacro(<< "Unknown point pixel type"); 00875 } 00876 } 00877 00878 outputFile << pointPixelComponentName << "\n"; 00879 if ( this->m_PointPixelType == SCALAR ) 00880 { 00881 outputFile << "LOOKUP_TABLE default\n"; 00882 } 00883 00884 itk::ByteSwapper< T >::SwapWriteRangeFromSystemToBigEndian(buffer, 00885 this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents, 00886 &outputFile); 00887 outputFile << "\n"; 00888 return; 00889 } 00890 00891 template< typename T > 00892 void WriteCellDataBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & cellPixelComponentName) 00893 { 00894 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 00895 StringType dataName; 00896 00897 outputFile << "CELL_DATA " << this->m_NumberOfCellPixels << '\n'; 00898 switch ( this->m_CellPixelType ) 00899 { 00900 case SCALAR: 00901 { 00902 outputFile << "SCALARS "; 00903 ExposeMetaData< StringType >(metaDic, "cellScalarDataName", dataName); 00904 outputFile << dataName << " "; 00905 break; 00906 } 00907 case OFFSET: 00908 case POINT: 00909 case COVARIANTVECTOR: 00910 case VECTOR: 00911 { 00912 outputFile << "VECTORS "; 00913 ExposeMetaData< StringType >(metaDic, "cellVectorDataName", dataName); 00914 outputFile << dataName << " "; 00915 break; 00916 } 00917 case SYMMETRICSECONDRANKTENSOR: 00918 case DIFFUSIONTENSOR3D: 00919 { 00920 outputFile << "TENSORS "; 00921 ExposeMetaData< StringType >(metaDic, "cellTensorDataName", dataName); 00922 outputFile << dataName << " "; 00923 break; 00924 } 00925 case ARRAY: 00926 case VARIABLELENGTHVECTOR: 00927 { 00928 outputFile << "COLOR_SCALARS "; 00929 ExposeMetaData< StringType >(metaDic, "cellColorScalarDataName", dataName); 00930 outputFile << dataName << " "; 00931 WriteColorScalarBufferAsASCII(outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels); 00932 return; 00933 } 00934 default: 00935 { 00936 itkExceptionMacro(<< "Unknown cell pixel type"); 00937 } 00938 } 00939 00940 outputFile << cellPixelComponentName << '\n'; 00941 if ( this->m_CellPixelType == SCALAR ) 00942 { 00943 outputFile << "LOOKUP_TABLE default" << '\n'; 00944 } 00945 00946 Indent indent(2); 00947 if ( this->m_CellPixelType == SYMMETRICSECONDRANKTENSOR ) 00948 { 00949 T *ptr = buffer; 00950 SizeValueType i = 0; 00951 const SizeValueType num = this->m_NumberOfCellPixelComponents * this->m_NumberOfCellPixels; 00952 if( this->m_NumberOfCellPixelComponents == 3 ) 00953 { 00954 T zero( itk::NumericTraits<T>::Zero ); 00955 T e12; 00956 while( i < num ) 00957 { 00958 // row 1 00959 outputFile << *ptr++ << indent; 00960 e12 = *ptr++; 00961 outputFile << e12 << indent; 00962 outputFile << zero << '\n'; 00963 // row 2 00964 outputFile << e12 << indent; 00965 outputFile << *ptr++ << indent; 00966 outputFile << zero << '\n'; 00967 // row 3 00968 outputFile << zero << indent << zero << indent << zero << "\n\n"; 00969 i += 3; 00970 } 00971 } 00972 else if( this->m_NumberOfCellPixelComponents == 3 ) 00973 { 00974 T e12; 00975 T e13; 00976 T e23; 00977 while( i < num ) 00978 { 00979 // row 1 00980 outputFile << *ptr++ << indent; 00981 e12 = *ptr++; 00982 outputFile << e12 << indent; 00983 e13 = *ptr++; 00984 outputFile << e13 << '\n'; 00985 // row 2 00986 outputFile << e12 << indent; 00987 outputFile << *ptr++ << indent; 00988 e23 = *ptr++; 00989 outputFile << e23 << '\n'; 00990 // row 3 00991 outputFile << e13 << indent; 00992 outputFile << e23 << indent; 00993 outputFile << *ptr++ << "\n\n"; 00994 i += 6; 00995 } 00996 } 00997 else 00998 { 00999 ::itk::ExceptionObject e_(__FILE__, __LINE__, 01000 "itk::ERROR: VTKPolyDataMeshIO: Unsupported number of components in tensor.", 01001 ITK_LOCATION); 01002 throw e_; 01003 } 01004 } 01005 else // not tensor 01006 { 01007 unsigned int jj; 01008 for ( SizeValueType ii = 0; ii < this->m_NumberOfCellPixels; ii++ ) 01009 { 01010 for ( jj = 0; jj < this->m_NumberOfCellPixelComponents - 1; jj++ ) 01011 { 01012 outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj] << indent; 01013 } 01014 outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj]; 01015 outputFile << '\n'; 01016 } 01017 } 01018 01019 return; 01020 } 01021 01022 template< typename T > 01023 void WriteCellDataBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & cellPixelComponentName) 01024 { 01025 MetaDataDictionary & metaDic = this->GetMetaDataDictionary(); 01026 StringType dataName; 01027 01028 outputFile << "CELL_DATA " << this->m_NumberOfCellPixels << "\n"; 01029 switch ( this->m_CellPixelType ) 01030 { 01031 case SCALAR: 01032 { 01033 outputFile << "SCALARS "; 01034 ExposeMetaData< StringType >(metaDic, "cellScalarDataName", dataName); 01035 outputFile << dataName << " "; 01036 break; 01037 } 01038 case OFFSET: 01039 case POINT: 01040 case COVARIANTVECTOR: 01041 case VECTOR: 01042 { 01043 outputFile << "VECTORS "; 01044 ExposeMetaData< StringType >(metaDic, "cellVectorDataName", dataName); 01045 outputFile << dataName << " "; 01046 break; 01047 } 01048 case SYMMETRICSECONDRANKTENSOR: 01049 case DIFFUSIONTENSOR3D: 01050 { 01051 outputFile << "TENSORS "; 01052 ExposeMetaData< StringType >(metaDic, "cellTensorDataName", dataName); 01053 outputFile << dataName << " "; 01054 break; 01055 } 01056 case ARRAY: 01057 case VARIABLELENGTHVECTOR: 01058 { 01059 outputFile << "COLOR_SCALARS "; 01060 ExposeMetaData< StringType >(metaDic, "cellColorScalarDataName", dataName); 01061 outputFile << dataName << " "; 01062 WriteColorScalarBufferAsBINARY(outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels); 01063 return; 01064 } 01065 default: 01066 { 01067 itkExceptionMacro(<< "Unknown cell pixel type"); 01068 } 01069 } 01070 01071 outputFile << cellPixelComponentName << "\n"; 01072 if ( this->m_CellPixelType == SCALAR ) 01073 { 01074 outputFile << "LOOKUP_TABLE default\n"; 01075 } 01076 01077 itk::ByteSwapper< T >::SwapWriteRangeFromSystemToBigEndian(buffer, 01078 this->m_NumberOfCells * this->m_NumberOfCellPixelComponents, 01079 &outputFile); 01080 outputFile << "\n"; 01081 return; 01082 } 01083 01084 template< typename T > 01085 void WriteColorScalarBufferAsASCII(std::ofstream & outputFile, 01086 T *buffer, 01087 unsigned int numberOfPixelComponents, 01088 SizeValueType numberOfPixels) 01089 { 01090 outputFile << numberOfPixelComponents << "\n"; 01091 Indent indent(2); 01092 for ( SizeValueType ii = 0; ii < numberOfPixels; ++ii ) 01093 { 01094 for ( unsigned int jj = 0; jj < numberOfPixelComponents; ++jj ) 01095 { 01096 outputFile << static_cast< float >( buffer[ii * numberOfPixelComponents + jj] ) << indent; 01097 } 01098 01099 outputFile << "\n"; 01100 } 01101 01102 return; 01103 } 01104 01105 template< typename T > 01106 void WriteColorScalarBufferAsBINARY(std::ofstream & outputFile, 01107 T *buffer, 01108 unsigned int numberOfPixelComponents, 01109 SizeValueType numberOfPixels) 01110 { 01111 outputFile << numberOfPixelComponents << "\n"; 01112 SizeValueType numberOfElements = numberOfPixelComponents * numberOfPixels; 01113 unsigned char *data = new unsigned char[numberOfElements]; 01114 for ( SizeValueType ii = 0; ii < numberOfElements; ++ii ) 01115 { 01116 data[ii] = static_cast< unsigned char >( buffer[ii] ); 01117 } 01118 01119 outputFile.write(reinterpret_cast< char * >( data ), numberOfElements); 01120 01121 delete[] data; 01122 outputFile << "\n"; 01123 return; 01124 } 01125 01128 template< typename TInput, typename TOutput > 01129 void ReadCellsBuffer(TInput *input, TOutput *output) 01130 { 01131 SizeValueType inputIndex = 0; 01132 SizeValueType outputIndex = 0; 01133 01134 if ( input && output ) 01135 { 01136 for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ ) 01137 { 01138 inputIndex++; 01139 unsigned int nn = static_cast< unsigned int >( input[inputIndex++] ); 01140 output[outputIndex++] = nn; 01141 for ( unsigned int jj = 0; jj < nn; jj++ ) 01142 { 01143 output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] ); 01144 } 01145 } 01146 } 01147 } 01148 01149 private: 01150 VTKPolyDataMeshIO(const Self &); // purposely not implemented 01151 void operator=(const Self &); // purposely not implemented 01152 }; 01153 } // end namespace itk 01154 01155 #endif // __itkVTKPolyDataMeshIO_h 01156