manifold_patches.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. VectorXi IC,_;
  19. allE.block(0*F.rows(),0,F.rows(),0) = F.col(1);
  20. allE.block(0*F.rows(),0,F.rows(),1) = F.col(2);
  21. allE.block(1*F.rows(),0,F.rows(),0) = F.col(2);
  22. allE.block(1*F.rows(),0,F.rows(),1) = F.col(0);
  23. allE.block(2*F.rows(),0,F.rows(),0) = F.col(0);
  24. allE.block(2*F.rows(),0,F.rows(),1) = F.col(1);
  25. // Sort each row
  26. sort(allE,2,true,sortallE,_);
  27. //IC(i) tells us where to find sortallE(i,:) in uE:
  28. // so that sortallE(i,:) = uE(IC(i),:)
  29. unique_rows(sortallE,uE,_,IC);
  30. // uE2F(e,f) = 1 means face f is adjacent to unique edge e
  31. vector<Triplet<AScalar> > uE2Fijv(IC.rows());
  32. for(int e = 0;e<IC.rows();e++)
  33. {
  34. uE2Fijv[e] = Triplet<AScalar>(IC(e),e%F.rows(),1);
  35. }
  36. SparseMatrix<AScalar> uE2F(uE.rows(),F.rows());
  37. uE2F.setFromTriplets(uE2Fijv.begin(),uE2Fijv.end());
  38. // kill non-manifold edges
  39. for(int j=0; j<uE2F.outerSize();j++)
  40. {
  41. // Iterate over inside
  42. for(typename SparseMatrix<AScalar>::InnerIterator it (uE2F,j); it; ++it)
  43. {
  44. if(it.value() > 2)
  45. {
  46. uE2F.coeffRef(it.row(),it.col()) = 0;
  47. }
  48. }
  49. }
  50. // Face-face Adjacency matrix
  51. SparseMatrix<AScalar> uE2FT;
  52. uE2FT = uE2F.transpose().eval();
  53. A = uE2FT*uE2F;
  54. // All ones
  55. for(int j=0; j<A.outerSize();j++)
  56. {
  57. // Iterate over inside
  58. for(typename SparseMatrix<AScalar>::InnerIterator it (A,j); it; ++it)
  59. {
  60. if(it.value() > 1)
  61. {
  62. A.coeffRef(it.row(),it.col()) = 1;
  63. }
  64. }
  65. }
  66. //% Connected components are patches
  67. //%C = components(A); % alternative to graphconncomp from matlab_bgl
  68. //[~,C] = graphconncomp(A);
  69. // graph connected components using boost
  70. components(A,C);
  71. }
  72. #ifndef IGL_HEADER_ONLY
  73. // Explicit template specialization
  74. 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>&);
  75. #endif