cotmatrix.cpp 2.0 KB

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