Wildmeshing Toolkit
Loading...
Searching...
No Matches
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
18
20
21Eigen::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 }
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
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:93
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
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