shapeup_local_projections.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2017 Amir Vaxman <avaxman@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. #ifndef IGL_SHAPEUP_LOCAL_PROJECTIONS_H
  9. #define IGL_SHAPEUP_LOCAL_PROJECTIONS_H
  10. #include <igl/igl_inline.h>
  11. #include <igl/setdiff.h>
  12. #include <igl/cat.h>
  13. #include <Eigen/Core>
  14. #include <vector>
  15. //This file implements several basic lcaol projection functions for the shapeup algorithm in shapeup.h
  16. namespace igl
  17. {
  18. //This projection does nothing but render points into projP. Mostly used for "echoing" the global step
  19. bool shapeup_identity_projection(const Eigen::MatrixXd& P, const Eigen::VectorXi& SC, const Eigen::MatrixXi& S, Eigen::MatrixXd& projP){
  20. projP.conservativeResize(SC.rows(), 3*SC.maxCoeff());
  21. for (int i=0;i<S.rows();i++){
  22. Eigen::RowVector3d avgCurrP=Eigen::RowVector3d::Zero();
  23. for (int j=0;j<sudata.SC(i);j++)
  24. avgCurrP+=currP.row(sudata.S(i,j))/(double)(sudata.SC(i));
  25. for (int j=0;j<sudata.SC(i);j++)
  26. projP.block(i,3*j,1,3)=currP.row(sudata.S(i,j))-avgCurrP;
  27. }
  28. }
  29. //the projection assumes that the sets are vertices of polygons in order
  30. IGL_INLINE void shapeup_regular_face_projection(const Eigen::MatrixXd& P, const Eigen::VectorXi& SC, const Eigen::MatrixXi& S, Eigen::MatrixXd& projP)
  31. {
  32. projP.conservativeResize(SC.rows(), 3*SC.maxCoeff());
  33. for (int currRow=0;currRow<SC.rows();currRow++){
  34. //computing average
  35. int N=SC(currRow);
  36. const Eigen::RowVectorXi SRow=S.row(currRow);
  37. Eigen::RowVector3d avgCurrP=Eigen::RowVector3d::Zero();
  38. Eigen::MatrixXd targetPos(N, 3);
  39. Eigen::MatrixXd sourcePos(N, 3);
  40. for (int j=0;j<N;j++)
  41. avgCurrP+=currP.row(SRow(j))/(double)(N);
  42. for (int j=0;j<N;j++)
  43. targetPolygon.row(j)=currP.row(SRow(j))-avgCurrP;
  44. //creating perfectly regular source polygon
  45. for (int j=0;j<N;j++)
  46. sourcePolygon.row(j)<<cos(2*M_PI*(double)j/(double(N))), sin(2*M_PI*(double)j/(double(N))),0.0;
  47. //finding closest similarity transformation between source and target
  48. Eigen::MatrixXd corrMat=sourcePolygon.transpose()*targetPolygon;
  49. Eigen::JacobiSVD<Eigen::Matrix3d> svd(corrMat, Eigen::ComputeFullU | Eigen::ComputeFullV);
  50. Eigen::MatrixXd R=svd.matrixU()*svd.matrixV().transpose();
  51. //getting scale by edge length change average. TODO: by singular values
  52. Eigen::VectorXd sourceEdgeLengths(N);
  53. Eigen::VectorXd targetEdgeLengths(N);
  54. for (int j=0;j<N;j++){
  55. sourceEdgeLengths(j)=(sourcePolygon.row((j+1)%N)-sourcePolygon.row(j)).norm();
  56. targetEdgeLengths(j)=(targetPolygon.row((j+1)%N)-targetPolygon.row(j)).norm();
  57. }
  58. double scale=(targetEdgeLengths.cwiseQuotient(sourceEdgeLengths)).mean();
  59. for (int j=0;j<N;j++)
  60. projP.block(currRow,3*j,1,3)=sourcePolygon.row(j)*R*scale;
  61. }
  62. }
  63. }
  64. #ifndef IGL_STATIC_LIBRARY
  65. #include "shapeup_local_projections.cpp"
  66. #endif
  67. #endif