ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkVTKPolyDataMeshIO.h
Go to the documentation of this file.
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