per_edge_normals.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "all_edges.h"
  2. #include "doublearea.h"
  3. #include "per_edge_normals.h"
  4. #include "get_seconds.h"
  5. #include "per_face_normals.h"
  6. #include "unique_simplices.h"
  7. #include <vector>
  8. template <
  9. typename DerivedV,
  10. typename DerivedF,
  11. typename DerivedFN,
  12. typename DerivedN,
  13. typename DerivedE,
  14. typename DerivedEMAP>
  15. IGL_INLINE void igl::per_edge_normals(
  16. const Eigen::PlainObjectBase<DerivedV>& V,
  17. const Eigen::PlainObjectBase<DerivedF>& F,
  18. const PerEdgeNormalsWeightingType weighting,
  19. const Eigen::PlainObjectBase<DerivedFN>& FN,
  20. Eigen::PlainObjectBase<DerivedN> & N,
  21. Eigen::PlainObjectBase<DerivedE> & E,
  22. Eigen::PlainObjectBase<DerivedEMAP> & EMAP)
  23. {
  24. using namespace Eigen;
  25. using namespace std;
  26. assert(F.cols() == 3 && "Faces must be triangles");
  27. // number of faces
  28. const int m = F.rows();
  29. // All occurances of directed edges
  30. MatrixXi allE;
  31. all_edges(F,allE);
  32. // Find unique undirected edges and mapping
  33. VectorXi _;
  34. unique_simplices(allE,E,_,EMAP);
  35. // now sort(allE,2) == E(EMAP,:), that is, if EMAP(i) = j, then E.row(j) is
  36. // the undirected edge corresponding to the directed edge allE.row(i).
  37. Eigen::VectorXd W;
  38. switch(weighting)
  39. {
  40. case PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM:
  41. // Do nothing
  42. break;
  43. default:
  44. assert(false && "Unknown weighting type");
  45. case PER_EDGE_NORMALS_WEIGHTING_TYPE_DEFAULT:
  46. case PER_EDGE_NORMALS_WEIGHTING_TYPE_AREA:
  47. {
  48. doublearea(V,F,W);
  49. break;
  50. }
  51. }
  52. N.setZero(E.rows(),3);
  53. for(int f = 0;f<m;f++)
  54. {
  55. for(int c = 0;c<3;c++)
  56. {
  57. if(weighting == PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM)
  58. {
  59. N.row(EMAP(f+c*m)) += FN.row(f);
  60. }else
  61. {
  62. N.row(EMAP(f+c*m)) += W(f) * FN.row(f);
  63. }
  64. }
  65. }
  66. }
  67. template <
  68. typename DerivedV,
  69. typename DerivedF,
  70. typename DerivedN,
  71. typename DerivedE,
  72. typename DerivedEMAP>
  73. IGL_INLINE void igl::per_edge_normals(
  74. const Eigen::PlainObjectBase<DerivedV>& V,
  75. const Eigen::PlainObjectBase<DerivedF>& F,
  76. const PerEdgeNormalsWeightingType weighting,
  77. Eigen::PlainObjectBase<DerivedN> & N,
  78. Eigen::PlainObjectBase<DerivedE> & E,
  79. Eigen::PlainObjectBase<DerivedEMAP> & EMAP)
  80. {
  81. Eigen::PlainObjectBase<DerivedN> FN;
  82. per_face_normals(V,F,FN);
  83. return per_edge_normals(V,F,weighting,FN,N,E,EMAP);
  84. }
  85. template <
  86. typename DerivedV,
  87. typename DerivedF,
  88. typename DerivedN,
  89. typename DerivedE,
  90. typename DerivedEMAP>
  91. IGL_INLINE void igl::per_edge_normals(
  92. const Eigen::PlainObjectBase<DerivedV>& V,
  93. const Eigen::PlainObjectBase<DerivedF>& F,
  94. Eigen::PlainObjectBase<DerivedN> & N,
  95. Eigen::PlainObjectBase<DerivedE> & E,
  96. Eigen::PlainObjectBase<DerivedEMAP> & EMAP)
  97. {
  98. return
  99. per_edge_normals(V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_DEFAULT,N,E,EMAP);
  100. }
  101. #ifdef IGL_STATIC_LIBRARY
  102. // Explicit template instanciation
  103. template void igl::per_edge_normals<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>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  104. #endif