Wildmeshing Toolkit
ParaviewWriter.cpp
Go to the documentation of this file.
1 #include "ParaviewWriter.hpp"
2 
3 
4 #include <wmtk/Mesh.hpp>
5 #include <wmtk/utils/Logger.hpp>
7 
8 #include <paraviewo/VTMWriter.hpp>
9 #include <paraviewo/VTUWriter.hpp>
10 
11 // #include <paraviewo/HDF5VTUWriter.hpp>
12 
13 #include <sstream>
14 
15 namespace wmtk::io {
16 
18 {
19  m_paraview_file = std::make_shared<paraviewo::VTUWriter>();
20  // m_paraview_file = std::make_shared<paraviewo::HDF5VTUWriter>();
21 }
22 
24  const std::filesystem::path& filename,
25  const std::string& vertices_name,
26  const Eigen::MatrixXi& elements,
27  const bool enabled)
28 {
29  m_vertices_name = vertices_name;
30  m_elements = elements;
31 
32  m_filename = filename;
33  m_enabled = enabled;
34 }
35 
37 {
38  if (m_enabled) m_paraview_file->write_mesh(m_filename.string(), m_vertices, m_elements);
39 }
40 
41 
43  const std::string& name,
44  const int64_t stride,
45  const std::vector<double>& val,
46  const bool is_cell_field)
47 {
48  Eigen::MatrixXd tmp =
49  Eigen::Map<const Eigen::MatrixXd>(&val[0], stride, val.size() / stride).transpose();
50 
51  if (stride == 1 || stride == 2 || stride == 3) {
52  if (is_cell_field) {
53  m_paraview_file->add_cell_field(name, tmp);
54  } else {
55  m_paraview_file->add_field(name, tmp);
56  }
57  } else if (stride % 3 == 0) {
58  for (int64_t i = 0; i < stride; i += 3) {
59  if (is_cell_field) {
60  m_paraview_file->add_cell_field(
61  name + "_" + std::to_string(i / 3),
62  tmp.block(0, i, tmp.rows(), 3));
63  } else {
64  m_paraview_file->add_field(
65  name + "_" + std::to_string(i / 3),
66  tmp.block(0, i, tmp.rows(), 3));
67  }
68  }
69  } else if (stride % 2 == 0) {
70  for (int64_t i = 0; i < stride; i += 2) {
71  if (is_cell_field) {
72  m_paraview_file->add_cell_field(
73  name + "_" + std::to_string(i / 2),
74  tmp.block(0, i, tmp.rows(), 2));
75  } else {
76  m_paraview_file->add_field(
77  name + "_" + std::to_string(i / 2),
78  tmp.block(0, i, tmp.rows(), 2));
79  }
80  }
81  } else {
82  for (int64_t i = 0; i < stride; ++i) {
83  if (is_cell_field) {
84  m_paraview_file->add_cell_field(name + "_" + std::to_string(i), tmp.col(i));
85  } else {
86  m_paraview_file->add_field(name + "_" + std::to_string(i), tmp.col(i));
87  }
88  }
89  }
90 }
91 
93  const std::filesystem::path& filename,
94  const std::string& vertices_name,
95  const Mesh& mesh,
96  bool write_points,
97  bool write_edges,
98  bool write_faces,
99  bool write_tetrahedra)
100  : m_vertices_name(vertices_name)
101 {
102  m_enabled[0] = write_points;
103  m_enabled[1] = write_edges;
104  m_enabled[2] = write_faces;
105  m_enabled[3] = write_tetrahedra;
106 
107  std::array<Eigen::MatrixXi, 4> cells;
108 
109  for (size_t i = 0; i < 4; ++i) {
110  const auto pt = PrimitiveType(i);
111  if (m_enabled[i]) {
112  // include deleted tuples so that attributes are aligned
113  const auto tuples = mesh.get_all(pt, true);
114  cells[i].resize(tuples.size(), i + 1);
115 
116  for (size_t j = 0; j < tuples.size(); ++j) {
117  const auto& t = tuples[j];
118  if (t.is_null()) {
119  for (size_t d = 0; d < cells[i].cols(); ++d) {
120  cells[i](j, d) = 0;
121  }
122  } else {
123  int64_t vid = mesh.id(t, PrimitiveType::Vertex);
124  cells[i](j, 0) = vid;
125  if (i > 0) {
126  auto t1 = mesh.switch_tuple(t, PrimitiveType::Vertex);
127 
128  cells[i](j, 1) = mesh.id(t1, PrimitiveType::Vertex);
129  }
130  if (i > 1) {
131  auto t1 = mesh.switch_tuple(t, PrimitiveType::Edge);
132  auto t2 = mesh.switch_tuple(t1, PrimitiveType::Vertex);
133 
134  cells[i](j, 2) = mesh.id(t2, PrimitiveType::Vertex);
135  }
136  if (i > 2) {
137  auto t1 = mesh.switch_tuple(t, PrimitiveType::Triangle);
138  auto t2 = mesh.switch_tuple(t1, PrimitiveType::Edge);
139  auto t3 = mesh.switch_tuple(t2, PrimitiveType::Vertex);
140 
141  cells[i](j, 3) = mesh.id(t3, PrimitiveType::Vertex);
142  }
143  }
144  }
145  }
146  }
147 
148  m_writers[0].init(filename.string() + "_verts.vtu", vertices_name, cells[0], m_enabled[0]);
149  m_writers[1].init(filename.string() + "_edges.vtu", vertices_name, cells[1], m_enabled[1]);
150  m_writers[2].init(filename.string() + "_faces.vtu", vertices_name, cells[2], m_enabled[2]);
151  m_writers[3].init(filename.string() + "_tets.vtu", vertices_name, cells[3], m_enabled[3]);
152 
153  if (m_enabled[0] + m_enabled[1] + m_enabled[2] + m_enabled[3] > 1) {
154  paraviewo::VTMWriter vtm;
155  if (m_enabled[0]) vtm.add_dataset("verts", "mesh", filename.string() + "_verts.vtu");
156  if (m_enabled[1]) vtm.add_dataset("edges", "mesh", filename.string() + "_edges.vtu");
157  if (m_enabled[2]) vtm.add_dataset("faces", "mesh", filename.string() + "_faces.vtu");
158  if (m_enabled[3]) vtm.add_dataset("tets", "mesh", filename.string() + "_tets.vtu");
159 
160  vtm.save(filename.string() + ".vtm");
161  }
162 }
163 
165  const std::string& name,
166  const int64_t type,
167  const int64_t stride,
168  const std::vector<int64_t>& val,
169  const int64_t default_val)
170 {
171  std::vector<double> tmp;
172  tmp.reserve(val.size());
173  for (const auto& v : val) tmp.push_back(v);
174 
175  write_internal(name, type, stride, tmp);
176 }
177 
179  const std::string& name,
180  const int64_t type,
181  const int64_t stride,
182  const std::vector<double>& val,
183  const double default_val)
184 {
185  write_internal(name, type, stride, val);
186 }
187 
189  const std::string& name,
190  const int64_t type,
191  const int64_t stride,
192  const std::vector<char>& val,
193  const char default_val)
194 {
195  std::vector<double> tmp;
196  tmp.reserve(val.size());
197  for (const auto& v : val) tmp.push_back(v);
198 
199  write_internal(name, type, stride, tmp);
200 }
201 
202 
204  const std::string& name,
205  const int64_t type,
206  const int64_t stride,
207  const std::vector<Rational>& val,
208  const Rational& default_val)
209 {
210  std::vector<double> tmp;
211  tmp.reserve(val.size());
212  for (const auto& v : val) tmp.push_back(double(v));
213 
214  write_internal(name, type, stride, tmp);
215 }
216 
218  const std::string& name,
219  const int64_t type,
220  const int64_t stride,
221  const std::vector<double>& val)
222 {
223  if (!m_write) return;
224 
225  if (name == m_vertices_name) {
226  assert(stride == 2 || stride == 3);
227 
228  Eigen::MatrixXd V =
229  Eigen::Map<const Eigen::MatrixXd>(&val[0], stride, val.size() / stride).transpose();
230 
231  for (int i = 0; i < m_writers.size(); ++i) {
232  if (m_enabled[i]) m_writers[i].vertices() = V;
233  }
234  } else if (type == 0) { // vertex attrs are always written
235  for (size_t i = 0; i < m_writers.size(); ++i) {
236  if (m_enabled[i]) m_writers[i].write(name, stride, val, false);
237  }
238  } else if (m_enabled[type]) {
239  m_writers[type].write(name, stride, val, true);
240  }
241 }
242 
243 
244 } // namespace wmtk::io
int64_t id(const Tuple &tuple, PrimitiveType type) const
return the global id of the Tuple of the given dimension
Definition: Mesh.hpp:1021
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition: Mesh.cpp:18
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
std::shared_ptr< paraviewo::ParaviewWriter > m_paraview_file
void write(const std::string &name, const int64_t stride, const std::vector< double > &val, const bool is_cell_field)
void init(const std::filesystem::path &filename, const std::string &vertices_name, const Eigen::MatrixXi &elements, const bool enabled)
ParaviewWriter(const std::filesystem::path &filename, const std::string &vertices_name, const Mesh &mesh, bool write_points=true, bool write_edges=true, bool write_faces=true, bool write_tetrahedra=true)
std::array< ParaviewInternalWriter, 4 > m_writers
bool write(const int dim) override
std::array< bool, 4 > m_enabled
void write_internal(const std::string &name, const int64_t type, const int64_t stride, const std::vector< double > &val)