GridFormat 0.2.1
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
vti_writer.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2// SPDX-License-Identifier: MIT
8#ifndef GRIDFORMAT_VTK_VTI_WRITER_HPP_
9#define GRIDFORMAT_VTK_VTI_WRITER_HPP_
10
11#include <array>
12#include <ranges>
13#include <ostream>
14#include <utility>
15#include <string>
16#include <optional>
17
18#include <gridformat/common/field_storage.hpp>
19#include <gridformat/common/lvalue_reference.hpp>
20
21#include <gridformat/grid/grid.hpp>
22#include <gridformat/grid/type_traits.hpp>
25
26namespace GridFormat {
27
32template<Concepts::ImageGrid Grid>
33class VTIWriter : public VTK::XMLWriterBase<Grid, VTIWriter<Grid>> {
35 using CType = CoordinateType<Grid>;
36 static constexpr std::size_t dim = dimension<Grid>;
37
38 public:
39 struct Domain {
40 std::array<CType, dim> origin;
41 std::array<std::size_t, dim> whole_extent;
42 };
43
44 using Offset = std::array<std::size_t, dim>;
45
46 explicit VTIWriter(LValueReferenceOf<const Grid> grid,
47 VTK::XMLOptions xml_opts = {})
48 : ParentType(grid.get(), ".vti", true, std::move(xml_opts))
49 {}
50
51 VTIWriter as_piece_for(Domain domain) const {
52 auto result = this->with(this->_xml_opts);
53 result._domain = std::move(domain);
54 result._offset = _offset;
55 return result;
56 }
57
58 VTIWriter with_offset(Offset offset) const {
59 auto result = this->with(this->_xml_opts);
60 result._offset = std::move(offset);
61 result._domain = _domain;
62 return result;
63 }
64
65 private:
66 VTIWriter _with(VTK::XMLOptions xml_opts) const override {
67 return VTIWriter{this->grid(), std::move(xml_opts)};
68 }
69
70 void _write(std::ostream& s) const override {
71 auto context = this->_get_write_context("ImageData");
72 _set_attributes(context);
73
74 FieldStorage vtk_point_fields;
75 FieldStorage vtk_cell_fields;
76 std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) {
77 vtk_cell_fields.set(name, VTK::make_vtk_field(this->_get_point_field_ptr(name)));
78 this->_set_data_array(context, "Piece/PointData", name, vtk_cell_fields.get(name));
79 });
80 std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) {
81 vtk_cell_fields.set(name, VTK::make_vtk_field(this->_get_cell_field_ptr(name)));
82 this->_set_data_array(context, "Piece/CellData", name, vtk_cell_fields.get(name));
83 });
84
85 this->_write_xml(std::move(context), s);
86 }
87
88 void _set_attributes(typename ParentType::WriteContext& context) const {
89 _set_domain_attributes(context);
90 _set_extent_attributes(context);
91 this->_set_attribute(context, "", "Spacing", VTK::CommonDetail::number_string_3d(spacing(this->grid())));
92 this->_set_attribute(context, "", "Direction", VTK::CommonDetail::direction_string(basis(this->grid())));
93 }
94
95 void _set_domain_attributes(typename ParentType::WriteContext& context) const {
96 using VTK::CommonDetail::extents_string;
97 using VTK::CommonDetail::number_string_3d;
98 if (_domain) {
99 this->_set_attribute(context, "", "WholeExtent", extents_string(_domain->whole_extent));
100 this->_set_attribute(context, "", "Origin", number_string_3d(_domain->origin));
101 } else {
102 this->_set_attribute(context, "", "WholeExtent", extents_string(this->grid()));
103 this->_set_attribute(context, "", "Origin", number_string_3d(origin(this->grid())));
104 }
105 }
106
107 void _set_extent_attributes(typename ParentType::WriteContext& context) const {
108 using VTK::CommonDetail::extents_string;
109 if (int i = 0; _offset) {
110 auto begin = (*_offset);
111 auto end = GridFormat::extents(this->grid());
112 std::ranges::for_each(end, [&] (std::integral auto& ex) { ex += begin[i++]; });
113 this->_set_attribute(context, "Piece", "Extent", extents_string(begin, end));
114 } else {
115 this->_set_attribute(context, "Piece", "Extent", extents_string(this->grid()));
116 }
117 }
118
119 std::optional<Domain> _domain;
120 std::optional<Offset> _offset;
121};
122
123template<typename G>
124VTIWriter(G&&, VTK::XMLOptions opts = {}) -> VTIWriter<std::remove_cvref_t<G>>;
125
126namespace Traits {
127
128template<typename... Args>
129struct WritesConnectivity<VTIWriter<Args...>> : public std::false_type {};
130
131} // namespace Traits
132} // namespace GridFormat
133
134#endif // GRIDFORMAT_VTK_VTI_WRITER_HPP_
Writer for .vti file format.
Definition: vti_writer.hpp:33
Base class for VTK-XML Writer implementations.
Definition: xml.hpp:190
Can be specialized by writers in case the file format does not contain connectivity information.
Definition: writer.hpp:36
Definition: vti_writer.hpp:39
Options for VTK-XML files for setting the desired encoding, data format and compression.
Definition: xml.hpp:99
Common functionality for VTK writers.
Helper classes and functions for VTK XML-type file format writers & readers.