grad_intrinsic.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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 "grad_intrinsic.h"
  9. #include "grad.h"
  10. template <typename Derivedl, typename DerivedF, typename Gtype>
  11. IGL_INLINE void igl::grad_intrinsic(
  12. const Eigen::MatrixBase<Derivedl>&l,
  13. const Eigen::MatrixBase<DerivedF>&F,
  14. Eigen::SparseMatrix<Gtype> &G)
  15. {
  16. assert(F.cols() ==3 && "Only triangles supported");
  17. // number of vertices
  18. const int n = F.maxCoeff()+1;
  19. // number of faces
  20. const int m = F.rows();
  21. typedef Eigen::Matrix<Gtype,Eigen::Dynamic,2> MatrixX2S;
  22. MatrixX2S V2 = MatrixX2S::Zero(3*m,2);
  23. // 1=[x,y]
  24. // /\
  25. // l3 / \ l2
  26. // / \
  27. // / \
  28. // 2-----------3
  29. // l1
  30. //
  31. // x = (l2²-l1²-l3²)/(-2*l1)
  32. // y = sqrt(l3² - x²)
  33. //
  34. //
  35. // Place 3rd vertex at [l(:,1) 0]
  36. V2.block(2*m,0,m,1) = l.col(0);
  37. // Place second vertex at [0 0]
  38. // Place third vertex at [x y]
  39. V2.block(0,0,m,1) =
  40. (l.col(1).cwiseAbs2()-l.col(0).cwiseAbs2()-l.col(2).cwiseAbs2()).array()/
  41. (-2.*l.col(0)).array();
  42. V2.block(0,1,m,1) =
  43. (l.col(2).cwiseAbs2() - V2.block(0,0,m,1).cwiseAbs2()).array().sqrt();
  44. DerivedF F2(F.rows(),F.cols());
  45. std::vector<Eigen::Triplet<Gtype> > Pijv;
  46. Pijv.reserve(F.size());
  47. for(int f = 0;f<m;f++)
  48. {
  49. for(int c = 0;c<F.cols();c++)
  50. {
  51. F2(f,c) = f+c*m;
  52. Pijv.emplace_back(F2(f,c),F(f,c),1);
  53. }
  54. }
  55. Eigen::SparseMatrix<Gtype> P(m*3,n);
  56. P.setFromTriplets(Pijv.begin(),Pijv.end());
  57. Eigen::SparseMatrix<Gtype> G2;
  58. grad(V2,F2,G2);
  59. G = G2*P;
  60. }
  61. #ifdef IGL_STATIC_LIBRARY
  62. // Explicit template instantiation
  63. // generated by autoexplicit.sh
  64. template void igl::grad_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>&);
  65. // generated by autoexplicit.sh
  66. template void igl::grad_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>&);
  67. #endif