qslim_optimal_collapse_edge_callbacks.cpp 6.0 KB

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