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 
19 #include "itkOFFMeshIO.h"
20 
21 #include <itksys/SystemTools.hxx>
22 
23 namespace itk
24 {
25 OFFMeshIO
OFFMeshIO()26 ::OFFMeshIO()
27 {
28   this->AddSupportedWriteExtension(".off");
29   this->SetByteOrderToBigEndian();
30   m_PointsStartPosition = itk::NumericTraits< StreamOffsetType >::ZeroValue();
31   m_TriangleCellType = true;
32 }
33 
34 OFFMeshIO
35 ::~OFFMeshIO() = default;
36 
37 bool
38 OFFMeshIO
CanReadFile(const char * fileName)39 ::CanReadFile(const char *fileName)
40 {
41   if ( !itksys::SystemTools::FileExists(fileName, true) )
42     {
43     return false;
44     }
45 
46   if ( itksys::SystemTools::GetFilenameLastExtension(fileName) != ".off" )
47     {
48     return false;
49     }
50 
51   return true;
52 }
53 
54 bool
55 OFFMeshIO
CanWriteFile(const char * fileName)56 ::CanWriteFile(const char *fileName)
57 {
58   if ( itksys::SystemTools::GetFilenameLastExtension(fileName) != ".off" )
59     {
60     return false;
61     }
62 
63   return true;
64 }
65 
66 void
67 OFFMeshIO
OpenFile()68 ::OpenFile()
69 {
70   if ( this->m_FileName.empty() )
71     {
72     itkExceptionMacro("No input FileName");
73     }
74 
75   if ( !itksys::SystemTools::FileExists( m_FileName.c_str() ) )
76     {
77     itkExceptionMacro("File " << this->m_FileName << " does not exist");
78     }
79 
80   // Read file as ascii
81   // Due to the windows doesn't work well for tellg() and seekg() for ASCII mode, hence we
82   //open the file with std::ios::binary
83   m_InputFile.open(this->m_FileName.c_str(), std::ios_base::in | std::ios::binary);
84 
85   // Test whether the file was opened
86   if ( !m_InputFile.is_open() )
87     {
88     itkExceptionMacro("Unable to open file " << this->m_FileName);
89     }
90 }
91 
92 void
93 OFFMeshIO
CloseFile()94 ::CloseFile()
95 {
96   if ( m_InputFile.is_open() )
97     {
98     m_InputFile.close();
99     }
100 }
101 
102 void
103 OFFMeshIO
ReadMeshInformation()104 ::ReadMeshInformation()
105 {
106   // Define input file stream and attach it to input file
107   OpenFile();
108 
109   // Read and analyze the first line in the file
110   std::string line;
111 
112   // The OFF file must containe "OFF"
113   std::getline(m_InputFile, line, '\n');  // delimiter is '\n'
114   if ( line.find("OFF") == std::string::npos )
115     {
116     itkExceptionMacro(<< "Error, the file doesn't begin with keyword \"OFF\" ");
117     }
118 
119   // If the file is binary file, it contains "BINARY"
120   if ( line.find("BINARY") != std::string::npos )
121     {
122     this->m_FileType = BINARY;
123     }
124   else
125     {
126     this->m_FileType = ASCII;
127     }
128 
129   // Read and Set point dimension
130   if ( line.find("nOFF") != std::string::npos )
131     {
132     m_InputFile >> this->m_PointDimension;
133     m_PointDimension++;
134     }
135   else if ( line.find("4OFF") != std::string::npos )
136     {
137     this->m_PointDimension = 4;
138     }
139   else
140     {
141     this->m_PointDimension = 3;
142     }
143 
144   // Ignore comment lines
145   std::getline(m_InputFile, line, '\n');
146   while ( line.find("#") != std::string::npos )
147     {
148     std::getline(m_InputFile, line, '\n');
149     }
150 
151   // Read points and cells information
152   if ( this->m_FileType == ASCII )
153     {
154     // Put the last line with output '#' into a stringstream.
155     std::stringstream ss;
156     ss << line;
157 
158     // Read number of points
159     ss >> this->m_NumberOfPoints;
160 
161     // Read number of cells
162     ss >> this->m_NumberOfCells;
163 
164     // Read number of edges
165     unsigned int numberOfEdges = 0;
166     ss >> numberOfEdges;
167 
168     // Read points start position in the file
169     m_PointsStartPosition = m_InputFile.tellg();
170 
171     for ( SizeValueType id = 0; id < this->m_NumberOfPoints; id++ )
172       {
173       std::getline(m_InputFile, line, '\n');
174       }
175 
176     // Set default cell component type
177     this->m_CellBufferSize = this->m_NumberOfCells * 2;
178 
179     //Read each ecll's number of points and put them to cell buffer size
180     unsigned int numberOfCellPoints = 0;
181     for ( SizeValueType id = 0; id < this->m_NumberOfCells; id++ )
182       {
183       m_InputFile >> numberOfCellPoints;
184       this->m_CellBufferSize += numberOfCellPoints;
185       std::getline(m_InputFile, line, '\n');
186 
187       if ( numberOfCellPoints != 3 )
188         {
189         m_TriangleCellType = false;
190         }
191       }
192     }
193   // Read points and cells information from binary mesh
194   else if ( this->m_FileType == BINARY )
195     {
196     // Read the number of points
197     itk::uint32_t numberOfPoints;
198     this->ReadBufferAsBinary(&numberOfPoints, m_InputFile, 1);
199     this->m_NumberOfPoints = numberOfPoints;
200 
201     // Read the number of cells
202     itk::uint32_t numberOfCells;
203     this->ReadBufferAsBinary(&numberOfCells, m_InputFile, 1);
204     this->m_NumberOfCells = numberOfCells;
205 
206     // Read number of edges
207     itk::uint32_t numberOfEdges;
208     this->ReadBufferAsBinary(&numberOfEdges, m_InputFile, 1);
209 
210     // Get points start position
211     m_PointsStartPosition = m_InputFile.tellg();
212 
213     // Read points
214     auto * pointsBuffer = new float[this->m_NumberOfPoints * this->m_PointDimension];
215     this->ReadBufferAsBinary(pointsBuffer, m_InputFile, this->m_NumberOfPoints * this->m_PointDimension);
216     delete[] pointsBuffer;
217 
218     // Set default cell component type
219     this->m_CellBufferSize = this->m_NumberOfCells * 2;
220 
221     // Read cells
222     itk::uint32_t  numberOfCellPoints = 0;
223     auto * cellsBuffer = new itk::uint32_t[this->m_NumberOfCells];
224     for ( unsigned long id = 0; id < this->m_NumberOfCells; id++ )
225       {
226       this->ReadBufferAsBinary(&numberOfCellPoints, m_InputFile, 1);
227       this->m_CellBufferSize += numberOfCellPoints;
228       this->ReadBufferAsBinary(cellsBuffer, m_InputFile, numberOfCellPoints);
229       if ( numberOfCellPoints != 3 )
230         {
231         m_TriangleCellType = false;
232         }
233       }
234     delete[] cellsBuffer;
235     }
236 
237   // Set default point component type
238   this->m_PointComponentType = FLOAT;
239 
240   // Set default cell component type
241   this->m_CellComponentType  = UINT;
242 
243   // If number of points is not equal zero, update points
244   if ( this->m_NumberOfPoints )
245     {
246     this->m_UpdatePoints = true;
247     }
248 
249   // If number of cells is not equal zero, update points
250   if ( this->m_NumberOfCells )
251     {
252     this->m_UpdateCells = true;
253     }
254 
255   // Set default point pixel component and point pixel type
256   this->m_PointPixelComponentType = FLOAT;
257   this->m_PointPixelType  = SCALAR;
258   this->m_UpdatePointData = false;
259   this->m_NumberOfPointPixelComponents = itk::NumericTraits< unsigned int >::OneValue();
260 
261   // Set default cell pixel component and point pixel type
262   this->m_CellPixelComponentType = FLOAT;
263   this->m_CellPixelType  = SCALAR;
264   this->m_UpdateCellData = false;
265   this->m_NumberOfCellPixelComponents = itk::NumericTraits< unsigned int >::OneValue();
266 }
267 
268 void
269 OFFMeshIO
ReadPoints(void * buffer)270 ::ReadPoints(void *buffer)
271 {
272   // Set file position to points start position
273   m_InputFile.seekg(m_PointsStartPosition, std::ios::beg);
274 
275   // Read file according to ASCII or BINARY
276   if ( this->m_FileType == ASCII )
277     {
278     this->ReadBufferAsAscii(static_cast< float * >( buffer ), m_InputFile, this->m_NumberOfPoints * this->m_PointDimension);
279     }
280   else if ( this->m_FileType == BINARY )
281     {
282     this->ReadBufferAsBinary(static_cast< float * >( buffer ), m_InputFile, this->m_NumberOfPoints * this->m_PointDimension);
283     }
284   else
285     {
286     itkExceptionMacro(<< "Invalid file type (not ASCII or BINARY)");
287     }
288 }
289 
290 void
291 OFFMeshIO
ReadCells(void * buffer)292 ::ReadCells(void *buffer)
293 {
294   auto * data = new itk::uint32_t[this->m_CellBufferSize - this->m_NumberOfCells];
295 
296   if ( this->m_FileType == ASCII )
297     {
298     this->ReadCellsBufferAsAscii(data, m_InputFile);
299     }
300   else if ( this->m_FileType == BINARY )
301     {
302     this->ReadBufferAsBinary(data, m_InputFile, this->m_CellBufferSize - this->m_NumberOfCells);
303     }
304   else
305     {
306     itkExceptionMacro(<< "Invalid file type (not ASCII or BINARY)");
307     }
308 
309   CloseFile();
310 
311   if ( m_TriangleCellType )
312     {
313     this->WriteCellsBuffer(data, static_cast< unsigned int * >( buffer ), TRIANGLE_CELL, this->m_NumberOfCells);
314     }
315   else
316     {
317     this->WriteCellsBuffer(data, static_cast< unsigned int * >( buffer ), POLYGON_CELL, this->m_NumberOfCells);
318     }
319 
320   delete[] data;
321 }
322 
323 void
324 OFFMeshIO
ReadPointData(void * itkNotUsed (buffer))325 ::ReadPointData(void * itkNotUsed( buffer) )
326 {
327 }
328 
329 void
330 OFFMeshIO
ReadCellData(void * itkNotUsed (buffer))331 ::ReadCellData(void * itkNotUsed( buffer) )
332 {
333 }
334 
335 void
336 OFFMeshIO
WriteMeshInformation()337 ::WriteMeshInformation()
338 {
339   // Check file name
340   if ( this->m_FileName.empty() )
341     {
342     itkExceptionMacro("No Input FileName");
343     }
344 
345   // Write to output file
346   std::ofstream outputFile;
347   if ( this->m_FileType == ASCII )
348     {
349     outputFile.open(this->m_FileName.c_str(), std::ios::out);
350     }
351   else if ( m_FileType == BINARY )
352     {
353     outputFile.open(this->m_FileName.c_str(), std::ios::out | std::ios::binary);
354     }
355 
356   if ( !outputFile.is_open() )
357     {
358     itkExceptionMacro("Unable to open file\n"
359                       "outputFilename= " << this->m_FileName);
360     }
361 
362   // Write Object file format header
363   outputFile << "OFF " << std::endl;
364 
365   //Read points and cells information
366   if ( this->m_FileType == ASCII )
367     {
368     // Write number of points
369     outputFile << this->m_NumberOfPoints << "    ";
370 
371     // Write number of cells
372     outputFile << this->m_NumberOfCells << "    ";
373 
374     // Write number of edges
375     unsigned int numberOfEdges = 0;
376     outputFile << numberOfEdges << std::endl;
377     }
378   else if ( this->m_FileType == BINARY )
379     {
380     // Write number of points
381     auto numberOfPoints = static_cast<itk::uint32_t>(this->m_NumberOfPoints);
382     this->WriteBufferAsBinary< itk::uint32_t >(&( numberOfPoints ), outputFile, 1);
383 
384     // Write number of cells
385     auto numberOfCells = static_cast<itk::uint32_t>(this->m_NumberOfCells);
386     this->WriteBufferAsBinary< itk::uint32_t >(&( numberOfCells ), outputFile, 1);
387 
388     // Write number of edges
389     itk::uint32_t numberOfEdges = 0;
390     this->WriteBufferAsBinary< itk::uint32_t >(&( numberOfEdges ), outputFile, 1);
391     }
392 
393   outputFile.close();
394 }
395 
396 void
397 OFFMeshIO
WritePoints(void * buffer)398 ::WritePoints(void *buffer)
399 {
400   // check file name
401   if ( this->m_FileName.empty() )
402     {
403     itkExceptionMacro("No Input FileName");
404     }
405 
406   // Write to output file
407   std::ofstream outputFile;
408   if ( this->m_FileType == ASCII )
409     {
410     outputFile.open(this->m_FileName.c_str(), std::ios::app);
411     }
412   else if ( m_FileType == BINARY )
413     {
414     outputFile.open(this->m_FileName.c_str(), std::ios::app | std::ios::binary);
415     }
416 
417   if ( !outputFile.is_open() )
418     {
419     itkExceptionMacro("Unable to open file\n"
420                       "outputFilename= " << this->m_FileName);
421     }
422 
423   // Write points
424   if ( this->m_FileType == ASCII )
425     {
426     switch ( this->m_PointComponentType )
427       {
428       case UCHAR:
429         {
430         WriteBufferAsAscii(static_cast< unsigned char * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
431         break;
432         }
433       case CHAR:
434         {
435         WriteBufferAsAscii(static_cast< char * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
436 
437         break;
438         }
439       case USHORT:
440         {
441         WriteBufferAsAscii(static_cast< unsigned short * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
442 
443         break;
444         }
445       case SHORT:
446         {
447         WriteBufferAsAscii(static_cast< short * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
448 
449         break;
450         }
451       case UINT:
452         {
453         WriteBufferAsAscii(static_cast< unsigned int * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
454 
455         break;
456         }
457       case INT:
458         {
459         WriteBufferAsAscii(static_cast< int * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
460 
461         break;
462         }
463       case ULONG:
464         {
465         WriteBufferAsAscii(static_cast< unsigned long * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
466 
467         break;
468         }
469       case LONG:
470         {
471         WriteBufferAsAscii(static_cast< long * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
472 
473         break;
474         }
475       case ULONGLONG:
476         {
477         WriteBufferAsAscii(static_cast< unsigned long long * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
478 
479         break;
480         }
481       case LONGLONG:
482         {
483         WriteBufferAsAscii(static_cast< long long * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
484 
485         break;
486         }
487       case FLOAT:
488         {
489         WriteBufferAsAscii(static_cast< float * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
490 
491         break;
492         }
493       case DOUBLE:
494         {
495         WriteBufferAsAscii(static_cast< double * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
496 
497         break;
498         }
499       case LDOUBLE:
500         {
501         WriteBufferAsAscii(static_cast< long double * >( buffer ), outputFile, m_NumberOfPoints, m_PointDimension);
502 
503         break;
504         }
505       default:
506         {
507         itkExceptionMacro(<< "Unknown point pixel component type" << std::endl);
508         }
509       }
510     }
511   else if ( this->m_FileType == BINARY )
512     {
513     switch ( this->m_PointComponentType )
514       {
515       case UCHAR:
516         {
517         WriteBufferAsBinary< float >(static_cast< unsigned char * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
518         break;
519         }
520       case CHAR:
521         {
522         WriteBufferAsBinary< float >(static_cast< char * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
523 
524         break;
525         }
526       case USHORT:
527         {
528         WriteBufferAsBinary< float >(static_cast< unsigned short * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
529 
530         break;
531         }
532       case SHORT:
533         {
534         WriteBufferAsBinary< float >(static_cast< short * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
535 
536         break;
537         }
538       case UINT:
539         {
540         WriteBufferAsBinary< float >(static_cast< unsigned int * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
541 
542         break;
543         }
544       case INT:
545         {
546         WriteBufferAsBinary< float >(static_cast< int * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
547 
548         break;
549         }
550       case ULONG:
551         {
552         WriteBufferAsBinary< float >(static_cast< unsigned long * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
553 
554         break;
555         }
556       case LONG:
557         {
558         WriteBufferAsBinary< float >(static_cast< long * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
559 
560         break;
561         }
562       case ULONGLONG:
563         {
564         WriteBufferAsBinary< float >(static_cast< unsigned long long * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
565 
566         break;
567         }
568       case LONGLONG:
569         {
570         WriteBufferAsBinary< float >(static_cast< long long * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
571 
572         break;
573         }
574       case FLOAT:
575         {
576         WriteBufferAsBinary< float >(static_cast< float * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
577 
578         break;
579         }
580       case DOUBLE:
581         {
582         WriteBufferAsBinary< float >(static_cast< double * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
583 
584         break;
585         }
586       case LDOUBLE:
587         {
588         WriteBufferAsBinary< float >(static_cast< long double * >( buffer ), outputFile, m_NumberOfPoints * m_PointDimension);
589 
590         break;
591         }
592       default:
593         {
594         itkExceptionMacro(<< "Unknown point pixel component type" << std::endl);
595         }
596       }
597     }
598 
599   outputFile.close();
600 }
601 
602 void
603 OFFMeshIO
WriteCells(void * buffer)604 ::WriteCells(void *buffer)
605 {
606   // Check file name
607   if ( this->m_FileName.empty() )
608     {
609     itkExceptionMacro("No Input FileName");
610     }
611 
612   // Write to output file
613   std::ofstream outputFile;
614   if ( this->m_FileType == ASCII )
615     {
616     outputFile.open(this->m_FileName.c_str(), std::ios::app);
617     }
618   else if ( m_FileType == BINARY )
619     {
620     outputFile.open(this->m_FileName.c_str(), std::ios::app | std::ios::binary);
621     }
622 
623   if ( !outputFile.is_open() )
624     {
625     itkExceptionMacro("Unable to open file\n"
626                       "outputFilename= " << this->m_FileName);
627     }
628 
629   // Write cells
630   if ( this->m_FileType == ASCII )
631     {
632     switch ( this->m_CellComponentType )
633       {
634       case UCHAR:
635         {
636         WriteCellsAsAscii(static_cast< unsigned char * >( buffer ), outputFile);
637 
638         break;
639         }
640       case CHAR:
641         {
642         WriteCellsAsAscii(static_cast< unsigned char * >( buffer ), outputFile);
643 
644         break;
645         }
646       case USHORT:
647         {
648         WriteCellsAsAscii(static_cast< unsigned short * >( buffer ), outputFile);
649 
650         break;
651         }
652       case SHORT:
653         {
654         WriteCellsAsAscii(static_cast< short * >( buffer ), outputFile);
655 
656         break;
657         }
658       case UINT:
659         {
660         WriteCellsAsAscii(static_cast< unsigned int * >( buffer ), outputFile);
661 
662         break;
663         }
664       case INT:
665         {
666         WriteCellsAsAscii(static_cast< int * >( buffer ), outputFile);
667 
668         break;
669         }
670       case ULONG:
671         {
672         WriteCellsAsAscii(static_cast< long * >( buffer ), outputFile);
673 
674         break;
675         }
676       case LONG:
677         {
678         WriteCellsAsAscii(static_cast< long * >( buffer ), outputFile);
679 
680         break;
681         }
682       case ULONGLONG:
683         {
684         WriteCellsAsAscii(static_cast< unsigned long long * >( buffer ), outputFile);
685 
686         break;
687         }
688       case LONGLONG:
689         {
690         WriteCellsAsAscii(static_cast< long long * >( buffer ), outputFile);
691 
692         break;
693         }
694       case FLOAT:
695         {
696         WriteCellsAsAscii(static_cast< float * >( buffer ), outputFile);
697 
698         break;
699         }
700       case DOUBLE:
701         {
702         WriteCellsAsAscii(static_cast< double * >( buffer ), outputFile);
703 
704         break;
705         }
706       case LDOUBLE:
707         {
708         WriteCellsAsAscii(static_cast< long double * >( buffer ), outputFile);
709 
710         break;
711         }
712       default:
713         {
714         itkExceptionMacro(<< "Unknown cell pixel component type" << std::endl);
715         }
716       }
717     }
718   else if ( this->m_FileType == BINARY )
719     {
720     switch ( this->m_CellComponentType )
721       {
722       case UCHAR:
723         {
724         WriteCellsAsBinary< itk::uint32_t >(static_cast< unsigned char * >( buffer ), outputFile);
725 
726         break;
727         }
728       case CHAR:
729         {
730         WriteCellsAsBinary< itk::uint32_t >(static_cast< char * >( buffer ), outputFile);
731 
732         break;
733         }
734       case USHORT:
735         {
736         WriteCellsAsBinary< itk::uint32_t >(static_cast< unsigned short * >( buffer ), outputFile);
737 
738         break;
739         }
740       case SHORT:
741         {
742         WriteCellsAsBinary< itk::uint32_t >(static_cast< short * >( buffer ), outputFile);
743 
744         break;
745         }
746       case UINT:
747         {
748         WriteCellsAsBinary< itk::uint32_t >(static_cast< unsigned int * >( buffer ), outputFile);
749 
750         break;
751         }
752       case INT:
753         {
754         WriteCellsAsBinary< itk::uint32_t >(static_cast< int * >( buffer ), outputFile);
755 
756         break;
757         }
758       case ULONG:
759         {
760         WriteCellsAsBinary< itk::uint32_t >(static_cast< long * >( buffer ), outputFile);
761 
762         break;
763         }
764       case LONG:
765         {
766         WriteCellsAsBinary< itk::uint32_t >(static_cast< long * >( buffer ), outputFile);
767 
768         break;
769         }
770       case ULONGLONG:
771         {
772         WriteCellsAsBinary< itk::uint32_t >(static_cast< unsigned long long * >( buffer ), outputFile);
773 
774         break;
775         }
776       case LONGLONG:
777         {
778         WriteCellsAsBinary< itk::uint32_t >(static_cast< long long * >( buffer ), outputFile);
779 
780         break;
781         }
782       case FLOAT:
783         {
784         WriteCellsAsBinary< itk::uint32_t >(static_cast< float * >( buffer ), outputFile);
785 
786         break;
787         }
788       case DOUBLE:
789         {
790         WriteCellsAsBinary< itk::uint32_t >(static_cast< double * >( buffer ), outputFile);
791 
792         break;
793         }
794       case LDOUBLE:
795         {
796         WriteCellsAsBinary< itk::uint32_t >(static_cast< long double * >( buffer ), outputFile);
797 
798         break;
799         }
800       default:
801         {
802         itkExceptionMacro(<< "Unknown cell pixel component type" << std::endl);
803         }
804       }
805     }
806 
807   outputFile.close();
808 }
809 
810 void
811 OFFMeshIO
WritePointData(void * itkNotUsed (buffer))812 ::WritePointData(void * itkNotUsed( buffer ) )
813 {
814 }
815 
816 void
817 OFFMeshIO
WriteCellData(void * itkNotUsed (buffer))818 ::WriteCellData(void * itkNotUsed( buffer ) )
819 {
820 }
821 
822 void
823 OFFMeshIO
Write()824 ::Write()
825 {
826 }
827 
828 void
829 OFFMeshIO
PrintSelf(std::ostream & os,Indent indent) const830 ::PrintSelf(std::ostream & os, Indent indent) const
831 {
832   Superclass::PrintSelf(os, indent);
833 }
834 } // namespace itk end
835