qslim.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "qslim.h"
  2. #include "collapse_edge.h"
  3. #include "connect_boundary_to_infinity.h"
  4. #include "decimate.h"
  5. #include "edge_flaps.h"
  6. #include "max_faces_stopping_condition.h"
  7. #include "per_vertex_point_to_plane_quadrics.h"
  8. #include "qslim_optimal_collapse_edge_callbacks.h"
  9. #include "quadric_binary_plus_operator.h"
  10. #include "remove_unreferenced.h"
  11. #include "slice.h"
  12. #include "slice_mask.h"
  13. IGL_INLINE bool igl::qslim(
  14. const Eigen::MatrixXd & V,
  15. const Eigen::MatrixXi & F,
  16. const size_t max_m,
  17. Eigen::MatrixXd & U,
  18. Eigen::MatrixXi & G,
  19. Eigen::VectorXi & J,
  20. Eigen::VectorXi & I)
  21. {
  22. using namespace igl;
  23. // Original number of faces
  24. const int orig_m = F.rows();
  25. // Tracking number of faces
  26. int m = F.rows();
  27. typedef Eigen::MatrixXd DerivedV;
  28. typedef Eigen::MatrixXi DerivedF;
  29. DerivedV VO;
  30. DerivedF FO;
  31. igl::connect_boundary_to_infinity(V,F,VO,FO);
  32. Eigen::VectorXi EMAP;
  33. Eigen::MatrixXi E,EF,EI;
  34. edge_flaps(FO,E,EMAP,EF,EI);
  35. // Quadrics per vertex
  36. typedef std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> Quadric;
  37. std::vector<Quadric> quadrics;
  38. per_vertex_point_to_plane_quadrics(VO,FO,EMAP,EF,EI,quadrics);
  39. // State variables keeping track of edge we just collapsed
  40. int v1 = -1;
  41. int v2 = -1;
  42. // Callbacks for computing and updating metric
  43. std::function<void(
  44. const int e,
  45. const Eigen::MatrixXd &,
  46. const Eigen::MatrixXi &,
  47. const Eigen::MatrixXi &,
  48. const Eigen::VectorXi &,
  49. const Eigen::MatrixXi &,
  50. const Eigen::MatrixXi &,
  51. double &,
  52. Eigen::RowVectorXd &)> cost_and_placement;
  53. std::function<bool(const int)> pre_collapse;
  54. std::function<void(const int,const bool)> post_collapse;
  55. qslim_optimal_collapse_edge_callbacks(
  56. E,quadrics,v1,v2, cost_and_placement, pre_collapse,post_collapse);
  57. // Call to greedy decimator
  58. bool ret = decimate(
  59. VO, FO,
  60. cost_and_placement,
  61. max_faces_stopping_condition(m,orig_m,max_m),
  62. pre_collapse,
  63. post_collapse,
  64. E, EMAP, EF, EI,
  65. U, G, J, I);
  66. // Remove phony boundary faces and clean up
  67. const Eigen::Array<bool,Eigen::Dynamic,1> keep = (J.array()<orig_m);
  68. igl::slice_mask(Eigen::MatrixXi(G),keep,1,G);
  69. igl::slice_mask(Eigen::VectorXi(J),keep,1,J);
  70. Eigen::VectorXi _1,I2;
  71. igl::remove_unreferenced(Eigen::MatrixXd(U),Eigen::MatrixXi(G),U,G,_1,I2);
  72. igl::slice(Eigen::VectorXi(I),I2,1,I);
  73. return ret;
  74. }