per_corner_normals.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 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 "per_corner_normals.h"
  9. #include "vertex_triangle_adjacency.h"
  10. #include "per_face_normals.h"
  11. #include "PI.h"
  12. template <typename DerivedV, typename DerivedF, typename DerivedCN>
  13. IGL_INLINE void igl::per_corner_normals(
  14. const Eigen::PlainObjectBase<DerivedV>& V,
  15. const Eigen::PlainObjectBase<DerivedF>& F,
  16. const double corner_threshold,
  17. Eigen::PlainObjectBase<DerivedCN> & CN)
  18. {
  19. using namespace Eigen;
  20. using namespace std;
  21. Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> FN;
  22. per_face_normals(V,F,FN);
  23. vector<vector<int> > VF,VFi;
  24. vertex_triangle_adjacency(V,F,VF,VFi);
  25. return per_corner_normals(V,F,FN,VF,corner_threshold,CN);
  26. }
  27. template <
  28. typename DerivedV,
  29. typename DerivedF,
  30. typename DerivedFN,
  31. typename DerivedCN>
  32. IGL_INLINE void igl::per_corner_normals(
  33. const Eigen::PlainObjectBase<DerivedV>& V,
  34. const Eigen::PlainObjectBase<DerivedF>& F,
  35. const Eigen::PlainObjectBase<DerivedFN>& FN,
  36. const double corner_threshold,
  37. Eigen::PlainObjectBase<DerivedCN> & CN)
  38. {
  39. using namespace Eigen;
  40. using namespace std;
  41. vector<vector<int> > VF,VFi;
  42. vertex_triangle_adjacency(V,F,VF,VFi);
  43. return per_corner_normals(V,F,FN,VF,corner_threshold,CN);
  44. }
  45. template <
  46. typename DerivedV,
  47. typename DerivedF,
  48. typename DerivedFN,
  49. typename IndexType,
  50. typename DerivedCN>
  51. IGL_INLINE void igl::per_corner_normals(
  52. const Eigen::PlainObjectBase<DerivedV>& /*V*/,
  53. const Eigen::PlainObjectBase<DerivedF>& F,
  54. const Eigen::PlainObjectBase<DerivedFN>& FN,
  55. const std::vector<std::vector<IndexType> >& VF,
  56. const double corner_threshold,
  57. Eigen::PlainObjectBase<DerivedCN> & CN)
  58. {
  59. using namespace Eigen;
  60. using namespace std;
  61. // number of faces
  62. const int m = F.rows();
  63. // valence of faces
  64. const int n = F.cols();
  65. // initialize output to ***zero***
  66. CN.setZero(m*n,3);
  67. // loop over faces
  68. for(size_t i = 0;int(i)<m;i++)
  69. {
  70. // Normal of this face
  71. Eigen::Matrix<typename DerivedV::Scalar,3,1> fn = FN.row(i);
  72. // loop over corners
  73. for(size_t j = 0;int(j)<n;j++)
  74. {
  75. const std::vector<IndexType> &incident_faces = VF[F(i,j)];
  76. // loop over faces sharing vertex of this corner
  77. for(int k = 0;k<(int)incident_faces.size();k++)
  78. {
  79. Eigen::Matrix<typename DerivedV::Scalar,3,1> ifn = FN.row(incident_faces[k]);
  80. // dot product between face's normal and other face's normal
  81. double dp = fn.dot(ifn);
  82. // if difference in normal is slight then add to average
  83. if(dp > cos(corner_threshold*PI/180))
  84. {
  85. // add to running sum
  86. CN.row(i*n+j) += ifn;
  87. // else ignore
  88. }else
  89. {
  90. }
  91. }
  92. // normalize to take average
  93. CN.row(i*n+j).normalize();
  94. }
  95. }
  96. }
  97. #ifdef IGL_STATIC_LIBRARY
  98. // Explicit template specialization
  99. // generated by autoexplicit.sh
  100. template void igl::per_corner_normals<Eigen::Matrix<double, -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&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  101. template void igl::per_corner_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<double, -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> > const&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  102. template void igl::per_corner_normals<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  103. template void igl::per_corner_normals<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<double, -1, 3, 0, -1, 3> >(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&, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  104. #endif