piecewise_constant_winding_number.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "piecewise_constant_winding_number.h"
  9. #include "unique_edge_map.h"
  10. template <
  11. typename DerivedF,
  12. typename DeriveduE,
  13. typename uE2EType>
  14. IGL_INLINE bool igl::piecewise_constant_winding_number(
  15. const Eigen::PlainObjectBase<DerivedF>& F,
  16. const Eigen::PlainObjectBase<DeriveduE>& uE,
  17. const std::vector<std::vector<uE2EType> >& uE2E)
  18. {
  19. const size_t num_faces = F.rows();
  20. const size_t num_edges = uE.rows();
  21. const auto edge_index_to_face_index = [&](size_t ei)
  22. {
  23. return ei % num_faces;
  24. };
  25. const auto is_consistent = [&](size_t fid, size_t s, size_t d)
  26. {
  27. if ((size_t)F(fid, 0) == s && (size_t)F(fid, 1) == d) return true;
  28. if ((size_t)F(fid, 1) == s && (size_t)F(fid, 2) == d) return true;
  29. if ((size_t)F(fid, 2) == s && (size_t)F(fid, 0) == d) return true;
  30. if ((size_t)F(fid, 0) == d && (size_t)F(fid, 1) == s) return false;
  31. if ((size_t)F(fid, 1) == d && (size_t)F(fid, 2) == s) return false;
  32. if ((size_t)F(fid, 2) == d && (size_t)F(fid, 0) == s) return false;
  33. throw "Invalid face!!";
  34. };
  35. for (size_t i=0; i<num_edges; i++)
  36. {
  37. const size_t s = uE(i,0);
  38. const size_t d = uE(i,1);
  39. int count=0;
  40. for (const auto& ei : uE2E[i])
  41. {
  42. const size_t fid = edge_index_to_face_index(ei);
  43. if (is_consistent(fid, s, d))
  44. {
  45. count++;
  46. }
  47. else
  48. {
  49. count--;
  50. }
  51. }
  52. if (count != 0)
  53. {
  54. return false;
  55. }
  56. }
  57. return true;
  58. }
  59. template <typename DerivedF>
  60. IGL_INLINE bool igl::piecewise_constant_winding_number(
  61. const Eigen::PlainObjectBase<DerivedF>& F)
  62. {
  63. Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> E, uE;
  64. Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> EMAP;
  65. std::vector<std::vector<size_t> > uE2E;
  66. unique_edge_map(F, E, uE, EMAP, uE2E);
  67. return piecewise_constant_winding_number(F,uE,uE2E);
  68. }