per_corner_normals.cpp 4.9 KB

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