per_vertex_normals.cpp 7.2 KB

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