cotmatrix_intrinsic.cpp 3.4 KB

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