ITK  4.2.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 
35 #include <string>
36 #include <complex>
37 #include <fstream>
38 
39 namespace itk
40 {
67 class ITK_EXPORT MeshIOBase:public LightProcessObject
68 {
69 public:
71  typedef MeshIOBase Self;
75 
77  typedef std::vector< std::string > ArrayOfExtensionsType;
78 
80  typedef std::streamoff StreamOffsetType;
81 
83 
89  class UnknownType {};
90 
92  itkTypeMacro(MeshIOBase, LightProcessObject);
93 
95  itkSetStringMacro(FileName);
96  itkGetStringMacro(FileName);
98 
102  typedef enum {UNKNOWNPIXELTYPE, SCALAR, RGB, RGBA, OFFSET, VECTOR,
103  POINT, COVARIANTVECTOR, SYMMETRICSECONDRANKTENSOR,
104  DIFFUSIONTENSOR3D, COMPLEX, FIXEDARRAY, ARRAY, MATRIX,
105  VARIABLELENGTHVECTOR, VARIABLESIZEMATRIX} IOPixelType;
106 
110  typedef enum {UNKNOWNCOMPONENTTYPE, UCHAR, CHAR, USHORT, SHORT, UINT, INT,
111  ULONG, LONG, LONGLONG, ULONGLONG, FLOAT, DOUBLE, LDOUBLE} IOComponentType;
112 
115  typedef enum {ASCII, BINARY, TYPENOTAPPLICABLE} FileType;
116 
119  typedef enum {BigEndian, LittleEndian, OrderNotApplicable} ByteOrder;
120 
122  typedef enum {VERTEX_CELL = 0, LINE_CELL, TRIANGLE_CELL,
123  QUADRILATERAL_CELL, POLYGON_CELL, TETRAHEDRON_CELL, HEXAHEDRON_CELL,
124  QUADRATIC_EDGE_CELL, QUADRATIC_TRIANGLE_CELL,
125  LAST_ITK_CELL, MAX_ITK_CELLS = 255} CellGeometryType;
126 
132  itkSetEnumMacro(PointPixelType, IOPixelType);
133  itkGetEnumMacro(PointPixelType, IOPixelType);
134  itkSetEnumMacro(CellPixelType, IOPixelType);
135  itkGetEnumMacro(CellPixelType, IOPixelType);
137 
140  itkSetEnumMacro(PointComponentType, IOComponentType);
141  itkGetEnumMacro(PointComponentType, IOComponentType);
142  itkSetEnumMacro(CellComponentType, IOComponentType);
143  itkGetEnumMacro(CellComponentType, IOComponentType);
144  itkSetEnumMacro(PointPixelComponentType, IOComponentType);
145  itkGetEnumMacro(PointPixelComponentType, IOComponentType);
146  itkSetEnumMacro(CellPixelComponentType, IOComponentType);
147  itkGetEnumMacro(CellPixelComponentType, IOComponentType);
149 
150  template< typename T >
152  static const IOComponentType CType = UNKNOWNCOMPONENTTYPE;
153  };
154 
155  template< typename T >
156  void SetPixelType(const T & itkNotUsed(dummy), bool UsePointPixel = true)
157  {
158  if ( UsePointPixel )
159  {
160  SetNumberOfPointPixelComponents(1);
161  SetPointPixelComponentType(MapComponentType< T >::CType);
162  SetPointPixelType(SCALAR);
163  }
164  else
165  {
166  SetNumberOfCellPixelComponents(1);
167  SetCellPixelComponentType(MapComponentType< T >::CType);
168  SetCellPixelType(SCALAR);
169  }
170  }
171 
172  template< typename T >
173  void SetPixelType(const RGBPixel< T > & itkNotUsed(dummy), bool UsePointPixel = true)
174  {
175  if ( UsePointPixel )
176  {
177  SetNumberOfPointPixelComponents(3);
178  SetPointPixelComponentType(MapComponentType< T >::CType);
179  SetPointPixelType(RGB);
180  }
181  else
182  {
183  SetNumberOfCellPixelComponents(3);
184  SetCellPixelComponentType(MapComponentType< T >::CType);
185  SetCellPixelType(RGB);
186  }
187  }
188 
189  template< typename T >
190  void SetPixelType(const RGBAPixel< T > & itkNotUsed(dummy), bool UsePointPixel = true)
191  {
192  if ( UsePointPixel )
193  {
194  SetNumberOfPointPixelComponents(4);
195  SetPointPixelComponentType(MapComponentType< T >::CType);
196  SetPointPixelType(RGBA);
197  }
198  else
199  {
200  SetNumberOfCellPixelComponents(4);
201  SetCellPixelComponentType(MapComponentType< T >::CType);
202  SetCellPixelType(RGBA);
203  }
204  }
205 
206  template< typename T, unsigned int VLength >
207  void SetPixelType(const Vector< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
208  {
209  if ( UsePointPixel )
210  {
211  SetNumberOfPointPixelComponents(VLength);
212  SetPointPixelComponentType(MapComponentType< T >::CType);
213  SetPointPixelType(VECTOR);
214  }
215  else
216  {
217  SetNumberOfCellPixelComponents(VLength);
218  SetCellPixelComponentType(MapComponentType< T >::CType);
219  SetCellPixelType(VECTOR);
220  }
221  }
222 
223  template< typename T, unsigned int VLength >
224  void SetPixelType(const CovariantVector< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
225  {
226  if ( UsePointPixel )
227  {
228  SetNumberOfPointPixelComponents(VLength);
229  SetPointPixelComponentType(MapComponentType< T >::CType);
230  SetPointPixelType(COVARIANTVECTOR);
231  }
232  else
233  {
234  SetNumberOfCellPixelComponents(VLength);
235  SetCellPixelComponentType(MapComponentType< T >::CType);
236  SetCellPixelType(COVARIANTVECTOR);
237  }
238  }
239 
240  template< typename T, unsigned int VLength >
241  void SetPixelType(const FixedArray< T, VLength > & itkNotUsed(dummy), bool UsePointPixel = true)
242  {
243  if ( UsePointPixel )
244  {
245  SetNumberOfPointPixelComponents(VLength);
246  SetPointPixelComponentType(MapComponentType< T >::CType);
247  SetPointPixelType(FIXEDARRAY);
248  }
249  else
250  {
251  SetNumberOfCellPixelComponents(VLength);
252  SetCellPixelComponentType(MapComponentType< T >::CType);
253  SetCellPixelType(FIXEDARRAY);
254  }
255  }
256 
257  template< typename T, unsigned int VLength >
258  void SetPixelType(const SymmetricSecondRankTensor< T, VLength > itkNotUsed(dummy), bool UsePointPixel = true)
259  {
260  if ( UsePointPixel )
261  {
262  SetNumberOfPointPixelComponents(VLength * ( VLength + 1 ) / 2);
263  SetPointPixelComponentType(MapComponentType< T >::CType);
264  SetPointPixelType(SYMMETRICSECONDRANKTENSOR);
265  }
266  else
267  {
268  SetNumberOfCellPixelComponents(VLength * ( VLength + 1 ) / 2);
269  SetCellPixelComponentType(MapComponentType< T >::CType);
270  SetCellPixelType(SYMMETRICSECONDRANKTENSOR);
271  }
272  }
273 
274  template< typename T >
275  void SetPixelType(const DiffusionTensor3D< T > & itkNotUsed(dummy), bool UsePointPixel = true)
276  {
277  if ( UsePointPixel )
278  {
279  SetNumberOfPointPixelComponents(6);
280  SetPointPixelComponentType(MapComponentType< T >::CType);
281  SetPointPixelType(DIFFUSIONTENSOR3D);
282  }
283  else
284  {
285  SetNumberOfCellPixelComponents(6);
286  SetCellPixelComponentType(MapComponentType< T >::CType);
287  SetCellPixelType(DIFFUSIONTENSOR3D);
288  }
289  }
290 
291  template< typename T, unsigned int NR, unsigned int NC >
292  void SetPixelType(const Matrix< T, NR, NC > & itkNotUsed(dummy), bool UsePointPixel = true)
293  {
294  if ( UsePointPixel )
295  {
296  SetNumberOfPointPixelComponents(NR * NC);
297  SetPointPixelComponentType(MapComponentType< T >::CType);
298  SetPointPixelType(MATRIX);
299  }
300  else
301  {
302  SetNumberOfCellPixelComponents(NR * NC);
303  SetCellPixelComponentType(MapComponentType< T >::CType);
304  SetCellPixelType(MATRIX);
305  }
306  }
307 
308  template< typename T >
309  void SetPixelType(const std::complex< T > & itkNotUsed(dummy), bool UsePointPixel = true)
310  {
311  if ( UsePointPixel )
312  {
313  SetNumberOfPointPixelComponents(2);
314  SetPointPixelComponentType(MapComponentType< T >::CType);
315  SetPointPixelType(COMPLEX);
316  }
317  else
318  {
319  SetNumberOfCellPixelComponents(2);
320  SetCellPixelComponentType(MapComponentType< T >::CType);
321  SetCellPixelType(COMPLEX);
322  }
323  }
324 
325  template< typename T >
326  void SetPixelType(const Array< T > & array, bool UsePointPixel = true)
327  {
328  if ( UsePointPixel )
329  {
330  SetNumberOfPointPixelComponents( array.Size() );
331  SetPointPixelComponentType(MapComponentType< T >::CType);
332  SetPointPixelType(ARRAY);
333  }
334  else
335  {
336  SetNumberOfCellPixelComponents( array.Size() );
337  SetCellPixelComponentType(MapComponentType< T >::CType);
338  SetCellPixelType(ARRAY);
339  }
340  }
341 
342  template< typename T >
343  void SetPixelType(const VariableLengthVector< T > & vector, bool UsePointPixel = true)
344  {
345  if ( UsePointPixel )
346  {
347  SetNumberOfPointPixelComponents( vector.Size() );
348  SetPointPixelComponentType(MapComponentType< T >::CType);
349  SetPointPixelType(VARIABLELENGTHVECTOR);
350  }
351  else
352  {
353  SetNumberOfCellPixelComponents( vector.Size() );
354  SetCellPixelComponentType(MapComponentType< T >::CType);
355  SetCellPixelType(VARIABLELENGTHVECTOR);
356  }
357  }
358 
359  template< typename T >
360  void SetPixelType(const VariableSizeMatrix< T > & matrix, bool UsePointPixel = true)
361  {
362  if ( UsePointPixel )
363  {
364  SetNumberOfPointPixelComponents( matrix.Rows() * matrix.Cols() );
365  SetPointPixelComponentType(MapComponentType< T >::CType);
366  SetPointPixelType(VARIABLESIZEMATRIX);
367  }
368  else
369  {
370  SetNumberOfCellPixelComponents( matrix.Rows() * matrix.Cols() );
371  SetCellPixelComponentType(MapComponentType< T >::CType);
372  SetCellPixelType(VARIABLESIZEMATRIX);
373  }
374  }
375 
380  itkSetMacro(NumberOfPointPixelComponents, unsigned int);
381  itkGetConstMacro(NumberOfPointPixelComponents, unsigned int);
382  itkSetMacro(NumberOfCellPixelComponents, unsigned int);
383  itkGetConstMacro(NumberOfCellPixelComponents, unsigned int);
384  itkSetMacro(PointDimension, unsigned int);
385  itkGetConstMacro(PointDimension, unsigned int);
386  itkSetMacro(NumberOfPoints, SizeValueType);
387  itkGetConstMacro(NumberOfPoints, SizeValueType);
388  itkSetMacro(NumberOfCells, SizeValueType);
389  itkGetConstMacro(NumberOfCells, SizeValueType);
390  itkSetMacro(NumberOfPointPixels, SizeValueType);
391  itkGetConstMacro(NumberOfPointPixels, SizeValueType);
392  itkSetMacro(NumberOfCellPixels, SizeValueType);
393  itkGetConstMacro(NumberOfCellPixels, SizeValueType);
394  itkSetMacro(CellBufferSize, SizeValueType);
395  itkGetConstMacro(CellBufferSize, SizeValueType);
396  itkSetMacro(UpdatePoints, bool);
397  itkGetConstMacro(UpdatePoints, bool);
398  itkSetMacro(UpdateCells, bool);
399  itkGetConstMacro(UpdateCells, bool);
400  itkSetMacro(UpdatePointData, bool);
401  itkGetConstMacro(UpdatePointData, bool);
402  itkSetMacro(UpdateCellData, bool);
403  itkGetConstMacro(UpdateCellData, bool);
405 
406  unsigned int GetComponentSize(IOComponentType componentType) const;
407 
410  std::string GetComponentTypeAsString(IOComponentType) const;
411 
414  std::string GetPixelTypeAsString(IOPixelType) const;
415 
418  itkSetEnumMacro(FileType, FileType);
419  itkGetEnumMacro(FileType, FileType);
421 
422  void SetFileTypeToASCII()
423  {
424  this->SetFileType(ASCII);
425  }
426 
427  void SetFileTypeToBinary()
428  {
429  this->SetFileType(BINARY);
430  }
431 
443  itkSetEnumMacro(ByteOrder, ByteOrder);
444  itkGetEnumMacro(ByteOrder, ByteOrder);
446 
447  void SetByteOrderToBigEndian()
448  {
449  this->SetByteOrder(BigEndian);
450  }
451 
452  void SetByteOrderToLittleEndian()
453  {
454  this->SetByteOrder(LittleEndian);
455  }
456 
458  itkSetMacro(UseCompression, bool);
459  itkGetConstMacro(UseCompression, bool);
460  itkBooleanMacro(UseCompression);
462 
465  std::string GetFileTypeAsString(FileType) const;
466 
469  std::string GetByteOrderAsString(ByteOrder) const;
470 
471  /*-------- This part of the interfaces deals with reading data ----- */
474  virtual bool CanReadFile(const char *) = 0;
475 
478  virtual void ReadMeshInformation() = 0;
479 
481  virtual void ReadPoints(void *buffer) = 0;
482 
483  virtual void ReadCells(void *buffer) = 0;
484 
485  virtual void ReadPointData(void *buffer) = 0;
486 
487  virtual void ReadCellData(void *buffer) = 0;
488 
489  /*-------- This part of the interfaces deals with writing data ----- */
490 
493  virtual bool CanWriteFile(const char *) = 0;
494 
495  virtual void WriteMeshInformation() = 0;
496 
497  virtual void WritePoints(void *buffer) = 0;
498 
499  virtual void WriteCells(void *buffer) = 0;
500 
501  virtual void WritePointData(void *buffer) = 0;
502 
503  virtual void WriteCellData(void *buffer) = 0;
504 
505  virtual void Write() = 0;
506 
511  const ArrayOfExtensionsType & GetSupportedReadExtensions() const;
512 
517  const ArrayOfExtensionsType & GetSupportedWriteExtensions() const;
518 
519 protected:
520  MeshIOBase();
521  virtual ~MeshIOBase(){}
522 
523  void PrintSelf(std::ostream & os, Indent indent) const;
524 
526  void AddSupportedReadExtension(const char *extension);
527 
529  void AddSupportedWriteExtension(const char *extension);
530 
532  template< class T >
533  void ReadBufferAsAscii(T *buffer, std::ifstream & inputFile, SizeValueType numberOfComponents)
534  {
535  for ( SizeValueType i = 0; i < numberOfComponents; i++ )
536  {
537  inputFile >> buffer[i];
538  }
539  }
541 
543  template< class T >
544  void ReadBufferAsBinary(T *buffer, std::ifstream & inputFile, SizeValueType numberOfComponents)
545  {
546  inputFile.read( reinterpret_cast< char * >( buffer ), numberOfComponents * sizeof( T ) );
547 
548  if ( m_ByteOrder == BigEndian )
549  {
551  {
552  itk::ByteSwapper< T >::SwapRangeFromSystemToBigEndian(buffer, numberOfComponents);
553  }
554  }
555  else if ( m_ByteOrder == LittleEndian )
556  {
558  {
560  }
561  }
562  }
563 
565  template< class T >
566  void WriteBufferAsAscii(T *buffer, std::ofstream & outputFile, SizeValueType numberOfLines, SizeValueType numberOfComponents)
567  {
568  for ( SizeValueType ii = 0; ii < numberOfLines; ii++ )
569  {
570  for ( SizeValueType jj = 0; jj < numberOfComponents; jj++ )
571  {
572  outputFile << buffer[ii * numberOfComponents + jj] << " ";
573  }
574  outputFile << '\n';
575  }
576  }
578 
580  template< class TOutput, class TInput >
581  void WriteBufferAsBinary(TInput *buffer, std::ofstream & outputFile, SizeValueType numberOfComponents)
582  {
583  if ( typeid( TInput ) == typeid( TOutput ) )
584  {
585  if ( m_ByteOrder == BigEndian && itk::ByteSwapper< TInput >::SystemIsLittleEndian() )
586  {
588  }
589  else if ( m_ByteOrder == LittleEndian && itk::ByteSwapper< TInput >::SystemIsBigEndian() )
590  {
592  }
594 
595  outputFile.write(reinterpret_cast< char * >( buffer ), numberOfComponents);
596  }
597  else
598  {
599  TOutput *data = new TOutput[numberOfComponents];
600  for ( SizeValueType ii = 0; ii < numberOfComponents; ii++ )
601  {
602  data[ii] = static_cast< TOutput >( buffer[ii] );
603  }
604 
605  if ( m_ByteOrder == BigEndian && itk::ByteSwapper< TOutput >::SystemIsLittleEndian() )
606  {
608  }
609  else if ( m_ByteOrder == LittleEndian && itk::ByteSwapper< TOutput >::SystemIsBigEndian() )
610  {
612  }
613 
614  outputFile.write(reinterpret_cast< char * >( data ), numberOfComponents);
615  }
616  }
617 
621  template< class TInput, class TOutput >
622  void ReadCellsBuffer(TInput *input, TOutput *output)
623  {
624  if ( input && output )
625  {
628  for ( SizeValueType ii = 0; ii < m_NumberOfCells; ii++ )
629  {
630  inputIndex++; // ignore the cell type
631  unsigned int numberOfPoints = static_cast< unsigned int >( input[inputIndex++] );
632  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
633  {
634  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
635  }
636  }
637  }
638  }
640 
644  template< class TInput, class TOutput >
645  void ReadCellsBuffer(TInput *input, TOutput *output, MeshIOBase::CellGeometryType type)
646  {
647  if ( input && output )
648  {
652 
653  for ( SizeValueType ii = 0; ii < m_NumberOfCells; ii++ )
654  {
655  MeshIOBase::CellGeometryType cellType = static_cast< MeshIOBase::CellGeometryType >( input[inputIndex++] );
656  unsigned int nn = static_cast< unsigned int >( input[inputIndex++] );
657  if ( cellType == type )
658  {
659  output[outputIndex++] = nn;
660  for ( unsigned int jj = 0; jj < nn; jj++ )
661  {
662  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
663  }
664  }
665  else
666  {
667  inputIndex += nn;
668  }
669  }
670  }
671  }
672 
675  template< class TInput, class TOutput >
676  void WriteCellsBuffer(TInput *input, TOutput *output, CellGeometryType cellType, unsigned int numberOfPoints, SizeValueType numberOfCells)
677  {
678  if ( input && output )
679  {
682  for ( SizeValueType ii = 0; ii < numberOfCells; ii++ )
683  {
684  output[outputIndex++] = static_cast< TOutput >( cellType );
685  output[outputIndex++] = static_cast< TOutput >( numberOfPoints );
686  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
687  {
688  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
689  }
690  }
691  }
692  }
694 
697  template< class TInput, class TOutput >
698  void WriteCellsBuffer(TInput *input, TOutput *output, CellGeometryType cellType, SizeValueType numberOfCells)
699  {
700  if ( input && output )
701  {
704  for ( SizeValueType ii = 0; ii < numberOfCells; ii++ )
705  {
706  unsigned int numberOfPoints = static_cast< unsigned int >( input[inputIndex++] );
707  output[outputIndex++] = static_cast< TOutput >( cellType );
708  output[outputIndex++] = static_cast< TOutput >( numberOfPoints );
709  for ( unsigned int jj = 0; jj < numberOfPoints; jj++ )
710  {
711  output[outputIndex++] = static_cast< TOutput >( input[inputIndex++] );
712  }
713  }
714  }
715  }
717 
718 protected:
722 
724  std::string m_FileName;
725 
728 
734 
738 
743 
745  unsigned int m_PointDimension;
746 
752 
755 
762 
763 private:
764  MeshIOBase(const Self &); // purposely not implemented
765  void operator=(const Self &); // purposely not implemented
766 
769 };
770 #define MESHIOBASE_TYPEMAP(type, ctype) \
771  template< > \
772  struct MeshIOBase:: MapComponentType< type > \
773  { \
774  static const IOComponentType CType = ctype; \
775  }
776 
777 MESHIOBASE_TYPEMAP(unsigned char, UCHAR);
778 MESHIOBASE_TYPEMAP(char, CHAR);
779 MESHIOBASE_TYPEMAP(unsigned short, USHORT);
780 MESHIOBASE_TYPEMAP(short, SHORT);
781 MESHIOBASE_TYPEMAP(unsigned int, UINT);
782 MESHIOBASE_TYPEMAP(int, INT);
783 MESHIOBASE_TYPEMAP(unsigned long, ULONG);
784 MESHIOBASE_TYPEMAP(long, LONG);
785 MESHIOBASE_TYPEMAP(unsigned long long, ULONGLONG);
786 MESHIOBASE_TYPEMAP(long long, LONGLONG);
787 MESHIOBASE_TYPEMAP(float, FLOAT);
788 MESHIOBASE_TYPEMAP(double, DOUBLE);
789 MESHIOBASE_TYPEMAP(long double, LDOUBLE);
790 #undef MESHIOBASE_TYPEMAP
791 } // end namespace itk
792 
793 #endif
794