ITK  4.4.0
Insight Segmentation and Registration Toolkit
itkMeshIOBase.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 __itkMeshIOBase_h
19 #define __itkMeshIOBase_h
20 
21 #include "itkByteSwapper.h"
22 #include "itkCellInterface.h"
23 #include "itkCovariantVector.h"
24 #include "itkDiffusionTensor3D.h"
25 #include "itkIntTypes.h"
26 #include "itkLightProcessObject.h"
27 #include "itkMatrix.h"
28 #include "itkRGBPixel.h"
29 #include "itkRGBAPixel.h"
32 #include "itkVariableSizeMatrix.h"
33 #include "itkVector.h"
34 #include "itkNumberToString.h"
35 
36 #include <string>
37 #include <complex>
38 #include <fstream>
39 
40 namespace itk
41 {
68 class ITK_EXPORT MeshIOBase:public LightProcessObject
69 {
70 public:
72  typedef MeshIOBase Self;
76 
78  typedef std::vector< std::string > ArrayOfExtensionsType;
79 
81  typedef std::streamoff StreamOffsetType;
82 
84 
90  class UnknownType {};
91 
93  itkTypeMacro(MeshIOBase, LightProcessObject);
94 
96  itkSetStringMacro(FileName);
97  itkGetStringMacro(FileName);
99 
103  typedef enum {UNKNOWNPIXELTYPE, SCALAR, RGB, RGBA, OFFSET, VECTOR,
104  POINT, COVARIANTVECTOR, SYMMETRICSECONDRANKTENSOR,
105  DIFFUSIONTENSOR3D, COMPLEX, FIXEDARRAY, ARRAY, MATRIX,
106  VARIABLELENGTHVECTOR, VARIABLESIZEMATRIX} IOPixelType;
107 
111  typedef enum {UNKNOWNCOMPONENTTYPE, UCHAR, CHAR, USHORT, SHORT, UINT, INT,
112  ULONG, LONG, LONGLONG, ULONGLONG, FLOAT, DOUBLE, LDOUBLE} IOComponentType;
113 
116  typedef enum {ASCII, BINARY, TYPENOTAPPLICABLE} FileType;
117 
120  typedef enum {BigEndian, LittleEndian, OrderNotApplicable} ByteOrder;
121 
123  typedef enum {VERTEX_CELL = 0, LINE_CELL, TRIANGLE_CELL,
124  QUADRILATERAL_CELL, POLYGON_CELL, TETRAHEDRON_CELL, HEXAHEDRON_CELL,
125  QUADRATIC_EDGE_CELL, QUADRATIC_TRIANGLE_CELL,
126  LAST_ITK_CELL, MAX_ITK_CELLS = 255} CellGeometryType;
127 
133  itkSetEnumMacro(PointPixelType, IOPixelType);
134  itkGetEnumMacro(PointPixelType, IOPixelType);
135  itkSetEnumMacro(CellPixelType, IOPixelType);
136  itkGetEnumMacro(CellPixelType, IOPixelType);
138 
141  itkSetEnumMacro(PointComponentType, IOComponentType);
142  itkGetEnumMacro(PointComponentType, IOComponentType);
143  itkSetEnumMacro(CellComponentType, IOComponentType);
144  itkGetEnumMacro(CellComponentType, IOComponentType);
145  itkSetEnumMacro(PointPixelComponentType, IOComponentType);
146  itkGetEnumMacro(PointPixelComponentType, IOComponentType);
147  itkSetEnumMacro(CellPixelComponentType, IOComponentType);
148  itkGetEnumMacro(CellPixelComponentType, IOComponentType);
150 
151  template< typename T >
153  static const IOComponentType CType = UNKNOWNCOMPONENTTYPE;
154  };
155 
156  template< typename T >
157  void SetPixelType(const T & itkNotUsed(dummy), bool UsePointPixel = true)
158  {
159  if ( UsePointPixel )
160  {
161  SetNumberOfPointPixelComponents(1);
162  SetPointPixelComponentType(MapComponentType< T >::CType);
163  SetPointPixelType(SCALAR);
164  }
165  else
166  {
167  SetNumberOfCellPixelComponents(1);
168  SetCellPixelComponentType(MapComponentType< T >::CType);
169  SetCellPixelType(SCALAR);
170  }
171  }
172 
173  template< typename T >
174  void SetPixelType(const RGBPixel< T > & itkNotUsed(dummy), bool UsePointPixel = true)
175  {
176  if ( UsePointPixel )
177  {
178  SetNumberOfPointPixelComponents(3);
179  SetPointPixelComponentType(MapComponentType< T >::CType);
180  SetPointPixelType(RGB);
181  }
182  else
183  {
184  SetNumberOfCellPixelComponents(3);
185  SetCellPixelComponentType(MapComponentType< T >::CType);
186  SetCellPixelType(RGB);
187  }
188  }
189 
190  template< typename T >
191  void SetPixelType(const RGBAPixel< T > & itkNotUsed(dummy), bool UsePointPixel = true)
192  {
193  if ( UsePointPixel )
194  {
195  SetNumberOfPointPixelComponents(4);
196  SetPointPixelComponentType(MapComponentType< T >::CType);
197  SetPointPixelType(RGBA);
198  }
199  else
200  {
201  SetNumberOfCellPixelComponents(4);
202  SetCellPixelComponentType(MapComponentType< T >::CType);
203  SetCellPixelType(RGBA);
204  }
205  }
206 
207  template< typename T, unsigned int VLength >
208  void SetPixelType(const Vector< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
209  {
210  if ( UsePointPixel )
211  {
212  SetNumberOfPointPixelComponents(VLength);
213  SetPointPixelComponentType(MapComponentType< T >::CType);
214  SetPointPixelType(VECTOR);
215  }
216  else
217  {
218  SetNumberOfCellPixelComponents(VLength);
219  SetCellPixelComponentType(MapComponentType< T >::CType);
220  SetCellPixelType(VECTOR);
221  }
222  }
223 
224  template< typename T, unsigned int VLength >
225  void SetPixelType(const CovariantVector< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
226  {
227  if ( UsePointPixel )
228  {
229  SetNumberOfPointPixelComponents(VLength);
230  SetPointPixelComponentType(MapComponentType< T >::CType);
231  SetPointPixelType(COVARIANTVECTOR);
232  }
233  else
234  {
235  SetNumberOfCellPixelComponents(VLength);
236  SetCellPixelComponentType(MapComponentType< T >::CType);
237  SetCellPixelType(COVARIANTVECTOR);
238  }
239  }
240 
241  template< typename T, unsigned int VLength >
242  void SetPixelType(const FixedArray< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
243  {
244  if ( UsePointPixel )
245  {
246  SetNumberOfPointPixelComponents(VLength);
247  SetPointPixelComponentType(MapComponentType< T >::CType);
248  SetPointPixelType(FIXEDARRAY);
249  }
250  else
251  {
252  SetNumberOfCellPixelComponents(VLength);
253  SetCellPixelComponentType(MapComponentType< T >::CType);
254  SetCellPixelType(FIXEDARRAY);
255  }
256  }
257 
258  template< typename T, unsigned int VLength >
259  void SetPixelType(const SymmetricSecondRankTensor< T, VLength > itkNotUsed(dummy), bool UsePointPixel = true)
260  {
261  if ( UsePointPixel )
262  {
263  SetNumberOfPointPixelComponents(VLength * ( VLength + 1 ) / 2);
264  SetPointPixelComponentType(MapComponentType< T >::CType);
265  SetPointPixelType(SYMMETRICSECONDRANKTENSOR);
266  }
267  else
268  {
269  SetNumberOfCellPixelComponents(VLength * ( VLength + 1 ) / 2);
270  SetCellPixelComponentType(MapComponentType< T >::CType);
271  SetCellPixelType(SYMMETRICSECONDRANKTENSOR);
272  }
273  }
274 
275  template< typename T >
276  void SetPixelType(const DiffusionTensor3D< T > & itkNotUsed(dummy), bool UsePointPixel = true)
277  {
278  if ( UsePointPixel )
279  {
280  SetNumberOfPointPixelComponents(6);
281  SetPointPixelComponentType(MapComponentType< T >::CType);
282  SetPointPixelType(DIFFUSIONTENSOR3D);
283  }
284  else
285  {
286  SetNumberOfCellPixelComponents(6);
287  SetCellPixelComponentType(MapComponentType< T >::CType);
288  SetCellPixelType(DIFFUSIONTENSOR3D);
289  }
290  }
291 
292  template< typename T, unsigned int NR, unsigned int NC >
293  void SetPixelType(const Matrix< T, NR, NC > & itkNotUsed(dummy), bool UsePointPixel = true)
294  {
295  if ( UsePointPixel )
296  {
297  SetNumberOfPointPixelComponents(NR * NC);
298  SetPointPixelComponentType(MapComponentType< T >::CType);
299  SetPointPixelType(MATRIX);
300  }
301  else
302  {
303  SetNumberOfCellPixelComponents(NR * NC);
304  SetCellPixelComponentType(MapComponentType< T >::CType);
305  SetCellPixelType(MATRIX);
306  }
307  }
308 
309  template< typename T >
310  void SetPixelType(const std::complex< T > & itkNotUsed(dummy), bool UsePointPixel = true)
311  {
312  if ( UsePointPixel )
313  {
314  SetNumberOfPointPixelComponents(2);
315  SetPointPixelComponentType(MapComponentType< T >::CType);
316  SetPointPixelType(COMPLEX);
317  }
318  else
319  {
320  SetNumberOfCellPixelComponents(2);
321  SetCellPixelComponentType(MapComponentType< T >::CType);
322  SetCellPixelType(COMPLEX);
323  }
324  }
325 
326  template< typename T >
327  void SetPixelType(const Array< T > & array, bool UsePointPixel = true)
328  {
329  if ( UsePointPixel )
330  {
331  SetNumberOfPointPixelComponents( array.Size() );
332  SetPointPixelComponentType(MapComponentType< T >::CType);
333  SetPointPixelType(ARRAY);
334  }
335  else
336  {
337  SetNumberOfCellPixelComponents( array.Size() );
338  SetCellPixelComponentType(MapComponentType< T >::CType);
339  SetCellPixelType(ARRAY);
340  }
341  }
342 
343  template< typename T >
344  void SetPixelType(const VariableLengthVector< T > & vector, bool UsePointPixel = true)
345  {
346  if ( UsePointPixel )
347  {
348  SetNumberOfPointPixelComponents( vector.Size() );
349  SetPointPixelComponentType(MapComponentType< T >::CType);
350  SetPointPixelType(VARIABLELENGTHVECTOR);
351  }
352  else
353  {
354  SetNumberOfCellPixelComponents( vector.Size() );
355  SetCellPixelComponentType(MapComponentType< T >::CType);
356  SetCellPixelType(VARIABLELENGTHVECTOR);
357  }
358  }
359 
360  template< typename T >
361  void SetPixelType(const VariableSizeMatrix< T > & matrix, bool UsePointPixel = true)
362  {
363  if ( UsePointPixel )
364  {
365  SetNumberOfPointPixelComponents( matrix.Rows() * matrix.Cols() );
366  SetPointPixelComponentType(MapComponentType< T >::CType);
367  SetPointPixelType(VARIABLESIZEMATRIX);
368  }
369  else
370  {
371  SetNumberOfCellPixelComponents( matrix.Rows() * matrix.Cols() );
372  SetCellPixelComponentType(MapComponentType< T >::CType);
373  SetCellPixelType(VARIABLESIZEMATRIX);
374  }
375  }
376 
381  itkSetMacro(NumberOfPointPixelComponents, unsigned int);
382  itkGetConstMacro(NumberOfPointPixelComponents, unsigned int);
383  itkSetMacro(NumberOfCellPixelComponents, unsigned int);
384  itkGetConstMacro(NumberOfCellPixelComponents, unsigned int);
385  itkSetMacro(PointDimension, unsigned int);
386  itkGetConstMacro(PointDimension, unsigned int);
387  itkSetMacro(NumberOfPoints, SizeValueType);
388  itkGetConstMacro(NumberOfPoints, SizeValueType);
389  itkSetMacro(NumberOfCells, SizeValueType);
390  itkGetConstMacro(NumberOfCells, SizeValueType);
391  itkSetMacro(NumberOfPointPixels, SizeValueType);
392  itkGetConstMacro(NumberOfPointPixels, SizeValueType);
393  itkSetMacro(NumberOfCellPixels, SizeValueType);
394  itkGetConstMacro(NumberOfCellPixels, SizeValueType);
395  itkSetMacro(CellBufferSize, SizeValueType);
396  itkGetConstMacro(CellBufferSize, SizeValueType);
397  itkSetMacro(UpdatePoints, bool);
398  itkGetConstMacro(UpdatePoints, bool);
399  itkSetMacro(UpdateCells, bool);
400  itkGetConstMacro(UpdateCells, bool);
401  itkSetMacro(UpdatePointData, bool);
402  itkGetConstMacro(UpdatePointData, bool);
403  itkSetMacro(UpdateCellData, bool);
404  itkGetConstMacro(UpdateCellData, bool);
406 
407  unsigned int GetComponentSize(IOComponentType componentType) const;
408 
411  std::string GetComponentTypeAsString(IOComponentType) const;
412 
415  std::string GetPixelTypeAsString(IOPixelType) const;
416 
419  itkSetEnumMacro(FileType, FileType);
420  itkGetEnumMacro(FileType, FileType);
422 
423  void SetFileTypeToASCII()
424  {
425  this->SetFileType(ASCII);
426  }
427 
428  void SetFileTypeToBinary()
429  {
430  this->SetFileType(BINARY);
431  }
432 
444  itkSetEnumMacro(ByteOrder, ByteOrder);
445  itkGetEnumMacro(ByteOrder, ByteOrder);
447 
448  void SetByteOrderToBigEndian()
449  {
450  this->SetByteOrder(BigEndian);
451  }
452 
453  void SetByteOrderToLittleEndian()
454  {
455  this->SetByteOrder(LittleEndian);
456  }
457 
459  itkSetMacro(UseCompression, bool);
460  itkGetConstMacro(UseCompression, bool);
461  itkBooleanMacro(UseCompression);
463 
466  std::string GetFileTypeAsString(FileType) const;
467 
470  std::string GetByteOrderAsString(ByteOrder) const;
471 
472  /*-------- This part of the interfaces deals with reading data ----- */
475  virtual bool CanReadFile(const char *) = 0;
476 
479  virtual void ReadMeshInformation() = 0;
480 
482  virtual void ReadPoints(void *buffer) = 0;
483 
484  virtual void ReadCells(void *buffer) = 0;
485 
486  virtual void ReadPointData(void *buffer) = 0;
487 
488  virtual void ReadCellData(void *buffer) = 0;
489 
490  /*-------- This part of the interfaces deals with writing data ----- */
491 
494  virtual bool CanWriteFile(const char *) = 0;
495 
496  virtual void WriteMeshInformation() = 0;
497 
498  virtual void WritePoints(void *buffer) = 0;
499 
500  virtual void WriteCells(void *buffer) = 0;
501 
502  virtual void WritePointData(void *buffer) = 0;
503 
504  virtual void WriteCellData(void *buffer) = 0;
505 
506  virtual void Write() = 0;
507 
512  const ArrayOfExtensionsType & GetSupportedReadExtensions() const;
513 
518  const ArrayOfExtensionsType & GetSupportedWriteExtensions() const;
519 
520 protected:
521  MeshIOBase();
522  virtual ~MeshIOBase(){}
523 
524  void PrintSelf(std::ostream & os, Indent indent) const;
525 
527  void AddSupportedReadExtension(const char *extension);
528 
530  void AddSupportedWriteExtension(const char *extension);
531 
533  template< class T >
534  void ReadBufferAsAscii(T *buffer, std::ifstream & inputFile, SizeValueType numberOfComponents)
535  {
536  for ( SizeValueType i = 0; i < numberOfComponents; i++ )
537  {
538  inputFile >> buffer[i];
539  }
540  }
542 
544  template< class T >
545  void ReadBufferAsBinary(T *buffer, std::ifstream & inputFile, SizeValueType numberOfComponents)
546  {
547  inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) );
548 
549  if ( m_ByteOrder == BigEndian )
550  {
552  {
553  itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents);
554  }
555  }
556  else if ( m_ByteOrder == LittleEndian )
557  {
559  {
561  }
562  }
563  }
564 
566  template< class T >
567  void WriteBufferAsAscii(T *buffer, std::ofstream & outputFile, SizeValueType numberOfLines, SizeValueType numberOfComponents)
568  {
569  NumberToString<T> convert;
570  for ( SizeValueType ii = 0; ii < numberOfLines; ii++ )
571  {
572  for ( SizeValueType jj = 0; jj < numberOfComponents; jj++ )
573  {
574  outputFile << convert(buffer[ii * numberOfComponents + jj]) << " ";
575  }
576  outputFile << '\n';
577  }
578  }
580 
582  template< class TOutput, class TInput >
583  void WriteBufferAsBinary(TInput *buffer, std::ofstream & outputFile, SizeValueType numberOfComponents)
584  {
585  if ( typeid( TInput ) == typeid( TOutput ) )
586  {
587  if ( m_ByteOrder == BigEndian && itk::ByteSwapper< TInput >::SystemIsLittleEndian() )
588  {
590  }
591  else if ( m_ByteOrder == LittleEndian && itk::ByteSwapper< TInput >::SystemIsBigEndian() )
592  {
594  }
596 
597  outputFile.write(reinterpret_cast< char * >( buffer ), numberOfComponents);
598  }
599  else
600  {
601  TOutput *data = new TOutput[numberOfComponents];
602  for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ )
603  {
604  data[ii] = static_cast< TOutput >( buffer[ii] );
605  }
606 
607  if ( m_ByteOrder == BigEndian && itk::ByteSwapper< TOutput >::SystemIsLittleEndian() )
608  {
610  }
611  else if ( m_ByteOrder == LittleEndian && itk::ByteSwapper< TOutput >::SystemIsBigEndian() )
612  {
614  }
615 
616  outputFile.write(reinterpret_cast< char * >( data ), numberOfComponents);
617  }
618  }
619 
623  template< class TInput, class TOutput >
624  void ReadCellsBuffer(TInput *input, TOutput *output)
625  {
626  if ( input && output )
627  {
630  for ( SizeValueType ii = 0; ii < m_NumberOfCells; ii++ )
631  {
632  inputIndex++; // ignore the cell type
633  unsigned int numberOfPoints = static_cast< unsigned int >( input[inputIndex++] );
634  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
635  {
636  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
637  }
638  }
639  }
640  }
642 
646  template< class TInput, class TOutput >
647  void ReadCellsBuffer(TInput *input, TOutput *output, MeshIOBase::CellGeometryType type)
648  {
649  if ( input && output )
650  {
654 
655  for ( SizeValueType ii = 0; ii < m_NumberOfCells; ii++ )
656  {
657  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( input[inputIndex++] );
658  unsigned int nn = static_cast< unsigned int >( input[inputIndex++] );
659  if ( cellType == type )
660  {
661  output[outputIndex++] = nn;
662  for ( unsigned int jj = 0; jj < nn; jj++ )
663  {
664  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
665  }
666  }
667  else
668  {
669  inputIndex += nn;
670  }
671  }
672  }
673  }
674 
677  template< class TInput, class TOutput >
678  void WriteCellsBuffer(TInput *input, TOutput *output, CellGeometryType cellType, unsigned int numberOfPoints, SizeValueType numberOfCells)
679  {
680  if ( input && output )
681  {
684  for ( SizeValueType ii = 0; ii < numberOfCells; ii++ )
685  {
686  output[outputIndex++] = static_cast< TOutput >( cellType );
687  output[outputIndex++] = static_cast< TOutput >( numberOfPoints );
688  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
689  {
690  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
691  }
692  }
693  }
694  }
696 
699  template< class TInput, class TOutput >
700  void WriteCellsBuffer(TInput *input, TOutput *output, CellGeometryType cellType, SizeValueType numberOfCells)
701  {
702  if ( input && output )
703  {
706  for ( SizeValueType ii = 0; ii < numberOfCells; ii++ )
707  {
708  unsigned int numberOfPoints = static_cast< unsigned int >( input[inputIndex++] );
709  output[outputIndex++] = static_cast< TOutput >( cellType );
710  output[outputIndex++] = static_cast< TOutput >( numberOfPoints );
711  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
712  {
713  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
714  }
715  }
716  }
717  }
719 
720 protected:
724 
726  std::string m_FileName;
727 
730 
736 
740 
745 
747  unsigned int m_PointDimension;
748 
754 
757 
764 
765 private:
766  MeshIOBase(const Self &); // purposely not implemented
767  void operator=(const Self &); // purposely not implemented
768 
771 };
772 #define MESHIOBASE_TYPEMAP(type, ctype) \
773  template< > \
774  struct MeshIOBase:: MapComponentType< type > \
775  { \
776  static const IOComponentType CType = ctype; \
777  }
778 
779 MESHIOBASE_TYPEMAP(unsigned char, UCHAR);
780 MESHIOBASE_TYPEMAP(char, CHAR);
781 MESHIOBASE_TYPEMAP(unsigned short, USHORT);
782 MESHIOBASE_TYPEMAP(short, SHORT);
783 MESHIOBASE_TYPEMAP(unsigned int, UINT);
784 MESHIOBASE_TYPEMAP(int, INT);
785 MESHIOBASE_TYPEMAP(unsigned long, ULONG);
786 MESHIOBASE_TYPEMAP(long, LONG);
787 MESHIOBASE_TYPEMAP(unsigned long long, ULONGLONG);
788 MESHIOBASE_TYPEMAP(long long, LONGLONG);
789 MESHIOBASE_TYPEMAP(float, FLOAT);
790 MESHIOBASE_TYPEMAP(double, DOUBLE);
791 MESHIOBASE_TYPEMAP(long double, LDOUBLE);
792 #undef MESHIOBASE_TYPEMAP
793 } // end namespace itk
794 
795 #endif
796