comb_frame_field.cpp 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Daniele Panozzo <[email protected]>, Olga Diamanti <[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. #ifdef WIN32
  9. #define _USE_MATH_DEFINES
  10. #endif
  11. #include <cmath>
  12. #include "comb_frame_field.h"
  13. #include "local_basis.h"
  14. #include "PI.h"
  15. #include "PlainMatrix.h"
  16. template <typename DerivedV, typename DerivedF, typename DerivedP>
  17. IGL_INLINE void igl::comb_frame_field(
  18. const Eigen::MatrixBase<DerivedV> &V,
  19. const Eigen::MatrixBase<DerivedF> &F,
  20. const Eigen::MatrixBase<DerivedP> &PD1,
  21. const Eigen::MatrixBase<DerivedP> &PD2,
  22. const Eigen::MatrixBase<DerivedP> &BIS1_combed,
  23. const Eigen::MatrixBase<DerivedP> &BIS2_combed,
  24. Eigen::PlainObjectBase<DerivedP> &PD1_combed,
  25. Eigen::PlainObjectBase<DerivedP> &PD2_combed)
  26. {
  27. PlainMatrix<DerivedV,Eigen::Dynamic> B1, B2, B3;
  28. igl::local_basis(V,F,B1,B2,B3);
  29. PD1_combed.resize(BIS1_combed.rows(),3);
  30. PD2_combed.resize(BIS2_combed.rows(),3);
  31. for (unsigned i=0; i<PD1.rows();++i)
  32. {
  33. Eigen::Matrix<typename DerivedP::Scalar,4,3> DIRs;
  34. DIRs <<
  35. PD1.row(i),
  36. -PD1.row(i),
  37. PD2.row(i),
  38. -PD2.row(i);
  39. std::vector<double> a(4);
  40. double a_combed = atan2(B2.row(i).dot(BIS1_combed.row(i)),B1.row(i).dot(BIS1_combed.row(i)));
  41. // center on the combed sector center
  42. for (unsigned j=0;j<4;++j)
  43. {
  44. a[j] = atan2(B2.row(i).dot(DIRs.row(j)),B1.row(i).dot(DIRs.row(j))) - a_combed;
  45. //make it positive by adding some multiple of 2pi
  46. a[j] += std::ceil (std::max(0., -a[j]) / (igl::PI*2.)) * (igl::PI*2.);
  47. //take modulo 2pi
  48. a[j] = fmod(a[j], (igl::PI*2.));
  49. }
  50. // now the max is u and the min is v
  51. int m = std::min_element(a.begin(),a.end())-a.begin();
  52. int M = std::max_element(a.begin(),a.end())-a.begin();
  53. assert(
  54. ((m>=0 && m<=1) && (M>=2 && M<=3))
  55. ||
  56. ((m>=2 && m<=3) && (M>=0 && M<=1))
  57. );
  58. PD1_combed.row(i) = DIRs.row(m);
  59. PD2_combed.row(i) = DIRs.row(M);
  60. }
  61. }
  62. #ifdef IGL_STATIC_LIBRARY
  63. // Explicit template instantiation
  64. template void igl::comb_frame_field<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
  65. template void igl::comb_frame_field<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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  66. #endif