outer_facet.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "outer_facet.h"
  2. #include "sort.h"
  3. #include "vertex_triangle_adjacency.h"
  4. #include <iostream>
  5. #define IGL_OUTER_FACET_DEBUG
  6. template <
  7. typename DerivedV,
  8. typename DerivedF,
  9. typename DerivedN,
  10. typename DerivedI,
  11. typename f_type>
  12. IGL_INLINE void igl::outer_facet(
  13. const Eigen::PlainObjectBase<DerivedV> & V,
  14. const Eigen::PlainObjectBase<DerivedF> & F,
  15. const Eigen::PlainObjectBase<DerivedN> & N,
  16. const Eigen::PlainObjectBase<DerivedI> & I,
  17. f_type & max_f,
  18. bool & flip)
  19. {
  20. using namespace std;
  21. typedef typename DerivedV::Scalar Scalar;
  22. typedef typename DerivedV::Index Index;
  23. typedef
  24. typename Eigen::Matrix<Index, DerivedV::RowsAtCompileTime,1> VectorXI;
  25. typedef
  26. typename Eigen::Matrix<Scalar, DerivedV::RowsAtCompileTime,1> VectorXS;
  27. // "Direct repair of self-intersecting meshes" [Attene 14]
  28. const Index mi = I.size();
  29. assert(V.cols() == 3);
  30. assert(N.cols() == 3);
  31. Index max_v = -1;
  32. auto generic_fabs = [&](Scalar val) {
  33. if (val >= 0) return val;
  34. else return -val;
  35. };
  36. for(size_t d = 0;d<(size_t)V.cols();d++)
  37. {
  38. Scalar max_d = -1e26;
  39. Scalar max_nd = -1e26;
  40. for(Index i = 0;i<mi;i++)
  41. {
  42. const Index f = I(i);
  43. const Scalar nd = N(f,d);
  44. if(generic_fabs(nd)>0)
  45. {
  46. for(Index c = 0;c<3;c++)
  47. {
  48. const Index v = F(f,c);
  49. if(v == max_v)
  50. {
  51. if(generic_fabs(nd) > max_nd)
  52. {
  53. // Just update max face and normal
  54. max_f = f;
  55. max_nd = generic_fabs(nd);
  56. flip = nd<0;
  57. } else if (generic_fabs(nd) == max_nd) {
  58. if (nd == max_nd) {
  59. if (flip) {
  60. max_f = f;
  61. max_nd = nd;
  62. flip = false;
  63. } else if (f > max_f){
  64. max_f = f;
  65. max_nd = nd;
  66. flip = false;
  67. }
  68. } else {
  69. if (flip && f < max_f) {
  70. max_f = f;
  71. max_nd = generic_fabs(nd);
  72. flip = true;
  73. }
  74. }
  75. }
  76. }else
  77. {
  78. const Scalar vd = V(v,d);
  79. if(vd>max_d)
  80. {
  81. // update max vertex, face and normal
  82. max_v = v;
  83. max_d = vd;
  84. max_f = f;
  85. max_nd = generic_fabs(nd);
  86. flip = nd<0;
  87. }
  88. }
  89. }
  90. }
  91. }
  92. if(max_v >= 0)
  93. {
  94. break;
  95. }
  96. // if we get here and max_v is still -1 then there were no faces with
  97. // |N(d)| > 0
  98. }
  99. #ifdef IGL_OUTER_FACET_DEBUG
  100. if(max_v <0)
  101. {
  102. cerr<<"Very degenerate case, no suitable face found."<<endl;
  103. }
  104. #endif
  105. assert(max_v >=0 && "Very degenerate case, no suitable face found.");
  106. }
  107. #ifdef IGL_STATIC_LIBRARY
  108. // Explicit template specialization
  109. template void igl::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
  110. template void igl::outer_facet<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 1, -1, -1>, unsigned long>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 1, -1, -1> > const&, unsigned long&, bool&);
  111. template void igl::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  112. template void igl::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  113. #endif