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