per_vertex_normals.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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. // Resize for output
  45. N.setZero(V.rows(),3);
  46. Eigen::Matrix<typename DerivedN::Scalar,DerivedF::RowsAtCompileTime,3>
  47. W(F.rows(),3);
  48. switch(weighting)
  49. {
  50. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_UNIFORM:
  51. W.setConstant(1.);
  52. break;
  53. default:
  54. assert(false && "Unknown weighting type");
  55. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT:
  56. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA:
  57. {
  58. Eigen::Matrix<typename DerivedN::Scalar,DerivedF::RowsAtCompileTime,1> A;
  59. doublearea(V,F,A);
  60. W = A.replicate(1,3);
  61. break;
  62. }
  63. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE:
  64. internal_angles(V,F,W);
  65. break;
  66. }
  67. // loop over faces
  68. for(int i = 0;i<F.rows();i++)
  69. {
  70. // throw normal at each corner
  71. for(int j = 0; j < 3;j++)
  72. {
  73. N.row(F(i,j)) += W(i,j) * FN.row(i);
  74. }
  75. }
  76. //// loop over faces
  77. //std::mutex critical;
  78. //std::vector<DerivedN> NN;
  79. //parallel_for(
  80. // F.rows(),
  81. // [&NN,&N](const size_t n){ NN.resize(n,DerivedN::Zero(N.rows(),3));},
  82. // [&F,&W,&FN,&NN,&critical](const int i, const size_t t)
  83. // {
  84. // // throw normal at each corner
  85. // for(int j = 0; j < 3;j++)
  86. // {
  87. // // Q: Does this need to be critical?
  88. // // A: Yes. Different (i,j)'s could produce the same F(i,j)
  89. // NN[t].row(F(i,j)) += W(i,j) * FN.row(i);
  90. // }
  91. // },
  92. // [&N,&NN](const size_t t){ N += NN[t]; },
  93. // 1000l);
  94. // take average via normalization
  95. N.rowwise().normalize();
  96. }
  97. template <
  98. typename DerivedV,
  99. typename DerivedF,
  100. typename DerivedFN,
  101. typename DerivedN>
  102. IGL_INLINE void igl::per_vertex_normals(
  103. const Eigen::MatrixBase<DerivedV>& V,
  104. const Eigen::MatrixBase<DerivedF>& F,
  105. const Eigen::MatrixBase<DerivedFN>& FN,
  106. Eigen::PlainObjectBase<DerivedN> & N)
  107. {
  108. return
  109. per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT,FN,N);
  110. }
  111. #ifdef IGL_STATIC_LIBRARY
  112. // Explicit template instantiation
  113. // generated by autoexplicit.sh
  114. 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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -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> >&);
  115. template void igl::per_vertex_normals<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&);
  116. // generated by autoexplicit.sh
  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, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(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, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
  118. // generated by autoexplicit.sh
  119. 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, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(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, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
  120. // generated by autoexplicit.sh
  121. 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, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(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, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  122. // generated by autoexplicit.sh
  123. 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> >&);
  124. 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> >&);
  125. 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> >&);
  126. 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> >&);
  127. 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> >&);
  128. 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> >&);
  129. 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> >&);
  130. 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> >&);
  131. #endif