cotmatrix_intrinsic.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2018 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 "cotmatrix_intrinsic.h"
  9. #include "cotmatrix_entries.h"
  10. #include <iostream>
  11. template <typename Derivedl, typename DerivedF, typename Scalar>
  12. IGL_INLINE void igl::cotmatrix_intrinsic(
  13. const Eigen::MatrixBase<Derivedl> & l,
  14. const Eigen::MatrixBase<DerivedF> & F,
  15. Eigen::SparseMatrix<Scalar>& L)
  16. {
  17. using namespace Eigen;
  18. using namespace std;
  19. // Cribbed from cotmatrix
  20. const int nverts = F.maxCoeff()+1;
  21. L.resize(nverts,nverts);
  22. Matrix<int,Dynamic,2> edges;
  23. int simplex_size = F.cols();
  24. // 3 for triangles, 4 for tets
  25. assert(simplex_size == 3);
  26. // This is important! it could decrease the comptuation time by a factor of 2
  27. // Laplacian for a closed 2d manifold mesh will have on average 7 entries per
  28. // row
  29. L.reserve(10*nverts);
  30. edges.resize(3,2);
  31. edges <<
  32. 1,2,
  33. 2,0,
  34. 0,1;
  35. // Gather cotangents
  36. Matrix<Scalar,Dynamic,Dynamic> C;
  37. cotmatrix_entries(l,C);
  38. vector<Triplet<Scalar> > IJV;
  39. IJV.reserve(F.rows()*edges.rows()*4);
  40. // Loop over triangles
  41. for(int i = 0; i < F.rows(); i++)
  42. {
  43. // loop over edges of element
  44. for(int e = 0;e<edges.rows();e++)
  45. {
  46. int source = F(i,edges(e,0));
  47. int dest = F(i,edges(e,1));
  48. IJV.push_back(Triplet<Scalar>(source,dest,C(i,e)));
  49. IJV.push_back(Triplet<Scalar>(dest,source,C(i,e)));
  50. IJV.push_back(Triplet<Scalar>(source,source,-C(i,e)));
  51. IJV.push_back(Triplet<Scalar>(dest,dest,-C(i,e)));
  52. }
  53. }
  54. L.setFromTriplets(IJV.begin(),IJV.end());
  55. }
  56. #ifdef IGL_STATIC_LIBRARY
  57. // Explicit template instantiation
  58. template void igl::cotmatrix_intrinsic<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
  59. template void igl::cotmatrix_intrinsic<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&);
  60. template void igl::cotmatrix_intrinsic<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 4, 0, -1, 4>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 4, 0, -1, 4> > const&, Eigen::SparseMatrix<double, 0, int>&);
  61. template void igl::cotmatrix_intrinsic<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::SparseMatrix<double, 0, int>&);
  62. template void igl::cotmatrix_intrinsic<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>&);
  63. #endif