per_vertex_normals.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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_vertex_normals.h"
  9. #include "get_seconds.h"
  10. #include "per_face_normals.h"
  11. #include "doublearea.h"
  12. #include "parallel_for.h"
  13. #include "internal_angles.h"
  14. template <typename DerivedV, typename DerivedF>
  15. IGL_INLINE void igl::per_vertex_normals(
  16. const Eigen::PlainObjectBase<DerivedV>& V,
  17. const Eigen::PlainObjectBase<DerivedF>& F,
  18. const igl::PerVertexNormalsWeightingType weighting,
  19. Eigen::PlainObjectBase<DerivedV> & N)
  20. {
  21. Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> PFN;
  22. igl::per_face_normals(V,F,PFN);
  23. return per_vertex_normals(V,F,weighting,PFN,N);
  24. }
  25. template <typename DerivedV, typename DerivedF>
  26. IGL_INLINE void igl::per_vertex_normals(
  27. const Eigen::PlainObjectBase<DerivedV>& V,
  28. const Eigen::PlainObjectBase<DerivedF>& F,
  29. Eigen::PlainObjectBase<DerivedV> & N)
  30. {
  31. return per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT,N);
  32. }
  33. template <typename DerivedV, typename DerivedF, typename DerivedFN, typename DerivedN>
  34. IGL_INLINE void igl::per_vertex_normals(
  35. const Eigen::PlainObjectBase<DerivedV>& V,
  36. const Eigen::PlainObjectBase<DerivedF>& F,
  37. const igl::PerVertexNormalsWeightingType weighting,
  38. const Eigen::PlainObjectBase<DerivedFN>& FN,
  39. Eigen::PlainObjectBase<DerivedN> & N)
  40. {
  41. using namespace std;
  42. // Resize for output
  43. N.setZero(V.rows(),3);
  44. Eigen::Matrix<typename DerivedN::Scalar,DerivedF::RowsAtCompileTime,3>
  45. W(F.rows(),3);
  46. switch(weighting)
  47. {
  48. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_UNIFORM:
  49. W.setConstant(1.);
  50. break;
  51. default:
  52. assert(false && "Unknown weighting type");
  53. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT:
  54. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA:
  55. {
  56. Eigen::Matrix<typename DerivedN::Scalar,DerivedF::RowsAtCompileTime,1> A;
  57. doublearea(V,F,A);
  58. W = A.replicate(1,3);
  59. break;
  60. }
  61. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE:
  62. internal_angles(V,F,W);
  63. break;
  64. }
  65. // loop over faces
  66. for(int i = 0;i<F.rows();i++)
  67. {
  68. // throw normal at each corner
  69. for(int j = 0; j < 3;j++)
  70. {
  71. N.row(F(i,j)) += W(i,j) * FN.row(i);
  72. }
  73. }
  74. //// loop over faces
  75. //std::mutex critical;
  76. //std::vector<DerivedN> NN;
  77. //parallel_for(
  78. // F.rows(),
  79. // [&NN,&N](const size_t n){ NN.resize(n,DerivedN::Zero(N.rows(),3));},
  80. // [&F,&W,&FN,&NN,&critical](const int i, const size_t t)
  81. // {
  82. // // throw normal at each corner
  83. // for(int j = 0; j < 3;j++)
  84. // {
  85. // // Q: Does this need to be critical?
  86. // // A: Yes. Different (i,j)'s could produce the same F(i,j)
  87. // NN[t].row(F(i,j)) += W(i,j) * FN.row(i);
  88. // }
  89. // },
  90. // [&N,&NN](const size_t t){ N += NN[t]; },
  91. // 1000l);
  92. // take average via normalization
  93. N.rowwise().normalize();
  94. }
  95. template <typename DerivedV, typename DerivedF>
  96. IGL_INLINE void igl::per_vertex_normals(
  97. const Eigen::PlainObjectBase<DerivedV>& V,
  98. const Eigen::PlainObjectBase<DerivedF>& F,
  99. const Eigen::PlainObjectBase<DerivedV>& FN,
  100. Eigen::PlainObjectBase<DerivedV> & N)
  101. {
  102. return
  103. per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT,FN,N);
  104. }
  105. #ifdef IGL_STATIC_LIBRARY
  106. // Explicit template specialization
  107. template void igl::per_vertex_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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  108. template void igl::per_vertex_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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  109. template void igl::per_vertex_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&, igl::PerVertexNormalsWeightingType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  110. template void igl::per_vertex_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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  111. template void igl::per_vertex_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&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  112. template void igl::per_vertex_normals<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
  113. template void igl::per_vertex_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&, igl::PerVertexNormalsWeightingType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  114. template void igl::per_vertex_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&, igl::PerVertexNormalsWeightingType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  115. #endif