per_corner_normals.cpp 5.3 KB

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