Tatooine
vtk_legacy.h
Go to the documentation of this file.
1#ifndef TATOOINE_VTK_LEGACY_H
2#define TATOOINE_VTK_LEGACY_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/parse.h>
8#include <tatooine/tensor.h>
12
13#include <cassert>
14#include <cstdlib>
15#include <exception>
16#include <fstream>
17#include <future>
18#include <iostream>
19#include <istream>
20#include <map>
21#include <sstream>
22#include <vector>
23//=============================================================================
24namespace tatooine::vtk {
25//=============================================================================
28auto read_until(std::istream &stream, char const terminator_char, char *buffer)
29 -> std::string;
30//-----------------------------------------------------------------------------
32auto read_binaryline(std::istream &stream, char *buffer) -> std::string;
33//-----------------------------------------------------------------------------
36auto read_word(std::istream &stream, char *buffer) -> std::string;
37//-----------------------------------------------------------------------------
38auto write_binary(std::ostream &stream, std::string const &str) -> void;
39//-----------------------------------------------------------------------------
40auto write_binary(std::ostream &stream, char const c) -> void;
41//------------------------------------------------------------------------------
43//------------------------------------------------------------------------------
44enum class dataset_type {
50 field,
52};
53//------------------------------------------------------------------------------
54constexpr auto to_string_view(dataset_type type) -> std::string_view {
55 switch (type) {
57 return "STRUCTURED_POINTS";
59 return "STRUCTURED_GRID";
61 return "UNSTRUCTURED_GRID";
63 return "POLYDATA";
65 return "RECTILINEAR_GRID";
67 return "FIELD";
68 default:
70 return "UNKNOWN";
71 }
72}
73//------------------------------------------------------------------------------
74auto parse_dataset_type(std::string const &) -> dataset_type;
75//==============================================================================
76enum class format { ascii, binary, unknown };
77//------------------------------------------------------------------------------
78constexpr auto to_string_view(format f) -> std::string_view {
79 switch (f) {
80 case format::ascii:
81 return "ASCII";
82 case format::binary:
83 return "BINARY";
84 default:
85 case format::unknown:
86 return "UNKNOWN";
87 }
88}
89//------------------------------------------------------------------------------
90auto parse_format(std::string const &) -> format;
91//==============================================================================
93 virtual ~legacy_file_listener() = default;
94 // header data
95 virtual auto on_version(unsigned short /*major*/, unsigned short /*minor*/)
96 -> void {}
97 virtual auto on_title(std::string const &) -> void {}
98 virtual auto on_format(format) -> void {}
99 virtual auto on_dataset_type(dataset_type) -> void {}
100
101 // coordinate data
102 virtual auto on_points(std::vector<std::array<float, 3>> const &) -> void {}
103 virtual auto on_points(std::vector<std::array<double, 3>> const &) -> void {}
104 virtual auto on_origin(double /*x*/, double /*y*/, double /*z*/) -> void {}
105 virtual auto on_spacing(double /*x*/, double /*y*/, double /*z*/) -> void {}
106 virtual auto on_dimensions(std::size_t /*x*/, std::size_t /*y*/,
107 std::size_t /*z*/) -> void {}
108 virtual auto on_x_coordinates(std::vector<float> const & /*xs*/) -> void {}
109 virtual auto on_x_coordinates(std::vector<double> const & /*xs*/) -> void {}
110 virtual auto on_y_coordinates(std::vector<float> const & /*ys*/) -> void {}
111 virtual auto on_y_coordinates(std::vector<double> const & /*ys*/) -> void {}
112 virtual auto on_z_coordinates(std::vector<float> const & /*zs*/) -> void {}
113 virtual auto on_z_coordinates(std::vector<double> const & /*zs*/) -> void {}
114
115 // index data
116 virtual auto on_cells(std::vector<int> const &) -> void {}
117 virtual auto on_cell_types(std::vector<cell_type> const &) -> void {}
118 virtual auto on_vertices(std::vector<int> const &) -> void {}
119 virtual auto on_lines(std::vector<int> const &) -> void {}
120 virtual auto on_polygons(std::vector<int> const &) -> void {}
121 virtual auto on_triangle_strips(std::vector<int> const &) -> void {}
122
123 // cell- / pointdata
124 virtual auto on_vectors(std::string const & /*name*/,
125 std::vector<std::array<float, 3>> const & /*vectors*/,
126 reader_data) -> void {}
127 virtual auto on_vectors(
128 std::string const & /*name*/,
129 std::vector<std::array<double, 3>> const & /*vectors*/, reader_data)
130 -> void {}
131 virtual auto on_normals(std::string const & /*name*/,
132 std::vector<std::array<float, 3>> const & /*normals*/,
133 reader_data) -> void {}
134 virtual auto on_normals(
135 std::string const & /*name*/,
136 std::vector<std::array<double, 3>> const & /*normals*/, reader_data)
137 -> void {}
139 std::string const & /*name*/,
140 std::vector<std::array<float, 2>> const & /*texture_coordinates*/,
141 reader_data) -> void {}
143 std::string const & /*name*/,
144 std::vector<std::array<double, 2>> const & /*texture_coordinates*/,
145 reader_data) -> void {}
146 virtual auto on_tensors(std::string const & /*name*/,
147 std::vector<std::array<float, 9>> const & /*tensors*/,
148 reader_data) -> void {}
149 virtual auto on_tensors(
150 std::string const & /*name*/,
151 std::vector<std::array<double, 9>> const & /*tensors*/, reader_data)
152 -> void {}
153
154 virtual auto on_scalars(std::string const & /*data_name*/,
155 std::string const & /*lookup_table_name*/,
156 std::size_t const /*num_comps*/,
157 std::vector<float> const & /*scalars*/, reader_data)
158 -> void {}
159 virtual auto on_scalars(std::string const & /*data_name*/,
160 std::string const & /*lookup_table_name*/,
161 std::size_t const /*num_comps*/,
162 std::vector<double> const & /*scalars*/, reader_data)
163 -> void {}
164 virtual auto on_point_data(std::size_t) -> void {}
165 virtual auto on_cell_data(std::size_t) -> void {}
166 virtual auto on_field_array(std::string const /*field_name*/,
167 std::string const /*field_array_name*/,
168 std::vector<int> const & /*data*/,
169 std::size_t /*num_comps*/,
170 std::size_t /*num_tuples*/) -> void {}
171 virtual auto on_field_array(std::string const /*field_name*/,
172 std::string const /*field_array_name*/,
173 std::vector<float> const & /*data*/,
174 std::size_t /*num_comps*/,
175 std::size_t /*num_tuples*/) -> void {}
176 virtual auto on_field_array(std::string const /*field_name*/,
177 std::string const /*field_array_name*/,
178 std::vector<double> const & /*data*/,
179 std::size_t /*num_comps*/,
180 std::size_t /*num_tuples*/
181 ) -> void {}
182};
183//------------------------------------------------------------------------------
185 std::vector<legacy_file_listener *> m_listeners;
186
187 filesystem::path m_path;
190 std::size_t m_data_size{}; // cell_data or point_data size
191 std::ifstream::pos_type m_begin_of_data{};
192 char buffer[256]{};
193
194 public:
195 auto add_listener(legacy_file_listener &listener) -> void;
196 //---------------------------------------------------------------------------
197 legacy_file(filesystem::path path);
198 //---------------------------------------------------------------------------
199 auto read() -> void;
200 //---------------------------------------------------------------------------
201 auto set_path(filesystem::path const &path) -> void { m_path = path; }
202 auto set_path(filesystem::path &&path) -> void { m_path = std::move(path); }
203 auto path() const -> auto const & { return m_path; }
204 //---------------------------------------------------------------------------
205 private:
206 auto read_header() -> void;
207 auto read_data() -> void;
208
209 auto read_spacing(std::ifstream &file) -> void;
210 auto read_dimensions(std::ifstream &file) -> void;
211 auto read_origin(std::ifstream &file) -> void;
212
213 auto read_points(std::ifstream &file) -> void;
214 template <typename Real>
215 auto read_points_ascii(std::ifstream &file, std::size_t const n) -> void;
216 template <typename Real>
217 auto read_points_binary(std::ifstream &file, std::size_t const n) -> void;
218
219 auto read_cell_types(std::ifstream &file) -> void;
220 auto read_cell_types_ascii(std::ifstream &file, std::size_t const n) -> void;
221 auto read_cell_types_binary(std::ifstream &file, std::size_t const n) -> void;
222
223 auto read_indices(std::ifstream &file) -> std::vector<int>;
224 static auto read_indices_ascii(std::ifstream &file, std::size_t const size)
225 -> std::vector<int>;
226 static auto read_indices_binary(std::ifstream &file, std::size_t const size)
227 -> std::vector<int>;
228
229 auto read_scalars_header(std::ifstream &file);
230 auto read_scalars(std::ifstream &file) -> void;
231 template <typename Real>
232 auto read_scalars_ascii(std::ifstream &file, std::string const &name,
233 std::string const &lookup_table,
234 std::size_t const num_comps) -> void;
235 template <typename Real>
236 auto read_scalars_binary(std::ifstream &file, std::string const &name,
237 std::string const &lookup_table,
238 std::size_t const num_comps) -> void;
239
240 auto read_data_header(std::ifstream &file);
241 template <typename Real, std::size_t N>
242 auto read_data(std::ifstream &file) -> std::vector<std::array<Real, N>>;
243 template <typename Real, std::size_t N>
244 auto read_data_ascii(std::ifstream &file) -> std::vector<std::array<Real, N>>;
245 template <typename Real, std::size_t N>
246 auto read_data_binary(std::ifstream &file)
247 -> std::vector<std::array<Real, N>>;
248 //----------------------------------------------------------------------------
249 // coordinates
250 auto read_coordinates_header(std::ifstream &file);
251 template <typename Real>
252 auto read_coordinates(std::ifstream &file, std::size_t n);
253 template <typename Real>
254 auto read_coordinates_ascii(std::ifstream &file, std::size_t n)
255 -> std::vector<Real>;
256 template <typename Real>
257 auto read_coordinates_binary(std::ifstream &file, std::size_t n)
258 -> std::vector<Real>;
259 //----------------------------------------------------------------------------
260 auto read_x_coordinates(std::ifstream &file) -> void;
261 auto read_y_coordinates(std::ifstream &file) -> void;
262 auto read_z_coordinates(std::ifstream &file) -> void;
263 //----------------------------------------------------------------------------
264 // index data
265 auto read_cells(std::ifstream &file) -> void;
266 auto read_vertices(std::ifstream &file) -> void;
267 auto read_lines(std::ifstream &file) -> void;
268 auto read_polygons(std::ifstream &file) -> void;
269 auto read_triangle_strips(std::ifstream &file) -> void;
270 //----------------------------------------------------------------------------
271 // fixed size data
272 auto read_vectors(std::ifstream &file) -> void;
273 auto read_normals(std::ifstream &file) -> void;
274 auto read_texture_coordinates(std::ifstream &file) -> void;
275 auto read_tensors(std::ifstream &file) -> void;
276 auto read_field_header(std::ifstream &file)
277 -> std::pair<std::string, std::size_t>;
278 //----------------------------------------------------------------------------
279 // field data
280 auto read_field_array_header(std::ifstream &file)
281 -> std::tuple<std::string, std::size_t, std::size_t, std::string>;
282 auto read_field(std::ifstream &file) -> void;
283
284 template <typename Real>
285 auto read_field_array_binary(std::ifstream &file, std::size_t num_comps,
286 std::size_t num_tuples) -> std::vector<Real>;
287 template <typename Real>
288 auto read_field_array_ascii(std::ifstream &file, std::size_t num_comps,
289 std::size_t num_tuples) -> std::vector<Real>;
290
291 static auto consume_trailing_break(std::ifstream &file) -> void;
292};
293//------------------------------------------------------------------------------
294template <typename Real>
295auto legacy_file::read_points_ascii(std::ifstream &file, std::size_t const n)
296 -> void {
297 std::vector<std::array<Real, 3>> points;
298 for (std::size_t i = 0; i < n; i++)
299 points.push_back(
300 {{static_cast<Real>(parse<Real>(vtk::read_word(file, buffer))),
301 static_cast<Real>(parse<Real>(vtk::read_word(file, buffer))),
302 static_cast<Real>(parse<Real>(vtk::read_word(file, buffer)))}});
303
304 for (auto l : m_listeners)
305 l->on_points(points);
306}
307//-----------------------------------------------------------------------------
308template <typename Real>
309auto legacy_file::read_points_binary(std::ifstream &file, std::size_t const n)
310 -> void {
311 std::vector<std::array<Real, 3>> points(n);
312 if (n > 0) {
313 file.read((char *)points.data(),
314 static_cast<std::streamsize>(sizeof(Real) * 3 * n));
315 swap_endianess(reinterpret_cast<Real *>(points.data()), n * 3);
316 for (auto l : m_listeners)
317 l->on_points(points);
318 consume_trailing_break(file);
319 }
320 // file.ignore(sizeof(Real) * 3 * n + 1);
321}
322//------------------------------------------------------------------------------
323template <typename Real, std::size_t n>
324auto legacy_file::read_data(std::ifstream &file)
325 -> std::vector<std::array<Real, n>> {
326 if (m_format == format::ascii)
327 return read_data_ascii<Real, n>(file);
328 else
329 return read_data_binary<Real, n>(file);
330}
331//-----------------------------------------------------------------------------
332template <typename Real, std::size_t n>
333auto legacy_file::read_data_ascii(std::ifstream &file)
334 -> std::vector<std::array<Real, n>> {
335 std::vector<std::array<Real, n>> data(m_data_size);
336 for (std::size_t i = 0; i < m_data_size; i++)
337 for (std::size_t j = 0; j < n; j++)
338 data[i][n] = parse<Real>(vtk::read_word(file, buffer));
339 return data;
340}
341//-----------------------------------------------------------------------------
342template <typename Real, std::size_t n>
343auto legacy_file::read_data_binary(std::ifstream &file)
344 -> std::vector<std::array<Real, n>> {
345 auto data = std::vector<std::array<Real, n>>(m_data_size);
346 file.read((char *)data.data(),
347 static_cast<std::streamsize>(sizeof(Real) * m_data_size * n));
348 swap_endianess(reinterpret_cast<Real *>(data.data()), n * m_data_size);
349 consume_trailing_break(file);
350 return data;
351}
352//------------------------------------------------------------------------------
353template <typename Real>
354auto legacy_file::read_coordinates(std::ifstream &file, std::size_t n) {
355 if (m_format == format::ascii)
356 return read_coordinates_ascii<Real>(file, n);
357
358 else /*if (m_format == format::binary)*/
359 return read_coordinates_binary<Real>(file, n);
360}
361//------------------------------------------------------------------------------
362template <typename Real>
363auto legacy_file::read_coordinates_ascii(std::ifstream &file,
364 std::size_t const n)
365 -> std::vector<Real> {
366 std::vector<Real> coordinates(n);
367 for (std::size_t i = 0; i < n; i++)
368 coordinates[i] = parse<Real>(vtk::read_word(file, buffer));
369 return coordinates;
370}
371//------------------------------------------------------------------------------
372template <typename Real>
373auto legacy_file::read_coordinates_binary(std::ifstream &file,
374 std::size_t const n)
375 -> std::vector<Real> {
376 auto coordinates = std::vector<Real>(n);
377 file.read((char *)coordinates.data(),
378 static_cast<std::streamsize>(sizeof(Real) * n));
379 swap_endianess(coordinates);
380 consume_trailing_break(file);
381 return coordinates;
382}
383//------------------------------------------------------------------------------
384template <typename Real>
385auto legacy_file::read_field_array_binary(std::ifstream &file,
386 std::size_t num_comps,
387 std::size_t num_tuples)
388 -> std::vector<Real> {
389 auto data = std::vector<Real>(num_comps * num_tuples);
390 file.read((char *)data.data(), static_cast<std::streamsize>(
391 sizeof(Real) * num_comps * num_tuples));
392 swap_endianess(data);
393
394 // consume trailing \n
395 auto consumer = char{};
396 file.read(&consumer, sizeof(char));
397
398 return data;
399}
400//------------------------------------------------------------------------------
401template <typename Real>
402auto legacy_file::read_field_array_ascii(std::ifstream &file,
403 std::size_t num_comps,
404 std::size_t num_tuples)
405 -> std::vector<Real> {
406 std::vector<Real> data;
407 data.reserve(num_comps * num_tuples);
408 for (std::size_t i = 0; i < num_comps * num_tuples; i++)
409 data.push_back(parse<Real>(vtk::read_word(file, buffer)));
410
411 return data;
412}
413//-----------------------------------------------------------------------------
414template <typename Real>
415auto legacy_file::read_scalars_ascii(std::ifstream &file,
416 std::string const &name,
417 std::string const &lookup_table,
418 std::size_t const num_comps) -> void {
419 std::vector<Real> scalars;
420 scalars.reserve(m_data_size * num_comps);
421 std::string val_str;
422 for (std::size_t i = 0; i < m_data_size * num_comps; i++) {
423 scalars.push_back(parse<Real>(vtk::read_word(file, buffer)));
424 }
425 for (auto l : m_listeners) {
426 l->on_scalars(name, lookup_table, num_comps, scalars, m_data);
427 }
428}
429//-----------------------------------------------------------------------------
430template <typename Real>
431auto legacy_file::read_scalars_binary(std::ifstream &file,
432 std::string const &name,
433 std::string const &lookup_table,
434 std::size_t const num_comps) -> void {
435 if (m_data_size > 0) {
436 auto data = std::vector<Real>(m_data_size * num_comps);
437 file.read((char *)data.data(), static_cast<std::streamsize>(
438 sizeof(Real) * m_data_size * num_comps));
439 swap_endianess(data);
440
441 consume_trailing_break(file);
442 for (auto l : m_listeners) {
443 l->on_scalars(name, lookup_table, num_comps, data, m_data);
444 }
445 }
446}
447//------------------------------------------------------------------------------
449 private:
450 std::ofstream m_file;
451 unsigned short m_major_version;
452 unsigned short m_minor_version;
454 std::string m_title;
455
456 public:
457 legacy_file_writer(filesystem::path const &path, dataset_type type,
458 unsigned short major = 2, unsigned short minor = 0,
459 std::string title = "");
462 virtual ~legacy_file_writer() = default;
463 auto is_open() -> bool;
464 auto close() -> void;
465 //---------------------------------------------------------------------------
466 private:
467 auto write_indices(std::string const &keyword,
468 std::vector<std::vector<std::size_t>> const &indices)
469 -> void;
470 template <std::size_t N>
471 auto write_indices(std::string const &keyword,
472 std::vector<std::array<std::size_t, N>> const &indices)
473 -> void;
474 template <typename Real, std::size_t N>
475 auto write_data(std::string const &keyword, std::string const &name,
476 std::vector<std::array<Real, N>> const &data) -> void;
477
478 public:
479 auto write_header() -> void;
480 template <typename Real>
481 auto write_points(std::vector<std::array<Real, 2>> const &points) -> void;
482 template <typename Real>
483 auto write_points(std::vector<std::array<Real, 3>> const &points) -> void;
484 template <typename Real>
485 auto write_points(std::vector<vec<Real, 2>> const &points) -> void;
486 template <typename Real>
487 auto write_points(std::vector<vec<Real, 3>> const &points) -> void;
488 auto write_cells(std::vector<std::vector<std::size_t>> const &cells) -> void;
489 auto write_cell_types(std::vector<cell_type> const &cell_types) -> void;
490
491 auto write_vertices(std::vector<std::vector<std::size_t>> const &vertices)
492 -> void;
493 auto write_lines(std::vector<std::vector<std::size_t>> const &lines) -> void;
494 auto write_polygons(std::vector<std::vector<std::size_t>> const &polygons)
495 -> void;
496 template <std::size_t N>
497 auto write_polygons(std::vector<std::array<std::size_t, N>> const &polygons)
498 -> void;
499 auto write_triangle_strips(std::vector<std::vector<std::size_t>> const &lines)
500 -> void;
501
502 auto write_coordinates(std::string_view name,
503 arithmetic_range auto const &coords) -> void {
504 using value_type = typename std::decay_t<decltype(coords)>::value_type;
505 auto ss = std::stringstream{};
506 ss << "\n"
507 << name << " " << ' ' << size(coords) << ' ' << type_to_str<value_type>()
508 << '\n';
509 vtk::write_binary(m_file, ss.str());
510 auto d = value_type{};
511 for (auto const &c : coords) {
512 d = swap_endianess(c);
513 m_file.write((char *)(&d), sizeof(value_type));
514 }
515 }
516 auto write_x_coordinates(arithmetic_range auto const &coords) -> void {
517 write_coordinates("X_COORDINATES", coords);
518 }
519 auto write_y_coordinates(arithmetic_range auto const &coords) -> void {
520 write_coordinates("Y_COORDINATES", coords);
521 }
522 auto write_z_coordinates(arithmetic_range auto const &coords) -> void {
523 write_coordinates("Z_COORDINATES", coords);
524 }
525 auto write_point_data(std::size_t i) -> void;
526 auto write_cell_data(std::size_t i) -> void;
527 template <typename Real>
528 auto write_normals(std::string const &name,
529 std::vector<std::array<Real, 3>> &normals) -> void;
530 //----------------------------------------------------------------------------
531 template <typename Real>
532 auto write_vectors(std::string const &name,
533 std::vector<std::array<Real, 3>> &vectors) -> void;
534 //----------------------------------------------------------------------------
535 template <typename Real>
536 auto write_texture_coordinates(
537 std::string const &name,
538 std::vector<std::array<Real, 2>> &texture_coordinates) -> void;
539 //----------------------------------------------------------------------------
540 template <typename Real>
541 auto write_tensors(std::string const &name,
542 std::vector<std::array<Real, 9>> &tensors) -> void;
543 //----------------------------------------------------------------------------
544 template <either_of<double, float, int> Data>
545 auto write_scalars(std::string const &name, std::vector<Data> const &data,
546 std::string const &lookup_table_name = "default") -> void;
547 //----------------------------------------------------------------------------
548 template <either_of<double, float, int> Data>
549 auto write_scalars(std::string const &name,
550 std::vector<std::vector<Data>> const &data,
551 std::string const &lookup_table_name = "default") -> void;
552 //----------------------------------------------------------------------------
553 template <either_of<double, float, int> Data, std::size_t N>
554 auto write_scalars(std::string const &name,
555 std::vector<std::array<Data, N>> const &data,
556 std::string const &lookup_table_name = "default") -> void {
557 std::stringstream ss;
558 ss << "\nSCALARS " << name << ' ' << type_to_str<Data>() << ' ' << N
559 << '\n';
560 vtk::write_binary(m_file, ss.str());
561 vtk::write_binary(m_file, "\nLOOKUP_TABLE " + lookup_table_name + '\n');
562 for (auto const &arr : data)
563 for (auto &comp : arr) {
564 comp = swap_endianess(comp);
565 m_file.write((char *)(&comp), sizeof(Data));
566 }
567 }
568 //----------------------------------------------------------------------------
569 template <either_of<double, float, int> Data, std::size_t N>
570 auto write_scalars(std::string const &name,
571 std::vector<vec<Data, N>> const &data,
572 std::string const &lookup_table_name = "default") -> void {
573 std::stringstream ss;
574 ss << "\nSCALARS " << name << ' ' << type_to_str<Data>() << ' ' << N
575 << '\n';
576 vtk::write_binary(m_file, ss.str());
577 vtk::write_binary(m_file, "\nLOOKUP_TABLE " + lookup_table_name + '\n');
578 Data d;
579 for (auto const &v : data)
580 for (std::size_t i = 0; i < N; ++i) {
581 d = swap_endianess(v(i));
582 m_file.write((char *)(&d), sizeof(Data));
583 }
584 }
585 //----------------------------------------------------------------------------
586 template <either_of<double, float, int> Real, std::size_t N>
587 auto write_scalars(std::string const &name,
588 std::vector<tensor<Real, N>> const &data,
589 std::string const &lookup_table_name = "default") -> void {
590 std::stringstream ss;
591 ss << "\nSCALARS " << name << ' ' << type_to_str<Real>() << ' ' << N
592 << '\n';
593 vtk::write_binary(m_file, ss.str());
594 vtk::write_binary(m_file, "\nLOOKUP_TABLE " + lookup_table_name + '\n');
595 Real d;
596 for (auto const &v : data)
597 for (std::size_t i = 0; i < N; ++i) {
598 d = swap_endianess(v(i));
599 m_file.write((char *)(&d), sizeof(Real));
600 }
601 }
602 //----------------------------------------------------------------------------
603 auto write_dimensions(std::size_t const dimx, std::size_t const dimy,
604 std::size_t const dimz) -> void;
605 //----------------------------------------------------------------------------
606 auto write_origin(double const orgx, double const orgy, double const orgz)
607 -> void;
608 //----------------------------------------------------------------------------
609 auto write_spacing(double const spax, double const spay, double const spaz)
610 -> void;
611 //---------------------------------------------------------------------------
612 auto set_version(unsigned short const major_version,
613 unsigned short const minor_version) -> void;
614 //---------------------------------------------------------------------------
615 auto major_version() const -> auto const & { return m_major_version; }
616 auto set_major_version(unsigned short const major_version) -> void {
617 m_major_version = major_version;
618 }
619 //---------------------------------------------------------------------------
620 auto minor_version() const -> auto const & { return m_minor_version; }
621 auto set_minor_version(unsigned short const minor_version) -> void {
622 m_minor_version = minor_version;
623 }
624 //---------------------------------------------------------------------------
625 auto type() const -> auto const & { return m_dataset_type; }
626 auto set_type(dataset_type const type) -> void { m_dataset_type = type; }
627 auto set_type(std::string const &type_str) -> void {
628 m_dataset_type = parse_dataset_type(type_str);
629 }
630 //---------------------------------------------------------------------------
631 auto title() const -> auto const & { return m_title; }
632 auto set_title(std::string const &title) -> void { m_title = title; }
633 auto set_title(std::string &&title) -> void { m_title = std::move(title); }
634};
635//=============================================================================
636template <typename Real>
637auto legacy_file_writer::write_points(
638 std::vector<std::array<Real, 2>> const &points2) -> void {
639 std::vector<std::array<Real, 3>> points3;
640 points3.reserve(points2.size());
641 for (auto const &x : points2) {
642 points3.push_back({x[0], x[1], Real(0)});
643 }
644 write_points(points3);
645}
646//------------------------------------------------------------------------------
647template <typename Real>
648auto legacy_file_writer::write_points(
649 std::vector<std::array<Real, 3>> const &points) -> void {
650 std::stringstream ss;
651 ss << "\nPOINTS " << points.size() << ' ' << type_to_str<Real>() << '\n';
652 vtk::write_binary(m_file, ss.str());
653 std::vector<std::array<Real, 3>> points_swapped(points);
654 swap_endianess(reinterpret_cast<Real *>(points_swapped.data()),
655 3 * points.size());
656 for (auto const &p : points_swapped) {
657 for (auto c : p) {
658 m_file.write((char *)(&c), sizeof(Real));
659 }
660 }
661}
662//------------------------------------------------------------------------------
663template <typename Real>
664auto legacy_file_writer::write_points(std::vector<vec<Real, 2>> const &points2)
665 -> void {
666 std::vector<std::array<Real, 3>> points3;
667 points3.reserve(points2.size());
668 for (auto const &x : points2) {
669 points3.push_back({x(0), x(1), Real(0)});
670 }
671 write_points(points3);
672}
673//------------------------------------------------------------------------------
674template <typename Real>
675auto legacy_file_writer::write_points(std::vector<vec<Real, 3>> const &points)
676 -> void {
677 std::stringstream ss;
678 ss << "\nPOINTS " << points.size() << ' ' << type_to_str<Real>() << '\n';
679 vtk::write_binary(m_file, ss.str());
680 auto points_swapped = points;
681 swap_endianess(reinterpret_cast<Real *>(points_swapped.data()),
682 3 * points.size());
683 for (auto const &p : points_swapped) {
684 for (std::size_t i = 0; i < 3; ++i) {
685 m_file.write((char *)(&p[i]), sizeof(Real));
686 }
687 }
688}
689//------------------------------------------------------------------------------
690template <std::size_t N>
691auto legacy_file_writer::write_indices(
692 std::string const &keyword,
693 std::vector<std::array<std::size_t, N>> const &indices) -> void {
694 std::size_t total_number = 0;
695 for (auto const &is : indices)
696 total_number += is.size() + 1;
697 vtk::write_binary(m_file, "\n" + keyword + " " +
698 std::to_string(indices.size()) + ' ' +
699 std::to_string(total_number) + '\n');
700 for (auto const &p : indices) {
701 int size = (int)p.size();
703 m_file.write((char *)(&size), sizeof(int));
704 for (int i : p) {
705 i = swap_endianess(i);
706 m_file.write((char *)(&i), sizeof(int));
707 }
708 }
709}
710//------------------------------------------------------------------------------
711template <typename Real, std::size_t N>
712auto legacy_file_writer::write_data(
713 std::string const &keyword, std::string const &name,
714 std::vector<std::array<Real, N>> const &data) -> void {
715 std::stringstream ss;
716 ss << "\n" << keyword << ' ' << name << ' ' << type_to_str<Real>() << '\n';
717 vtk::write_binary(m_file, ss.str());
718 for (auto const &vec : data)
719 for (auto comp : vec) {
720 comp = swap_endianess(comp);
721 m_file.write((char *)(&comp), sizeof(Real));
722 }
723}
724//-----------------------------------------------------------------------------
725template <std::size_t N>
726auto legacy_file_writer::write_polygons(
727 std::vector<std::array<std::size_t, N>> const &polygons) -> void {
728 write_indices("POLYGONS", polygons);
729}
730//-----------------------------------------------------------------------------
731template <typename Real>
732auto legacy_file_writer::write_normals(
733 std::string const &name, std::vector<std::array<Real, 3>> &normals)
734 -> void {
735 write_data<3>("NORMALS", name, normals);
736}
737//-----------------------------------------------------------------------------
738template <typename Real>
739auto legacy_file_writer::write_vectors(
740 std::string const &name, std::vector<std::array<Real, 3>> &vectors)
741 -> void {
742 write_data<3>("VECTORS", name, vectors);
743}
744//-----------------------------------------------------------------------------
745template <typename Real>
746auto legacy_file_writer::write_texture_coordinates(
747 std::string const &name,
748 std::vector<std::array<Real, 2>> &texture_coordinates) -> void {
749 write_data<2>("TEXTURE_COORDINATES", name, texture_coordinates);
750}
751//-----------------------------------------------------------------------------
752template <typename Real>
753auto legacy_file_writer::write_tensors(
754 std::string const &name, std::vector<std::array<Real, 9>> &tensors)
755 -> void {
756 write_data<9>("TENSORS", name, tensors);
757}
758//-----------------------------------------------------------------------------
759template <either_of<double, float, int> Data>
760auto legacy_file_writer::write_scalars(std::string const &name,
761 std::vector<Data> const &data,
762 std::string const &lookup_table_name)
763 -> void {
764 std::stringstream ss;
765 ss << "\nSCALARS " << name << ' ' << type_to_str<Data>() << " 1\n";
766 vtk::write_binary(m_file, ss.str());
767 vtk::write_binary(m_file, "\nLOOKUP_TABLE " + lookup_table_name + '\n');
768 for (auto comp : data) {
769 comp = swap_endianess(comp);
770 m_file.write((char *)(&comp), sizeof(Data));
771 }
772}
773//------------------------------------------------------------------------------
774template <either_of<double, float, int> Data>
775auto legacy_file_writer::write_scalars(
776 std::string const &name, std::vector<std::vector<Data>> const &data,
777 std::string const &lookup_table_name) -> void {
778 std::stringstream ss;
779 ss << "\nSCALARS " << name << ' ' << type_to_str<Data>()
780 << std::to_string(data.front().size()) + '\n';
781 vtk::write_binary(m_file, ss.str());
782 vtk::write_binary(m_file, "\nLOOKUP_TABLE " + lookup_table_name + '\n');
783 for (auto const &vec : data)
784 for (auto comp : vec) {
785 comp = swap_endianess(comp);
786 m_file.write((char *)(&comp), sizeof(Data));
787 }
788}
789//=============================================================================
790} // namespace tatooine::vtk
791//=============================================================================
792#endif
Definition: vtk_legacy.h:448
auto set_title(std::string &&title) -> void
Definition: vtk_legacy.h:633
auto write_point_data(std::size_t i) -> void
auto set_title(std::string const &title) -> void
Definition: vtk_legacy.h:632
auto write_z_coordinates(arithmetic_range auto const &coords) -> void
Definition: vtk_legacy.h:522
auto minor_version() const -> auto const &
Definition: vtk_legacy.h:620
auto write_cell_data(std::size_t i) -> void
auto write_lines(std::vector< std::vector< std::size_t > > const &lines) -> void
auto write_spacing(double const spax, double const spay, double const spaz) -> void
auto operator=(legacy_file_writer const &) -> legacy_file_writer &=delete
auto write_indices(std::string const &keyword, std::vector< std::vector< std::size_t > > const &indices) -> void
auto set_major_version(unsigned short const major_version) -> void
Definition: vtk_legacy.h:616
auto title() const -> auto const &
Definition: vtk_legacy.h:631
auto write_coordinates(std::string_view name, arithmetic_range auto const &coords) -> void
Definition: vtk_legacy.h:502
auto write_polygons(std::vector< std::vector< std::size_t > > const &polygons) -> void
auto set_version(unsigned short const major_version, unsigned short const minor_version) -> void
unsigned short m_major_version
Definition: vtk_legacy.h:451
auto type() const -> auto const &
Definition: vtk_legacy.h:625
virtual ~legacy_file_writer()=default
auto set_type(std::string const &type_str) -> void
Definition: vtk_legacy.h:627
dataset_type m_dataset_type
Definition: vtk_legacy.h:453
legacy_file_writer(filesystem::path const &path, dataset_type type, unsigned short major=2, unsigned short minor=0, std::string title="")
auto write_vertices(std::vector< std::vector< std::size_t > > const &vertices) -> void
auto write_origin(double const orgx, double const orgy, double const orgz) -> void
auto write_dimensions(std::size_t const dimx, std::size_t const dimy, std::size_t const dimz) -> void
auto write_scalars(std::string const &name, std::vector< vec< Data, N > > const &data, std::string const &lookup_table_name="default") -> void
Definition: vtk_legacy.h:570
legacy_file_writer(legacy_file_writer const &)=delete
std::ofstream m_file
Definition: vtk_legacy.h:450
unsigned short m_minor_version
Definition: vtk_legacy.h:452
std::string m_title
Definition: vtk_legacy.h:454
auto write_cell_types(std::vector< cell_type > const &cell_types) -> void
auto write_y_coordinates(arithmetic_range auto const &coords) -> void
Definition: vtk_legacy.h:519
auto set_minor_version(unsigned short const minor_version) -> void
Definition: vtk_legacy.h:621
auto write_scalars(std::string const &name, std::vector< std::array< Data, N > > const &data, std::string const &lookup_table_name="default") -> void
Definition: vtk_legacy.h:554
auto set_type(dataset_type const type) -> void
Definition: vtk_legacy.h:626
auto write_scalars(std::string const &name, std::vector< tensor< Real, N > > const &data, std::string const &lookup_table_name="default") -> void
Definition: vtk_legacy.h:587
auto write_triangle_strips(std::vector< std::vector< std::size_t > > const &lines) -> void
auto major_version() const -> auto const &
Definition: vtk_legacy.h:615
auto write_x_coordinates(arithmetic_range auto const &coords) -> void
Definition: vtk_legacy.h:516
auto write_cells(std::vector< std::vector< std::size_t > > const &cells) -> void
Definition: vtk_legacy.h:184
auto read_cell_types_ascii(std::ifstream &file, std::size_t const n) -> void
auto read_x_coordinates(std::ifstream &file) -> void
auto read_coordinates_header(std::ifstream &file)
auto read_data_binary(std::ifstream &file) -> std::vector< std::array< Real, N > >
Definition: vtk_legacy.h:343
auto read_header() -> void
auto read_field_array_binary(std::ifstream &file, std::size_t num_comps, std::size_t num_tuples) -> std::vector< Real >
Definition: vtk_legacy.h:385
auto read_cell_types(std::ifstream &file) -> void
auto read_scalars(std::ifstream &file) -> void
auto read_spacing(std::ifstream &file) -> void
auto read_field_array_ascii(std::ifstream &file, std::size_t num_comps, std::size_t num_tuples) -> std::vector< Real >
Definition: vtk_legacy.h:402
auto read_lines(std::ifstream &file) -> void
static auto read_indices_ascii(std::ifstream &file, std::size_t const size) -> std::vector< int >
auto read_indices(std::ifstream &file) -> std::vector< int >
auto set_path(filesystem::path &&path) -> void
Definition: vtk_legacy.h:202
auto read_scalars_ascii(std::ifstream &file, std::string const &name, std::string const &lookup_table, std::size_t const num_comps) -> void
Definition: vtk_legacy.h:415
auto read_tensors(std::ifstream &file) -> void
auto read_y_coordinates(std::ifstream &file) -> void
auto read_texture_coordinates(std::ifstream &file) -> void
auto read_field_header(std::ifstream &file) -> std::pair< std::string, std::size_t >
auto read_scalars_header(std::ifstream &file)
filesystem::path m_path
Definition: vtk_legacy.h:187
char buffer[256]
Definition: vtk_legacy.h:192
auto path() const -> auto const &
Definition: vtk_legacy.h:203
format m_format
Definition: vtk_legacy.h:188
auto read_triangle_strips(std::ifstream &file) -> void
auto read_normals(std::ifstream &file) -> void
auto read_field_array_header(std::ifstream &file) -> std::tuple< std::string, std::size_t, std::size_t, std::string >
auto read_points_ascii(std::ifstream &file, std::size_t const n) -> void
Definition: vtk_legacy.h:295
std::vector< legacy_file_listener * > m_listeners
Definition: vtk_legacy.h:185
auto read_coordinates(std::ifstream &file, std::size_t n)
Definition: vtk_legacy.h:354
auto read_points(std::ifstream &file) -> void
auto read_dimensions(std::ifstream &file) -> void
auto read_polygons(std::ifstream &file) -> void
auto read_vectors(std::ifstream &file) -> void
auto read_field(std::ifstream &file) -> void
auto read_vertices(std::ifstream &file) -> void
auto read_coordinates_binary(std::ifstream &file, std::size_t n) -> std::vector< Real >
Definition: vtk_legacy.h:373
static auto read_indices_binary(std::ifstream &file, std::size_t const size) -> std::vector< int >
auto read_coordinates_ascii(std::ifstream &file, std::size_t n) -> std::vector< Real >
Definition: vtk_legacy.h:363
std::ifstream::pos_type m_begin_of_data
Definition: vtk_legacy.h:191
auto add_listener(legacy_file_listener &listener) -> void
auto read_cell_types_binary(std::ifstream &file, std::size_t const n) -> void
auto read_data_header(std::ifstream &file)
auto read_scalars_binary(std::ifstream &file, std::string const &name, std::string const &lookup_table, std::size_t const num_comps) -> void
Definition: vtk_legacy.h:431
auto read_points_binary(std::ifstream &file, std::size_t const n) -> void
Definition: vtk_legacy.h:309
auto read_z_coordinates(std::ifstream &file) -> void
auto read_data_ascii(std::ifstream &file) -> std::vector< std::array< Real, N > >
Definition: vtk_legacy.h:333
reader_data m_data
Definition: vtk_legacy.h:189
auto set_path(filesystem::path const &path) -> void
Definition: vtk_legacy.h:201
auto read_cells(std::ifstream &file) -> void
std::size_t m_data_size
Definition: vtk_legacy.h:190
legacy_file(filesystem::path path)
auto read_origin(std::ifstream &file) -> void
static auto consume_trailing_break(std::ifstream &file) -> void
Definition: concepts.h:87
Definition: cell_type.h:6
auto read_binaryline(std::istream &stream, char *buffer) -> std::string
reads stream until a linebreak was found. buffer will not contain the break
auto parse_format(std::string const &) -> format
reader_data
Definition: vtk_legacy.h:42
auto read_until(std::istream &stream, char const terminator_char, char *buffer) -> std::string
auto write_binary(std::ostream &stream, std::string const &str) -> void
auto read_word(std::istream &stream, char *buffer) -> std::string
dataset_type
Definition: vtk_legacy.h:44
constexpr auto to_string_view(cell_type const ct) -> std::string_view
Definition: cell_type.h:26
auto parse_dataset_type(std::string const &) -> dataset_type
format
Definition: vtk_legacy.h:76
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
constexpr Data swap_endianess(Data data)
Definition: swap_endianess.h:9
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
Definition: tensor.h:17
Definition: vec.h:12
Definition: vtk_legacy.h:92
virtual auto on_texture_coordinates(std::string const &, std::vector< std::array< float, 2 > > const &, reader_data) -> void
Definition: vtk_legacy.h:138
virtual auto on_y_coordinates(std::vector< float > const &) -> void
Definition: vtk_legacy.h:110
virtual auto on_point_data(std::size_t) -> void
Definition: vtk_legacy.h:164
virtual auto on_cells(std::vector< int > const &) -> void
Definition: vtk_legacy.h:116
virtual auto on_normals(std::string const &, std::vector< std::array< double, 3 > > const &, reader_data) -> void
Definition: vtk_legacy.h:134
virtual auto on_z_coordinates(std::vector< double > const &) -> void
Definition: vtk_legacy.h:113
virtual auto on_triangle_strips(std::vector< int > const &) -> void
Definition: vtk_legacy.h:121
virtual auto on_tensors(std::string const &, std::vector< std::array< float, 9 > > const &, reader_data) -> void
Definition: vtk_legacy.h:146
virtual auto on_spacing(double, double, double) -> void
Definition: vtk_legacy.h:105
virtual auto on_texture_coordinates(std::string const &, std::vector< std::array< double, 2 > > const &, reader_data) -> void
Definition: vtk_legacy.h:142
virtual auto on_scalars(std::string const &, std::string const &, std::size_t const, std::vector< double > const &, reader_data) -> void
Definition: vtk_legacy.h:159
virtual auto on_points(std::vector< std::array< float, 3 > > const &) -> void
Definition: vtk_legacy.h:102
virtual auto on_vectors(std::string const &, std::vector< std::array< float, 3 > > const &, reader_data) -> void
Definition: vtk_legacy.h:124
virtual auto on_points(std::vector< std::array< double, 3 > > const &) -> void
Definition: vtk_legacy.h:103
virtual auto on_scalars(std::string const &, std::string const &, std::size_t const, std::vector< float > const &, reader_data) -> void
Definition: vtk_legacy.h:154
virtual auto on_polygons(std::vector< int > const &) -> void
Definition: vtk_legacy.h:120
virtual ~legacy_file_listener()=default
virtual auto on_y_coordinates(std::vector< double > const &) -> void
Definition: vtk_legacy.h:111
virtual auto on_cell_data(std::size_t) -> void
Definition: vtk_legacy.h:165
virtual auto on_format(format) -> void
Definition: vtk_legacy.h:98
virtual auto on_tensors(std::string const &, std::vector< std::array< double, 9 > > const &, reader_data) -> void
Definition: vtk_legacy.h:149
virtual auto on_cell_types(std::vector< cell_type > const &) -> void
Definition: vtk_legacy.h:117
virtual auto on_version(unsigned short, unsigned short) -> void
Definition: vtk_legacy.h:95
virtual auto on_field_array(std::string const, std::string const, std::vector< float > const &, std::size_t, std::size_t) -> void
Definition: vtk_legacy.h:171
virtual auto on_z_coordinates(std::vector< float > const &) -> void
Definition: vtk_legacy.h:112
virtual auto on_normals(std::string const &, std::vector< std::array< float, 3 > > const &, reader_data) -> void
Definition: vtk_legacy.h:131
virtual auto on_lines(std::vector< int > const &) -> void
Definition: vtk_legacy.h:119
virtual auto on_dataset_type(dataset_type) -> void
Definition: vtk_legacy.h:99
virtual auto on_x_coordinates(std::vector< double > const &) -> void
Definition: vtk_legacy.h:109
virtual auto on_title(std::string const &) -> void
Definition: vtk_legacy.h:97
virtual auto on_dimensions(std::size_t, std::size_t, std::size_t) -> void
Definition: vtk_legacy.h:106
virtual auto on_vertices(std::vector< int > const &) -> void
Definition: vtk_legacy.h:118
virtual auto on_field_array(std::string const, std::string const, std::vector< double > const &, std::size_t, std::size_t) -> void
Definition: vtk_legacy.h:176
virtual auto on_vectors(std::string const &, std::vector< std::array< double, 3 > > const &, reader_data) -> void
Definition: vtk_legacy.h:127
virtual auto on_field_array(std::string const, std::string const, std::vector< int > const &, std::size_t, std::size_t) -> void
Definition: vtk_legacy.h:166
virtual auto on_origin(double, double, double) -> void
Definition: vtk_legacy.h:104
virtual auto on_x_coordinates(std::vector< float > const &) -> void
Definition: vtk_legacy.h:108