qslim_optimal_collapse_edge_callbacks.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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(const int)> & pre_collapse,
  21. std::function<void(const int,const bool)> & post_collapse)
  22. {
  23. typedef std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> Quadric;
  24. cost_and_placement = [&quadrics,&v1,&v2](
  25. const int e,
  26. const Eigen::MatrixXd & V,
  27. const Eigen::MatrixXi & /*F*/,
  28. const Eigen::MatrixXi & E,
  29. const Eigen::VectorXi & /*EMAP*/,
  30. const Eigen::MatrixXi & /*EF*/,
  31. const Eigen::MatrixXi & /*EI*/,
  32. double & cost,
  33. Eigen::RowVectorXd & p)
  34. {
  35. // Combined quadric
  36. Quadric quadric_p;
  37. quadric_p = quadrics[E(e,0)] + quadrics[E(e,1)];
  38. // Quadric: p'Ap + 2b'p + c
  39. // optimal point: Ap = -b, or rather because we have row vectors: pA=-b
  40. const auto & A = std::get<0>(quadric_p);
  41. const auto & b = std::get<1>(quadric_p);
  42. const auto & c = std::get<2>(quadric_p);
  43. p = -b*A.inverse();
  44. cost = p.dot(p*A) + 2*p.dot(b) + c;
  45. // Force infs and nans to infinity
  46. if(isinf(cost) || cost!=cost)
  47. {
  48. cost = std::numeric_limits<double>::infinity();
  49. }
  50. };
  51. // Remember endpoints
  52. pre_collapse = [&v1,&v2,&E](const int e)->bool
  53. {
  54. v1 = E(e,0);
  55. v2 = E(e,1);
  56. return true;
  57. };
  58. // update quadric
  59. post_collapse = [&v1,&v2,&quadrics](
  60. const int e,
  61. const bool collapsed)
  62. {
  63. if(collapsed)
  64. {
  65. quadrics[v1<v2?v1:v2] = quadrics[v1] + quadrics[v2];
  66. }
  67. };
  68. }