peel_outer_hull_layers.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. {
  64. cout<<"calling outer hull..." << iter <<endl;
  65. std::stringstream ss;
  66. ss << "outer_hull_" << iter << ".ply";
  67. Eigen::MatrixXd vertices(V.rows(), V.cols());
  68. std::transform(V.data(), V.data() + V.rows()*V.cols(),
  69. vertices.data(),
  70. [](typename DerivedV::Scalar val)
  71. {return CGAL::to_double(val); });
  72. writePLY(ss.str(), vertices, Fr);
  73. }
  74. #endif
  75. outer_hull(V,Fr,Fo,Jo,flipr);
  76. #ifdef IGL_PEEL_OUTER_HULL_LAYERS_DEBUG
  77. writePLY(STR("outer-hull-output-"<<iter<<".ply"),V,Fo);
  78. cout<<"reindex, flip..."<<endl;
  79. #endif
  80. assert(Fo.rows() != 0);
  81. assert(Fo.rows() == Jo.rows());
  82. // all faces in Fo of Fr
  83. vector<bool> in_outer(Fr.rows(),false);
  84. for(Index g = 0;g<Jo.rows();g++)
  85. {
  86. I(IM(Jo(g))) = iter;
  87. P(IM(Jo(g))) = iter;
  88. in_outer[Jo(g)] = true;
  89. flip(IM(Jo(g))) = flipr(Jo(g));
  90. }
  91. // Fr = Fr - Fo
  92. // update IM
  93. MatrixXF prev_Fr = Fr;
  94. MatrixXI prev_IM = IM;
  95. Fr.resize(prev_Fr.rows() - Fo.rows(),F.cols());
  96. IM.resize(Fr.rows());
  97. {
  98. Index g = 0;
  99. for(Index f = 0;f<prev_Fr.rows();f++)
  100. {
  101. if(!in_outer[f])
  102. {
  103. Fr.row(g) = prev_Fr.row(f);
  104. IM(g) = prev_IM(f);
  105. g++;
  106. }
  107. }
  108. }
  109. iter++;
  110. }
  111. return iter;
  112. }
  113. #ifdef IGL_STATIC_LIBRARY
  114. // Explicit template specialization
  115. 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> >&);
  116. #endif