polyvector_field_cut_mesh_with_singularities.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 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 <igl/polyvector_field_cut_mesh_with_singularities.h>
  9. #include <igl/dijkstra.h>
  10. #include <igl/vertex_triangle_adjacency.h>
  11. #include <igl/adjacency_list.h>
  12. #include <igl/triangle_triangle_adjacency.h>
  13. #include <igl/is_border_vertex.h>
  14. #include <igl/cut_mesh_from_singularities.h>
  15. #include <set>
  16. template <typename DerivedV, typename DerivedF, typename VFType, typename VVType, typename DerivedTT, typename DerivedC, typename DerivedS>
  17. IGL_INLINE void igl::polyvector_field_cut_mesh_with_singularities(
  18. const Eigen::PlainObjectBase<DerivedV> &V,
  19. const Eigen::PlainObjectBase<DerivedF> &F,
  20. const std::vector<std::vector<VFType> >& VF,
  21. const std::vector<std::vector<VVType> >& VV,
  22. const Eigen::PlainObjectBase<DerivedTT>& TT,
  23. const Eigen::PlainObjectBase<DerivedTT>& TTi,
  24. const Eigen::PlainObjectBase<DerivedS> &singularities,
  25. Eigen::PlainObjectBase<DerivedC> &cuts)
  26. {
  27. //first, get a spanning tree for the mesh (no missmatch needed)
  28. igl::cut_mesh_from_singularities(V, F, Eigen::MatrixXd::Zero(F.rows(), 3).eval(), cuts);
  29. std::set<int> vertices_in_cut;
  30. for (int i =0; i< cuts.rows(); ++i)
  31. for (int j =0;j< cuts.cols(); ++j)
  32. if (cuts(i,j))
  33. vertices_in_cut.insert(F(i,j));
  34. //then, add all singularities one by one by using Dijkstra's algorithm
  35. for (int i = 0; i<singularities.rows(); ++i)
  36. {
  37. std::vector<int> path;
  38. Eigen::VectorXd min_distance;
  39. Eigen::VectorXi previous;
  40. int vertex_found = igl::dijkstra_compute_paths(singularities[i], vertices_in_cut, VV, min_distance, previous);
  41. if(vertex_found ==-1)
  42. // this means that there are no cuts
  43. path.push_back(singularities[i]);
  44. else
  45. igl::dijkstra_get_shortest_path_to(vertex_found, previous, path);
  46. vertices_in_cut.insert(path.begin(), path.end());
  47. //insert to cut
  48. for (int ii = 0; ii<path.size()-1; ++ii)
  49. {
  50. const int &v0 = path[ii];
  51. const int &v1 = path[ii+1];
  52. std::vector<int> vf0 = VF[v0];
  53. std::sort(vf0.begin(), vf0.end());
  54. std::vector<int> vf1 = VF[v1];
  55. std::sort(vf1.begin(), vf1.end());
  56. std::vector<int> common_face_v(std::max(vf0.size(),vf1.size()));
  57. std::vector<int>::iterator it;
  58. it=std::set_intersection (vf0.begin(), vf0.end(), vf1.begin(), vf1.end(), common_face_v.begin());
  59. common_face_v.resize(it-common_face_v.begin());
  60. assert(common_face_v.size() == 2);
  61. const int &fi = common_face_v[0];
  62. int j=-1;
  63. for (unsigned z=0; z<3; ++z)
  64. if (((F(fi,z) == v0) && (F(fi,(z+1)%3) == v1)) ||((F(fi,z) == v1) && (F(fi,(z+1)%3) == v0)))
  65. j=z;
  66. assert(j!=-1);
  67. cuts(fi,j) = 1;
  68. cuts(TT(fi,j), TTi(fi,j)) = 1;
  69. }
  70. }
  71. }
  72. //Wrapper of the above with only vertices and faces as mesh input
  73. template <typename DerivedV, typename DerivedF, typename DerivedC, typename DerivedS>
  74. IGL_INLINE void igl::polyvector_field_cut_mesh_with_singularities(
  75. const Eigen::PlainObjectBase<DerivedV> &V,
  76. const Eigen::PlainObjectBase<DerivedF> &F,
  77. const Eigen::PlainObjectBase<DerivedS> &singularities,
  78. Eigen::PlainObjectBase<DerivedC> &cuts)
  79. {
  80. std::vector<std::vector<int> > VF, VFi;
  81. igl::vertex_triangle_adjacency(V,F,VF,VFi);
  82. std::vector<std::vector<int> > VV;
  83. igl::adjacency_list(F, VV);
  84. Eigen::MatrixXi TT, TTi;
  85. igl::triangle_triangle_adjacency(F,TT,TTi);
  86. igl::polyvector_field_cut_mesh_with_singularities(V, F, VF, VV, TT, TTi, singularities, cuts);
  87. }
  88. #ifdef IGL_STATIC_LIBRARY
  89. // Explicit template instantiation
  90. template void igl::polyvector_field_cut_mesh_with_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, int, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  91. template void igl::polyvector_field_cut_mesh_with_singularities<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  92. #endif