project_isometrically_to_plane.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 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 "project_isometrically_to_plane.h"
  9. #include "edge_lengths.h"
  10. template <
  11. typename DerivedV,
  12. typename DerivedF,
  13. typename DerivedU,
  14. typename DerivedUF,
  15. typename Scalar>
  16. IGL_INLINE void igl::project_isometrically_to_plane(
  17. const Eigen::MatrixBase<DerivedV> & V,
  18. const Eigen::MatrixBase<DerivedF> & F,
  19. Eigen::PlainObjectBase<DerivedU> & U,
  20. Eigen::PlainObjectBase<DerivedUF> & UF,
  21. Eigen::SparseMatrix<Scalar>& I)
  22. {
  23. assert(F.cols() == 3 && "F should contain triangles");
  24. typedef Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
  25. MatrixX l;
  26. edge_lengths(V,F,l);
  27. // Number of faces
  28. const int m = F.rows();
  29. // First corner at origin
  30. U = DerivedU::Zero(m*3,2);
  31. // Second corner along x-axis
  32. U.block(m,0,m,1) = l.col(2);
  33. // Third corner rotated onto plane
  34. U.block(m*2,0,m,1) =
  35. (-l.col(0).array().square() +
  36. l.col(1).array().square() +
  37. l.col(2).array().square())/(2.*l.col(2).array());
  38. U.block(m*2,1,m,1) =
  39. (l.col(1).array().square()-U.block(m*2,0,m,1).array().square()).sqrt();
  40. typedef Eigen::Triplet<Scalar> IJV;
  41. std::vector<IJV > ijv;
  42. ijv.reserve(3*m);
  43. UF.resize(m,3);
  44. for(int f = 0;f<m;f++)
  45. {
  46. for(int c = 0;c<3;c++)
  47. {
  48. UF(f,c) = c*m+f;
  49. ijv.push_back(IJV(F(f,c),c*m+f,1));
  50. }
  51. }
  52. I.resize(V.rows(),m*3);
  53. I.setFromTriplets(ijv.begin(),ijv.end());
  54. }
  55. #ifdef IGL_STATIC_LIBRARY
  56. template void igl::project_isometrically_to_plane<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::SparseMatrix<double, 0, int>&);
  57. #endif