| 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/field_storage.hpp> | ||
| 19 | #include <gridformat/common/lvalue_reference.hpp> | ||
| 20 | |||
| 21 | #include <gridformat/grid/grid.hpp> | ||
| 22 | #include <gridformat/grid/filtered.hpp> | ||
| 23 | |||
| 24 | #include <gridformat/vtk/common.hpp> | ||
| 25 | #include <gridformat/vtk/xml.hpp> | ||
| 26 | |||
| 27 | namespace GridFormat { | ||
| 28 | |||
| 29 | #ifndef DOXYGEN | ||
| 30 | namespace Detail { | ||
| 31 | |||
| 32 | template<typename Grid, std::size_t size> | ||
| 33 | struct CellTypesPredicate { | ||
| 34 | std::reference_wrapper<const Grid> grid; | ||
| 35 | std::array<CellType, size> cell_types; | ||
| 36 | |||
| 37 | 166672 | bool operator()(const Cell<Grid>& cell) const { | |
| 38 | 311886 | return std::ranges::any_of(cell_types, [&] (const CellType& _ct) { | |
| 39 | 145214 | return _ct == type(grid.get(), cell); | |
| 40 | 166672 | }); | |
| 41 | } | ||
| 42 | }; | ||
| 43 | |||
| 44 | template<typename G, std::size_t s> | ||
| 45 | CellTypesPredicate(G&&, std::array<CellType, s>&&) -> CellTypesPredicate<std::remove_cvref_t<G>, s>; | ||
| 46 | template<typename G, std::size_t s> | ||
| 47 | CellTypesPredicate(G&&, const std::array<CellType, s>&) -> CellTypesPredicate<std::remove_cvref_t<G>, s>; | ||
| 48 | |||
| 49 | } // namespace Detail | ||
| 50 | #endif // DOXYGEN | ||
| 51 | |||
| 52 | /*! | ||
| 53 | * \ingroup VTK | ||
| 54 | * \brief Writer for .vtu file format | ||
| 55 | */ | ||
| 56 | template<Concepts::UnstructuredGrid Grid> | ||
| 57 | class VTPWriter : public VTK::XMLWriterBase<Grid, VTPWriter<Grid>> { | ||
| 58 | using ParentType = VTK::XMLWriterBase<Grid, VTPWriter<Grid>>; | ||
| 59 | |||
| 60 | static constexpr std::array zero_d_types{CellType::vertex}; | ||
| 61 | static constexpr std::array one_d_types{CellType::segment}; | ||
| 62 | static constexpr std::array two_d_types{ | ||
| 63 | CellType::quadrilateral, | ||
| 64 | CellType::pixel, | ||
| 65 | CellType::polygon, | ||
| 66 | CellType::triangle | ||
| 67 | }; | ||
| 68 | |||
| 69 | public: | ||
| 70 | 909 | explicit VTPWriter(LValueReferenceOf<const Grid> grid, | |
| 71 | VTK::XMLOptions xml_opts = {}) | ||
| 72 |
2/4✓ Branch 2 taken 496 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 496 times.
✗ Branch 7 not taken.
|
1818 | : ParentType(grid.get(), ".vtp", false, std::move(xml_opts)) |
| 73 | 909 | {} | |
| 74 | |||
| 75 | private: | ||
| 76 | 562 | VTPWriter _with(VTK::XMLOptions xml_opts) const override { | |
| 77 |
1/2✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
|
562 | return VTPWriter{this->grid(), std::move(xml_opts)}; |
| 78 | } | ||
| 79 | |||
| 80 | 372 | void _write(std::ostream& s) const override { | |
| 81 | 372 | FilteredGrid verts{this->grid(), Detail::CellTypesPredicate{this->grid(), zero_d_types}}; | |
| 82 | 372 | FilteredGrid lines{this->grid(), Detail::CellTypesPredicate{this->grid(), one_d_types}}; | |
| 83 | 372 | FilteredGrid polys{this->grid(), Detail::CellTypesPredicate{this->grid(), two_d_types}}; | |
| 84 | 372 | FilteredGrid unsupported{ | |
| 85 | 372 | this->grid(), | |
| 86 | 3114 | [p=Detail::CellTypesPredicate{ | |
| 87 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
744 | this->grid(), Ranges::merged(Ranges::merged(zero_d_types, one_d_types), two_d_types) |
| 88 | }] (const Cell<Grid>& cell) { | ||
| 89 | 8456 | return !p(cell); | |
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | auto verts_range = cells(verts); |
| 94 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | auto lines_range = cells(lines); |
| 95 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | auto polys_range = cells(polys); |
| 96 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | auto unsupported_range = cells(unsupported); |
| 97 | |||
| 98 |
3/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 228 times.
|
372 | if (Ranges::size(unsupported_range) > 0) |
| 99 |
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."); |
| 100 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 231 times.
✗ Branch 5 not taken.
|
372 | if (!std::ranges::empty(this->_cell_field_names()) |
| 101 |
4/6✓ Branch 0 taken 206 times.
✓ Branch 1 taken 25 times.
✓ Branch 3 taken 206 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 231 times.
|
701 | && !std::ranges::empty(verts_range) |
| 102 |
1/2✓ Branch 1 taken 206 times.
✗ Branch 2 not taken.
|
329 | + !std::ranges::empty(lines_range) |
| 103 |
2/4✓ Branch 1 taken 206 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 206 times.
|
329 | + !std::ranges::empty(polys_range) |
| 104 | > 1) | ||
| 105 | ✗ | this->_log_warning( | |
| 106 | "You appear to have cell data defined and your grid consists of multiple cell types " | ||
| 107 | "(vertices, lines, polys).\nNote that for correct cell data visualization with vtk, " | ||
| 108 | "your cell iterator must be such that it iterates over the cell types in order " | ||
| 109 | "(vertices -> lines -> polys)." | ||
| 110 | ); | ||
| 111 | |||
| 112 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | const auto num_verts = Ranges::size(verts_range); |
| 113 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | const auto num_lines = Ranges::size(lines_range); |
| 114 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | const auto num_polys = Ranges::size(polys_range); |
| 115 | |||
| 116 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 231 times.
✗ Branch 5 not taken.
|
744 | auto context = this->_get_write_context("PolyData"); |
| 117 |
5/9✓ Branch 2 taken 20 times.
✓ Branch 3 taken 211 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 211 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20 times.
✗ Branch 10 not taken.
|
744 | this->_set_attribute(context, "Piece", "NumberOfPoints", number_of_points(this->grid())); |
| 118 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
744 | this->_set_attribute(context, "Piece", "NumberOfVerts", num_verts); |
| 119 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
744 | this->_set_attribute(context, "Piece", "NumberOfLines", num_lines); |
| 120 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
744 | this->_set_attribute(context, "Piece", "NumberOfStrips", "0"); |
| 121 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
744 | this->_set_attribute(context, "Piece", "NumberOfPolys", num_polys); |
| 122 | |||
| 123 | 372 | FieldStorage vtk_point_fields; | |
| 124 | 372 | FieldStorage vtk_cell_fields; | |
| 125 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 231 times.
✗ Branch 5 not taken.
|
1822 | std::ranges::for_each(this->_point_field_names(), [&] (const std::string& name) { |
| 126 |
24/48✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 518 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 518 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.
|
1151 | vtk_point_fields.set(name, VTK::make_vtk_field(this->_get_point_field_ptr(name))); |
| 127 |
16/32✓ Branch 2 taken 518 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 518 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.
|
1151 | this->_set_data_array(context, "Piece/PointData", name, vtk_point_fields.get(name)); |
| 128 | }); | ||
| 129 |
2/4✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 231 times.
✗ Branch 5 not taken.
|
1818 | std::ranges::for_each(this->_cell_field_names(), [&] (const std::string& name) { |
| 130 |
24/48✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 516 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 516 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.
|
1147 | vtk_cell_fields.set(name, VTK::make_vtk_field(this->_get_cell_field_ptr(name))); |
| 131 |
16/32✓ Branch 2 taken 516 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 516 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.
|
1147 | this->_set_data_array(context, "Piece/CellData", name, vtk_cell_fields.get(name)); |
| 132 | }); | ||
| 133 | |||
| 134 | 321 | const FieldPtr coords_field = std::visit([&] <typename T> (const Precision<T>&) { | |
| 135 | 231 | return VTK::make_coordinates_field<T>(this->grid(), false); | |
| 136 |
1/2✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
|
372 | }, this->_xml_settings.coordinate_precision); |
| 137 |
3/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✓ Branch 7 taken 20 times.
|
780 | this->_set_data_array(context, "Piece/Points", "Coordinates", *coords_field); |
| 138 | |||
| 139 |
1/2✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
|
336 | const auto point_id_map = make_point_id_map(this->grid()); |
| 140 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto verts_connectivity_field = _make_connectivity_field(verts, point_id_map); |
| 141 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto verts_offsets_field = _make_offsets_field(verts); |
| 142 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Verts", "connectivity", *verts_connectivity_field); |
| 143 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Verts", "offsets", *verts_offsets_field); |
| 144 | |||
| 145 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto lines_connectivity_field = _make_connectivity_field(lines, point_id_map); |
| 146 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto lines_offsets_field = _make_offsets_field(lines); |
| 147 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Lines", "connectivity", *lines_connectivity_field); |
| 148 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Lines", "offsets", *lines_offsets_field); |
| 149 | |||
| 150 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto polys_connectivity_field = _make_connectivity_field(polys, point_id_map); |
| 151 |
1/2✓ Branch 1 taken 211 times.
✗ Branch 2 not taken.
|
336 | const auto polys_offsets_field = _make_offsets_field(polys); |
| 152 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Polys", "connectivity", *polys_connectivity_field); |
| 153 |
2/4✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 211 times.
✗ Branch 7 not taken.
|
672 | this->_set_data_array(context, "Piece/Polys", "offsets", *polys_offsets_field); |
| 154 | |||
| 155 |
1/2✓ Branch 2 taken 211 times.
✗ Branch 3 not taken.
|
336 | this->_write_xml(std::move(context), s); |
| 156 | 480 | } | |
| 157 | |||
| 158 | template<typename G, typename PointMap> | ||
| 159 | 1266 | FieldPtr _make_connectivity_field(G&& grid, const PointMap& point_id_map) const { | |
| 160 | 1899 | return std::visit([&] <typename T> (const Precision<T>&) { | |
| 161 | 633 | return VTK::make_connectivity_field<T>(grid, point_id_map); | |
| 162 |
1/2✓ Branch 1 taken 633 times.
✗ Branch 2 not taken.
|
2532 | }, this->_xml_settings.header_precision); |
| 163 | } | ||
| 164 | |||
| 165 | template<typename G> | ||
| 166 | 633 | FieldPtr _make_offsets_field(G&& grid) const { | |
| 167 | 1266 | return std::visit([&] <typename T> (const Precision<T>&) { | |
| 168 | 633 | return VTK::make_offsets_field<T>(grid); | |
| 169 | 1266 | }, this->_xml_settings.header_precision); | |
| 170 | } | ||
| 171 | }; | ||
| 172 | |||
| 173 | template<typename G> | ||
| 174 | VTPWriter(G&&, VTK::XMLOptions = {}) -> VTPWriter<std::remove_cvref_t<G>>; | ||
| 175 | |||
| 176 | } // namespace GridFormat | ||
| 177 | |||
| 178 | #endif // GRIDFORMAT_VTK_VTP_WRITER_HPP_ | ||
| 179 |