ITK  4.3.0
Insight Segmentation and Registration Toolkit
itkVTKPolyDataMeshIO.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkVTKPolyDataMeshIO_h
19 #define __itkVTKPolyDataMeshIO_h
20 
21 #include "itkByteSwapper.h"
22 #include "itkMetaDataObject.h"
23 #include "itkMeshIOBase.h"
24 #include "itkVectorContainer.h"
25 
26 #include <fstream>
27 #include <vector>
28 
29 namespace itk
30 {
38 class ITK_EXPORT VTKPolyDataMeshIO:public MeshIOBase
39 {
40 public:
46 
48 
49  typedef std::string StringType;
50  typedef std::vector< StringType > StringVectorType;
51  typedef std::stringstream StringStreamType;
52  typedef std::vector< SizeValueType > PointIdVector;
55 
57  itkNewMacro(Self);
58 
60  itkTypeMacro(VTKPolyDataMeshIO, MeshIOBase);
61 
69  virtual bool CanReadFile(const char *FileNameToRead);
70 
72  virtual void ReadMeshInformation();
73 
75  virtual void ReadPoints(void *buffer);
76 
77  virtual void ReadCells(void *buffer);
78 
79  virtual void ReadPointData(void *buffer);
80 
81  virtual void ReadCellData(void *buffer);
82 
83  /*-------- This part of the interfaces deals with writing data. ----- */
89  virtual bool CanWriteFile(const char *FileNameToWrite);
90 
92  virtual void WriteMeshInformation();
93 
96  virtual void WritePoints(void *buffer);
97 
98  virtual void WriteCells(void *buffer);
99 
100  virtual void WritePointData(void *buffer);
101 
102  virtual void WriteCellData(void *buffer);
103 
104  virtual void Write();
105 
106 protected:
108  virtual ~VTKPolyDataMeshIO() {}
109 
110  void PrintSelf(std::ostream & os, Indent indent) const;
111 
112  template< typename T >
113  void UpdateCellInformation(T *buffer)
114  {
115  unsigned int numberOfVertices = 0;
116  unsigned int numberOfVertexIndices = 0;
117  unsigned int numberOfLines = 0;
118  unsigned int numberOfLineIndices = 0;
119  unsigned int numberOfPolygons = 0;
120  unsigned int numberOfPolygonIndices = 0;
121 
122  SizeValueType index = 0;
123 
124  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
125  {
126  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) );
127  unsigned int nn = static_cast< unsigned int >( buffer[index++] );
128  switch ( cellType )
129  {
130  case VERTEX_CELL:
131  numberOfVertices++;
132  numberOfVertexIndices += nn + 1;
133  break;
134  case LINE_CELL:
135  numberOfLines++;
136  numberOfLineIndices += nn + 1;
137  break;
138  case TRIANGLE_CELL:
139  numberOfPolygons++;
140  numberOfPolygonIndices += nn + 1;
141  break;
142  case POLYGON_CELL:
143  numberOfPolygons++;
144  numberOfPolygonIndices += nn + 1;
145  break;
146  case QUADRILATERAL_CELL:
147  numberOfPolygons++;
148  numberOfPolygonIndices += nn + 1;
149  break;
150  default:
151  itkExceptionMacro(<< "Currently we dont support this cell type");
152  }
153 
154  index += nn;
155  }
156 
157  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
158  EncapsulateMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices);
159  EncapsulateMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices);
160  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines);
161  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices);
162  EncapsulateMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons);
163  EncapsulateMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices);
164  return;
165  }
166 
167  template< typename T >
168  void ReadPointsBufferAsASCII(std::ifstream & inputFile, T *buffer)
169  {
170  std::string line;
171 
172  while ( !inputFile.eof() )
173  {
174  std::getline(inputFile, line, '\n');
175 
176  if ( line.find("POINTS") != std::string::npos )
177  {
179  SizeValueType numberOfComponents = this->m_NumberOfPoints * this->m_PointDimension;
180  for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ )
181  {
182  inputFile >> buffer[ii];
183  }
184  }
185  }
186  }
187 
188  template< typename T >
189  void ReadPointsBufferAsBINARY(std::ifstream & inputFile, T *buffer)
190  {
191  std::string line;
192 
193  while ( !inputFile.eof() )
194  {
195  std::getline(inputFile, line, '\n');
196 
197  if ( line.find("POINTS") != std::string::npos )
198  {
200  SizeValueType numberOfComponents = this->m_NumberOfPoints * this->m_PointDimension;
201  inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) );
203  {
204  itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents);
205  }
206  }
207  }
208  }
210 
211  void ReadCellsBufferAsASCII(std::ifstream & inputFile, void *buffer);
212 
213  void ReadCellsBufferAsBINARY(std::ifstream & inputFile, void *buffer);
214 
215  template< typename T >
216  void ReadPointDataBufferAsASCII(std::ifstream & inputFile, T *buffer)
217  {
218  StringType line;
219 
220  while ( !inputFile.eof() )
221  {
222  std::getline(inputFile, line, '\n');
223  if ( line.find("POINT_DATA") != std::string::npos )
224  {
225  if ( !inputFile.eof() )
226  {
227  std::getline(inputFile, line, '\n');
228  }
229  else
230  {
231  itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA");
232  }
233 
235  if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos )
236  {
237  if ( !inputFile.eof() )
238  {
239  std::getline(inputFile, line, '\n');
240  if ( line.find("LOOKUP_TABLE") == std::string::npos )
241  {
242  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
243  }
244  }
245  else
246  {
247  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
248  }
249  }
251 
253  SizeValueType numberOfComponents = this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents;
254  for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ )
255  {
256  inputFile >> buffer[ii];
257  }
258  }
259  }
260  }
261 
262  template< typename T >
263  void ReadPointDataBufferAsBINARY(std::ifstream & inputFile, T *buffer)
264  {
265  StringType line;
266 
267  while ( !inputFile.eof() )
268  {
269  std::getline(inputFile, line, '\n');
270  if ( line.find("POINT_DATA") != std::string::npos )
271  {
272  if ( !inputFile.eof() )
273  {
274  std::getline(inputFile, line, '\n');
275  }
276  else
277  {
278  itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA");
279  }
280 
282  if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos )
283  {
284  if ( !inputFile.eof() )
285  {
286  std::getline(inputFile, line, '\n');
287  if ( line.find("LOOKUP_TABLE") == std::string::npos )
288  {
289  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
290  }
291  }
292  else
293  {
294  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
295  }
296  }
298 
300  SizeValueType numberOfComponents = this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents;
301  inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) );
303  {
304  itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents);
305  }
306  }
307  }
308  }
310 
311  template< typename T >
312  void ReadCellDataBufferAsASCII(std::ifstream & inputFile, T *buffer)
313  {
314  StringType line;
315 
316  while ( !inputFile.eof() )
317  {
318  std::getline(inputFile, line, '\n');
319  if ( line.find("CELL_DATA") != std::string::npos )
320  {
321  if ( !inputFile.eof() )
322  {
323  std::getline(inputFile, line, '\n');
324  }
325  else
326  {
327  itkExceptionMacro("UnExpected end of line while trying to read CELL_DATA");
328  }
329 
331  if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos )
332  {
333  if ( !inputFile.eof() )
334  {
335  std::getline(inputFile, line, '\n');
336  if ( line.find("LOOKUP_TABLE") == std::string::npos )
337  {
338  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
339  }
340  }
341  else
342  {
343  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
344  }
345  }
347 
349  SizeValueType numberOfComponents = this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents;
350  for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ )
351  {
352  inputFile >> buffer[ii];
353  }
354  }
355  }
356  }
357 
358  template< typename T >
359  void ReadCellDataBufferAsBINARY(std::ifstream & inputFile, T *buffer)
360  {
361  StringType line;
362 
363  while ( !inputFile.eof() )
364  {
365  std::getline(inputFile, line, '\n');
366  if ( line.find("POINT_DATA") != std::string::npos )
367  {
368  if ( !inputFile.eof() )
369  {
370  std::getline(inputFile, line, '\n');
371  }
372  else
373  {
374  itkExceptionMacro("UnExpected end of line while trying to read POINT_DATA");
375  }
376 
378  if ( line.find("SCALARS") != std::string::npos && line.find("COLOR_SCALARS") == std::string::npos )
379  {
380  if ( !inputFile.eof() )
381  {
382  std::getline(inputFile, line, '\n');
383  if ( line.find("LOOKUP_TABLE") == std::string::npos )
384  {
385  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
386  }
387  }
388  else
389  {
390  itkExceptionMacro("UnExpected end of line while trying to read LOOKUP_TABLE");
391  }
392  }
393 
395  SizeValueType numberOfComponents = this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents;
396  inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) );
398  {
399  itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents);
400  }
401  }
402  }
403  }
405 
406  template< typename T >
407  void WritePointsBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & pointComponentType)
408  {
410  outputFile << "POINTS " << this->m_NumberOfPoints;
411 
412  outputFile << pointComponentType << '\n';
413  for ( SizeValueType ii = 0; ii < this->m_NumberOfPoints; ii++ )
414  {
415  for ( unsigned int jj = 0; jj < this->m_PointDimension - 1; jj++ )
416  {
417  outputFile << buffer[ii * this->m_PointDimension + jj] << " ";
418  }
419 
420  outputFile << buffer[ii * this->m_PointDimension + this->m_PointDimension - 1] << '\n';
421  }
422 
423  return;
424  }
425 
426  template< typename T >
427  void WritePointsBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & pointComponentType)
428  {
430  outputFile << "POINTS " << this->m_NumberOfPoints;
431  outputFile << pointComponentType << "\n";
432  itk::ByteSwapper< T >::SwapWriteRangeFromSystemToBigEndian(buffer, this->m_NumberOfPoints * this->m_PointDimension, &outputFile);
433  outputFile << "\n";
434 
435  return;
436  }
437 
438  template< typename T >
439  void WriteCellsBufferAsASCII(std::ofstream & outputFile, T *buffer)
440  {
441  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
442  unsigned int numberOfVertices = 0;
443  unsigned int numberOfVertexIndices = 0;
444  unsigned int numberOfLines = 0;
445  unsigned int numberOfLineIndices = 0;
446  unsigned int numberOfPolygons = 0;
447  unsigned int numberOfPolygonIndices = 0;
448 
450  SizeValueType index = 0;
451 
452  ExposeMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices);
453  if ( numberOfVertices )
454  {
455  ExposeMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices);
456  outputFile << "VERTICES " << numberOfVertices << " " << numberOfVertexIndices << '\n';
457  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
458  {
459  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) );
460  unsigned int nn = static_cast< unsigned int >( buffer[index++] );
461  if ( cellType == VERTEX_CELL )
462  {
463  outputFile << nn;
464  for ( unsigned int jj = 0; jj < nn; jj++ )
465  {
466  outputFile << " " << buffer[index++];
467  }
468  outputFile << '\n';
469  }
470  else
471  {
472  index += nn;
473  }
474  }
475  }
476 
478  index = 0;
479  ExposeMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines);
480  if ( numberOfLines )
481  {
482  numberOfLineIndices = 0;
483  SizeValueType numberOfPolylines = 0;
484  PolylinesContainerPointer polylines = PolylinesContainerType::New();
485  PointIdVector pointIds;
486  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
487  {
488  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) );
489  unsigned int nn = static_cast< unsigned int >( buffer[index++] );
490  if ( cellType == LINE_CELL )
491  {
492  if ( pointIds.size() >= nn )
493  {
494  SizeValueType id = pointIds.back();
495  if ( id == static_cast< SizeValueType >( buffer[index] ) )
496  {
497  pointIds.push_back( static_cast< SizeValueType >( buffer[index + 1] ) );
498  }
499  else if ( id == static_cast< SizeValueType >( buffer[index + 1] ) )
500  {
501  pointIds.push_back( static_cast< SizeValueType >( buffer[index] ) );
502  }
503  else
504  {
505  polylines->InsertElement(numberOfPolylines++, pointIds);
506  numberOfLineIndices += pointIds.size();
507  pointIds.clear();
509 
510  for ( unsigned int jj = 0; jj < nn; jj++ )
511  {
512  pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) );
513  }
514  }
515  }
516  else
517  {
518  for ( unsigned int jj = 0; jj < nn; jj++ )
519  {
520  pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) );
521  }
522  }
523  }
524 
525  index += nn;
526  }
527  polylines->InsertElement(numberOfPolylines++, pointIds);
528  numberOfLineIndices += pointIds.size();
529  pointIds.clear();
530 
531  numberOfLines = polylines->Size();
532  numberOfLineIndices += numberOfLines;
533  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines);
534  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices);
535  outputFile << "LINES " << numberOfLines << " " << numberOfLineIndices << '\n';
536  for ( SizeValueType ii = 0; ii < polylines->Size(); ++ii )
537  {
538  unsigned int nn = polylines->ElementAt(ii).size();
539  outputFile << nn;
540  for ( unsigned int jj = 0; jj < nn; ++jj )
541  {
542  outputFile << " " << polylines->ElementAt(ii)[jj];
543  }
544  outputFile << '\n';
545  }
546  }
547 
549  index = 0;
550  ExposeMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons);
551  if ( numberOfPolygons )
552  {
553  ExposeMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices);
554  outputFile << "POLYGONS " << numberOfPolygons << " " << numberOfPolygonIndices << '\n';
555  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
556  {
557  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) );
558  unsigned int nn = static_cast< unsigned int >( buffer[index++] );
559  if ( cellType == POLYGON_CELL ||
560  cellType == TRIANGLE_CELL ||
561  cellType == QUADRILATERAL_CELL )
562  {
563  outputFile << nn;
564  for ( unsigned int jj = 0; jj < nn; jj++ )
565  {
566  outputFile << " " << buffer[index++];
567  }
568  outputFile << '\n';
569  }
570  else
571  {
572  index += nn;
573  }
574  }
575  }
576  }
578 
579  template< typename T >
580  void WriteCellsBufferAsBINARY(std::ofstream & outputFile, T *buffer)
581  {
582  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
583  unsigned int numberOfVertices = 0;
584  unsigned int numberOfVertexIndices = 0;
585  unsigned int numberOfLines = 0;
586  unsigned int numberOfLineIndices = 0;
587  unsigned int numberOfPolygons = 0;
588  unsigned int numberOfPolygonIndices = 0;
589 
591  SizeValueType index = 0;
592 
593  ExposeMetaData< unsigned int >(metaDic, "numberOfVertices", numberOfVertices);
594  if ( numberOfVertices )
595  {
596  ExposeMetaData< unsigned int >(metaDic, "numberOfVertexIndices", numberOfVertexIndices);
597  outputFile << "VERTICES " << numberOfVertices << " " << numberOfVertexIndices << '\n';
598  unsigned int *data = new unsigned int[numberOfVertexIndices];
599  ReadCellsBuffer(buffer, data);
600  itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfVertexIndices, &outputFile);
601  outputFile << "\n";
602  delete[] data;
603  }
604 
606  index = 0;
607  ExposeMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines);
608  if ( numberOfLines )
609  {
610  numberOfLineIndices = 0;
611  SizeValueType numberOfPolylines = 0;
612  PolylinesContainerPointer polylines = PolylinesContainerType::New();
613  PointIdVector pointIds;
614  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
615  {
616  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( static_cast< int >( buffer[index++] ) );
617  unsigned int nn = static_cast< unsigned int >( buffer[index++] );
618  if ( cellType == LINE_CELL )
619  {
620  if ( pointIds.size() >= nn )
621  {
622  SizeValueType id = pointIds.back();
623  if ( id == static_cast< SizeValueType >( buffer[index] ) )
624  {
625  pointIds.push_back( static_cast< SizeValueType >( buffer[index + 1] ) );
626  }
627  else if ( id == static_cast< SizeValueType >( buffer[index + 1] ) )
628  {
629  pointIds.push_back( static_cast< SizeValueType >( buffer[index] ) );
630  }
631  else
632  {
633  polylines->InsertElement(numberOfPolylines++, pointIds);
634  numberOfLineIndices += pointIds.size();
635  pointIds.clear();
637 
638  for ( unsigned int jj = 0; jj < nn; jj++ )
639  {
640  pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) );
641  }
642  }
643  }
644  else
645  {
646  for ( unsigned int jj = 0; jj < nn; jj++ )
647  {
648  pointIds.push_back( static_cast< SizeValueType >( buffer[index + jj] ) );
649  }
650  }
651  }
652 
653  index += nn;
654  }
655  polylines->InsertElement(numberOfPolylines++, pointIds);
656  numberOfLineIndices += pointIds.size();
657  pointIds.clear();
658 
659  numberOfLines = polylines->Size();
660  numberOfLineIndices += numberOfLines;
661  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLines", numberOfLines);
662  EncapsulateMetaData< unsigned int >(metaDic, "numberOfLineIndices", numberOfLineIndices);
663 
664  outputFile << "LINES " << numberOfLines << " " << numberOfLineIndices << '\n';
665  unsigned int *data = new unsigned int[numberOfLineIndices];
666  unsigned long outputIndex = 0;
667  for ( SizeValueType ii = 0; ii < polylines->Size(); ++ii )
668  {
669  unsigned int nn = polylines->ElementAt(ii).size();
670  data[outputIndex++] = nn;
671  for ( unsigned int jj = 0; jj < nn; ++jj )
672  {
673  data[outputIndex++] = polylines->ElementAt(ii)[jj];
674  }
675  }
676 
677  itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfLineIndices, &outputFile);
678  outputFile << "\n";
679  delete[] data;
680  }
681 
683  index = 0;
684  ExposeMetaData< unsigned int >(metaDic, "numberOfPolygons", numberOfPolygons);
685  if ( numberOfPolygons )
686  {
687  ExposeMetaData< unsigned int >(metaDic, "numberOfPolygonIndices", numberOfPolygonIndices);
688  outputFile << "POLYGONS " << numberOfPolygons << " " << numberOfPolygonIndices << '\n';
689  unsigned int *data = new unsigned int[numberOfPolygonIndices];
690  ReadCellsBuffer(buffer, data);
691  itk::ByteSwapper< unsigned int >::SwapWriteRangeFromSystemToBigEndian(data, numberOfPolygonIndices, &outputFile);
692  outputFile << "\n";
693  delete[] data;
694  }
695  }
697 
698  template< typename T >
699  void WritePointDataBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & pointPixelComponentName)
700  {
701  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
702  StringType dataName;
703 
704  outputFile << "POINT_DATA " << this->m_NumberOfPointPixels << '\n';
705  switch ( this->m_PointPixelType )
706  {
707  case SCALAR:
708  {
709  outputFile << "SCALARS ";
710  ExposeMetaData< StringType >(metaDic, "pointScalarDataName", dataName);
711  outputFile << dataName << " ";
712  break;
713  }
714  case OFFSET:
715  case POINT:
716  case COVARIANTVECTOR:
717  case VECTOR:
718  {
719  outputFile << "VECTORS ";
720  ExposeMetaData< StringType >(metaDic, "pointVectorDataName", dataName);
721  outputFile << dataName << " ";
722  break;
723  }
724  case SYMMETRICSECONDRANKTENSOR:
725  case DIFFUSIONTENSOR3D:
726  {
727  outputFile << "TENSORS ";
728  ExposeMetaData< StringType >(metaDic, "pointTensorDataName", dataName);
729  outputFile << dataName << " ";
730  break;
731  }
732  case ARRAY:
733  case VARIABLELENGTHVECTOR:
734  {
735  outputFile << "COLOR_SCALARS ";
736  ExposeMetaData< StringType >(metaDic, "pointColorScalarDataName", dataName);
737  outputFile << dataName << " ";
738  WriteColorScalarBufferAsASCII(outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels);
739  return;
740  }
741  default:
742  {
743  itkExceptionMacro(<< "Unknown point pixel type");
744  }
745  }
746 
747  outputFile << pointPixelComponentName << '\n';
748 
749  if ( this->m_PointPixelType == SCALAR )
750  {
751  outputFile << "LOOKUP_TABLE default" << '\n';
752  }
753 
754  Indent indent(2);
755  if ( this->m_PointPixelType == SYMMETRICSECONDRANKTENSOR )
756  {
757  T *ptr = buffer;
758  SizeValueType i = 0;
759  const SizeValueType num = this->m_NumberOfPointPixelComponents * this->m_NumberOfPointPixels;
760  // Note that only the 3D tensors are supported in the VTK File Format
761  // documentation.
762  if( this->m_NumberOfPointPixelComponents == 3 )
763  {
764  T zero( itk::NumericTraits<T>::Zero );
765  T e12;
766  while( i < num )
767  {
768  // row 1
769  outputFile << *ptr++ << indent;
770  e12 = *ptr++;
771  outputFile << e12 << indent;
772  outputFile << zero << '\n';
773  // row 2
774  outputFile << e12 << indent;
775  outputFile << *ptr++ << indent;
776  outputFile << zero << '\n';
777  // row 3
778  outputFile << zero << indent << zero << indent << zero << "\n\n";
779  i += 3;
780  }
781  }
782  else if( this->m_NumberOfPointPixelComponents == 6 )
783  {
784  T e12;
785  T e13;
786  T e23;
787  while( i < num )
788  {
789  // row 1
790  outputFile << *ptr++ << indent;
791  e12 = *ptr++;
792  outputFile << e12 << indent;
793  e13 = *ptr++;
794  outputFile << e13 << '\n';
795  // row 2
796  outputFile << e12 << indent;
797  outputFile << *ptr++ << indent;
798  e23 = *ptr++;
799  outputFile << e23 << '\n';
800  // row 3
801  outputFile << e13 << indent;
802  outputFile << e23 << indent;
803  outputFile << *ptr++ << "\n\n";
804  i += 6;
805  }
806  }
807  else
808  {
809  ::itk::ExceptionObject e_(__FILE__, __LINE__,
810  "itk::ERROR: VTKImageIO2: Unsupported number of components in tensor.",
811  ITK_LOCATION);
812  throw e_;
813  }
814  }
815  else // not tensor
816  {
817  unsigned int jj;
818  for ( SizeValueType ii = 0; ii < this->m_NumberOfPointPixels; ii++ )
819  {
820  for ( jj = 0; jj < this->m_NumberOfPointPixelComponents - 1; jj++ )
821  {
822  outputFile << buffer[ii * this->m_NumberOfPointPixelComponents + jj] << indent;
823  }
824  outputFile << buffer[ii * this->m_NumberOfPointPixelComponents + jj];
825  outputFile << '\n';
826  }
827  }
828 
829  return;
830  }
831 
832  template< typename T >
833  void WritePointDataBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & pointPixelComponentName)
834  {
835  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
836  StringType dataName;
837 
838  outputFile << "POINT_DATA " << this->m_NumberOfPointPixels << "\n";
839  switch ( this->m_PointPixelType )
840  {
841  case SCALAR:
842  {
843  outputFile << "SCALARS ";
844  ExposeMetaData< StringType >(metaDic, "pointScalarDataName", dataName);
845  outputFile << dataName << " ";
846  break;
847  }
848  case OFFSET:
849  case POINT:
850  case COVARIANTVECTOR:
851  case VECTOR:
852  {
853  outputFile << "VECTORS ";
854  ExposeMetaData< StringType >(metaDic, "pointVectorDataName", dataName);
855  outputFile << dataName << " ";
856  break;
857  }
858  case SYMMETRICSECONDRANKTENSOR:
859  case DIFFUSIONTENSOR3D:
860  {
861  outputFile << "TENSORS ";
862  ExposeMetaData< StringType >(metaDic, "pointTensorDataName", dataName);
863  outputFile << dataName << " ";
864  break;
865  }
866  case ARRAY:
867  case VARIABLELENGTHVECTOR:
868  {
869  outputFile << "COLOR_SCALARS ";
870  ExposeMetaData< StringType >(metaDic, "pointColorScalarDataName", dataName);
871  outputFile << dataName << " ";
872  WriteColorScalarBufferAsBINARY(outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels);
873  return;
874  }
875  default:
876  {
877  itkExceptionMacro(<< "Unknown point pixel type");
878  }
879  }
880 
881  outputFile << pointPixelComponentName << "\n";
882  if ( this->m_PointPixelType == SCALAR )
883  {
884  outputFile << "LOOKUP_TABLE default\n";
885  }
886 
888  this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents,
889  &outputFile);
890  outputFile << "\n";
891  return;
892  }
893 
894  template< typename T >
895  void WriteCellDataBufferAsASCII(std::ofstream & outputFile, T *buffer, const StringType & cellPixelComponentName)
896  {
897  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
898  StringType dataName;
899 
900  outputFile << "CELL_DATA " << this->m_NumberOfCellPixels << '\n';
901  switch ( this->m_CellPixelType )
902  {
903  case SCALAR:
904  {
905  outputFile << "SCALARS ";
906  ExposeMetaData< StringType >(metaDic, "cellScalarDataName", dataName);
907  outputFile << dataName << " ";
908  break;
909  }
910  case OFFSET:
911  case POINT:
912  case COVARIANTVECTOR:
913  case VECTOR:
914  {
915  outputFile << "VECTORS ";
916  ExposeMetaData< StringType >(metaDic, "cellVectorDataName", dataName);
917  outputFile << dataName << " ";
918  break;
919  }
920  case SYMMETRICSECONDRANKTENSOR:
921  case DIFFUSIONTENSOR3D:
922  {
923  outputFile << "TENSORS ";
924  ExposeMetaData< StringType >(metaDic, "cellTensorDataName", dataName);
925  outputFile << dataName << " ";
926  break;
927  }
928  case ARRAY:
929  case VARIABLELENGTHVECTOR:
930  {
931  outputFile << "COLOR_SCALARS ";
932  ExposeMetaData< StringType >(metaDic, "cellColorScalarDataName", dataName);
933  outputFile << dataName << " ";
934  WriteColorScalarBufferAsASCII(outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels);
935  return;
936  }
937  default:
938  {
939  itkExceptionMacro(<< "Unknown cell pixel type");
940  }
941  }
942 
943  outputFile << cellPixelComponentName << '\n';
944  if ( this->m_CellPixelType == SCALAR )
945  {
946  outputFile << "LOOKUP_TABLE default" << '\n';
947  }
948 
949  Indent indent(2);
950  if ( this->m_CellPixelType == SYMMETRICSECONDRANKTENSOR )
951  {
952  T *ptr = buffer;
953  SizeValueType i = 0;
954  const SizeValueType num = this->m_NumberOfCellPixelComponents * this->m_NumberOfCellPixels;
955  if( this->m_NumberOfCellPixelComponents == 3 )
956  {
957  T zero( itk::NumericTraits<T>::Zero );
958  T e12;
959  while( i < num )
960  {
961  // row 1
962  outputFile << *ptr++ << indent;
963  e12 = *ptr++;
964  outputFile << e12 << indent;
965  outputFile << zero << '\n';
966  // row 2
967  outputFile << e12 << indent;
968  outputFile << *ptr++ << indent;
969  outputFile << zero << '\n';
970  // row 3
971  outputFile << zero << indent << zero << indent << zero << "\n\n";
972  i += 3;
973  }
974  }
975  else if( this->m_NumberOfCellPixelComponents == 3 )
976  {
977  T e12;
978  T e13;
979  T e23;
980  while( i < num )
981  {
982  // row 1
983  outputFile << *ptr++ << indent;
984  e12 = *ptr++;
985  outputFile << e12 << indent;
986  e13 = *ptr++;
987  outputFile << e13 << '\n';
988  // row 2
989  outputFile << e12 << indent;
990  outputFile << *ptr++ << indent;
991  e23 = *ptr++;
992  outputFile << e23 << '\n';
993  // row 3
994  outputFile << e13 << indent;
995  outputFile << e23 << indent;
996  outputFile << *ptr++ << "\n\n";
997  i += 6;
998  }
999  }
1000  else
1001  {
1002  ::itk::ExceptionObject e_(__FILE__, __LINE__,
1003  "itk::ERROR: VTKPolyDataMeshIO: Unsupported number of components in tensor.",
1004  ITK_LOCATION);
1005  throw e_;
1006  }
1007  }
1008  else // not tensor
1009  {
1010  unsigned int jj;
1011  for ( SizeValueType ii = 0; ii < this->m_NumberOfCellPixels; ii++ )
1012  {
1013  for ( jj = 0; jj < this->m_NumberOfCellPixelComponents - 1; jj++ )
1014  {
1015  outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj] << indent;
1016  }
1017  outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj];
1018  outputFile << '\n';
1019  }
1020  }
1021 
1022  return;
1023  }
1024 
1025  template< typename T >
1026  void WriteCellDataBufferAsBINARY(std::ofstream & outputFile, T *buffer, const StringType & cellPixelComponentName)
1027  {
1028  MetaDataDictionary & metaDic = this->GetMetaDataDictionary();
1029  StringType dataName;
1030 
1031  outputFile << "CELL_DATA " << this->m_NumberOfCellPixels << "\n";
1032  switch ( this->m_CellPixelType )
1033  {
1034  case SCALAR:
1035  {
1036  outputFile << "SCALARS ";
1037  ExposeMetaData< StringType >(metaDic, "cellScalarDataName", dataName);
1038  outputFile << dataName << " ";
1039  break;
1040  }
1041  case OFFSET:
1042  case POINT:
1043  case COVARIANTVECTOR:
1044  case VECTOR:
1045  {
1046  outputFile << "VECTORS ";
1047  ExposeMetaData< StringType >(metaDic, "cellVectorDataName", dataName);
1048  outputFile << dataName << " ";
1049  break;
1050  }
1051  case SYMMETRICSECONDRANKTENSOR:
1052  case DIFFUSIONTENSOR3D:
1053  {
1054  outputFile << "TENSORS ";
1055  ExposeMetaData< StringType >(metaDic, "cellTensorDataName", dataName);
1056  outputFile << dataName << " ";
1057  break;
1058  }
1059  case ARRAY:
1060  case VARIABLELENGTHVECTOR:
1061  {
1062  outputFile << "COLOR_SCALARS ";
1063  ExposeMetaData< StringType >(metaDic, "cellColorScalarDataName", dataName);
1064  outputFile << dataName << " ";
1065  WriteColorScalarBufferAsBINARY(outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels);
1066  return;
1067  }
1068  default:
1069  {
1070  itkExceptionMacro(<< "Unknown cell pixel type");
1071  }
1072  }
1073 
1074  outputFile << cellPixelComponentName << "\n";
1075  if ( this->m_CellPixelType == SCALAR )
1076  {
1077  outputFile << "LOOKUP_TABLE default\n";
1078  }
1079 
1081  this->m_NumberOfCells * this->m_NumberOfCellPixelComponents,
1082  &outputFile);
1083  outputFile << "\n";
1084  return;
1085  }
1086 
1087  template< typename T >
1088  void WriteColorScalarBufferAsASCII(std::ofstream & outputFile,
1089  T *buffer,
1090  unsigned int numberOfPixelComponents,
1091  SizeValueType numberOfPixels)
1092  {
1093  outputFile << numberOfPixelComponents << "\n";
1094  Indent indent(2);
1095  for ( SizeValueType ii = 0; ii < numberOfPixels; ++ii )
1096  {
1097  for ( unsigned int jj = 0; jj < numberOfPixelComponents; ++jj )
1098  {
1099  outputFile << static_cast< float >( buffer[ii * numberOfPixelComponents + jj] ) << indent;
1100  }
1101 
1102  outputFile << "\n";
1103  }
1104 
1105  return;
1106  }
1107 
1108  template< typename T >
1109  void WriteColorScalarBufferAsBINARY(std::ofstream & outputFile,
1110  T *buffer,
1111  unsigned int numberOfPixelComponents,
1112  SizeValueType numberOfPixels)
1113  {
1114  outputFile << numberOfPixelComponents << "\n";
1115  SizeValueType numberOfElements = numberOfPixelComponents * numberOfPixels;
1116  unsigned char *data = new unsigned char[numberOfElements];
1117  for ( SizeValueType ii = 0; ii < numberOfElements; ++ii )
1118  {
1119  data[ii] = static_cast< unsigned char >( buffer[ii] );
1120  }
1121 
1122  outputFile.write(reinterpret_cast< char * >( data ), numberOfElements);
1123 
1124  delete[] data;
1125  outputFile << "\n";
1126  return;
1127  }
1128 
1131  template< typename TInput, typename TOutput >
1132  void ReadCellsBuffer(TInput *input, TOutput *output)
1133  {
1134  SizeValueType inputIndex = 0;
1135  SizeValueType outputIndex = 0;
1136 
1137  if ( input && output )
1138  {
1139  for ( SizeValueType ii = 0; ii < this->m_NumberOfCells; ii++ )
1140  {
1141  inputIndex++;
1142  unsigned int nn = static_cast< unsigned int >( input[inputIndex++] );
1143  output[outputIndex++] = nn;
1144  for ( unsigned int jj = 0; jj < nn; jj++ )
1145  {
1146  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
1147  }
1148  }
1149  }
1150  }
1151 
1152 private:
1153  VTKPolyDataMeshIO(const Self &); // purposely not implemented
1154  void operator=(const Self &); // purposely not implemented
1155 };
1156 } // end namespace itk
1157 
1158 #endif // __itkVTKPolyDataMeshIO_h
1159