Newer
Older
#ifndef VTKMESHDATAREADER_H
#define VTKMESHDATAREADER_H
#include "../Traits.h"
#include "../MeshDataContainer.h"
#include <istream>
#include <map>
#include <sstream>
template <unsigned int MeshDimension, typename IndexType>
class VTKMeshDataReader {
static_assert (MeshDimension == 2 || MeshDimension == 3, "The VTK file format can represent data only in 2D or 3D");
/**
* @brief readColumn
* reads a single column of traited data
*/
static void readColumn(std::istream& ist [[maybe_unused]],...){
DBGMSG("capture");
throw std::runtime_error("capture of read column must not be called.");
}
template<typename T, unsigned int Index, unsigned int Position>
static auto readColumn(std::istream& ist, DataContainer<T, Position, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
-> typename std::enable_if<
Detail::is_indexable<typename Traits<T>::ttype::template type<Index>>::value &&
MeshDimension == 3
>::type
{
ist.seekg(dataPositions[Traits<T>::ttype::template getName<Index>()]);
typename Traits<T>::ttype::template type<Index> value;
for (IndexType i = 0; i < data.size(); i++) {
for (unsigned int j = 0; j < Traits<T>::ttype::template getValue<Index>(data.at(i)).size(); j++){
ist >> value[j];
}
Traits<T>::ttype::template setValue<Index>(data.at(i), value);
}
}
template<typename T, unsigned int Index, unsigned int Position>
static auto readColumn(std::istream& ist, DataContainer<T, Position, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
-> typename std::enable_if<
Detail::is_indexable<typename Traits<T>::ttype::template type<Index>>::value &&
MeshDimension == 2
>::type
{
ist.seekg(dataPositions[Traits<T>::ttype::template getName<Index>()]);
typename Traits<T>::ttype::template type<Index> value;
typename Traits<T>::ttype::template type<Index> dummy;
for (IndexType i = 0; i < data.size(); i++) {
for (unsigned int j = 0; j < Traits<T>::ttype::template getValue<Index>(data.at(i)).size(); j++){
ist >> value[j];
}
ist >> dummy[0];
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Traits<T>::ttype::template setValue<Index>(data.at(i), value);
}
}
template<typename T, unsigned int Index, unsigned int Position>
static auto readColumn(std::istream& ist, DataContainer<T, Position, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
-> typename std::enable_if<
!Detail::is_indexable<typename Traits<T>::ttype::template type<Index>>::value
>::type
{
ist.seekg(dataPositions[Traits<T>::ttype::template getName<Index>()]);
typename Traits<T>::ttype::template type<Index> value;
for (IndexType i = 0; i < data.size(); i++){
ist >> value;
Traits<T>::ttype::template setValue<Index>(data.at(i), value);
}
}
private:
template<typename T,unsigned int Index = 0, typename VOID = void>
struct readCellData{};
template<typename T,unsigned int Index, typename... Types>
struct readCellData <Traits<T, Types...>, Index, std::enable_if_t<Index < Traits<T, Types...>::size() - 1>>{
template<unsigned int Position>
static void read(std::istream& ist, DataContainer<T, Position, MeshDimension> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
DBGVAR(Detail::is_indexable<typename Traits<T>::ttype::template type<Index>>::value);
readColumn<T, Index, Position>(ist, data, dataPositions);
readCellData<Traits<T, Types...>, Index + 1>::read(ist, data, dataPositions);
}
};
template<typename T,unsigned int Index, typename ... Types>
struct readCellData <Traits<T, Types...>, Index, std::enable_if_t<Index == Traits<T, Types...>::size() - 1>>{
template<unsigned int Position>
static void read(std::istream& ist, DataContainer<T, Position, MeshDimension> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
readColumn<T, Index, Position>(ist, data, dataPositions);
}
};
public:
static std::map<std::string, std::istream::pos_type> indexData(std::istream& ist) {
std::map<std::string, std::istream::pos_type> dataPositions;
std::string line;
ist.seekg(ist.beg);
while(getline(ist, line)) {
int flag = (line.find("SCALARS")!= line.npos ? 1
: line.find("VECTORS") != line.npos ? 2
: 0 );
if (flag != 0){
std::string dataName;
std::stringstream sstream(line);
sstream.ignore(9, ' ');
sstream >> dataName;
if (flag == 1) { // scalar quantity found
ist.ignore(500, '\n');
}
dataPositions.insert(std::pair(dataName, ist.tellg()));
}
}
ist.clear();
return dataPositions;
}
template<typename T, unsigned int Position>
static void readData(std::istream& ist, DataContainer<T, Position, MeshDimension>& data) {
std::map<std::string, std::istream::pos_type> dataPositions = indexData(ist);
readCellData<typename Traits<T>::ttype>::read(ist, data, dataPositions);
}
};
#endif // VTKMESHDATAREADER_H