peel_outer_hull_layers.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 "peel_outer_hull_layers.h"
  9. #include "../per_face_normals.h"
  10. #include "outer_hull.h"
  11. #include <vector>
  12. #include <iostream>
  13. //#define IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  14. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  15. #include "../writePLY.h"
  16. #include "../writeDMAT.h"
  17. #include "../STR.h"
  18. #endif
  19. template <
  20. typename DerivedV,
  21. typename DerivedF,
  22. typename DerivedN,
  23. typename Derivedodd,
  24. typename Derivedflip>
  25. IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
  26. const Eigen::PlainObjectBase<DerivedV > & V,
  27. const Eigen::PlainObjectBase<DerivedF > & F,
  28. const Eigen::PlainObjectBase<DerivedN > & N,
  29. Eigen::PlainObjectBase<Derivedodd > & odd,
  30. Eigen::PlainObjectBase<Derivedflip > & flip)
  31. {
  32. using namespace Eigen;
  33. using namespace std;
  34. typedef typename DerivedF::Index Index;
  35. typedef Matrix<typename DerivedF::Scalar,Dynamic,DerivedF::ColsAtCompileTime> MatrixXF;
  36. typedef Matrix<typename DerivedN::Scalar,Dynamic,DerivedN::ColsAtCompileTime> MatrixXN;
  37. typedef Matrix<Index,Dynamic,1> MatrixXI;
  38. typedef Matrix<typename Derivedflip::Scalar,Dynamic,Derivedflip::ColsAtCompileTime> MatrixXflip;
  39. const Index m = F.rows();
  40. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  41. cout<<"peel outer hull layers..."<<endl;
  42. #endif
  43. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  44. cout<<"calling outer hull..."<<endl;
  45. writePLY(STR("peel-outer-hull-input.ply"),V,F);
  46. #endif
  47. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  48. cout<<"resize output ..."<<endl;
  49. #endif
  50. // keep track of iteration parity and whether flipped in hull
  51. MatrixXF Fr = F;
  52. MatrixXN Nr = N;
  53. odd.resize(m,1);
  54. flip.resize(m,1);
  55. // Keep track of index map
  56. MatrixXI IM = MatrixXI::LinSpaced(m,0,m-1);
  57. // This is O(n * layers)
  58. bool odd_iter = true;
  59. MatrixXI P(m,1);
  60. Index iter = 0;
  61. while(Fr.size() > 0)
  62. {
  63. assert(Fr.rows() == IM.rows());
  64. // Compute outer hull of current Fr
  65. MatrixXF Fo;
  66. MatrixXI Jo;
  67. MatrixXflip flipr;
  68. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  69. cout<<"calling outer hull..."<<endl;
  70. writePLY(STR("outer-hull-input-"<<iter<<".ply"),V,Fr);
  71. writeDMAT(STR("outer-hull-input-"<<iter<<".dmat"),Nr);
  72. #endif
  73. outer_hull(V,Fr,Nr,Fo,Jo,flipr);
  74. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  75. writePLY(STR("outer-hull-output-"<<iter<<".ply"),V,Fo);
  76. cout<<"reindex, flip..."<<endl;
  77. #endif
  78. assert(Fo.rows() == Jo.rows());
  79. // all faces in Fo of Fr
  80. vector<bool> in_outer(Fr.rows(),false);
  81. for(Index g = 0;g<Jo.rows();g++)
  82. {
  83. odd(IM(Jo(g))) = odd_iter;
  84. P(IM(Jo(g))) = iter;
  85. in_outer[Jo(g)] = true;
  86. flip(IM(Jo(g))) = flipr(Jo(g));
  87. }
  88. // Fr = Fr - Fo
  89. // update IM
  90. MatrixXF prev_Fr = Fr;
  91. MatrixXN prev_Nr = Nr;
  92. MatrixXI prev_IM = IM;
  93. Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
  94. Nr.resize(Fr.rows(),3);
  95. IM.resize(Fr.rows());
  96. {
  97. Index g = 0;
  98. for(Index f = 0;f<prev_Fr.rows();f++)
  99. {
  100. if(!in_outer[f])
  101. {
  102. Fr.row(g) = prev_Fr.row(f);
  103. Nr.row(g) = prev_Nr.row(f);
  104. IM(g) = prev_IM(f);
  105. g++;
  106. }
  107. }
  108. }
  109. odd_iter = !odd_iter;
  110. iter++;
  111. }
  112. return iter;
  113. }
  114. template <
  115. typename DerivedV,
  116. typename DerivedF,
  117. typename Derivedodd,
  118. typename Derivedflip>
  119. IGL_INLINE size_t igl::cgal::peel_outer_hull_layers(
  120. const Eigen::PlainObjectBase<DerivedV > & V,
  121. const Eigen::PlainObjectBase<DerivedF > & F,
  122. Eigen::PlainObjectBase<Derivedodd > & odd,
  123. Eigen::PlainObjectBase<Derivedflip > & flip)
  124. {
  125. using namespace std;
  126. Eigen::Matrix<typename DerivedV::Scalar,DerivedF::RowsAtCompileTime,3> N;
  127. per_face_normals(V,F,N);
  128. return peel_outer_hull_layers(V,F,N,odd,flip);
  129. }
  130. #ifdef IGL_STATIC_LIBRARY
  131. // Explicit template specialization
  132. template size_t igl::cgal::peel_outer_hull_layers<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
  133. template size_t igl::cgal::peel_outer_hull_layers<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::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&);
  134. #endif