manifold_patches.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "manifold_patches.h"
  2. #include "components.h"
  3. #include <igl/sort.h>
  4. #include <igl/unique.h>
  5. #include <vector>
  6. template <typename DerivedF, typename DerivedC, typename AScalar>
  7. void igl::manifold_patches(
  8. const Eigen::PlainObjectBase<DerivedF> & F,
  9. Eigen::PlainObjectBase<DerivedC> & C,
  10. Eigen::SparseMatrix<AScalar> & A)
  11. {
  12. using namespace Eigen;
  13. using namespace std;
  14. // simplex size
  15. assert(F.cols() == 3);
  16. // List of all "half"-edges: 3*#F by 2
  17. Matrix<typename DerivedF::Scalar, Dynamic, 2> allE,sortallE,uE;
  18. allE.resize(F.rows()*3,2);
  19. VectorXi IC,_;
  20. allE.block(0*F.rows(),0,F.rows(),1) = F.col(1);
  21. allE.block(0*F.rows(),0,F.rows(),1) = F.col(2);
  22. allE.block(1*F.rows(),0,F.rows(),1) = F.col(2);
  23. allE.block(1*F.rows(),0,F.rows(),1) = F.col(0);
  24. allE.block(2*F.rows(),0,F.rows(),1) = F.col(0);
  25. allE.block(2*F.rows(),0,F.rows(),1) = F.col(1);
  26. // Sort each row
  27. sort(allE,2,true,sortallE,_);
  28. //IC(i) tells us where to find sortallE(i,:) in uE:
  29. // so that sortallE(i,:) = uE(IC(i),:)
  30. unique_rows(sortallE,uE,_,IC);
  31. // uE2F(e,f) = 1 means face f is adjacent to unique edge e
  32. vector<Triplet<AScalar> > uE2Fijv(IC.rows());
  33. for(int e = 0;e<IC.rows();e++)
  34. {
  35. uE2Fijv[e] = Triplet<AScalar>(IC(e),e%F.rows(),1);
  36. }
  37. SparseMatrix<AScalar> uE2F(uE.rows(),F.rows());
  38. uE2F.setFromTriplets(uE2Fijv.begin(),uE2Fijv.end());
  39. // kill non-manifold edges
  40. for(int j=0; j<uE2F.outerSize();j++)
  41. {
  42. // Iterate over inside
  43. for(typename SparseMatrix<AScalar>::InnerIterator it (uE2F,j); it; ++it)
  44. {
  45. if(it.value() > 2)
  46. {
  47. uE2F.coeffRef(it.row(),it.col()) = 0;
  48. }
  49. }
  50. }
  51. // Face-face Adjacency matrix
  52. SparseMatrix<AScalar> uE2FT;
  53. uE2FT = uE2F.transpose().eval();
  54. A = uE2FT*uE2F;
  55. // All ones
  56. for(int j=0; j<A.outerSize();j++)
  57. {
  58. // Iterate over inside
  59. for(typename SparseMatrix<AScalar>::InnerIterator it (A,j); it; ++it)
  60. {
  61. if(it.value() > 1)
  62. {
  63. A.coeffRef(it.row(),it.col()) = 1;
  64. }
  65. }
  66. }
  67. //% Connected components are patches
  68. //%C = components(A); % alternative to graphconncomp from matlab_bgl
  69. //[~,C] = graphconncomp(A);
  70. // graph connected components using boost
  71. components(A,C);
  72. }
  73. #ifndef IGL_HEADER_ONLY
  74. // Explicit template specialization
  75. template void igl::manifold_patches<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::SparseMatrix<int, 0, int>&);
  76. #endif