mapping_energy_with_jacobians.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2018 Zhongshi Jiang <jiangzs@nyu.edu>
  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 "mapping_energy_with_jacobians.h"
  9. #include "polar_svd.h"
  10. IGL_INLINE double igl::mapping_energy_with_jacobians(
  11. const Eigen::MatrixXd &Ji,
  12. const Eigen::VectorXd &areas,
  13. igl::MappingEnergyType slim_energy,
  14. double exp_factor){
  15. double energy = 0;
  16. if (Ji.cols() == 4)
  17. {
  18. Eigen::Matrix<double, 2, 2> ji;
  19. for (int i = 0; i < Ji.rows(); i++)
  20. {
  21. ji(0, 0) = Ji(i, 0);
  22. ji(0, 1) = Ji(i, 1);
  23. ji(1, 0) = Ji(i, 2);
  24. ji(1, 1) = Ji(i, 3);
  25. typedef Eigen::Matrix<double, 2, 2> Mat2;
  26. typedef Eigen::Matrix<double, 2, 1> Vec2;
  27. Mat2 ri, ti, ui, vi;
  28. Vec2 sing;
  29. igl::polar_svd(ji, ri, ti, ui, sing, vi);
  30. double s1 = sing(0);
  31. double s2 = sing(1);
  32. switch (slim_energy)
  33. {
  34. case igl::MappingEnergyType::ARAP:
  35. {
  36. energy += areas(i) * (pow(s1 - 1, 2) + pow(s2 - 1, 2));
  37. break;
  38. }
  39. case igl::MappingEnergyType::SYMMETRIC_DIRICHLET:
  40. {
  41. energy += areas(i) * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2));
  42. break;
  43. }
  44. case igl::MappingEnergyType::EXP_SYMMETRIC_DIRICHLET:
  45. {
  46. energy += areas(i) * exp(exp_factor * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2)));
  47. break;
  48. }
  49. case igl::MappingEnergyType::LOG_ARAP:
  50. {
  51. energy += areas(i) * (pow(log(s1), 2) + pow(log(s2), 2));
  52. break;
  53. }
  54. case igl::MappingEnergyType::CONFORMAL:
  55. {
  56. energy += areas(i) * ((pow(s1, 2) + pow(s2, 2)) / (2 * s1 * s2));
  57. break;
  58. }
  59. case igl::MappingEnergyType::EXP_CONFORMAL:
  60. {
  61. energy += areas(i) * exp(exp_factor * ((pow(s1, 2) + pow(s2, 2)) / (2 * s1 * s2)));
  62. break;
  63. }
  64. }
  65. }
  66. }
  67. else
  68. {
  69. Eigen::Matrix<double, 3, 3> ji;
  70. for (int i = 0; i < Ji.rows(); i++)
  71. {
  72. ji(0, 0) = Ji(i, 0);
  73. ji(0, 1) = Ji(i, 1);
  74. ji(0, 2) = Ji(i, 2);
  75. ji(1, 0) = Ji(i, 3);
  76. ji(1, 1) = Ji(i, 4);
  77. ji(1, 2) = Ji(i, 5);
  78. ji(2, 0) = Ji(i, 6);
  79. ji(2, 1) = Ji(i, 7);
  80. ji(2, 2) = Ji(i, 8);
  81. typedef Eigen::Matrix<double, 3, 3> Mat3;
  82. typedef Eigen::Matrix<double, 3, 1> Vec3;
  83. Mat3 ri, ti, ui, vi;
  84. Vec3 sing;
  85. igl::polar_svd(ji, ri, ti, ui, sing, vi);
  86. double s1 = sing(0);
  87. double s2 = sing(1);
  88. double s3 = sing(2);
  89. switch (slim_energy)
  90. {
  91. case igl::MappingEnergyType::ARAP:
  92. {
  93. energy += areas(i) * (pow(s1 - 1, 2) + pow(s2 - 1, 2) + pow(s3 - 1, 2));
  94. break;
  95. }
  96. case igl::MappingEnergyType::SYMMETRIC_DIRICHLET:
  97. {
  98. energy += areas(i) * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2));
  99. break;
  100. }
  101. case igl::MappingEnergyType::EXP_SYMMETRIC_DIRICHLET:
  102. {
  103. energy += areas(i) * exp(exp_factor *
  104. (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2)));
  105. break;
  106. }
  107. case igl::MappingEnergyType::LOG_ARAP:
  108. {
  109. energy += areas(i) * (pow(log(s1), 2) + pow(log(std::abs(s2)), 2) + pow(log(std::abs(s3)), 2));
  110. break;
  111. }
  112. case igl::MappingEnergyType::CONFORMAL:
  113. {
  114. energy += areas(i) * ((pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
  115. break;
  116. }
  117. case igl::MappingEnergyType::EXP_CONFORMAL:
  118. {
  119. energy += areas(i) * exp((pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
  120. break;
  121. }
  122. }
  123. }
  124. }
  125. return energy;
  126. }
  127. #ifdef IGL_STATIC_LIBRARY
  128. // Explicit template instantiation
  129. #endif