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