Tatooine
vts_writer.h
Go to the documentation of this file.
1#ifndef TATOOINE_DETAIL_STRUCTURED_GRID_VTS_WRITER_H
2#define TATOOINE_DETAIL_STRUCTURED_GRID_VTS_WRITER_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/linspace.h>
7#include <tatooine/vtk/xml.h>
8
9#include <array>
10#include <vector>
11//==============================================================================
13//==============================================================================
14template <typename Grid, unsigned_integral HeaderType>
15struct vts_writer {
16 using vertex_property_type = typename Grid::vertex_property_type;
17 template <typename T>
19 typename Grid::template typed_vertex_property_type<T>;
20 //----------------------------------------------------------------------------
21 Grid const& m_grid;
22 //----------------------------------------------------------------------------
23 auto write(filesystem::path const& path) const {
24 auto file = std::ofstream{path};
25 if (!file.is_open()) {
26 throw std::runtime_error{"Could open file " + path.string() +
27 " for writing."};
28 }
29 auto offset = std::size_t{};
30 write_vtk_file(file, offset);
31 }
32 //----------------------------------------------------------------------------
33 private:
34 auto write_vtk_file(std::ofstream& file, auto& offset) const {
35 file << "<VTKFile"
36 << " type=\"StructuredGrid\""
37 << " version=\"1.0\""
38 << " byte_order=\"LittleEndian\""
39 << " header_type=\"" << tatooine::vtk::xml::to_data_type<HeaderType>()
40 << "\">\n";
41 write_structured_grid(file, offset);
43 file << "</VTKFile>";
44 }
45 //----------------------------------------------------------------------------
46 auto write_structured_grid(std::ofstream& file, auto& offset) const {
47 file << " <StructuredGrid WholeExtent=\"" << 0 << " " << m_grid.size(0) - 1
48 << " " << 0 << " " << m_grid.size(1) - 1;
49 if (m_grid.num_dimensions() == 3) {
50 file << " " << 0 << " " << m_grid.size(2) - 1;
51 } else if (m_grid.num_dimensions() == 2) {
52 file << " " << 0 << " " << 0;
53 }
54 file << "\">\n";
55 write_piece(file, offset);
56 file << " </StructuredGrid>\n";
57 }
58 //----------------------------------------------------------------------------
59 auto write_piece(std::ofstream& file, auto& offset) const {
60 file << " <Piece Extent=\"";
61 file << "0 " << m_grid.size(0) - 1;
62 file << " 0 " << m_grid.size(1) - 1;
63 if (m_grid.num_dimensions() == 3) {
64 file << " 0 " << m_grid.size(2) - 1;
65 } else if (m_grid.num_dimensions() == 2) {
66 file << " 0 0";
67 }
68 file << "\">\n";
69 write_points(file, offset);
70 write_point_data(file, offset);
71 write_cell_data(file, offset);
72 file << " </Piece>\n";
73 }
74 //----------------------------------------------------------------------------
75 auto write_points(std::ofstream& file, std::size_t& offset) const {
76 file << " <Points>\n";
77 file << " <DataArray"
78 << " format=\"appended\""
79 << " offset=\"" << offset << "\""
80 << " type=\"" << vtk::xml::to_data_type<typename Grid::real_type>()
81 << "\" NumberOfComponents=\"3\"/>\n";
82 file << " </Points>\n";
83 auto const num_bytes = HeaderType(sizeof(typename Grid::real_type) * 3 *
84 m_grid.num_components());
85 offset += num_bytes + sizeof(HeaderType);
86 }
87 //------------------------------------------------------------------------------
88 auto write_point_data(std::ofstream& file, std::size_t& offset) const {
89 file << " <PointData>\n";
90 for (auto const& [name, prop] : m_grid.vertex_properties()) {
93 name, *prop, file, offset);
94 }
95 file << " </PointData>\n";
96 }
97 //----------------------------------------------------------------------------
98 template <typename... Ts>
99 auto write_point_data(std::string const& name, vertex_property_type const& prop,
100 std::ofstream& file, std::size_t& offset) const {
101 invoke([&] {
102 if (prop.type() == typeid(Ts)) {
103 if constexpr (tensor_rank<Ts> <= 1) {
104 file << " <DataArray"
105 << " Name=\"" << name << "\""
106 << " format=\"appended\""
107 << " offset=\"" << offset << "\""
108 << " type=\""
109 << tatooine::vtk::xml::to_data_type<tatooine::value_type<Ts>>()
110 << "\" NumberOfComponents=\""
111 << tensor_num_components<Ts> << "\"/>\n";
112 offset += m_grid.num_vertices() * sizeof(Ts) + sizeof(HeaderType);
113 } else if constexpr (tensor_rank<Ts> == 2) {
114 for (std::size_t i = 0; i < Ts::dimension(1); ++i) {
115 file << " <DataArray"
116 << " Name=\"" << name << "_col_" << i << "\""
117 << " format=\"appended\""
118 << " offset=\"" << offset << "\""
119 << " type=\""
120 << vtk::xml::to_data_type<tatooine::value_type<Ts>>()
121 << "\" NumberOfComponents=\"" << Ts::dimension(0) << "\"/>\n";
122 offset += m_grid.num_vertices() * sizeof(tatooine::value_type<Ts>) *
123 tensor_dimension<Ts, 0> +
124 sizeof(HeaderType);
125 }
126 }
127 }
128 }...);
129 }
130 //------------------------------------------------------------------------------
131 auto write_cell_data(std::ofstream& file, std::size_t& /*offset*/) const {
132 file << " <CellData>\n";
133 // TODO
134 file << " </CellData>\n";
135 }
136 //----------------------------------------------------------------------------
137 auto write_appended_data(std::ofstream& file) const {
138 file << " <AppendedData encoding=\"raw\">\n _";
139 write_appended_data_points(file);
140 write_appended_data_point_data(file);
141 write_appended_data_cell_data(file);
142 file << "\n </AppendedData>\n";
143 }
144 //----------------------------------------------------------------------------
145 auto write_appended_data_points(std::ofstream& file) const {
146 auto arr_size = HeaderType(sizeof(typename Grid::real_type) * 3 *
147 m_grid.vertices().size());
148 file.write(reinterpret_cast<char const*>(&arr_size), sizeof(HeaderType));
149 auto zero = (typename Grid::real_type)(0);
150 for (auto const v : m_grid.vertices()) {
151 if constexpr (m_grid.num_dimensions() == 2) {
152 file.write(reinterpret_cast<char const*>(m_grid[v].data()),
153 sizeof(typename Grid::real_type) * 2);
154 file.write(reinterpret_cast<char const*>(&zero),
155 sizeof(typename Grid::real_type));
156 } else if constexpr (m_grid.num_dimensions() == 3) {
157 file.write(reinterpret_cast<char const*>(m_grid[v].data()),
158 sizeof(typename Grid::real_type) * 3);
159 }
160 }
161 }
162 //----------------------------------------------------------------------------
163 auto write_appended_data_point_data(std::ofstream& file) const {
164 for (auto const& [name, prop] : m_grid.vertex_properties()) {
165 write_appended_data_point_data<float, vec2f, vec3f, vec4f, mat2f, mat3f,
167 mat3d, mat4d>(*prop, file);
168 }
169 }
170 //----------------------------------------------------------------------------
171 template <typename... Ts>
173 std::ofstream& file) const {
174 invoke([&] {
175 if (prop.type() == typeid(Ts)) {
176 write_appended_data_point_data(prop.template cast_to_typed<Ts>(), file);
177 }
178 }...);
179 }
180 //----------------------------------------------------------------------------
181 template <typename T>
183 std::ofstream& file) const {
184 if constexpr (tensor_rank<T> <= 1) {
185 auto data = std::vector<T>{};
186 for (auto const v : m_grid.vertices()) {
187 data.push_back(prop[v]);
188 }
189 auto const num_bytes =
190 HeaderType(sizeof(tatooine::value_type<T>) * tensor_num_components<T> *
191 m_grid.num_vertices());
192 file.write(reinterpret_cast<char const*>(&num_bytes), sizeof(HeaderType));
193 file.write(reinterpret_cast<char const*>(data.data()), num_bytes);
194 } else if constexpr (tensor_rank<T> == 2) {
195 auto const num_bytes =
196 HeaderType(sizeof(tatooine::value_type<T>) * tensor_num_components<T> *
197 m_grid.num_vertices() / tensor_dimension<T, 0>);
198 for (std::size_t i = 0; i < tensor_dimension<T, 1>; ++i) {
199 file.write(reinterpret_cast<char const*>(&num_bytes),
200 sizeof(HeaderType));
201 for (auto const v : m_grid.vertices()) {
202 auto data_begin = &prop[v](0, i);
203 file.write(reinterpret_cast<char const*>(data_begin),
204 sizeof(tatooine::value_type<T>) * tensor_dimension<T, 0>);
205 }
206 }
207 }
208 }
209 //----------------------------------------------------------------------------
210 auto write_appended_data_cell_data(std::ofstream& /*file*/) const {
211 // TODO
212 }
213};
214//==============================================================================
215} // namespace tatooine::detail::structured_grid
216//==============================================================================
217#endif
Definition: vertex_container.h:18
VecF< 3 > vec3f
Definition: vec_typedefs.h:40
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
mat44f mat4f
Definition: mat_typedefs.h:299
VecD< 3 > vec3d
Definition: vec_typedefs.h:51
mat22d mat2d
Definition: mat_typedefs.h:370
mat33d mat3d
Definition: mat_typedefs.h:371
constexpr auto invoke(invocable auto &&...funcs)
Definition: functional.h:8
mat33f mat3f
Definition: mat_typedefs.h:298
VecD< 2 > vec2d
Definition: vec_typedefs.h:50
VecF< 4 > vec4f
Definition: vec_typedefs.h:41
VecD< 4 > vec4d
Definition: vec_typedefs.h:52
mat22f mat2f
Definition: mat_typedefs.h:297
VecF< 2 > vec2f
Definition: vec_typedefs.h:39
auto write_appended_data_point_data(vertex_property_type const &prop, std::ofstream &file) const
Definition: vts_writer.h:172
auto write_appended_data_point_data(typed_vertex_property_type< T > const &prop, std::ofstream &file) const
Definition: vts_writer.h:182
auto write_appended_data_points(std::ofstream &file) const
Definition: vts_writer.h:145
typename Grid::vertex_property_type vertex_property_type
Definition: vts_writer.h:16
auto write_point_data(std::string const &name, vertex_property_type const &prop, std::ofstream &file, std::size_t &offset) const
Definition: vts_writer.h:99
auto write_structured_grid(std::ofstream &file, auto &offset) const
Definition: vts_writer.h:46
auto write_appended_data_cell_data(std::ofstream &) const
Definition: vts_writer.h:210
auto write_piece(std::ofstream &file, auto &offset) const
Definition: vts_writer.h:59
auto write_appended_data_point_data(std::ofstream &file) const
Definition: vts_writer.h:163
Grid const & m_grid
Definition: vts_writer.h:21
auto write_appended_data(std::ofstream &file) const
Definition: vts_writer.h:137
auto write_cell_data(std::ofstream &file, std::size_t &) const
Definition: vts_writer.h:131
typename Grid::template typed_vertex_property_type< T > typed_vertex_property_type
Definition: vts_writer.h:19
auto write(filesystem::path const &path) const
Definition: vts_writer.h:23
auto write_points(std::ofstream &file, std::size_t &offset) const
Definition: vts_writer.h:75
auto write_point_data(std::ofstream &file, std::size_t &offset) const
Definition: vts_writer.h:88
auto write_vtk_file(std::ofstream &file, auto &offset) const
Definition: vts_writer.h:34
Definition: mat.h:14