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