project_isometrically_to_plane.cpp 2.3 KB

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