bbw.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 "bbw.h"
  9. #include "mosek_quadprog.h"
  10. #include "../harmonic.h"
  11. #include "../slice_into.h"
  12. #include <Eigen/Sparse>
  13. #include <iostream>
  14. #include <cstdio>
  15. template <
  16. typename DerivedV,
  17. typename DerivedEle,
  18. typename Derivedb,
  19. typename Derivedbc,
  20. typename DerivedW>
  21. IGL_INLINE bool igl::mosek::bbw(
  22. const Eigen::PlainObjectBase<DerivedV> & V,
  23. const Eigen::PlainObjectBase<DerivedEle> & Ele,
  24. const Eigen::PlainObjectBase<Derivedb> & b,
  25. const Eigen::PlainObjectBase<Derivedbc> & bc,
  26. igl::BBWData & data,
  27. igl::mosek::MosekData & mosek_data,
  28. Eigen::PlainObjectBase<DerivedW> & W
  29. )
  30. {
  31. using namespace std;
  32. using namespace Eigen;
  33. assert(!data.partition_unity && "partition_unity not implemented yet");
  34. // number of domain vertices
  35. int n = V.rows();
  36. // number of handles
  37. int m = bc.cols();
  38. // Build biharmonic operator
  39. Eigen::SparseMatrix<typename DerivedV::Scalar> Q;
  40. harmonic(V,Ele,2,Q);
  41. W.derived().resize(n,m);
  42. // No linear terms
  43. VectorXd c = VectorXd::Zero(n);
  44. // No linear constraints
  45. SparseMatrix<typename DerivedW::Scalar> A(0,n);
  46. VectorXd uc(0,1),lc(0,1);
  47. // Upper and lower box constraints (Constant bounds)
  48. VectorXd ux = VectorXd::Ones(n);
  49. VectorXd lx = VectorXd::Zero(n);
  50. // Loop over handles
  51. for(int i = 0;i<m;i++)
  52. {
  53. if(data.verbosity >= 1)
  54. {
  55. cout<<"BBW: Computing weight for handle "<<i+1<<" out of "<<m<<
  56. "."<<endl;
  57. }
  58. VectorXd bci = bc.col(i);
  59. VectorXd Wi;
  60. // impose boundary conditions via bounds
  61. slice_into(bci,b,ux);
  62. slice_into(bci,b,lx);
  63. bool r = mosek_quadprog(Q,c,0,A,lc,uc,lx,ux,mosek_data,Wi);
  64. if(!r)
  65. {
  66. return false;
  67. }
  68. W.col(i) = Wi;
  69. }
  70. #ifndef NDEBUG
  71. const double min_rowsum = W.rowwise().sum().array().abs().minCoeff();
  72. if(min_rowsum < 0.1)
  73. {
  74. cerr<<"bbw.cpp: Warning, minimum row sum is very low. Consider more "
  75. "active set iterations or enforcing partition of unity."<<endl;
  76. }
  77. #endif
  78. return true;
  79. }
  80. #ifdef IGL_STATIC_LIBRARY
  81. // Explicit template instantiation
  82. template bool igl::mosek::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&, igl::mosek::MosekData&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  83. #endif