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::VTPReader | ||
7 | */ | ||
8 | #ifndef GRIDFORMAT_VTK_VTP_READER_HPP_ | ||
9 | #define GRIDFORMAT_VTK_VTP_READER_HPP_ | ||
10 | |||
11 | #include <string> | ||
12 | #include <optional> | ||
13 | #include <iterator> | ||
14 | #include <utility> | ||
15 | |||
16 | #include <gridformat/common/string_conversion.hpp> | ||
17 | #include <gridformat/common/exceptions.hpp> | ||
18 | #include <gridformat/common/field.hpp> | ||
19 | |||
20 | #include <gridformat/grid/cell_type.hpp> | ||
21 | #include <gridformat/grid/reader.hpp> | ||
22 | #include <gridformat/vtk/xml.hpp> | ||
23 | |||
24 | namespace GridFormat { | ||
25 | |||
26 | /*! | ||
27 | * \ingroup VTK | ||
28 | * \brief Reader for .vtp file format | ||
29 | */ | ||
30 | class VTPReader : public GridReader { | ||
31 | private: | ||
32 | 231 | void _open(const std::string& filename, typename GridReader::FieldNames& fields) override { | |
33 |
1/2✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
|
231 | auto helper = VTK::XMLReaderHelper::make_from(filename, "PolyData"); |
34 | |||
35 |
3/6✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 231 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 231 times.
✗ Branch 10 not taken.
|
231 | _num_points = from_string<std::size_t>(helper.get("PolyData/Piece").get_attribute("NumberOfPoints")); |
36 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 231 times.
✗ Branch 7 not taken.
|
231 | _num_verts = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfVerts"); |
37 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 231 times.
✗ Branch 7 not taken.
|
231 | _num_lines = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfLines"); |
38 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 231 times.
✗ Branch 7 not taken.
|
231 | _num_strips = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfStrips"); |
39 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 231 times.
✗ Branch 7 not taken.
|
231 | _num_polys = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfPolys"); |
40 | |||
41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
|
231 | if (_num_strips > 0) |
42 | ✗ | throw NotImplemented("Triangle strips are not (yet) supported"); | |
43 | |||
44 |
2/4✓ Branch 2 taken 231 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 231 times.
✗ Branch 6 not taken.
|
231 | VTK::XMLDetail::copy_field_names_from(helper.get("PolyData"), fields); |
45 | 231 | _helper.emplace(std::move(helper)); | |
46 | 231 | } | |
47 | |||
48 | 43 | void _close() override { | |
49 | 43 | _helper.reset(); | |
50 | 43 | _num_points = 0; | |
51 | 43 | _num_verts = 0; | |
52 | 43 | _num_lines = 0; | |
53 | 43 | _num_strips = 0; | |
54 | 43 | _num_polys = 0; | |
55 | 43 | } | |
56 | |||
57 | 1 | std::string _name() const override { | |
58 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return "VTPReader"; |
59 | } | ||
60 | |||
61 | 889 | std::size_t _number_of_cells() const override { | |
62 | 889 | return _num_verts + _num_lines + _num_strips + _num_polys; | |
63 | } | ||
64 | |||
65 | 1289 | std::size_t _number_of_points() const override { | |
66 | 1289 | return _num_points; | |
67 | } | ||
68 | |||
69 | 7 | std::size_t _number_of_pieces() const override { | |
70 | 7 | return 1; | |
71 | } | ||
72 | |||
73 | 85 | bool _is_sequence() const override { | |
74 | 85 | return false; | |
75 | } | ||
76 | |||
77 | 161 | FieldPtr _points() const override { | |
78 |
1/2✓ Branch 4 taken 161 times.
✗ Branch 5 not taken.
|
161 | return _helper.value().make_points_field("PolyData/Piece/Points", _number_of_points()); |
79 | } | ||
80 | |||
81 | 269 | void _visit_cells(const typename GridReader::CellVisitor& visitor) const override { | |
82 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | if (_num_verts > 0) |
83 | ✗ | _visit_cells("Verts", CellType::vertex, _num_verts, visitor); | |
84 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
|
269 | if (_num_lines > 0) |
85 | ✗ | _visit_cells("Lines", CellType::segment, _num_lines, visitor); | |
86 |
1/2✓ Branch 0 taken 269 times.
✗ Branch 1 not taken.
|
269 | if (_num_polys > 0) |
87 |
1/2✓ Branch 2 taken 269 times.
✗ Branch 3 not taken.
|
269 | _visit_cells("Polys", CellType::polygon, _num_polys, visitor); |
88 | 269 | } | |
89 | |||
90 | 631 | FieldPtr _cell_field(std::string_view name) const override { | |
91 |
2/4✓ Branch 2 taken 631 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 631 times.
✗ Branch 8 not taken.
|
631 | return _helper.value().make_data_array_field(name, "PolyData/Piece/CellData", _number_of_cells()); |
92 | } | ||
93 | |||
94 | 634 | FieldPtr _point_field(std::string_view name) const override { | |
95 |
2/4✓ Branch 2 taken 634 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 634 times.
✗ Branch 8 not taken.
|
634 | return _helper.value().make_data_array_field(name, "PolyData/Piece/PointData", _number_of_points()); |
96 | } | ||
97 | |||
98 | 54 | FieldPtr _meta_data_field(std::string_view name) const override { | |
99 |
1/2✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
|
54 | return _helper.value().make_data_array_field(name, "PolyData/FieldData"); |
100 | } | ||
101 | |||
102 | 269 | void _visit_cells(std::string_view type_name, | |
103 | const CellType& cell_type, | ||
104 | const std::size_t expected_size, | ||
105 | const typename GridReader::CellVisitor& visitor) const { | ||
106 |
2/4✓ Branch 1 taken 269 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 269 times.
✗ Branch 5 not taken.
|
269 | const std::string path = "PolyData/Piece/" + std::string{type_name}; |
107 |
2/4✓ Branch 1 taken 269 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 269 times.
✗ Branch 8 not taken.
|
538 | const auto offsets = _helper.value().make_data_array_field( |
108 | "offsets", path, expected_size | ||
109 |
1/2✓ Branch 2 taken 269 times.
✗ Branch 3 not taken.
|
269 | )->template export_to<std::vector<std::size_t>>(); |
110 |
2/4✓ Branch 1 taken 269 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 269 times.
✗ Branch 8 not taken.
|
538 | const auto connectivity = _helper.value().make_data_array_field( |
111 | "connectivity", path | ||
112 |
1/2✓ Branch 2 taken 269 times.
✗ Branch 3 not taken.
|
269 | )->template export_to<std::vector<std::size_t>>(); |
113 | |||
114 | 269 | std::vector<std::size_t> corners; | |
115 |
2/2✓ Branch 0 taken 6132 times.
✓ Branch 1 taken 269 times.
|
6401 | for (std::size_t i = 0; i < expected_size; ++i) { |
116 | 6132 | corners.clear(); | |
117 |
3/4✓ Branch 0 taken 5863 times.
✓ Branch 1 taken 269 times.
✓ Branch 3 taken 5863 times.
✗ Branch 4 not taken.
|
6132 | const std::size_t offset_begin = (i == 0 ? 0 : offsets.at(i-1)); |
118 |
1/2✓ Branch 1 taken 6132 times.
✗ Branch 2 not taken.
|
6132 | const std::size_t offset_end = offsets.at(i); |
119 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6132 times.
|
6132 | if (connectivity.size() < offset_end) |
120 | ✗ | throw SizeError("Connectivity array read from the file is too small"); | |
121 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6132 times.
|
6132 | if (offset_end < offset_begin) |
122 | ✗ | throw ValueError("Invalid offset array"); | |
123 |
2/4✓ Branch 1 taken 6132 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 6132 times.
✗ Branch 7 not taken.
|
6132 | std::copy_n(connectivity.begin() + offset_begin, offset_end - offset_begin, std::back_inserter(corners)); |
124 | |||
125 |
1/2✓ Branch 0 taken 6132 times.
✗ Branch 1 not taken.
|
12264 | const CellType ct = cell_type == CellType::polygon ? ( |
126 |
2/2✓ Branch 1 taken 6131 times.
✓ Branch 2 taken 1 times.
|
12263 | corners.size() == 3 ? CellType::triangle |
127 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6130 times.
|
6131 | : (corners.size() == 4 ? CellType::quadrilateral : cell_type) |
128 | 6132 | ) : cell_type; | |
129 |
1/2✓ Branch 1 taken 6132 times.
✗ Branch 2 not taken.
|
6132 | visitor(ct, corners); |
130 | } | ||
131 | 269 | } | |
132 | |||
133 | std::optional<VTK::XMLReaderHelper> _helper; | ||
134 | std::size_t _num_points; | ||
135 | std::size_t _num_verts; | ||
136 | std::size_t _num_lines; | ||
137 | std::size_t _num_strips; | ||
138 | std::size_t _num_polys; | ||
139 | }; | ||
140 | |||
141 | } // namespace GridFormat | ||
142 | |||
143 | #endif // GRIDFORMAT_VTK_VTP_READER_HPP_ | ||
144 |