18 #ifndef itkVTKPolyDataMeshIO_h
19 #define itkVTKPolyDataMeshIO_h
20 #include "ITKIOMeshVTKExport.h"
76 CanReadFile(
const char * fileName)
override;
80 ReadMeshInformation()
override;
84 ReadPoints(
void * buffer)
override;
87 ReadCells(
void * buffer)
override;
90 ReadPointData(
void * buffer)
override;
93 ReadCellData(
void * buffer)
override;
102 CanWriteFile(
const char * fileName)
override;
106 WriteMeshInformation()
override;
111 WritePoints(
void * buffer)
override;
114 WriteCells(
void * buffer)
override;
117 WritePointData(
void * buffer)
override;
120 WriteCellData(
void * buffer)
override;
130 PrintSelf(std::ostream & os,
Indent indent)
const override;
134 GetNextLine(std::ifstream & ifs, std::string & line,
bool lowerCase =
true,
SizeValueType count = 0);
136 template <
typename T>
140 unsigned int numberOfVertices = 0;
141 unsigned int numberOfVertexIndices = 0;
142 unsigned int numberOfLines = 0;
144 unsigned int numberOfPolygons = 0;
145 unsigned int numberOfPolygonIndices = 0;
151 auto cellType = static_cast<CellGeometryEnum>(static_cast<int>(buffer[index++]));
152 auto nn = static_cast<unsigned int>(buffer[index++]);
157 numberOfVertexIndices += nn + 1;
161 numberOfLineIndices += nn + 1;
165 numberOfLineIndices += nn + 1;
169 numberOfPolygonIndices += nn + 1;
173 numberOfPolygonIndices += nn + 1;
177 numberOfPolygonIndices += nn + 1;
180 itkExceptionMacro(
"Currently we dont support this cell type");
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);
196 template <
typename T>
202 while (!inputFile.eof())
204 std::getline(inputFile, line,
'\n');
206 if (line.find(
"POINTS") != std::string::npos)
209 Self::ReadComponentsAsASCII(inputFile, buffer, this->m_NumberOfPoints * this->m_PointDimension);
214 template <
typename T>
220 while (!inputFile.eof())
222 std::getline(inputFile, line,
'\n');
224 if (line.find(
"POINTS") != std::string::npos)
227 SizeValueType numberOfComponents = this->m_NumberOfPoints * this->m_PointDimension;
228 inputFile.read(reinterpret_cast<char *>(buffer), numberOfComponents *
sizeof(T));
239 ReadCellsBufferAsASCII(std::ifstream & inputFile,
void * buffer);
242 ReadCellsBufferAsBINARY(std::ifstream & inputFile,
void * buffer);
244 template <
typename T>
250 while (!inputFile.eof())
252 std::getline(inputFile, line,
'\n');
253 if (line.find(
"POINT_DATA") != std::string::npos)
255 if (!inputFile.eof())
257 std::getline(inputFile, line,
'\n');
261 itkExceptionMacro(
"UnExpected end of line while trying to read POINT_DATA");
265 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
267 if (!inputFile.eof())
269 std::getline(inputFile, line,
'\n');
270 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
272 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
277 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
283 Self::ReadComponentsAsASCII(
284 inputFile, buffer, this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents);
289 template <
typename T>
295 while (!inputFile.eof())
297 std::getline(inputFile, line,
'\n');
298 if (line.find(
"POINT_DATA") != std::string::npos)
300 if (!inputFile.eof())
302 std::getline(inputFile, line,
'\n');
306 itkExceptionMacro(
"UnExpected end of line while trying to read POINT_DATA");
310 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
312 if (!inputFile.eof())
314 std::getline(inputFile, line,
'\n');
315 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
317 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
322 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
328 SizeValueType numberOfComponents = this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents;
329 inputFile.read(reinterpret_cast<char *>(buffer), numberOfComponents *
sizeof(T));
339 template <
typename T>
345 while (!inputFile.eof())
347 std::getline(inputFile, line,
'\n');
348 if (line.find(
"CELL_DATA") != std::string::npos)
350 if (!inputFile.eof())
352 std::getline(inputFile, line,
'\n');
356 itkExceptionMacro(
"UnExpected end of line while trying to read CELL_DATA");
360 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
362 if (!inputFile.eof())
364 std::getline(inputFile, line,
'\n');
365 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
367 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
372 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
378 Self::ReadComponentsAsASCII(
379 inputFile, buffer, this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents);
384 template <
typename T>
390 while (!inputFile.eof())
392 std::getline(inputFile, line,
'\n');
393 if (line.find(
"POINT_DATA") != std::string::npos)
395 if (!inputFile.eof())
397 std::getline(inputFile, line,
'\n');
401 itkExceptionMacro(
"UnExpected end of line while trying to read POINT_DATA");
405 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
407 if (!inputFile.eof())
409 std::getline(inputFile, line,
'\n');
410 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
412 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
417 itkExceptionMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
422 SizeValueType numberOfComponents = this->m_NumberOfCellPixels * this->m_NumberOfCellPixelComponents;
423 inputFile.read(reinterpret_cast<char *>(buffer), numberOfComponents *
sizeof(T));
433 template <
typename T>
438 outputFile <<
"POINTS " << this->m_NumberOfPoints;
440 outputFile << pointComponentType <<
'\n';
441 for (
SizeValueType ii = 0; ii < this->m_NumberOfPoints; ++ii)
443 for (
unsigned int jj = 0; jj < this->m_PointDimension - 1; ++jj)
448 outputFile <<
ConvertNumberToString(buffer[ii * this->m_PointDimension + this->m_PointDimension - 1]) <<
'\n';
454 template <
typename T>
459 outputFile <<
"POINTS " << this->m_NumberOfPoints << pointComponentType <<
'\n';
461 buffer, this->m_NumberOfPoints * this->m_PointDimension, &outputFile);
467 template <
typename T>
472 unsigned int numberOfVertices = 0;
473 unsigned int numberOfVertexIndices = 0;
474 unsigned int numberOfLines = 0;
475 unsigned int numberOfLineIndices = 0;
476 unsigned int numberOfPolygons = 0;
477 unsigned int numberOfPolygonIndices = 0;
482 ExposeMetaData<unsigned int>(metaDic,
"numberOfVertices", numberOfVertices);
483 if (numberOfVertices)
485 ExposeMetaData<unsigned int>(metaDic,
"numberOfVertexIndices", numberOfVertexIndices);
486 outputFile <<
"VERTICES " << numberOfVertices <<
' ' << numberOfVertexIndices <<
'\n';
489 auto cellType = static_cast<CellGeometryEnum>(static_cast<int>(buffer[index++]));
490 auto nn = static_cast<unsigned int>(buffer[index++]);
494 for (
unsigned int jj = 0; jj < nn; ++jj)
496 outputFile <<
' ' << buffer[index++];
509 ExposeMetaData<unsigned int>(metaDic,
"numberOfLines", numberOfLines);
512 numberOfLineIndices = 0;
518 auto cellType = static_cast<CellGeometryEnum>(static_cast<int>(buffer[index++]));
519 auto nn = static_cast<unsigned int>(buffer[index++]);
525 pointIds.push_back(static_cast<SizeValueType>(buffer[index]));
526 pointIds.push_back(static_cast<SizeValueType>(buffer[index + 1]));
530 for (
unsigned int jj = 0; jj < nn; ++jj)
532 pointIds.push_back(static_cast<SizeValueType>(buffer[index + jj]));
536 polylines->InsertElement(numberOfPolylines++, pointIds);
537 numberOfLineIndices += pointIds.size();
541 numberOfLines = polylines->Size();
542 numberOfLineIndices += numberOfLines;
543 EncapsulateMetaData<unsigned int>(metaDic,
"numberOfLines", numberOfLines);
544 EncapsulateMetaData<unsigned int>(metaDic,
"numberOfLineIndices", numberOfLineIndices);
545 outputFile <<
"LINES " << numberOfLines <<
' ' << numberOfLineIndices <<
'\n';
548 auto nn = static_cast<unsigned int>(polylines->ElementAt(ii).size());
550 for (
unsigned int jj = 0; jj < nn; ++jj)
552 outputFile <<
' ' << polylines->ElementAt(ii)[jj];
560 ExposeMetaData<unsigned int>(metaDic,
"numberOfPolygons", numberOfPolygons);
561 if (numberOfPolygons)
563 ExposeMetaData<unsigned int>(metaDic,
"numberOfPolygonIndices", numberOfPolygonIndices);
564 outputFile <<
"POLYGONS " << numberOfPolygons <<
' ' << numberOfPolygonIndices <<
'\n';
567 auto cellType = static_cast<CellGeometryEnum>(static_cast<int>(buffer[index++]));
568 auto nn = static_cast<unsigned int>(buffer[index++]);
573 for (
unsigned int jj = 0; jj < nn; ++jj)
575 outputFile <<
' ' << buffer[index++];
588 template <
typename T>
593 unsigned int numberOfVertices = 0;
594 unsigned int numberOfVertexIndices = 0;
595 unsigned int numberOfLines = 0;
596 unsigned int numberOfLineIndices = 0;
597 unsigned int numberOfPolygons = 0;
598 unsigned int numberOfPolygonIndices = 0;
603 ExposeMetaData<unsigned int>(metaDic,
"numberOfVertices", numberOfVertices);
604 if (numberOfVertices)
606 ExposeMetaData<unsigned int>(metaDic,
"numberOfVertexIndices", numberOfVertexIndices);
607 outputFile <<
"VERTICES " << numberOfVertices <<
' ' << numberOfVertexIndices <<
'\n';
608 const auto data = make_unique_for_overwrite<unsigned int[]>(numberOfVertexIndices);
609 ReadCellsBuffer(buffer, data.get());
611 data.get(), numberOfVertexIndices, &outputFile);
617 ExposeMetaData<unsigned int>(metaDic,
"numberOfLines", numberOfLines);
620 numberOfLineIndices = 0;
626 auto cellType = static_cast<CellGeometryEnum>(static_cast<int>(buffer[index++]));
627 auto nn = static_cast<unsigned int>(buffer[index++]);
633 pointIds.push_back(static_cast<SizeValueType>(buffer[index]));
634 pointIds.push_back(static_cast<SizeValueType>(buffer[index + 1]));
638 for (
unsigned int jj = 0; jj < nn; ++jj)
640 pointIds.push_back(static_cast<SizeValueType>(buffer[index + jj]));
643 polylines->InsertElement(numberOfPolylines++, pointIds);
644 numberOfLineIndices += pointIds.size();
648 numberOfLines = polylines->Size();
649 numberOfLineIndices += numberOfLines;
650 EncapsulateMetaData<unsigned int>(metaDic,
"numberOfLines", numberOfLines);
651 EncapsulateMetaData<unsigned int>(metaDic,
"numberOfLineIndices", numberOfLineIndices);
653 outputFile <<
"LINES " << numberOfLines <<
' ' << numberOfLineIndices <<
'\n';
654 const auto data = make_unique_for_overwrite<unsigned int[]>(numberOfLineIndices);
655 unsigned long outputIndex = 0;
658 auto nn = static_cast<unsigned int>(polylines->ElementAt(ii).size());
659 data[outputIndex++] = nn;
660 for (
unsigned int jj = 0; jj < nn; ++jj)
662 data[outputIndex++] = polylines->ElementAt(ii)[jj];
672 ExposeMetaData<unsigned int>(metaDic,
"numberOfPolygons", numberOfPolygons);
673 if (numberOfPolygons)
675 ExposeMetaData<unsigned int>(metaDic,
"numberOfPolygonIndices", numberOfPolygonIndices);
676 outputFile <<
"POLYGONS " << numberOfPolygons <<
' ' << numberOfPolygonIndices <<
'\n';
677 const auto data = make_unique_for_overwrite<unsigned int[]>(numberOfPolygonIndices);
678 ReadCellsBuffer(buffer, data.get());
680 data.get(), numberOfPolygonIndices, &outputFile);
686 template <
typename T>
693 outputFile <<
"POINT_DATA " << this->m_NumberOfPointPixels <<
'\n';
694 switch (this->m_PointPixelType)
698 outputFile <<
"SCALARS ";
699 ExposeMetaData<StringType>(metaDic,
"pointScalarDataName", dataName);
700 outputFile << dataName <<
" ";
708 outputFile <<
"VECTORS ";
709 ExposeMetaData<StringType>(metaDic,
"pointVectorDataName", dataName);
710 outputFile << dataName <<
" ";
716 outputFile <<
"TENSORS ";
717 ExposeMetaData<StringType>(metaDic,
"pointTensorDataName", dataName);
718 outputFile << dataName <<
" ";
724 outputFile <<
"COLOR_SCALARS ";
725 ExposeMetaData<StringType>(metaDic,
"pointColorScalarDataName", dataName);
726 outputFile << dataName <<
" ";
727 WriteColorScalarBufferAsASCII(
728 outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels);
733 itkExceptionMacro(
"Unknown point pixel type");
737 outputFile << pointPixelComponentName <<
'\n';
741 outputFile <<
"LOOKUP_TABLE default" <<
'\n';
749 const SizeValueType num = this->m_NumberOfPointPixelComponents * this->m_NumberOfPointPixels;
752 if (this->m_NumberOfPointPixelComponents == 3)
771 else if (this->m_NumberOfPointPixelComponents == 6)
796 itk::ExceptionObject e_(
797 __FILE__, __LINE__,
"itk::ERROR: VTKImageIO2: Unsupported number of components in tensor.", ITK_LOCATION);
804 for (
SizeValueType ii = 0; ii < this->m_NumberOfPointPixels; ++ii)
806 for (jj = 0; jj < this->m_NumberOfPointPixelComponents - 1; ++jj)
808 outputFile <<
ConvertNumberToString(buffer[ii * this->m_NumberOfPointPixelComponents + jj]) << indent;
817 template <
typename T>
824 outputFile <<
"POINT_DATA " << this->m_NumberOfPointPixels <<
'\n';
825 switch (this->m_PointPixelType)
829 outputFile <<
"SCALARS ";
830 ExposeMetaData<StringType>(metaDic,
"pointScalarDataName", dataName);
831 outputFile << dataName <<
" ";
839 outputFile <<
"VECTORS ";
840 ExposeMetaData<StringType>(metaDic,
"pointVectorDataName", dataName);
841 outputFile << dataName <<
" ";
847 outputFile <<
"TENSORS ";
848 ExposeMetaData<StringType>(metaDic,
"pointTensorDataName", dataName);
849 outputFile << dataName <<
" ";
855 outputFile <<
"COLOR_SCALARS ";
856 ExposeMetaData<StringType>(metaDic,
"pointColorScalarDataName", dataName);
857 outputFile << dataName <<
" ";
858 WriteColorScalarBufferAsBINARY(
859 outputFile, buffer, this->m_NumberOfPointPixelComponents, this->m_NumberOfPointPixels);
864 itkExceptionMacro(
"Unknown point pixel type");
868 outputFile << pointPixelComponentName <<
'\n';
871 outputFile <<
"LOOKUP_TABLE default\n";
875 buffer, this->m_NumberOfPointPixels * this->m_NumberOfPointPixelComponents, &outputFile);
880 template <
typename T>
887 outputFile <<
"CELL_DATA " << this->m_NumberOfCellPixels <<
'\n';
888 switch (this->m_CellPixelType)
892 outputFile <<
"SCALARS ";
893 ExposeMetaData<StringType>(metaDic,
"cellScalarDataName", dataName);
894 outputFile << dataName <<
" ";
902 outputFile <<
"VECTORS ";
903 ExposeMetaData<StringType>(metaDic,
"cellVectorDataName", dataName);
904 outputFile << dataName <<
" ";
910 outputFile <<
"TENSORS ";
911 ExposeMetaData<StringType>(metaDic,
"cellTensorDataName", dataName);
912 outputFile << dataName <<
" ";
918 outputFile <<
"COLOR_SCALARS ";
919 ExposeMetaData<StringType>(metaDic,
"cellColorScalarDataName", dataName);
920 outputFile << dataName <<
" ";
921 WriteColorScalarBufferAsASCII(
922 outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels);
927 itkExceptionMacro(
"Unknown cell pixel type");
931 outputFile << cellPixelComponentName <<
'\n';
934 outputFile <<
"LOOKUP_TABLE default" <<
'\n';
942 const SizeValueType num = this->m_NumberOfCellPixelComponents * this->m_NumberOfCellPixels;
943 if (this->m_NumberOfCellPixelComponents == 2)
950 outputFile << *ptr++ << indent;
952 outputFile << e12 << indent << zero <<
'\n';
954 outputFile << e12 << indent << *ptr++ << indent << zero <<
'\n';
956 outputFile << zero << indent << zero << indent << zero <<
"\n\n";
960 else if (this->m_NumberOfCellPixelComponents == 3)
968 outputFile << *ptr++ << indent;
970 outputFile << e12 << indent;
972 outputFile << e13 <<
'\n';
974 outputFile << e12 << indent << *ptr++ << indent;
976 outputFile << e23 <<
'\n';
978 outputFile << e13 << indent << e23 << indent << *ptr++ <<
"\n\n";
984 ExceptionObject e_(__FILE__,
986 "itk::ERROR: VTKPolyDataMeshIO: Unsupported number of components in tensor.",
994 for (
SizeValueType ii = 0; ii < this->m_NumberOfCellPixels; ++ii)
996 for (jj = 0; jj < this->m_NumberOfCellPixelComponents - 1; ++jj)
998 outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj] << indent;
1000 outputFile << buffer[ii * this->m_NumberOfCellPixelComponents + jj] <<
'\n';
1007 template <
typename T>
1014 outputFile <<
"CELL_DATA " << this->m_NumberOfCellPixels <<
'\n';
1015 switch (this->m_CellPixelType)
1019 outputFile <<
"SCALARS ";
1020 ExposeMetaData<StringType>(metaDic,
"cellScalarDataName", dataName);
1021 outputFile << dataName <<
" ";
1029 outputFile <<
"VECTORS ";
1030 ExposeMetaData<StringType>(metaDic,
"cellVectorDataName", dataName);
1031 outputFile << dataName <<
" ";
1037 outputFile <<
"TENSORS ";
1038 ExposeMetaData<StringType>(metaDic,
"cellTensorDataName", dataName);
1039 outputFile << dataName <<
" ";
1045 outputFile <<
"COLOR_SCALARS ";
1046 ExposeMetaData<StringType>(metaDic,
"cellColorScalarDataName", dataName);
1047 outputFile << dataName <<
" ";
1048 WriteColorScalarBufferAsBINARY(
1049 outputFile, buffer, this->m_NumberOfCellPixelComponents, this->m_NumberOfCellPixels);
1054 itkExceptionMacro(
"Unknown cell pixel type");
1058 outputFile << cellPixelComponentName <<
'\n';
1061 outputFile <<
"LOOKUP_TABLE default\n";
1065 buffer, this->m_NumberOfCells * this->m_NumberOfCellPixelComponents, &outputFile);
1070 template <
typename T>
1074 unsigned int numberOfPixelComponents,
1077 outputFile << numberOfPixelComponents <<
'\n';
1081 for (
unsigned int jj = 0; jj < numberOfPixelComponents; ++jj)
1083 outputFile << ConvertNumberToString(static_cast<float>(buffer[ii * numberOfPixelComponents + jj])) << indent;
1092 template <
typename T>
1096 unsigned int numberOfPixelComponents,
1099 outputFile << numberOfPixelComponents <<
'\n';
1100 SizeValueType numberOfElements = numberOfPixelComponents * numberOfPixels;
1101 const auto data = make_unique_for_overwrite<unsigned char[]>(numberOfElements);
1104 data[ii] = static_cast<unsigned char>(buffer[ii]);
1107 outputFile.write(reinterpret_cast<char *>(data.get()), numberOfElements);
1114 template <
typename TInput,
typename TOutput>
1121 if (input && output)
1123 for (
SizeValueType ii = 0; ii < this->m_NumberOfCells; ++ii)
1126 auto nn = static_cast<unsigned int>(input[inputIndex++]);
1127 output[outputIndex++] = nn;
1128 for (
unsigned int jj = 0; jj < nn; ++jj)
1130 output[outputIndex++] = static_cast<TOutput>(input[inputIndex++]);
1138 GetComponentTypeFromString(
const std::string & pointType);
1145 template <
typename T>
1151 if (!(inputFile >> buffer[i]))
1153 itkGenericExceptionMacro(
"Failed to read a component from the specified ASCII input file!");
1160 ReadComponentsAsASCII(std::ifstream & inputFile,
float *
const buffer,
const SizeValueType numberOfComponents);
1163 ReadComponentsAsASCII(std::ifstream & inputFile,
double *
const buffer,
const SizeValueType numberOfComponents);
1165 template <
typename TOffset>
1167 ReadCellsBufferAsBINARYOffsetType(std::ifstream & inputFile,
void * buffer);
1169 template <
typename TOffset,
typename TConnectivity>
1171 ReadCellsBufferAsBINARYConnectivityType(std::ifstream & inputFile,
void * buffer);
1173 uint8_t m_ReadMeshVersionMajor{ 4 };
1177 #endif // itkVTKPolyDataMeshIO_h