18#ifndef itkVTKPolyDataMeshIO_h
19#define itkVTKPolyDataMeshIO_h
20#include "ITKIOMeshVTKExport.h"
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++]);
155 case CellGeometryEnum::VERTEX_CELL:
157 numberOfVertexIndices += nn + 1;
159 case CellGeometryEnum::LINE_CELL:
161 numberOfLineIndices += nn + 1;
163 case CellGeometryEnum::POLYLINE_CELL:
165 numberOfLineIndices += nn + 1;
167 case CellGeometryEnum::TRIANGLE_CELL:
169 numberOfPolygonIndices += nn + 1;
171 case CellGeometryEnum::POLYGON_CELL:
173 numberOfPolygonIndices += nn + 1;
175 case CellGeometryEnum::QUADRILATERAL_CELL:
177 numberOfPolygonIndices += nn + 1;
180 itkExceptionStringMacro(
"Currently we dont support this cell type");
195 template <
typename T>
201 while (!inputFile.eof())
203 std::getline(inputFile, line,
'\n');
205 if (line.find(
"POINTS") != std::string::npos)
213 template <
typename T>
219 while (!inputFile.eof())
221 std::getline(inputFile, line,
'\n');
223 if (line.find(
"POINTS") != std::string::npos)
227 inputFile.read(
reinterpret_cast<char *
>(buffer), numberOfComponents *
sizeof(T));
242 template <
typename T>
248 while (!inputFile.eof())
250 std::getline(inputFile, line,
'\n');
251 if (line.find(
"POINT_DATA") != std::string::npos)
253 if (!inputFile.eof())
255 std::getline(inputFile, line,
'\n');
259 itkExceptionStringMacro(
"UnExpected end of line while trying to read POINT_DATA");
263 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
265 if (!inputFile.eof())
267 std::getline(inputFile, line,
'\n');
268 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
270 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
275 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
281 else if (line.find(
"FIELD") != std::string::npos)
283 if (!inputFile.eof())
285 std::getline(inputFile, line,
'\n');
289 itkExceptionStringMacro(
"UnExpected end of line while trying to read FIELD array header");
300 template <
typename T>
306 while (!inputFile.eof())
308 std::getline(inputFile, line,
'\n');
309 if (line.find(
"POINT_DATA") != std::string::npos)
311 if (!inputFile.eof())
313 std::getline(inputFile, line,
'\n');
317 itkExceptionStringMacro(
"UnExpected end of line while trying to read POINT_DATA");
321 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
323 if (!inputFile.eof())
325 std::getline(inputFile, line,
'\n');
326 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
328 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
333 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
339 else if (line.find(
"FIELD") != std::string::npos)
341 if (!inputFile.eof())
343 std::getline(inputFile, line,
'\n');
347 itkExceptionStringMacro(
"UnExpected end of line while trying to read FIELD array header");
353 inputFile.read(
reinterpret_cast<char *
>(buffer), numberOfComponents *
sizeof(T));
362 template <
typename T>
368 while (!inputFile.eof())
370 std::getline(inputFile, line,
'\n');
371 if (line.find(
"CELL_DATA") != std::string::npos)
373 if (!inputFile.eof())
375 std::getline(inputFile, line,
'\n');
379 itkExceptionStringMacro(
"UnExpected end of line while trying to read CELL_DATA");
383 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
385 if (!inputFile.eof())
387 std::getline(inputFile, line,
'\n');
388 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
390 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
395 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
399 else if (line.find(
"FIELD") != std::string::npos)
401 if (!inputFile.eof())
403 std::getline(inputFile, line,
'\n');
407 itkExceptionStringMacro(
"UnExpected end of line while trying to read FIELD array header");
418 template <
typename T>
424 while (!inputFile.eof())
426 std::getline(inputFile, line,
'\n');
427 if (line.find(
"CELL_DATA") != std::string::npos)
429 if (!inputFile.eof())
431 std::getline(inputFile, line,
'\n');
435 itkExceptionStringMacro(
"UnExpected end of line while trying to read CELL_DATA");
439 if (line.find(
"SCALARS") != std::string::npos && line.find(
"COLOR_SCALARS") == std::string::npos)
441 if (!inputFile.eof())
443 std::getline(inputFile, line,
'\n');
444 if (line.find(
"LOOKUP_TABLE") == std::string::npos)
446 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
451 itkExceptionStringMacro(
"UnExpected end of line while trying to read LOOKUP_TABLE");
455 else if (line.find(
"FIELD") != std::string::npos)
457 if (!inputFile.eof())
459 std::getline(inputFile, line,
'\n');
463 itkExceptionStringMacro(
"UnExpected end of line while trying to read FIELD array header");
469 inputFile.read(
reinterpret_cast<char *
>(buffer), numberOfComponents *
sizeof(T));
478 template <
typename T>
485 outputFile << pointComponentType <<
'\n';
486 for (
SizeValueType ii = 0; ii < this->m_NumberOfPoints; ++ii)
493 outputFile <<
ConvertNumberToString(buffer[ii * this->m_PointDimension + this->m_PointDimension - 1]) <<
'\n';
497 template <
typename T>
502 outputFile <<
"POINTS " << this->
m_NumberOfPoints << pointComponentType <<
'\n';
508 template <
typename T>
513 unsigned int numberOfVertices = 0;
514 unsigned int numberOfVertexIndices = 0;
515 unsigned int numberOfLines = 0;
516 unsigned int numberOfLineIndices = 0;
517 unsigned int numberOfPolygons = 0;
518 unsigned int numberOfPolygonIndices = 0;
524 if (numberOfVertices)
527 outputFile <<
"VERTICES " << numberOfVertices <<
' ' << numberOfVertexIndices <<
'\n';
530 auto cellType =
static_cast<CellGeometryEnum>(
static_cast<int>(buffer[index++]));
531 auto nn =
static_cast<unsigned int>(buffer[index++]);
532 if (cellType == CellGeometryEnum::VERTEX_CELL)
535 for (
unsigned int jj = 0; jj < nn; ++jj)
537 outputFile <<
' ' << buffer[index++];
553 numberOfLineIndices = 0;
559 auto cellType =
static_cast<CellGeometryEnum>(
static_cast<int>(buffer[index++]));
560 auto nn =
static_cast<unsigned int>(buffer[index++]);
563 if (cellType == CellGeometryEnum::LINE_CELL)
565 pointIds.push_back(
static_cast<SizeValueType>(buffer[index]));
566 pointIds.push_back(
static_cast<SizeValueType>(buffer[index + 1]));
568 else if (cellType == CellGeometryEnum::POLYLINE_CELL)
570 for (
unsigned int jj = 0; jj < nn; ++jj)
572 pointIds.push_back(
static_cast<SizeValueType>(buffer[index + jj]));
576 polylines->InsertElement(numberOfPolylines++, pointIds);
577 numberOfLineIndices += pointIds.size();
581 numberOfLines = polylines->Size();
582 numberOfLineIndices += numberOfLines;
585 outputFile <<
"LINES " << numberOfLines <<
' ' << numberOfLineIndices <<
'\n';
588 auto nn =
static_cast<unsigned int>(polylines->ElementAt(ii).size());
590 for (
unsigned int jj = 0; jj < nn; ++jj)
592 outputFile <<
' ' << polylines->ElementAt(ii)[jj];
601 if (numberOfPolygons)
604 outputFile <<
"POLYGONS " << numberOfPolygons <<
' ' << numberOfPolygonIndices <<
'\n';
607 auto cellType =
static_cast<CellGeometryEnum>(
static_cast<int>(buffer[index++]));
608 auto nn =
static_cast<unsigned int>(buffer[index++]);
609 if (cellType == CellGeometryEnum::POLYGON_CELL || cellType == CellGeometryEnum::TRIANGLE_CELL ||
610 cellType == CellGeometryEnum::QUADRILATERAL_CELL)
613 for (
unsigned int jj = 0; jj < nn; ++jj)
615 outputFile <<
' ' << buffer[index++];
627 template <
typename T>
632 unsigned int numberOfVertices = 0;
633 unsigned int numberOfVertexIndices = 0;
634 unsigned int numberOfLines = 0;
635 unsigned int numberOfLineIndices = 0;
636 unsigned int numberOfPolygons = 0;
637 unsigned int numberOfPolygonIndices = 0;
643 if (numberOfVertices)
646 outputFile <<
"VERTICES " << numberOfVertices <<
' ' << numberOfVertexIndices <<
'\n';
650 data.get(), numberOfVertexIndices, &outputFile);
659 numberOfLineIndices = 0;
665 auto cellType =
static_cast<CellGeometryEnum>(
static_cast<int>(buffer[index++]));
666 auto nn =
static_cast<unsigned int>(buffer[index++]);
669 if (cellType == CellGeometryEnum::LINE_CELL)
671 pointIds.push_back(
static_cast<SizeValueType>(buffer[index]));
672 pointIds.push_back(
static_cast<SizeValueType>(buffer[index + 1]));
674 else if (cellType == CellGeometryEnum::POLYLINE_CELL)
676 for (
unsigned int jj = 0; jj < nn; ++jj)
678 pointIds.push_back(
static_cast<SizeValueType>(buffer[index + jj]));
681 polylines->InsertElement(numberOfPolylines++, pointIds);
682 numberOfLineIndices += pointIds.size();
686 numberOfLines = polylines->Size();
687 numberOfLineIndices += numberOfLines;
691 outputFile <<
"LINES " << numberOfLines <<
' ' << numberOfLineIndices <<
'\n';
693 unsigned long outputIndex = 0;
696 auto nn =
static_cast<unsigned int>(polylines->ElementAt(ii).size());
697 data[outputIndex++] = nn;
698 for (
unsigned int jj = 0; jj < nn; ++jj)
700 data[outputIndex++] = polylines->ElementAt(ii)[jj];
711 if (numberOfPolygons)
714 outputFile <<
"POLYGONS " << numberOfPolygons <<
' ' << numberOfPolygonIndices <<
'\n';
718 data.get(), numberOfPolygonIndices, &outputFile);
723 template <
typename T>
733 case IOPixelEnum::SCALAR:
735 outputFile <<
"SCALARS ";
737 outputFile << dataName <<
" ";
740 case IOPixelEnum::OFFSET:
741 case IOPixelEnum::POINT:
742 case IOPixelEnum::COVARIANTVECTOR:
743 case IOPixelEnum::VECTOR:
745 outputFile <<
"VECTORS ";
747 outputFile << dataName <<
" ";
750 case IOPixelEnum::SYMMETRICSECONDRANKTENSOR:
751 case IOPixelEnum::DIFFUSIONTENSOR3D:
753 outputFile <<
"TENSORS ";
755 outputFile << dataName <<
" ";
758 case IOPixelEnum::ARRAY:
759 case IOPixelEnum::VARIABLELENGTHVECTOR:
761 outputFile <<
"COLOR_SCALARS ";
763 outputFile << dataName <<
" ";
770 itkExceptionStringMacro(
"Unknown point pixel type");
774 outputFile << pointPixelComponentName <<
'\n';
778 outputFile <<
"LOOKUP_TABLE default" <<
'\n';
834 __FILE__, __LINE__,
"itk::ERROR: VTKImageIO2: Unsupported number of components in tensor.", ITK_LOCATION);
840 for (
SizeValueType ii = 0; ii < this->m_NumberOfPointPixels; ++ii)
845 outputFile <<
ConvertNumberToString(buffer[ii * this->m_NumberOfPointPixelComponents + jj]) << indent;
852 template <
typename T>
862 case IOPixelEnum::SCALAR:
864 outputFile <<
"SCALARS ";
866 outputFile << dataName <<
" ";
869 case IOPixelEnum::OFFSET:
870 case IOPixelEnum::POINT:
871 case IOPixelEnum::COVARIANTVECTOR:
872 case IOPixelEnum::VECTOR:
874 outputFile <<
"VECTORS ";
876 outputFile << dataName <<
" ";
879 case IOPixelEnum::SYMMETRICSECONDRANKTENSOR:
880 case IOPixelEnum::DIFFUSIONTENSOR3D:
882 outputFile <<
"TENSORS ";
884 outputFile << dataName <<
" ";
887 case IOPixelEnum::ARRAY:
888 case IOPixelEnum::VARIABLELENGTHVECTOR:
890 outputFile <<
"COLOR_SCALARS ";
892 outputFile << dataName <<
" ";
899 itkExceptionStringMacro(
"Unknown point pixel type");
903 outputFile << pointPixelComponentName <<
'\n';
906 outputFile <<
"LOOKUP_TABLE default\n";
914 template <
typename T>
924 case IOPixelEnum::SCALAR:
926 outputFile <<
"SCALARS ";
928 outputFile << dataName <<
" ";
931 case IOPixelEnum::OFFSET:
932 case IOPixelEnum::POINT:
933 case IOPixelEnum::COVARIANTVECTOR:
934 case IOPixelEnum::VECTOR:
936 outputFile <<
"VECTORS ";
938 outputFile << dataName <<
" ";
941 case IOPixelEnum::SYMMETRICSECONDRANKTENSOR:
942 case IOPixelEnum::DIFFUSIONTENSOR3D:
944 outputFile <<
"TENSORS ";
946 outputFile << dataName <<
" ";
949 case IOPixelEnum::ARRAY:
950 case IOPixelEnum::VARIABLELENGTHVECTOR:
952 outputFile <<
"COLOR_SCALARS ";
954 outputFile << dataName <<
" ";
961 itkExceptionStringMacro(
"Unknown cell pixel type");
965 outputFile << cellPixelComponentName <<
'\n';
968 outputFile <<
"LOOKUP_TABLE default" <<
'\n';
1023 "itk::ERROR: VTKPolyDataMeshIO: Unsupported number of components in tensor.",
1030 for (
SizeValueType ii = 0; ii < this->m_NumberOfCellPixels; ++ii)
1032 unsigned int jj = 0;
1035 outputFile <<
ConvertNumberToString(buffer[ii * this->m_NumberOfCellPixelComponents + jj]) << indent;
1042 template <
typename T>
1052 case IOPixelEnum::SCALAR:
1054 outputFile <<
"SCALARS ";
1056 outputFile << dataName <<
" ";
1059 case IOPixelEnum::OFFSET:
1060 case IOPixelEnum::POINT:
1061 case IOPixelEnum::COVARIANTVECTOR:
1062 case IOPixelEnum::VECTOR:
1064 outputFile <<
"VECTORS ";
1066 outputFile << dataName <<
" ";
1069 case IOPixelEnum::SYMMETRICSECONDRANKTENSOR:
1070 case IOPixelEnum::DIFFUSIONTENSOR3D:
1072 outputFile <<
"TENSORS ";
1074 outputFile << dataName <<
" ";
1077 case IOPixelEnum::ARRAY:
1078 case IOPixelEnum::VARIABLELENGTHVECTOR:
1080 outputFile <<
"COLOR_SCALARS ";
1082 outputFile << dataName <<
" ";
1089 itkExceptionStringMacro(
"Unknown cell pixel type");
1093 outputFile << cellPixelComponentName <<
'\n';
1096 outputFile <<
"LOOKUP_TABLE default\n";
1104 template <
typename T>
1108 unsigned int numberOfPixelComponents,
1111 outputFile << numberOfPixelComponents <<
'\n';
1115 for (
unsigned int jj = 0; jj < numberOfPixelComponents; ++jj)
1124 template <
typename T>
1128 unsigned int numberOfPixelComponents,
1131 outputFile << numberOfPixelComponents <<
'\n';
1132 const SizeValueType numberOfElements = numberOfPixelComponents * numberOfPixels;
1136 data[ii] =
static_cast<unsigned char>(buffer[ii]);
1139 outputFile.write(
reinterpret_cast<char *
>(data.get()), numberOfElements);
1145 template <
typename TInput,
typename TOutput>
1152 if (input && output)
1157 auto nn =
static_cast<unsigned int>(input[inputIndex++]);
1158 output[outputIndex++] = nn;
1159 for (
unsigned int jj = 0; jj < nn; ++jj)
1161 output[outputIndex++] =
static_cast<TOutput
>(input[inputIndex++]);
1176 template <
typename T>
1182 if (!(inputFile >> buffer[i]))
1184 itkGenericExceptionMacro(
"Failed to read a component from the specified ASCII input file!");
1195 template <
typename TOffset>
1199 template <
typename TOffset,
typename TConnectivity>
static constexpr bool SystemIsLittleEndian()
static void SwapWriteRangeFromSystemToBigEndian(const T *p, int num, std::ostream *fp)
static void SwapRangeFromSystemToBigEndian(T *p, BufferSizeType num)
Standard exception handling object.
Control indentation during Print() invocation.
IOPixelEnum m_CellPixelType
unsigned int m_NumberOfPointPixelComponents
SizeValueType m_NumberOfPoints
IdentifierType SizeValueType
unsigned int m_PointDimension
IOPixelEnum m_PointPixelType
SizeValueType m_NumberOfPointPixels
SizeValueType m_NumberOfCellPixels
unsigned int m_NumberOfCellPixelComponents
SizeValueType m_NumberOfCells
MetaDataDictionary & GetMetaDataDictionary()
Implements transparent reference counting.
void ReadCellsBufferAsBINARYConnectivityType(std::ifstream &inputFile, void *buffer)
static void ReadComponentsAsASCII(std::ifstream &inputFile, float *const buffer, const SizeValueType numberOfComponents)
void ReadPointDataBufferAsASCII(std::ifstream &inputFile, T *buffer)
static void ReadComponentsAsASCII(std::ifstream &inputFile, double *const buffer, const SizeValueType numberOfComponents)
void WriteCellDataBufferAsASCII(std::ofstream &outputFile, T *buffer, const StringType &cellPixelComponentName)
void WritePointDataBufferAsASCII(std::ofstream &outputFile, T *buffer, const StringType &pointPixelComponentName)
IOComponentEnum GetComponentTypeFromString(const std::string &pointType)
void WriteCells(void *buffer) override
void WritePointData(void *buffer) override
void ReadCellData(void *buffer) override
PolylinesContainerType::Pointer PolylinesContainerPointer
std::vector< SizeValueType > PointIdVector
SmartPointer< Self > Pointer
bool CanWriteFile(const char *fileName) override
void ReadPointData(void *buffer) override
void WriteMeshInformation() override
SmartPointer< const Self > ConstPointer
void WriteCellData(void *buffer) override
void ReadCellsBufferAsASCII(std::ifstream &inputFile, void *buffer)
void WritePointDataBufferAsBINARY(std::ofstream &outputFile, T *buffer, const StringType &pointPixelComponentName)
void ReadPointDataBufferAsBINARY(std::ifstream &inputFile, T *buffer)
void WriteCellsBufferAsBINARY(std::ofstream &outputFile, T *buffer)
void WriteCellDataBufferAsBINARY(std::ofstream &outputFile, T *buffer, const StringType &cellPixelComponentName)
void PrintSelf(std::ostream &os, Indent indent) const override
void WritePointsBufferAsBINARY(std::ofstream &outputFile, T *buffer, const StringType &pointComponentType)
void WriteColorScalarBufferAsBINARY(std::ofstream &outputFile, T *buffer, unsigned int numberOfPixelComponents, SizeValueType numberOfPixels)
void ReadCellsBufferAsBINARYOffsetType(std::ifstream &inputFile, void *buffer)
void ReadCellsBuffer(TInput *input, TOutput *output)
void ReadPointsBufferAsBINARY(std::ifstream &inputFile, T *buffer)
VectorContainer< PointIdVector > PolylinesContainerType
void ReadCellsBufferAsBINARY(std::ifstream &inputFile, void *buffer)
uint8_t m_ReadMeshVersionMajor
std::vector< StringType > StringVectorType
~VTKPolyDataMeshIO() override
void WritePoints(void *buffer) override
void WritePointsBufferAsASCII(std::ofstream &outputFile, T *buffer, const StringType &pointComponentType)
Superclass::SizeValueType SizeValueType
void ReadCellDataBufferAsBINARY(std::ifstream &inputFile, T *buffer)
void WriteColorScalarBufferAsASCII(std::ofstream &outputFile, T *buffer, unsigned int numberOfPixelComponents, SizeValueType numberOfPixels)
void UpdateCellInformation(T *buffer)
void ReadPointsBufferAsASCII(std::ifstream &inputFile, T *buffer)
void WriteCellsBufferAsASCII(std::ofstream &outputFile, T *buffer)
void ReadCells(void *buffer) override
bool CanReadFile(const char *fileName) override
void ReadMeshInformation() override
static void ReadComponentsAsASCII(std::ifstream &inputFile, T *const buffer, const SizeValueType numberOfComponents)
std::stringstream StringStreamType
int GetNextLine(std::ifstream &ifs, std::string &line, bool lowerCase=true, SizeValueType count=0)
void ReadPoints(void *buffer) override
void ReadCellDataBufferAsASCII(std::ifstream &inputFile, T *buffer)
SmartPointer< Self > Pointer
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
void EncapsulateMetaData(MetaDataDictionary &Dictionary, const std::string &key, const T &invalue)
CommonEnums::IOComponent IOComponentEnum
detail::VectorContainer< std::conditional_t< std::is_void_v< T2 >, SizeValueType, T1 >, std::conditional_t< std::is_void_v< T2 >, T1, T2 > > VectorContainer
std::string ConvertNumberToString(const TValue val)
bool ExposeMetaData(const MetaDataDictionary &Dictionary, const std::string key, T &outval)
CommonEnums::CellGeometry CellGeometryEnum
auto make_unique_for_overwrite(const vcl_size_t numberOfElements)