5template <
typename MeshCont>
7 std::filesystem::path
const& path,
8 std::string
const& title =
"tatooine edgeset") {
9 vtk::legacy_file_writer writer(path, vtk::dataset_type::polydata);
10 if (!writer.is_open()) {
13 auto num_pts = std::size_t{};
14 auto cur_first = std::size_t{};
15 for (
auto const& m : edgesets) {
16 num_pts += m.vertices().size();
19 std::vector<std::array<typename MeshCont::value_type::real_type, 3>>{};
20 auto edges = std::vector<std::vector<std::size_t>>{};
21 points.reserve(num_pts);
22 edges.reserve(edgesets.size());
24 for (
auto const& m : edgesets) {
26 for (
auto const& v : m.vertices()) {
27 points.push_back(std::array{m[v](0), m[v](1), m[v](2)});
31 for (
auto s : m.simplices()) {
34 edges.back().push_back(cur_first + v0.index());
35 edges.back().push_back(cur_first + v1.index());
37 cur_first += m.vertices().size();
41 writer.set_title(title);
42 writer.write_header();
43 writer.write_points(points);
44 writer.write_polygons(edges);
48template <
typename Real, std::
size_t NumDimensions>
50 std::filesystem::path
const& path) {
51 auto file = std::ofstream{path, std::ios::binary};
52 if (!file.is_open()) {
53 throw std::runtime_error{
"Could not write " + path.string()};
55 auto offset = std::size_t{};
56 using header_type = std::uint64_t;
57 using lines_connectivity_int_t = std::int32_t;
58 using lines_offset_int_t = lines_connectivity_int_t;
60 <<
" type=\"PolyData\""
61 <<
" version=\"1.0\" "
62 "byte_order=\"LittleEndian\""
64 << vtk::xml::data_array::to_string(
65 vtk::xml::data_array::to_type<header_type>())
67 file <<
"<PolyData>\n";
70 <<
" NumberOfPoints=\"" << es.vertices().size() <<
"\""
71 <<
" NumberOfPolys=\"0\""
72 <<
" NumberOfVerts=\"0\""
73 <<
" NumberOfLines=\"" << es.simplices().size() <<
"\""
74 <<
" NumberOfStrips=\"0\""
80 <<
" format=\"appended\""
81 <<
" offset=\"" << offset <<
"\""
83 << vtk::xml::data_array::to_string(
84 vtk::xml::data_array::to_type<real_type>())
85 <<
"\" NumberOfComponents=\"3\"/>";
86 auto const num_bytes_points =
87 header_type(
sizeof(
real_type) * es.num_dimensions() *
88 es.vertices().data_container().size());
89 offset += num_bytes_points +
sizeof(header_type);
90 file <<
"</Points>\n";
95 file <<
"<DataArray format=\"appended\" offset=\"" << offset <<
"\" type=\""
96 << vtk::xml::data_array::to_string(
97 vtk::xml::data_array::to_type<lines_connectivity_int_t>())
98 <<
"\" Name=\"connectivity\"/>\n";
99 auto const num_bytes_lines_connectivity = es.simplices().size() *
100 es.num_vertices_per_simplex() *
101 sizeof(lines_connectivity_int_t);
102 offset += num_bytes_lines_connectivity +
sizeof(header_type);
105 file <<
"<DataArray format=\"appended\" offset=\"" << offset <<
"\" type=\""
106 << vtk::xml::data_array::to_string(
107 vtk::xml::data_array::to_type<lines_offset_int_t>())
108 <<
"\" Name=\"offsets\"/>\n";
109 auto const num_bytes_lines_offsets =
110 sizeof(lines_offset_int_t) * es.simplices().size();
111 offset += num_bytes_lines_offsets +
sizeof(header_type);
112 file <<
"</Lines>\n";
113 file <<
"</Piece>\n\n";
114 file <<
"</PolyData>\n";
116 file <<
"<AppendedData encoding=\"raw\">_";
117 using namespace std::ranges;
119 auto const num_bytes =
120 header_type(
sizeof(
real_type) * 3 * es.vertices().size());
121 file.write(
reinterpret_cast<char const*
>(&num_bytes),
sizeof(header_type));
122 if constexpr (NumDimensions == 2) {
123 auto point_data = std::vector<vec<real_type, 3>>{};
124 point_data.reserve(es.vertices().size());
125 auto position = [
this](
auto const v) ->
auto& {
return at(v); };
126 constexpr auto to_3d = [](
auto const& p) {
129 for (
auto const v : es.vertices()) {
130 point_data.push_back(to_3d(es[v]));
133 file.write(
reinterpret_cast<char const*
>(point_data.data()), num_bytes);
134 }
else if constexpr (NumDimensions == 3) {
135 file.write(
reinterpret_cast<char const*
>(es.vertices().data()), num_bytes);
139 auto connectivity_data = std::vector<lines_connectivity_int_t>(
140 es.simplices().size() * es.num_vertices_per_simplex());
142 es.simplices().data_container() |
143 std::views::transform([](
auto const x) -> lines_connectivity_int_t {
146 begin(connectivity_data));
147 arr_size = es.simplices().size() * es.num_vertices_per_simplex() *
148 sizeof(lines_connectivity_int_t);
149 file.write(
reinterpret_cast<char const*
>(&arr_size),
sizeof(header_type));
150 file.write(
reinterpret_cast<char const*
>(connectivity_data.data()),
156 auto offsets = std::vector<lines_offset_int_t>(
157 es.simplices().size(), es.num_vertices_per_simplex());
158 for (std::size_t i = 1; i < size(offsets); ++i) {
159 offsets[i] += offsets[i - 1];
161 arr_size =
sizeof(lines_offset_int_t) * es.simplices().size();
162 file.write(
reinterpret_cast<char const*
>(&arr_size),
sizeof(header_type));
163 file.write(
reinterpret_cast<char const*
>(offsets.data()), arr_size);
165 file <<
"</AppendedData>";
166 file <<
"</VTKFile>";
170 std::filesystem::path
const& path) {
171 auto file = std::ofstream{path, std::ios::binary};
172 if (!file.is_open()) {
173 throw std::runtime_error{
"Could not write " + path.string()};
175 auto offset = std::size_t{};
176 using header_type = std::uint64_t;
177 using lines_connectivity_int_t = std::int32_t;
178 using lines_offset_int_t = lines_connectivity_int_t;
180 <<
" type=\"PolyData\""
181 <<
" version=\"1.0\" "
182 "byte_order=\"LittleEndian\""
184 << vtk::xml::data_array::to_string(
185 vtk::xml::data_array::to_type<header_type>())
187 file <<
"<PolyData>\n";
188 for (
auto const& g : edgesets) {
191 <<
" NumberOfPoints=\"" << g.vertices().size() <<
"\""
192 <<
" NumberOfPolys=\"0\""
193 <<
" NumberOfVerts=\"0\""
194 <<
" NumberOfLines=\"" << es.simplices().size() <<
"\""
195 <<
" NumberOfStrips=\"0\""
201 <<
" format=\"appended\""
202 <<
" offset=\"" << offset <<
"\""
204 << vtk::xml::data_array::to_string(
205 vtk::xml::data_array::to_type<real_type>())
206 <<
"\" NumberOfComponents=\"" << g.num_dimensions() <<
"\"/>";
207 auto const num_bytes_points =
208 header_type(
sizeof(
real_type) * g.num_dimensions() *
209 g.vertices().data_container().size());
210 offset += num_bytes_points +
sizeof(header_type);
211 file <<
"</Points>\n";
216 file <<
"<DataArray format=\"appended\" offset=\"" << offset <<
"\" type=\""
217 << vtk::xml::data_array::to_string(
218 vtk::xml::data_array::to_type<lines_connectivity_int_t>())
219 <<
"\" Name=\"connectivity\"/>\n";
220 auto const num_bytes_lines_connectivity = g.simplices().size() *
221 g.num_vertices_per_simplex() *
222 sizeof(lines_connectivity_int_t);
223 offset += num_bytes_lines_connectivity +
sizeof(header_type);
226 file <<
"<DataArray format=\"appended\" offset=\"" << offset <<
"\" type=\""
227 << vtk::xml::data_array::to_string(
228 vtk::xml::data_array::to_type<lines_offset_int_t>())
229 <<
"\" Name=\"offsets\"/>\n";
230 auto const num_bytes_lines_offsets =
231 sizeof(lines_offset_int_t) * g.simplices().size();
232 offset += num_bytes_lines_offsets +
sizeof(header_type);
233 file <<
"</Lines>\n";
234 file <<
"</Piece>\n\n";
236 file <<
"</PolyData>\n";
238 file <<
"<AppendedData encoding=\"raw\">_";
240 auto arr_size = header_type{};
242 for (
auto const& g : edgesets) {
244 arr_size = header_type(
sizeof(
real_type) * g.num_dimensions() *
245 g.vertices().data_container().size());
246 file.write(
reinterpret_cast<char const*
>(&arr_size),
sizeof(header_type));
247 file.write(
reinterpret_cast<char const*
>(g.vertices().data()), arr_size);
251 auto connectivity_data = std::vector<lines_connectivity_int_t>(
252 g.simplices().size() * g.num_vertices_per_simplex());
253 std::ranges::copy(g.simplices().data_container() |
254 std::views::transform(
255 [](
auto const x) -> lines_connectivity_int_t {
258 begin(connectivity_data));
259 arr_size = g.simplices().size() * g.num_vertices_per_simplex() *
260 sizeof(lines_connectivity_int_t);
261 file.write(
reinterpret_cast<char const*
>(&arr_size),
sizeof(header_type));
262 file.write(
reinterpret_cast<char const*
>(connectivity_data.data()),
268 auto offsets = std::vector<lines_offset_int_t>(
269 g.simplices().size(), g.num_vertices_per_simplex());
270 for (std::size_t i = 1; i < size(offsets); ++i) {
271 offsets[i] += offsets[i - 1];
273 arr_size =
sizeof(lines_offset_int_t) * g.simplices().size();
274 file.write(
reinterpret_cast<char const*
>(&arr_size),
sizeof(header_type));
275 file.write(
reinterpret_cast<char const*
>(offsets.data()), arr_size);
278 file <<
"</AppendedData>";
279 file <<
"</VTKFile>";
Definition: vtp_writer.h:3
auto write_container_to_vtp(range auto const &edgesets, std::filesystem::path const &path)
Definition: vtp_writer.h:169
auto write_to_vtp(edgeset< Real, NumDimensions > const &es, std::filesystem::path const &path)
Definition: vtp_writer.h:49
auto write_container_to_vtk(MeshCont const &edgesets, std::filesystem::path const &path, std::string const &title="tatooine edgeset")
Definition: vtp_writer.h:6