peel_outer_hull_layers.cpp 3.5 KB

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