Wildmeshing Toolkit
winding_number.cpp
Go to the documentation of this file.
1 #include "winding_number.hpp"
2 
3 #include <wmtk/EdgeMesh.hpp>
4 #include <wmtk/TetMesh.hpp>
6 
7 #include <igl/bfs_orient.h>
8 #if defined(__GNUG__) && !defined(__clang__)
9 #pragma GCC diagnostic push
10 #pragma GCC diagnostic ignored "-Warray-bounds"
11 #endif
12 #include <igl/fast_winding_number.h>
13 #include <igl/winding_number.h>
14 #if defined(__GNUG__) && !defined(__clang__)
15 #pragma GCC diagnostic pop
16 #endif
17 #include <wmtk/utils/Rational.hpp>
18 
20 
21 Eigen::VectorXd winding_number(const Mesh& m, const TriMesh& surface)
22 {
23  wmtk::utils::EigenMatrixWriter m_writer, surface_writer;
24  m.serialize(m_writer);
25  surface.serialize(surface_writer);
26 
27  Eigen::MatrixX<Rational> m_pos_rational, surface_pos_rational;
28  Eigen::MatrixXd m_pos, surface_pos;
29  MatrixX<int64_t> m_FV, surface_FV;
30 
31  m_writer.get_position_matrix(m_pos_rational);
32  assert(m_pos_rational.cols() == 3);
33  m_pos.resize(m_pos_rational.rows(), m_pos_rational.cols());
34 
35  m_pos = m_pos_rational.cast<double>();
36  surface_writer.get_position_matrix(surface_pos_rational);
37  surface_pos.resize(surface_pos_rational.rows(), surface_pos_rational.cols());
38  surface_pos = surface_pos_rational.cast<double>();
39 
40  switch (m.top_simplex_type()) {
42  m_writer.get_TV_matrix(m_FV);
43  break;
44  }
45  case (PrimitiveType::Triangle): {
46  m_writer.get_FV_matrix(m_FV);
47  break;
48  }
49  case (PrimitiveType::Edge): {
50  m_writer.get_EV_matrix(m_FV);
51  break;
52  }
53  default: throw std::runtime_error("Unsupported Mesh Type");
54  }
55 
56  surface_writer.get_FV_matrix(surface_FV);
57 
58  Eigen::MatrixXd centroids;
59  centroids.resize(m_FV.rows(), 3);
60 
61  for (int64_t i = 0; i < m_FV.rows(); ++i) {
62  Eigen::Vector3d centroid(0, 0, 0);
63  for (int64_t j = 0; j < m_FV.cols(); ++j) {
64  Vector3d v_pos = m_pos.row(m_FV(i, j));
65  centroid = centroid + v_pos;
66  }
67  centroids.row(i) = centroid / m_FV.cols();
68  }
69 
70  // correct the orientation of the surface mesh
72  igl::bfs_orient(surface_FV, surface_FV, _C);
73 
74  Eigen::VectorXd winding_numbers = winding_number_internal(centroids, surface_pos, surface_FV);
75  return winding_numbers;
76 }
77 
78 Eigen::VectorXd winding_number_internal(
79  const Eigen::MatrixXd& query_points,
80  const Eigen::MatrixXd& surface_V,
81  const MatrixX<int64_t>& surface_F)
82 {
83  Eigen::VectorXd winding_numbers;
84  igl::fast_winding_number(surface_V, surface_F, query_points, winding_numbers);
85  return winding_numbers;
86 }
87 
88 
89 } // namespace wmtk::components::internal
void serialize(MeshWriter &writer, const Mesh *local_root=nullptr) const
Definition: Mesh.cpp:92
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
void get_position_matrix(MatrixX< double > &matrix)
void get_EV_matrix(MatrixX< int64_t > &matrix)
void get_TV_matrix(MatrixX< int64_t > &matrix)
void get_FV_matrix(MatrixX< int64_t > &matrix)
Eigen::VectorXd winding_number(const Mesh &m, const TriMesh &surface)
Eigen::VectorXd winding_number_internal(const Eigen::MatrixXd &query_points, const Eigen::MatrixXd &surface_V, const MatrixX< int64_t > &surface_F)
Vector< double, 3 > Vector3d
Definition: Types.hpp:39
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: Types.hpp:14