bbw.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #define VERBOSE
  2. #include "bbw.h"
  3. #include <igl/cotmatrix.h>
  4. #include <igl/massmatrix.h>
  5. #include <igl/invert_diag.h>
  6. #include <igl/speye.h>
  7. #include <igl/slice_into.h>
  8. #include <igl/normalize_row_sums.h>
  9. #include <igl/verbose.h>
  10. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  11. #include <Eigen/Sparse>
  12. #include <iostream>
  13. #include <cstdio>
  14. igl::BBWData::BBWData():
  15. partition_unity(false),
  16. qp_solver(QP_SOLVER_IGL_ACTIVE_SET)
  17. {}
  18. void igl::BBWData::print()
  19. {
  20. using namespace std;
  21. cout<<"partition_unity: "<<partition_unity<<endl;
  22. cout<<"W0=["<<endl<<W0<<endl<<"];"<<endl;
  23. cout<<"qp_solver: "<<QPSolverNames[qp_solver]<<endl;
  24. }
  25. template <
  26. typename DerivedV,
  27. typename DerivedEle,
  28. typename Derivedb,
  29. typename Derivedbc,
  30. typename DerivedW>
  31. IGL_INLINE bool igl::bbw(
  32. const Eigen::PlainObjectBase<DerivedV> & V,
  33. const Eigen::PlainObjectBase<DerivedEle> & Ele,
  34. const Eigen::PlainObjectBase<Derivedb> & b,
  35. const Eigen::PlainObjectBase<Derivedbc> & bc,
  36. igl::BBWData & data,
  37. Eigen::PlainObjectBase<DerivedW> & W
  38. )
  39. {
  40. using namespace igl;
  41. using namespace std;
  42. using namespace Eigen;
  43. // number of domain vertices
  44. int n = V.rows();
  45. // number of handles
  46. int m = bc.cols();
  47. SparseMatrix<typename DerivedW::Scalar> L;
  48. cotmatrix(V,Ele,L);
  49. MassMatrixType mmtype = MASSMATRIX_VORONOI;
  50. if(Ele.cols() == 4)
  51. {
  52. mmtype = MASSMATRIX_BARYCENTRIC;
  53. }
  54. SparseMatrix<typename DerivedW::Scalar> M;
  55. SparseMatrix<typename DerivedW::Scalar> Mi;
  56. massmatrix(V,Ele,mmtype,M);
  57. invert_diag(M,Mi);
  58. // Biharmonic operator
  59. SparseMatrix<typename DerivedW::Scalar> Q = L.transpose() * Mi * L;
  60. W.derived().resize(n,m);
  61. if(data.partition_unity)
  62. {
  63. // Not yet implemented
  64. assert(false);
  65. }else
  66. {
  67. // No linear terms
  68. VectorXd c = VectorXd::Zero(n);
  69. // No linear constraints
  70. SparseMatrix<typename DerivedW::Scalar> A(0,n),Aeq(0,n),Aieq(0,n);
  71. VectorXd uc(0,1),Beq(0,1),Bieq(0,1),lc(0,1);
  72. // Upper and lower box constraints (Constant bounds)
  73. VectorXd ux = VectorXd::Ones(n);
  74. VectorXd lx = VectorXd::Zero(n);
  75. // Loop over handles
  76. for(int i = 0;i<m;i++)
  77. {
  78. verbose("\n^%s: Computing weight for handle %d out of %d.\n\n",
  79. __FUNCTION__,i+1,m);
  80. VectorXd bci = bc.col(i);
  81. VectorXd Wi;
  82. switch(data.qp_solver)
  83. {
  84. case QP_SOLVER_IGL_ACTIVE_SET:
  85. {
  86. SolverStatus ret = active_set(
  87. Q,c,b,bci,Aeq,Beq,Aieq,Bieq,lx,ux,data.active_set_params,Wi);
  88. switch(ret)
  89. {
  90. case SOLVER_STATUS_CONVERGED:
  91. break;
  92. case SOLVER_STATUS_MAX_ITER:
  93. cout<<"active_set: max iter without convergence."<<endl;
  94. break;
  95. case SOLVER_STATUS_ERROR:
  96. default:
  97. cout<<"active_set error."<<endl;
  98. return false;
  99. }
  100. break;
  101. }
  102. case QP_SOLVER_MOSEK:
  103. {
  104. // impose boundary conditions via bounds
  105. slice_into(bci,b,ux);
  106. slice_into(bci,b,lx);
  107. bool r = mosek_quadprog(Q,c,0,A,lc,uc,lx,ux,data.mosek_data,Wi);
  108. if(!r)
  109. {
  110. return false;
  111. }
  112. break;
  113. }
  114. default:
  115. {
  116. assert(false && "Unknown qp_solver");
  117. return false;
  118. }
  119. }
  120. W.col(i) = Wi;
  121. }
  122. // Need to normalize
  123. igl::normalize_row_sums(W,W);
  124. }
  125. return true;
  126. }
  127. #ifndef IGL_HEADER_ONLY
  128. // Explicit template specialization
  129. template bool igl::bbw<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<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -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<double, -1, -1, 0, -1, -1> > const&, igl::BBWData&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  130. #endif