8#ifndef GRIDFORMAT_VTK_VTP_READER_HPP_
9#define GRIDFORMAT_VTK_VTP_READER_HPP_
16#include <gridformat/common/string_conversion.hpp>
17#include <gridformat/common/exceptions.hpp>
20#include <gridformat/grid/cell_type.hpp>
33 auto helper = VTK::XMLReaderHelper::make_from(
filename,
"PolyData");
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");
42 throw NotImplemented(
"Triangle strips are not (yet) supported");
44 VTK::XMLDetail::copy_field_names_from(helper.get(
"PolyData"), fields);
45 _helper.emplace(std::move(helper));
48 void _close()
override {
57 std::string _name()
const override {
61 std::size_t _number_of_cells()
const override {
62 return _num_verts + _num_lines + _num_strips + _num_polys;
65 std::size_t _number_of_points()
const override {
69 std::size_t _number_of_pieces()
const override {
73 bool _is_sequence()
const override {
78 return _helper.value().make_points_field(
"PolyData/Piece/Points", _number_of_points());
81 void _visit_cells(
const typename GridReader::CellVisitor& visitor)
const override {
83 _visit_cells(
"Verts", CellType::vertex, _num_verts, visitor);
85 _visit_cells(
"Lines", CellType::segment, _num_lines, visitor);
87 _visit_cells(
"Polys", CellType::polygon, _num_polys, visitor);
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());
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());
98 FieldPtr _meta_data_field(std::string_view
name)
const override {
99 return _helper.value().make_data_array_field(
name,
"PolyData/FieldData");
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(
112 )->template export_to<std::vector<std::size_t>>();
114 std::vector<std::size_t> corners;
115 for (std::size_t i = 0; i < expected_size; ++i) {
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));
125 const CellType ct = cell_type == CellType::polygon ? (
126 corners.size() == 3 ? CellType::triangle
127 : (corners.size() == 4 ? CellType::quadrilateral : cell_type)
129 visitor(ct, corners);
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;
Base class for grid data readers.
std::shared_ptr< const Field > FieldPtr
Pointer type used by writers/readers for fields.
Definition: field.hpp:186
Helper classes and functions for VTK XML-type file format writers & readers.