GridFormat 0.2.1
I/O-Library for grid-like data structures
Loading...
Searching...
No Matches
vtp_reader.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_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>
19
20#include <gridformat/grid/cell_type.hpp>
23
24namespace GridFormat {
25
30class VTPReader : public GridReader {
31 private:
32 void _open(const std::string& filename, typename GridReader::FieldNames& fields) override {
33 auto helper = VTK::XMLReaderHelper::make_from(filename, "PolyData");
34
35 _num_points = from_string<std::size_t>(helper.get("PolyData/Piece").get_attribute("NumberOfPoints"));
36 _num_verts = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfVerts");
37 _num_lines = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfLines");
38 _num_strips = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfStrips");
39 _num_polys = helper.get("PolyData/Piece").get_attribute_or(std::size_t{0}, "NumberOfPolys");
40
41 if (_num_strips > 0)
42 throw NotImplemented("Triangle strips are not (yet) supported");
43
44 VTK::XMLDetail::copy_field_names_from(helper.get("PolyData"), fields);
45 _helper.emplace(std::move(helper));
46 }
47
48 void _close() override {
49 _helper.reset();
50 _num_points = 0;
51 _num_verts = 0;
52 _num_lines = 0;
53 _num_strips = 0;
54 _num_polys = 0;
55 }
56
57 std::string _name() const override {
58 return "VTPReader";
59 }
60
61 std::size_t _number_of_cells() const override {
62 return _num_verts + _num_lines + _num_strips + _num_polys;
63 }
64
65 std::size_t _number_of_points() const override {
66 return _num_points;
67 }
68
69 std::size_t _number_of_pieces() const override {
70 return 1;
71 }
72
73 bool _is_sequence() const override {
74 return false;
75 }
76
77 FieldPtr _points() const override {
78 return _helper.value().make_points_field("PolyData/Piece/Points", _number_of_points());
79 }
80
81 void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
82 if (_num_verts > 0)
83 _visit_cells("Verts", CellType::vertex, _num_verts, visitor);
84 if (_num_lines > 0)
85 _visit_cells("Lines", CellType::segment, _num_lines, visitor);
86 if (_num_polys > 0)
87 _visit_cells("Polys", CellType::polygon, _num_polys, visitor);
88 }
89
90 FieldPtr _cell_field(std::string_view name) const override {
91 return _helper.value().make_data_array_field(name, "PolyData/Piece/CellData", _number_of_cells());
92 }
93
94 FieldPtr _point_field(std::string_view name) const override {
95 return _helper.value().make_data_array_field(name, "PolyData/Piece/PointData", _number_of_points());
96 }
97
98 FieldPtr _meta_data_field(std::string_view name) const override {
99 return _helper.value().make_data_array_field(name, "PolyData/FieldData");
100 }
101
102 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 const std::string path = "PolyData/Piece/" + std::string{type_name};
107 const auto offsets = _helper.value().make_data_array_field(
108 "offsets", path, expected_size
109 )->template export_to<std::vector<std::size_t>>();
110 const auto connectivity = _helper.value().make_data_array_field(
111 "connectivity", path
112 )->template export_to<std::vector<std::size_t>>();
113
114 std::vector<std::size_t> corners;
115 for (std::size_t i = 0; i < expected_size; ++i) {
116 corners.clear();
117 const std::size_t offset_begin = (i == 0 ? 0 : offsets.at(i-1));
118 const std::size_t offset_end = offsets.at(i);
119 if (connectivity.size() < offset_end)
120 throw SizeError("Connectivity array read from the file is too small");
121 if (offset_end < offset_begin)
122 throw ValueError("Invalid offset array");
123 std::copy_n(connectivity.begin() + offset_begin, offset_end - offset_begin, std::back_inserter(corners));
124
125 const CellType ct = cell_type == CellType::polygon ? (
126 corners.size() == 3 ? CellType::triangle
127 : (corners.size() == 4 ? CellType::quadrilateral : cell_type)
128 ) : cell_type;
129 visitor(ct, corners);
130 }
131 }
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_
Abstract base class for all readers, defines the common interface.
Definition: reader.hpp:51
const std::string & filename() const
Return the name of the opened grid file (empty string until open() is called)
Definition: reader.hpp:92
std::string name() const
Return the name of this reader.
Definition: reader.hpp:73
Reader for .vtp file format.
Definition: vtp_reader.hpp:30
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition: field.hpp:186
Definition: reader.hpp:266
Helper classes and functions for VTK XML-type file format writers & readers.