1#ifndef TATOOINE_UNSTRUCTURED_TRIANGULAR_GRID_H
2#define TATOOINE_UNSTRUCTURED_TRIANGULAR_GRID_H
8template <
typename Real, std::
size_t NumDimensions>
17 template <
typename... Handles>
19 is_same<Handles, vertex_handle>&&...) {
29template <std::
size_t NumDimensions>
32template <
typename Real>
34template <
typename Real>
36template <
typename Real>
38template <
typename Real>
47template <
typename Real, std::
size_t NumDimensions>
56template <
typename MeshCont>
58 MeshCont
const& grids, std::filesystem::path
const& path,
59 std::string
const& title =
"tatooine grids") {
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();
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());
72 for (
auto const& m : grids) {
74 for (
auto const& v : m.vertices()) {
75 points.push_back(std::array{m[v](0), m[v](1), m[v](2)});
79 for (
auto c : m.simplices()) {
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());
86 cur_first += m.vertices().size();
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()};
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;
110 <<
" type=\"PolyData\""
111 <<
" version=\"1.0\" "
112 "byte_order=\"LittleEndian\""
115 vtk::xml::to_data_type<header_type>())
117 file <<
"<PolyData>\n";
118 for (
auto const& g : grids) {
121 <<
" NumberOfPoints=\"" << g.vertices().size() <<
"\""
122 <<
" NumberOfPolys=\"" << g.simplices().size() <<
"\""
123 <<
" NumberOfVerts=\"0\""
124 <<
" NumberOfLines=\"0\""
125 <<
" NumberOfStrips=\"0\""
131 <<
" format=\"appended\""
132 <<
" offset=\"" << offset <<
"\""
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";
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);
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";
165 file <<
"</PolyData>\n";
167 file <<
"<AppendedData encoding=\"raw\">_";
169 auto arr_size = header_type{};
171 for (
auto const& g : grids) {
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);
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 {
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));
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];
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));
208 file <<
"</AppendedData>";
209 file <<
"</VTKFile>";
214 range auto const& grids, std::filesystem::path
const& path,
215 std::string
const& title =
225 range auto const& grids,
226 std::filesystem::path
const&
235 range auto const& grids,
236 std::filesystem::path
const&
241 auto const ext = path.extension();
244 }
else if (ext ==
".vtk") {
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
auto write_header() -> 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: vertex_handle.h:10
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