qslim_optimal_collapse_edge_callbacks.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "qslim_optimal_collapse_edge_callbacks.h"
  2. #include "quadric_binary_plus_operator.h"
  3. #include <Eigen/LU>
  4. IGL_INLINE void igl::qslim_optimal_collapse_edge_callbacks(
  5. Eigen::MatrixXi & E,
  6. std::vector<std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> > &
  7. quadrics,
  8. int & v1,
  9. int & v2,
  10. std::function<void(
  11. const int e,
  12. const Eigen::MatrixXd &,
  13. const Eigen::MatrixXi &,
  14. const Eigen::MatrixXi &,
  15. const Eigen::VectorXi &,
  16. const Eigen::MatrixXi &,
  17. const Eigen::MatrixXi &,
  18. double &,
  19. Eigen::RowVectorXd &)> & cost_and_placement,
  20. std::function<bool(
  21. const Eigen::MatrixXd & ,/*V*/
  22. const Eigen::MatrixXi & ,/*F*/
  23. const Eigen::MatrixXi & ,/*E*/
  24. const Eigen::VectorXi & ,/*EMAP*/
  25. const Eigen::MatrixXi & ,/*EF*/
  26. const Eigen::MatrixXi & ,/*EI*/
  27. const std::set<std::pair<double,int> > & ,/*Q*/
  28. const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
  29. const Eigen::MatrixXd & ,/*C*/
  30. const int /*e*/
  31. )> & pre_collapse,
  32. std::function<void(
  33. const Eigen::MatrixXd & , /*V*/
  34. const Eigen::MatrixXi & , /*F*/
  35. const Eigen::MatrixXi & , /*E*/
  36. const Eigen::VectorXi & ,/*EMAP*/
  37. const Eigen::MatrixXi & , /*EF*/
  38. const Eigen::MatrixXi & , /*EI*/
  39. const std::set<std::pair<double,int> > & , /*Q*/
  40. const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
  41. const Eigen::MatrixXd & , /*C*/
  42. const int , /*e*/
  43. const int , /*e1*/
  44. const int , /*e2*/
  45. const int , /*f1*/
  46. const int , /*f2*/
  47. const bool /*collapsed*/
  48. )> & post_collapse)
  49. {
  50. typedef std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> Quadric;
  51. cost_and_placement = [&quadrics,&v1,&v2](
  52. const int e,
  53. const Eigen::MatrixXd & V,
  54. const Eigen::MatrixXi & /*F*/,
  55. const Eigen::MatrixXi & E,
  56. const Eigen::VectorXi & /*EMAP*/,
  57. const Eigen::MatrixXi & /*EF*/,
  58. const Eigen::MatrixXi & /*EI*/,
  59. double & cost,
  60. Eigen::RowVectorXd & p)
  61. {
  62. // Combined quadric
  63. Quadric quadric_p;
  64. quadric_p = quadrics[E(e,0)] + quadrics[E(e,1)];
  65. // Quadric: p'Ap + 2b'p + c
  66. // optimal point: Ap = -b, or rather because we have row vectors: pA=-b
  67. const auto & A = std::get<0>(quadric_p);
  68. const auto & b = std::get<1>(quadric_p);
  69. const auto & c = std::get<2>(quadric_p);
  70. p = -b*A.inverse();
  71. cost = p.dot(p*A) + 2*p.dot(b) + c;
  72. // Force infs and nans to infinity
  73. if(isinf(cost) || cost!=cost)
  74. {
  75. cost = std::numeric_limits<double>::infinity();
  76. // Prevent NaNs. Actually NaNs might be useful for debugging.
  77. p.setConstant(0);
  78. }
  79. };
  80. // Remember endpoints
  81. pre_collapse = [&v1,&v2](
  82. const Eigen::MatrixXd & ,/*V*/
  83. const Eigen::MatrixXi & ,/*F*/
  84. const Eigen::MatrixXi & E,
  85. const Eigen::VectorXi & ,/*EMAP*/
  86. const Eigen::MatrixXi & ,/*EF*/
  87. const Eigen::MatrixXi & ,/*EI*/
  88. const std::set<std::pair<double,int> > & ,/*Q*/
  89. const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
  90. const Eigen::MatrixXd & ,/*C*/
  91. const int e)->bool
  92. {
  93. v1 = E(e,0);
  94. v2 = E(e,1);
  95. return true;
  96. };
  97. // update quadric
  98. post_collapse = [&v1,&v2,&quadrics](
  99. const Eigen::MatrixXd & , /*V*/
  100. const Eigen::MatrixXi & , /*F*/
  101. const Eigen::MatrixXi & , /*E*/
  102. const Eigen::VectorXi & ,/*EMAP*/
  103. const Eigen::MatrixXi & , /*EF*/
  104. const Eigen::MatrixXi & , /*EI*/
  105. const std::set<std::pair<double,int> > & , /*Q*/
  106. const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
  107. const Eigen::MatrixXd & , /*C*/
  108. const int , /*e*/
  109. const int , /*e1*/
  110. const int , /*e2*/
  111. const int , /*f1*/
  112. const int , /*f2*/
  113. const bool collapsed
  114. )->void
  115. {
  116. if(collapsed)
  117. {
  118. quadrics[v1<v2?v1:v2] = quadrics[v1] + quadrics[v2];
  119. }
  120. };
  121. }