per_vertex_normals.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "per_face_normals.h"
  10. #include "doublearea.h"
  11. #include "internal_angles.h"
  12. template <typename DerivedV, typename DerivedF>
  13. IGL_INLINE void igl::per_vertex_normals(
  14. const Eigen::PlainObjectBase<DerivedV>& V,
  15. const Eigen::PlainObjectBase<DerivedF>& F,
  16. const igl::PerVertexNormalsWeightingType weighting,
  17. Eigen::PlainObjectBase<DerivedV> & N)
  18. {
  19. Eigen::PlainObjectBase<DerivedV> PFN;
  20. igl::per_face_normals(V,F,PFN);
  21. return per_vertex_normals(V,F,weighting,PFN,N);
  22. }
  23. template <typename DerivedV, typename DerivedF>
  24. IGL_INLINE void igl::per_vertex_normals(
  25. const Eigen::PlainObjectBase<DerivedV>& V,
  26. const Eigen::PlainObjectBase<DerivedF>& F,
  27. Eigen::PlainObjectBase<DerivedV> & N)
  28. {
  29. return per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT,N);
  30. }
  31. template <typename DerivedV, typename DerivedF, typename DerivedFN, typename DerivedN>
  32. IGL_INLINE void igl::per_vertex_normals(
  33. const Eigen::PlainObjectBase<DerivedV>& V,
  34. const Eigen::PlainObjectBase<DerivedF>& F,
  35. const igl::PerVertexNormalsWeightingType weighting,
  36. const Eigen::PlainObjectBase<DerivedFN>& FN,
  37. Eigen::PlainObjectBase<DerivedN> & N)
  38. {
  39. // Resize for output
  40. N.setZero(V.rows(),3);
  41. Eigen::MatrixXd W(F.rows(),3);
  42. switch(weighting)
  43. {
  44. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_UNIFORM:
  45. W.setConstant(1.);
  46. break;
  47. default:
  48. assert(false && "Unknown weighting type");
  49. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT:
  50. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_AREA:
  51. {
  52. Eigen::VectorXd A;
  53. doublearea(V,F,A);
  54. W = A.replicate(1,3);
  55. break;
  56. }
  57. case PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE:
  58. internal_angles(V,F,W);
  59. break;
  60. }
  61. // loop over faces
  62. const int Frows = F.rows();
  63. //// Minimum number of iterms per openmp thread
  64. //#ifndef IGL_OMP_MIN_VALUE
  65. //# define IGL_OMP_MIN_VALUE 1000
  66. //#endif
  67. //#pragma omp parallel for if (Frows>IGL_OMP_MIN_VALUE)
  68. for(int i = 0; i < Frows;i++)
  69. {
  70. // throw normal at each corner
  71. for(int j = 0; j < 3;j++)
  72. {
  73. // Does this need to be critical?
  74. //#pragma omp critical
  75. N.row(F(i,j)) += W(i,j)*FN.row(i);
  76. }
  77. }
  78. // take average via normalization
  79. N.rowwise().normalize();
  80. }
  81. template <typename DerivedV, typename DerivedF>
  82. IGL_INLINE void igl::per_vertex_normals(
  83. const Eigen::PlainObjectBase<DerivedV>& V,
  84. const Eigen::PlainObjectBase<DerivedF>& F,
  85. const Eigen::PlainObjectBase<DerivedV>& FN,
  86. Eigen::PlainObjectBase<DerivedV> & N)
  87. {
  88. return
  89. per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_DEFAULT,FN,N);
  90. }
  91. #ifdef IGL_STATIC_LIBRARY
  92. // Explicit template specialization
  93. // generated by autoexplicit.sh
  94. #endif