Tatooine
unstructured_triangular_grid.h
Go to the documentation of this file.
1#ifndef TATOOINE_UNSTRUCTURED_TRIANGULAR_GRID_H
2#define TATOOINE_UNSTRUCTURED_TRIANGULAR_GRID_H
3//==============================================================================
5//==============================================================================
6namespace tatooine {
7//==============================================================================
8template <typename Real, std::size_t NumDimensions>
10 : unstructured_simplicial_grid<Real, NumDimensions, 2> {
14 using typename parent_type::vertex_handle;
16 constexpr unstructured_triangular_grid() = default;
17 template <typename... Handles>
18 auto insert_triangle(Handles const... handles) requires(
19 is_same<Handles, vertex_handle>&&...) {
20 return this->insert_simplex(handles...);
21 }
22 auto triangle_at(triangle_handle const h) { return this->simplex_at(h); }
23 auto triangle_at(triangle_handle const h) const {
24 return this->simplex_at(h);
25 }
26 auto triangles() { return this->simplices(); }
27 auto triangles() const { return this->simplices(); }
28};
29template <std::size_t NumDimensions>
32template <typename Real>
34template <typename Real>
36template <typename Real>
38template <typename Real>
44//==============================================================================
45template <typename T>
46struct is_unstructured_triangular_grid_impl : std::false_type {};
47template <typename Real, std::size_t NumDimensions>
49 unstructured_triangular_grid<Real, NumDimensions>> : std::true_type {};
50template <typename T>
51static constexpr auto is_unstructured_triangular_grid =
53//==============================================================================
54namespace detail {
55//==============================================================================
56template <typename MeshCont>
58 MeshCont const& grids, std::filesystem::path const& path,
59 std::string const& title = "tatooine grids") {
61 if (writer.is_open()) {
62 std::size_t num_pts = 0;
63 std::size_t cur_first = 0;
64 for (auto const& m : grids) {
65 num_pts += m.vertices().size();
66 }
67 std::vector<std::array<typename MeshCont::value_type::real_type, 3>> points;
68 std::vector<std::vector<std::size_t>> faces;
69 points.reserve(num_pts);
70 faces.reserve(grids.size());
71
72 for (auto const& m : grids) {
73 // add points
74 for (auto const& v : m.vertices()) {
75 points.push_back(std::array{m[v](0), m[v](1), m[v](2)});
76 }
77
78 // add faces
79 for (auto c : m.simplices()) {
80 faces.emplace_back();
81 auto [v0, v1, v2] = m[c];
82 faces.back().push_back(cur_first + v0.index());
83 faces.back().push_back(cur_first + v1.index());
84 faces.back().push_back(cur_first + v2.index());
85 }
86 cur_first += m.vertices().size();
87 }
88
89 // write
90 writer.set_title(title);
91 writer.write_header();
92 writer.write_points(points);
93 writer.write_polygons(faces);
94 // writer.write_point_data(num_pts);
95 writer.close();
96 }
97}
98//==============================================================================
100 range auto const& grids, std::filesystem::path const& path) {
101 auto file = std::ofstream{path, std::ios::binary};
102 if (!file.is_open()) {
103 throw std::runtime_error{"Could not write " + path.string()};
104 }
105 auto offset = std::size_t{};
106 using header_type = std::uint64_t;
107 using polys_connectivity_int_t = std::int32_t;
108 using polys_offset_int_t = polys_connectivity_int_t;
109 file << "<VTKFile"
110 << " type=\"PolyData\""
111 << " version=\"1.0\" "
112 "byte_order=\"LittleEndian\""
113 << " header_type=\""
115 vtk::xml::to_data_type<header_type>())
116 << "\">";
117 file << "<PolyData>\n";
118 for (auto const& g : grids) {
119 using real_type = typename std::decay_t<decltype(g)>::real_type;
120 file << "<Piece"
121 << " NumberOfPoints=\"" << g.vertices().size() << "\""
122 << " NumberOfPolys=\"" << g.simplices().size() << "\""
123 << " NumberOfVerts=\"0\""
124 << " NumberOfLines=\"0\""
125 << " NumberOfStrips=\"0\""
126 << ">\n";
127
128 // Points
129 file << "<Points>";
130 file << "<DataArray"
131 << " format=\"appended\""
132 << " offset=\"" << offset << "\""
133 << " type=\""
135 vtk::xml::to_data_type<real_type>())
136 << "\" NumberOfComponents=\"" << g.num_dimensions() << "\"/>";
137 auto const num_bytes_points =
138 header_type(sizeof(real_type) * g.num_dimensions() *
139 g.vertices().data_container().size());
140 offset += num_bytes_points + sizeof(header_type);
141 file << "</Points>\n";
142
143 // Polys
144 file << "<Polys>\n";
145 // Polys - connectivity
146 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
148 vtk::xml::to_data_type<polys_connectivity_int_t>())
149 << "\" Name=\"connectivity\"/>\n";
150 auto const num_bytes_polys_connectivity = g.simplices().size() *
151 g.num_vertices_per_simplex() *
152 sizeof(polys_connectivity_int_t);
153 offset += num_bytes_polys_connectivity + sizeof(header_type);
154
155 // Polys - offsets
156 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
157 << vtk::xml::to_data_type<polys_offset_int_t>()
158 << "\" Name=\"offsets\"/>\n";
159 auto const num_bytes_polys_offsets =
160 sizeof(polys_offset_int_t) * g.simplices().size();
161 offset += num_bytes_polys_offsets + sizeof(header_type);
162 file << "</Polys>\n";
163 file << "</Piece>\n\n";
164 }
165 file << "</PolyData>\n";
166
167 file << "<AppendedData encoding=\"raw\">_";
168 // Writing vertex data to appended data section
169 auto arr_size = header_type{};
170
171 for (auto const& g : grids) {
172 using real_type = typename std::decay_t<decltype(g)>::real_type;
173 arr_size = header_type(sizeof(real_type) * g.num_dimensions() *
174 g.vertices().data_container().size());
175 file.write(reinterpret_cast<char const*>(&arr_size), sizeof(header_type));
176 file.write(reinterpret_cast<char const*>(g.vertices().data()), arr_size);
177
178 // Writing polys connectivity data to appended data section
179 {
180 auto connectivity_data = std::vector<polys_connectivity_int_t>(
181 g.simplices().size() * g.num_vertices_per_simplex());
182 std::ranges::copy(g.simplices().data_container() |
183 std::views::transform(
184 [](auto const x) -> polys_connectivity_int_t {
185 return x.index();
186 }),
187 begin(connectivity_data));
188 arr_size = g.simplices().size() * g.num_vertices_per_simplex() *
189 sizeof(polys_connectivity_int_t);
190 file.write(reinterpret_cast<char const*>(&arr_size), sizeof(header_type));
191 file.write(reinterpret_cast<char const*>(connectivity_data.data()),
192 static_cast<std::streamsize>(arr_size));
193 }
194
195 // Writing polys offsets to appended data section
196 {
197 auto offsets = std::vector<polys_offset_int_t>(
198 g.simplices().size(), g.num_vertices_per_simplex());
199 for (std::size_t i = 1; i < size(offsets); ++i) {
200 offsets[i] += offsets[i - 1];
201 }
202 arr_size = sizeof(polys_offset_int_t) * g.simplices().size();
203 file.write(reinterpret_cast<char const*>(&arr_size), sizeof(header_type));
204 file.write(reinterpret_cast<char const*>(offsets.data()),
205 static_cast<std::streamsize>(arr_size));
206 }
208 file << "</AppendedData>";
209 file << "</VTKFile>";
210}
211} // namespace detail
212//==============================================================================
214 range auto const& grids, std::filesystem::path const& path,
215 std::string const& title =
216 "tatooine grids") requires is_unstructured_triangular_grid<typename std::
217 decay_t<decltype(
218 grids)>::
219 value_type> {
221 title);
222}
223//------------------------------------------------------------------------------
225 range auto const& grids,
226 std::filesystem::path const&
227 path) requires is_unstructured_triangular_grid<typename std::
228 decay_t<decltype(
229 grids)>::
230 value_type> {
232}
233//------------------------------------------------------------------------------
234auto write(
235 range auto const& grids,
236 std::filesystem::path const&
237 path) requires is_unstructured_triangular_grid<typename std::
238 decay_t<decltype(
239 grids)>::
240 value_type> {
241 auto const ext = path.extension();
242 if (ext == ".vtp") {
244 } else if (ext == ".vtk") {
246 }
247}
248//==============================================================================
249} // namespace tatooine
250//==============================================================================
251#endif
Definition: vtk_legacy.h:448
auto set_title(std::string const &title) -> void
Definition: vtk_legacy.h:632
auto write_points(std::vector< std::array< Real, 2 > > const &points) -> void
Definition: vtk_legacy.h:637
auto write_polygons(std::vector< std::vector< std::size_t > > const &polygons) -> void
Definition: concepts.h:84
Definition: vtp_writer.h:3
auto write_unstructured_triangular_grid_container_to_vtk(MeshCont const &grids, std::filesystem::path const &path, std::string const &title="tatooine grids")
Definition: unstructured_triangular_grid.h:57
auto write_unstructured_triangular_grid_container_to_vtp(range auto const &grids, std::filesystem::path const &path)
Definition: unstructured_triangular_grid.h:99
auto to_string(data_type const t) -> std::string_view
Definition: algorithm.h:6
auto write_vtk(Lines const &lines, filesystem::path const &path, std::string const &title="tatooine lines") -> void
Definition: write.h:163
auto begin(Range &&range)
Definition: iterator_facade.h:318
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto write(Lines const &lines, filesystem::path const &path) -> void
Definition: write.h:218
auto write_vtp(Lines const &lines, filesystem::path const &path) -> void
Definition: write.h:38
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
static constexpr auto is_unstructured_triangular_grid
Definition: unstructured_triangular_grid.h:51
Definition: unstructured_triangular_grid.h:46
Definition: unstructured_simplicial_grid.h:87
Definition: unstructured_simplicial_grid.h:52
auto simplices() const
Definition: unstructured_simplicial_grid.h:515
auto simplex_at(simplex_handle t) const -> auto
Definition: unstructured_simplicial_grid.h:303
auto insert_simplex(Handles const ... handles)
Definition: unstructured_simplicial_grid.h:427
Definition: unstructured_triangular_grid.h:10
auto triangles()
Definition: unstructured_triangular_grid.h:26
auto triangle_at(triangle_handle const h)
Definition: unstructured_triangular_grid.h:22
auto insert_triangle(Handles const ... handles)
Definition: unstructured_triangular_grid.h:18
typename parent_type::simplex_handle triangle_handle
Definition: unstructured_triangular_grid.h:15
constexpr unstructured_triangular_grid()=default
auto triangle_at(triangle_handle const h) const
Definition: unstructured_triangular_grid.h:23
auto triangles() const
Definition: unstructured_triangular_grid.h:27