cotmatrix.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include "cotmatrix.h"
  2. // For error printing
  3. #include <cstdio>
  4. #include "cotangent.h"
  5. // Bug in unsupported/Eigen/SparseExtra needs iostream first
  6. #include <iostream>
  7. #include <unsupported/Eigen/SparseExtra>
  8. template <typename DerivedV, typename DerivedF, typename Scalar>
  9. IGL_INLINE void igl::cotmatrix(
  10. const Eigen::MatrixBase<DerivedV> & V,
  11. const Eigen::MatrixBase<DerivedF> & F,
  12. Eigen::SparseMatrix<Scalar>& L)
  13. {
  14. using namespace igl;
  15. using namespace Eigen;
  16. Eigen::DynamicSparseMatrix<double> foo;
  17. DynamicSparseMatrix<Scalar, RowMajor> dyn_L (V.rows(), V.rows());
  18. Matrix<int,Dynamic,2> edges;
  19. int simplex_size = F.cols();
  20. // 3 for triangles, 4 for tets
  21. assert(simplex_size == 3 || simplex_size == 4);
  22. if(simplex_size == 3)
  23. {
  24. // This is important! it could decrease the comptuation time by a factor of 2
  25. // Laplacian for a closed 2d manifold mesh will have on average 7 entries per
  26. // row
  27. dyn_L.reserve(7*V.rows());
  28. edges.resize(3,2);
  29. edges <<
  30. 1,2,
  31. 2,0,
  32. 0,1;
  33. }else if(simplex_size == 4)
  34. {
  35. dyn_L.reserve(17*V.rows());
  36. edges.resize(6,2);
  37. edges <<
  38. 1,2,
  39. 2,0,
  40. 0,1,
  41. 3,0,
  42. 3,1,
  43. 3,2;
  44. }else
  45. {
  46. return;
  47. }
  48. // Gather cotangents
  49. Matrix<Scalar,Dynamic,Dynamic> C;
  50. cotangent(V,F,C);
  51. // Loop over triangles
  52. for(int i = 0; i < F.rows(); i++)
  53. {
  54. // loop over edges of element
  55. for(int e = 0;e<edges.rows();e++)
  56. {
  57. int source = F(i,edges(e,0));
  58. int dest = F(i,edges(e,1));
  59. dyn_L.coeffRef(source,dest) += C(i,e);
  60. dyn_L.coeffRef(dest,source) += C(i,e);
  61. dyn_L.coeffRef(source,source) += -C(i,e);
  62. dyn_L.coeffRef(dest,dest) += -C(i,e);
  63. }
  64. }
  65. // Corner indices of this triangle
  66. L = SparseMatrix<Scalar>(dyn_L);
  67. }
  68. #ifndef IGL_HEADER_ONLY
  69. // Explicit template specialization
  70. // generated by autoexplicit.sh
  71. template void igl::cotmatrix<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
  72. #endif