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