mapping_energy_with_jacobians.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2018 Zhongshi Jiang <[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. #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. default: assert(false);
  65. }
  66. }
  67. }
  68. else
  69. {
  70. Eigen::Matrix<double, 3, 3> ji;
  71. for (int i = 0; i < Ji.rows(); i++)
  72. {
  73. ji(0, 0) = Ji(i, 0);
  74. ji(0, 1) = Ji(i, 1);
  75. ji(0, 2) = Ji(i, 2);
  76. ji(1, 0) = Ji(i, 3);
  77. ji(1, 1) = Ji(i, 4);
  78. ji(1, 2) = Ji(i, 5);
  79. ji(2, 0) = Ji(i, 6);
  80. ji(2, 1) = Ji(i, 7);
  81. ji(2, 2) = Ji(i, 8);
  82. typedef Eigen::Matrix<double, 3, 3> Mat3;
  83. typedef Eigen::Matrix<double, 3, 1> Vec3;
  84. Mat3 ri, ti, ui, vi;
  85. Vec3 sing;
  86. igl::polar_svd(ji, ri, ti, ui, sing, vi);
  87. double s1 = sing(0);
  88. double s2 = sing(1);
  89. double s3 = sing(2);
  90. switch (slim_energy)
  91. {
  92. case igl::MappingEnergyType::ARAP:
  93. {
  94. energy += areas(i) * (pow(s1 - 1, 2) + pow(s2 - 1, 2) + pow(s3 - 1, 2));
  95. break;
  96. }
  97. case igl::MappingEnergyType::SYMMETRIC_DIRICHLET:
  98. {
  99. energy += areas(i) * (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2));
  100. break;
  101. }
  102. case igl::MappingEnergyType::EXP_SYMMETRIC_DIRICHLET:
  103. {
  104. energy += areas(i) * exp(exp_factor *
  105. (pow(s1, 2) + pow(s1, -2) + pow(s2, 2) + pow(s2, -2) + pow(s3, 2) + pow(s3, -2)));
  106. break;
  107. }
  108. case igl::MappingEnergyType::LOG_ARAP:
  109. {
  110. energy += areas(i) * (pow(log(s1), 2) + pow(log(std::abs(s2)), 2) + pow(log(std::abs(s3)), 2));
  111. break;
  112. }
  113. case igl::MappingEnergyType::CONFORMAL:
  114. {
  115. energy += areas(i) * ((pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
  116. break;
  117. }
  118. case igl::MappingEnergyType::EXP_CONFORMAL:
  119. {
  120. energy += areas(i) * exp(exp_factor * (pow(s1, 2) + pow(s2, 2) + pow(s3, 2)) / (3 * pow(s1 * s2 * s3, 2. / 3.)));
  121. break;
  122. }
  123. default: assert(false);
  124. }
  125. }
  126. }
  127. return energy;
  128. }
  129. #ifdef IGL_STATIC_LIBRARY
  130. // Explicit template instantiation
  131. #endif