outer_facet.cpp 5.2 KB

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