shapeup.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2017 Amir Vaxman <[email protected]>
  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. #ifndef IGL_SHAPEUP_H
  9. #define IGL_SHAPEUP_H
  10. #include "min_quad_with_fixed.h"
  11. #include "igl_inline.h"
  12. #include "setdiff.h"
  13. #include "cat.h"
  14. #include <Eigen/Core>
  15. #include <vector>
  16. #include "PI.h"
  17. //This file implements the following algorithm:
  18. //Bouaziz et al.
  19. //Shape-Up: Shaping Discrete Geometry with Projections
  20. //Computer Graphics Forum (Proc. SGP) 31(5), 2012
  21. namespace igl
  22. {
  23. /// Parameters and precomputed data for ShapeUp
  24. ///
  25. /// \fileinfo
  26. struct ShapeupData{
  27. //input data
  28. Eigen::MatrixXd P;
  29. Eigen::VectorXi SC;
  30. Eigen::MatrixXi S;
  31. Eigen::VectorXi b;
  32. int maxIterations; //referring to number of local-global pairs.
  33. double pTolerance; //algorithm stops when max(|P_k-P_{k-1}|)<pTolerance.
  34. double shapeCoeff, closeCoeff, smoothCoeff;
  35. //Internally-used matrices
  36. Eigen::SparseMatrix<double> DShape, DClose, DSmooth, Q, A, At, W;
  37. min_quad_with_fixed_data<double> solver_data;
  38. ShapeupData():
  39. maxIterations(50),
  40. pTolerance(10e-6),
  41. shapeCoeff(1.0),
  42. closeCoeff(100.0),
  43. smoothCoeff(0.0){}
  44. };
  45. // Alec: I'm not sure why these are using PlainObjectBase but then not
  46. // templating.
  47. /// Every function here defines a local projection for ShapeUp, and must have
  48. /// the following structure to qualify:
  49. ///
  50. /// @param[in] P #P by 3 set of points, either the initial solution, or from
  51. /// previous iteration.
  52. /// @param[in] SC #Set by 1 cardinalities of sets in S
  53. /// @param[in] S #Sets by max(SC) independent sets where the local projection
  54. /// applies. Values beyond column SC(i)-1 in row S(i,:) are "don't care"
  55. /// @param[out] projP #S by 3*max(SC) in format xyzxyzxyz, where the
  56. /// projected points correspond to each set in S in the same order.
  57. /// @return Return value appears to be ignored
  58. ///
  59. /// \fileinfo
  60. //typedef std::function<
  61. // bool(
  62. // const Eigen::PlainObjectBase<Eigen::MatrixXd>&,
  63. // const Eigen::PlainObjectBase<Eigen::VectorXi>&,
  64. // const Eigen::PlainObjectBase<Eigen::MatrixXi>&,
  65. // Eigen::PlainObjectBase<Eigen::MatrixXd>&)>
  66. // shapeup_projection_function;
  67. using
  68. shapeup_projection_function
  69. =
  70. std::function<
  71. bool(
  72. const Eigen::PlainObjectBase<Eigen::MatrixXd>&,
  73. const Eigen::PlainObjectBase<Eigen::VectorXi>&,
  74. const Eigen::PlainObjectBase<Eigen::MatrixXi>&,
  75. Eigen::PlainObjectBase<Eigen::MatrixXd>&)> ;
  76. /// This projection does nothing but render points into projP. Mostly used for
  77. /// "echoing" the global step
  78. ///
  79. /// @param[in] P #P by 3 set of points, either the initial solution, or from
  80. /// previous iteration.
  81. /// @param[in] SC #Set by 1 cardinalities of sets in S
  82. /// @param[in] S #Sets by max(SC) independent sets where the local projection
  83. /// applies. Values beyond column SC(i)-1 in row S(i,:) are "don't care"
  84. /// @param[out] projP #S by 3*max(SC) in format xyzxyzxyz, where the
  85. /// projected points correspond to each set in S in the same order.
  86. /// @return Return value appears to be ignored
  87. ///
  88. /// \fileinfo
  89. IGL_INLINE bool shapeup_identity_projection(
  90. const Eigen::PlainObjectBase<Eigen::MatrixXd>& P,
  91. const Eigen::PlainObjectBase<Eigen::VectorXi>& SC,
  92. const Eigen::PlainObjectBase<Eigen::MatrixXi>& S,
  93. Eigen::PlainObjectBase<Eigen::MatrixXd>& projP);
  94. /// the projection assumes that the sets are vertices of polygons in cyclic
  95. /// order
  96. ///
  97. /// @param[in] P #P by 3 set of points, either the initial solution, or from
  98. /// previous iteration.
  99. /// @param[in] SC #Set by 1 cardinalities of sets in S
  100. /// @param[in] S #Sets by max(SC) independent sets where the local projection
  101. /// applies. Values beyond column SC(i)-1 in row S(i,:) are "don't care"
  102. /// @param[out] projP #S by 3*max(SC) in format xyzxyzxyz, where the
  103. /// projected points correspond to each set in S in the same order.
  104. /// @return Return value appears to be ignored
  105. ///
  106. /// \fileinfo
  107. IGL_INLINE bool shapeup_regular_face_projection(
  108. const Eigen::PlainObjectBase<Eigen::MatrixXd>& P,
  109. const Eigen::PlainObjectBase<Eigen::VectorXi>& SC,
  110. const Eigen::PlainObjectBase<Eigen::MatrixXi>& S,
  111. Eigen::PlainObjectBase<Eigen::MatrixXd>& projP);
  112. /// This function precomputation the necessary matrices for the ShapeUp
  113. /// process, and prefactorizes them.
  114. ///
  115. /// @param[in] P #P by 3 point positions
  116. /// @param[in] SC #Set by 1 cardinalities of sets in S
  117. /// @param[in] S #Sets by max(SC) independent sets where the local projection
  118. /// applies. Values beyond column SC(i)-1 in row S(i,:) are "don't care"
  119. /// @param[in] E #E by 2 the "edges" of the set P; used for the smoothness
  120. /// energy.
  121. /// @param[in] b #b by 1 boundary (fixed) vertices from P.
  122. /// @param[in] wShape #Set by 1
  123. /// @param[in] wSmooth #b by 1 weights for constraints from S and positional
  124. /// constraints (used in the global step)
  125. /// @param[out] sudata struct ShapeupData the data necessary to solve the
  126. /// system in shapeup_solve
  127. /// @return true if precomputation was successful, false otherwise
  128. ///
  129. /// \fileinfo
  130. template <
  131. typename DerivedP,
  132. typename DerivedSC,
  133. typename DerivedS,
  134. typename Derivedw>
  135. IGL_INLINE bool shapeup_precomputation(
  136. const Eigen::PlainObjectBase<DerivedP>& P,
  137. const Eigen::PlainObjectBase<DerivedSC>& SC,
  138. const Eigen::PlainObjectBase<DerivedS>& S,
  139. const Eigen::PlainObjectBase<DerivedS>& E,
  140. const Eigen::PlainObjectBase<DerivedSC>& b,
  141. const Eigen::PlainObjectBase<Derivedw>& wShape,
  142. const Eigen::PlainObjectBase<Derivedw>& wSmooth,
  143. ShapeupData & sudata);
  144. /// This function solve the shapeup project optimization. shapeup_precompute
  145. /// must be called before with the same sudata, or results are unpredictable
  146. ///
  147. /// @param[in] bc #b by 3 fixed point values corresonding to "b" in sudata
  148. /// @param[in] local_projection function pointer taking (P,SC,S,projP),
  149. /// where the first three parameters are as defined, and "projP" is the output, as a #S by 3*max(SC) function in format xyzxyzxyz, and where it returns the projected points corresponding to each set in S in the same order.
  150. /// NOTE: the input values in P0 don't need to correspond to prescribed values in bc; the iterations will project them automatically (by design).
  151. /// @param[in] P0 #P by 3 initial solution (point positions)
  152. /// @param[in] sudata the ShapeUpData structure computed in shapeup_precomputation()
  153. /// @param[in] quietIterations flagging if to output iteration information.
  154. /// @param[out] P the solution to the problem, indices corresponding to P0.
  155. /// @returns true if the solver converged, false otherwise.
  156. ///
  157. /// \fileinfo
  158. template <
  159. typename DerivedP,
  160. typename DerivedSC,
  161. typename DerivedS>
  162. IGL_INLINE bool shapeup_solve(
  163. const Eigen::PlainObjectBase<DerivedP>& bc,
  164. const std::function<bool(const Eigen::PlainObjectBase<DerivedP>&, const Eigen::PlainObjectBase<DerivedSC>&, const Eigen::PlainObjectBase<DerivedS>&, Eigen::PlainObjectBase<DerivedP>&)>& local_projection,
  165. const Eigen::PlainObjectBase<DerivedP>& P0,
  166. const ShapeupData & sudata,
  167. const bool quietIterations,
  168. Eigen::PlainObjectBase<DerivedP>& P);
  169. }
  170. #ifndef IGL_STATIC_LIBRARY
  171. #include "shapeup.cpp"
  172. #endif
  173. #endif