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