GCC Code Coverage Report


Directory: gridformat/
File: gridformat/vtk/vtp_writer.hpp
Date: 2024-11-10 16:24:00
Exec Total Coverage
Lines: 69 70 98.6%
Functions: 203 217 93.5%
Branches: 152 299 50.8%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2 // SPDX-License-Identifier: MIT
3 /*!
4 * \file
5 * \ingroup VTK
6 * \copydoc GridFormat::VTPWriter
7 */
8 #ifndef GRIDFORMAT_VTK_VTP_WRITER_HPP_
9 #define GRIDFORMAT_VTK_VTP_WRITER_HPP_
10
11 #include <ranges>
12 #include <ostream>
13 #include <iostream>
14 #include <algorithm>
15 #include <functional>
16
17 #include <gridformat/common/ranges.hpp>
18 #include <gridformat/common/filtered_range.hpp>
19 #include <gridformat/common/field_storage.hpp>
20 #include <gridformat/common/lvalue_reference.hpp>
21
22 #include <gridformat/grid/grid.hpp>
23 #include <gridformat/vtk/common.hpp>
24 #include <gridformat/vtk/xml.hpp>
25
26 namespace GridFormat {
27
28 #ifndef DOXYGEN
29 namespace Detail {
30
31 template<typename Grid, std::size_t size>
32 struct CellTypesPredicate {
33 std::reference_wrapper<const Grid> grid;
34 std::array<CellType, size> cell_types;
35
36 148306 bool operator()(const Cell<Grid>& cell) const {
37 268966 return std::ranges::any_of(cell_types, [&] (const CellType& _ct) {
38 120660 return _ct == type(grid.get(), cell);
39 148306 });
40 }
41 };
42
43 template<typename G, std::size_t s>
44 CellTypesPredicate(G&&, std::array<CellType, s>&&) -> CellTypesPredicate<std::remove_cvref_t<G>, s>;
45 template<typename G, std::size_t s>
46 CellTypesPredicate(G&&, const std::array<CellType, s>&) -> CellTypesPredicate<std::remove_cvref_t<G>, s>;
47
48 } // namespace Detail
49 #endif // DOXYGEN
50
51 /*!
52 * \ingroup VTK
53 * \brief Writer for .vtu file format
54 */
55 template<Concepts::UnstructuredGrid Grid>
56 class VTPWriter : public VTK::XMLWriterBase<Grid, VTPWriter<Grid>> {
57 using ParentType = VTK::XMLWriterBase<Grid, VTPWriter<Grid>>;
58
59 static constexpr std::array zero_d_types{CellType::vertex};
60 static constexpr std::array one_d_types{CellType::segment};
61 static constexpr std::array two_d_types{
62 CellType::quadrilateral,
63 CellType::pixel,
64 CellType::polygon,
65 CellType::triangle
66 };
67
68 public:
69 905 explicit VTPWriter(LValueReferenceOf<const Grid> grid,
70 VTK::XMLOptions xml_opts = {})
71
2/4
✓ Branch 2 taken 492 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 492 times.
✗ Branch 7 not taken.
1810 : ParentType(grid.get(), ".vtp", false, std::move(xml_opts))
72 905 {}
73
74 private:
75 560 VTPWriter _with(VTK::XMLOptions xml_opts) const override {
76
1/2
✓ Branch 4 taken 280 times.
✗ Branch 5 not taken.
560 return VTPWriter{this->grid(), std::move(xml_opts)};
77 }
78
79 370 void _write(std::ostream& s) const override {
80
1/2
✓ Branch 3 taken 229 times.
✗ Branch 4 not taken.
370 auto verts_range = _get_cell_range(Detail::CellTypesPredicate{this->grid(), zero_d_types});
81
1/2
✓ Branch 3 taken 229 times.
✗ Branch 4 not taken.
370 auto lines_range = _get_cell_range(Detail::CellTypesPredicate{this->grid(), one_d_types});
82
1/2
✓ Branch 3 taken 229 times.
✗ Branch 4 not taken.
370 auto polys_range = _get_cell_range(Detail::CellTypesPredicate{this->grid(), two_d_types});
83
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
370 auto unsupported_range = _get_cell_range(
84 1741 [p=Detail::CellTypesPredicate{
85
2/4
✓ Branch 2 taken 229 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 229 times.
✗ Branch 6 not taken.
740 this->grid(), Ranges::merged(Ranges::merged(zero_d_types, one_d_types), two_d_types)
86 }] (const Cell<Grid>& cell) {
87 4208 return !p(cell);
88 }
89 );
90
91
3/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 226 times.
370 if (Ranges::size(unsupported_range) > 0)
92
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
4 this->_log_warning("Grid contains cell types not supported by .vtp; These will be ignored.");
93
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 229 times.
✗ Branch 5 not taken.
370 if (!std::ranges::empty(this->_cell_field_names())
94
4/6
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 25 times.
✓ Branch 3 taken 204 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 229 times.
697 && !std::ranges::empty(verts_range)
95
1/2
✓ Branch 1 taken 204 times.
✗ Branch 2 not taken.
327 + !std::ranges::empty(lines_range)
96
2/4
✓ Branch 1 taken 204 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 204 times.
327 + !std::ranges::empty(polys_range)
97 > 1)
98 this->_log_warning(
99 "You appear to have cell data defined and your grid consists of multiple cell types "
100 "(vertices, lines, polys).\nNote that for correct cell data visualization with vtk, "
101 "your cell iterator must be such that it iterates over the cell types in order "
102 "(vertices -> lines -> polys)."
103 );
104
105
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
370 const auto num_verts = Ranges::size(verts_range);
106
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
370 const auto num_lines = Ranges::size(lines_range);
107
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
370 const auto num_polys = Ranges::size(polys_range);
108
109
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 229 times.
✗ Branch 5 not taken.
740 auto context = this->_get_write_context("PolyData");
110
5/9
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 209 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 209 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20 times.
✗ Branch 10 not taken.
740 this->_set_attribute(context, "Piece", "NumberOfPoints", number_of_points(this->grid()));
111
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 229 times.
✗ Branch 6 not taken.
740 this->_set_attribute(context, "Piece", "NumberOfVerts", num_verts);
112
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 229 times.
✗ Branch 6 not taken.
740 this->_set_attribute(context, "Piece", "NumberOfLines", num_lines);
113
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 229 times.
✗ Branch 6 not taken.
740 this->_set_attribute(context, "Piece", "NumberOfStrips", "0");
114
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 229 times.
✗ Branch 6 not taken.
740 this->_set_attribute(context, "Piece", "NumberOfPolys", num_polys);
115
116 370 FieldStorage vtk_point_fields;
117 370 FieldStorage vtk_cell_fields;
118
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 229 times.
✗ Branch 5 not taken.
1820 std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) {
119
24/48
✓ Branch 1 taken 506 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 506 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 506 times.
✗ Branch 8 not taken.
✓ Branch 15 taken 92 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 92 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 92 times.
✗ Branch 22 not taken.
✓ Branch 29 taken 91 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 91 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 91 times.
✗ Branch 36 not taken.
✓ Branch 43 taken 90 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 90 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 90 times.
✗ Branch 50 not taken.
✓ Branch 57 taken 90 times.
✗ Branch 58 not taken.
✓ Branch 60 taken 90 times.
✗ Branch 61 not taken.
✓ Branch 63 taken 90 times.
✗ Branch 64 not taken.
✓ Branch 71 taken 90 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 90 times.
✗ Branch 75 not taken.
✓ Branch 77 taken 90 times.
✗ Branch 78 not taken.
✓ Branch 85 taken 90 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 90 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 90 times.
✗ Branch 92 not taken.
✓ Branch 99 taken 90 times.
✗ Branch 100 not taken.
✓ Branch 102 taken 90 times.
✗ Branch 103 not taken.
✓ Branch 105 taken 90 times.
✗ Branch 106 not taken.
1139 vtk_point_fields.set(name, VTK::make_vtk_field(this->_get_point_field_ptr(name)));
120
16/32
✓ Branch 2 taken 506 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 506 times.
✗ Branch 7 not taken.
✓ Branch 12 taken 92 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 92 times.
✗ Branch 17 not taken.
✓ Branch 22 taken 91 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 91 times.
✗ Branch 27 not taken.
✓ Branch 32 taken 90 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 90 times.
✗ Branch 37 not taken.
✓ Branch 42 taken 90 times.
✗ Branch 43 not taken.
✓ Branch 46 taken 90 times.
✗ Branch 47 not taken.
✓ Branch 52 taken 90 times.
✗ Branch 53 not taken.
✓ Branch 56 taken 90 times.
✗ Branch 57 not taken.
✓ Branch 62 taken 90 times.
✗ Branch 63 not taken.
✓ Branch 66 taken 90 times.
✗ Branch 67 not taken.
✓ Branch 72 taken 90 times.
✗ Branch 73 not taken.
✓ Branch 76 taken 90 times.
✗ Branch 77 not taken.
1139 this->_set_data_array(context, "Piece/PointData", name, vtk_point_fields.get(name));
121 });
122
2/4
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 229 times.
✗ Branch 5 not taken.
1816 std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) {
123
24/48
✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 504 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 504 times.
✗ Branch 8 not taken.
✓ Branch 15 taken 91 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 91 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 91 times.
✗ Branch 22 not taken.
✓ Branch 29 taken 90 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 90 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 90 times.
✗ Branch 36 not taken.
✓ Branch 43 taken 90 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 90 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 90 times.
✗ Branch 50 not taken.
✓ Branch 57 taken 90 times.
✗ Branch 58 not taken.
✓ Branch 60 taken 90 times.
✗ Branch 61 not taken.
✓ Branch 63 taken 90 times.
✗ Branch 64 not taken.
✓ Branch 71 taken 90 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 90 times.
✗ Branch 75 not taken.
✓ Branch 77 taken 90 times.
✗ Branch 78 not taken.
✓ Branch 85 taken 90 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 90 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 90 times.
✗ Branch 92 not taken.
✓ Branch 99 taken 90 times.
✗ Branch 100 not taken.
✓ Branch 102 taken 90 times.
✗ Branch 103 not taken.
✓ Branch 105 taken 90 times.
✗ Branch 106 not taken.
1135 vtk_cell_fields.set(name, VTK::make_vtk_field(this->_get_cell_field_ptr(name)));
124
16/32
✓ Branch 2 taken 504 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 504 times.
✗ Branch 7 not taken.
✓ Branch 12 taken 91 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 91 times.
✗ Branch 17 not taken.
✓ Branch 22 taken 90 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 90 times.
✗ Branch 27 not taken.
✓ Branch 32 taken 90 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 90 times.
✗ Branch 37 not taken.
✓ Branch 42 taken 90 times.
✗ Branch 43 not taken.
✓ Branch 46 taken 90 times.
✗ Branch 47 not taken.
✓ Branch 52 taken 90 times.
✗ Branch 53 not taken.
✓ Branch 56 taken 90 times.
✗ Branch 57 not taken.
✓ Branch 62 taken 90 times.
✗ Branch 63 not taken.
✓ Branch 66 taken 90 times.
✗ Branch 67 not taken.
✓ Branch 72 taken 90 times.
✗ Branch 73 not taken.
✓ Branch 76 taken 90 times.
✗ Branch 77 not taken.
1135 this->_set_data_array(context, "Piece/CellData", name, vtk_cell_fields.get(name));
125 });
126
127 317 const FieldPtr coords_field = std::visit([&] <typename T> (const Precision<T>&) {
128 229 return VTK::make_coordinates_field<T>(this->grid(), false);
129
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
370 }, this->_xml_settings.coordinate_precision);
130
3/4
✓ Branch 2 taken 229 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✓ Branch 7 taken 20 times.
776 this->_set_data_array(context, "Piece/Points", "Coordinates", *coords_field);
131
132
1/2
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
334 const auto point_id_map = make_point_id_map(this->grid());
133
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto verts_connectivity_field = _make_connectivity_field(verts_range, point_id_map);
134
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto verts_offsets_field = _make_offsets_field(verts_range);
135
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Verts", "connectivity", *verts_connectivity_field);
136
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Verts", "offsets", *verts_offsets_field);
137
138
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto lines_connectivity_field = _make_connectivity_field(lines_range, point_id_map);
139
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto lines_offsets_field = _make_offsets_field(lines_range);
140
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Lines", "connectivity", *lines_connectivity_field);
141
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Lines", "offsets", *lines_offsets_field);
142
143
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto polys_connectivity_field = _make_connectivity_field(polys_range, point_id_map);
144
1/2
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
334 const auto polys_offsets_field = _make_offsets_field(polys_range);
145
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Polys", "connectivity", *polys_connectivity_field);
146
2/4
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
668 this->_set_data_array(context, "Piece/Polys", "offsets", *polys_offsets_field);
147
148
1/2
✓ Branch 2 taken 209 times.
✗ Branch 3 not taken.
334 this->_write_xml(std::move(context), s);
149 478 }
150
151 template<typename Predicate>
152 1832 std::ranges::forward_range auto _get_cell_range(Predicate&& pred) const {
153
3/6
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 92 times.
✗ Branch 7 not taken.
1832 return Ranges::filter_by(std::forward<Predicate>(pred), cells(this->grid()));
154 }
155
156 template<typename CellsRange, typename PointMap>
157 1254 FieldPtr _make_connectivity_field(CellsRange&& cells, const PointMap& point_id_map) const {
158 1881 return std::visit([&] <typename T> (const Precision<T>&) {
159 627 return VTK::make_connectivity_field<T>(this->grid(), cells, point_id_map);
160
1/2
✓ Branch 1 taken 627 times.
✗ Branch 2 not taken.
2508 }, this->_xml_settings.header_precision);
161 }
162
163 template<typename CellsRange>
164 627 FieldPtr _make_offsets_field(CellsRange&& cells) const {
165 1254 return std::visit([&] <typename T> (const Precision<T>&) {
166 627 return VTK::make_offsets_field<T>(this->grid(), cells);
167 1254 }, this->_xml_settings.header_precision);
168 }
169 };
170
171 template<typename G>
172 VTPWriter(G&&, VTK::XMLOptions = {}) -> VTPWriter<std::remove_cvref_t<G>>;
173
174 } // namespace GridFormat
175
176 #endif // GRIDFORMAT_VTK_VTP_WRITER_HPP_
177