volume.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <[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 "volume.h"
  9. #include "cross.h"
  10. #include <Eigen/Geometry>
  11. template <
  12. typename DerivedV,
  13. typename DerivedT,
  14. typename Derivedvol>
  15. IGL_INLINE void igl::volume(
  16. const Eigen::MatrixBase<DerivedV>& V,
  17. const Eigen::MatrixBase<DerivedT>& T,
  18. Eigen::PlainObjectBase<Derivedvol>& vol)
  19. {
  20. const int m = T.rows();
  21. vol.resize(m,1);
  22. for(int t = 0;t<m;t++)
  23. {
  24. typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
  25. const RowVector3S & a = V.row(T(t,0));
  26. const RowVector3S & b = V.row(T(t,1));
  27. const RowVector3S & c = V.row(T(t,2));
  28. const RowVector3S & d = V.row(T(t,3));
  29. vol(t) = -(a-d).dot((b-d).cross(c-d))/6.;
  30. }
  31. }
  32. template <
  33. typename DerivedA,
  34. typename DerivedB,
  35. typename DerivedC,
  36. typename DerivedD,
  37. typename Derivedvol>
  38. IGL_INLINE void igl::volume(
  39. const Eigen::MatrixBase<DerivedA> & A,
  40. const Eigen::MatrixBase<DerivedB> & B,
  41. const Eigen::MatrixBase<DerivedC> & C,
  42. const Eigen::MatrixBase<DerivedD> & D,
  43. Eigen::PlainObjectBase<Derivedvol> & vol)
  44. {
  45. const auto & AmD = A-D;
  46. const auto & BmD = B-D;
  47. const auto & CmD = C-D;
  48. Eigen::Matrix<typename Derivedvol::Scalar,Eigen::Dynamic,3> BmDxCmD;
  49. cross(BmD.eval(),CmD.eval(),BmDxCmD);
  50. const auto & AmDdx = (AmD.array() * BmDxCmD.array()).rowwise().sum();
  51. vol = -AmDdx/6.;
  52. }
  53. template <
  54. typename VecA,
  55. typename VecB,
  56. typename VecC,
  57. typename VecD>
  58. IGL_INLINE typename VecA::Scalar igl::volume_single(
  59. const VecA & a,
  60. const VecB & b,
  61. const VecC & c,
  62. const VecD & d)
  63. {
  64. return -(a-d).dot((b-d).cross(c-d))/6.;
  65. }
  66. template <
  67. typename DerivedL,
  68. typename Derivedvol>
  69. IGL_INLINE void igl::volume(
  70. const Eigen::MatrixBase<DerivedL>& L,
  71. Eigen::PlainObjectBase<Derivedvol>& vol)
  72. {
  73. const int m = L.rows();
  74. typedef typename Derivedvol::Scalar ScalarS;
  75. vol.resize(m,1);
  76. for(int t = 0;t<m;t++)
  77. {
  78. const ScalarS u = L(t,0);
  79. const ScalarS v = L(t,1);
  80. const ScalarS w = L(t,2);
  81. const ScalarS U = L(t,3);
  82. const ScalarS V = L(t,4);
  83. const ScalarS W = L(t,5);
  84. const ScalarS X = (w - U + v)*(U + v + w);
  85. const ScalarS x = (U - v + w)*(v - w + U);
  86. const ScalarS Y = (u - V + w)*(V + w + u);
  87. const ScalarS y = (V - w + u)*(w - u + V);
  88. const ScalarS Z = (v - W + u)*(W + u + v);
  89. const ScalarS z = (W - u + v)*(u - v + W);
  90. const ScalarS a = sqrt(x*Y*Z);
  91. const ScalarS b = sqrt(y*Z*X);
  92. const ScalarS c = sqrt(z*X*Y);
  93. const ScalarS d = sqrt(x*y*z);
  94. vol(t) = sqrt(
  95. (-a + b + c + d)*
  96. ( a - b + c + d)*
  97. ( a + b - c + d)*
  98. ( a + b + c - d))/
  99. (192.*u*v*w);
  100. }
  101. }
  102. #ifdef IGL_STATIC_LIBRARY
  103. // Explicit template instantiation
  104. // generated by autoexplicit.sh
  105. template void igl::volume<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  106. // Nonsense template
  107. namespace igl{ template<> void volume<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&){} }
  108. // generated by autoexplicit.sh
  109. template void igl::volume<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<unsigned int, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  110. // generated by autoexplicit.sh
  111. template void igl::volume<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  112. // generated by autoexplicit.sh
  113. template void igl::volume<Eigen::Matrix<double, -1, 6, 0, -1, 6>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 6, 0, -1, 6> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  114. // generated by autoexplicit.sh
  115. template void igl::volume<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  116. template Eigen::Matrix<double, 1, 3, 1, 1, 3>::Scalar igl::volume_single<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3> const&);
  117. template void igl::volume<Eigen::Matrix<double,-1,3,0,-1,3>,Eigen::Matrix<int,-1,3,0,-1,3>,Eigen::Matrix<double,-1,1,0,-1,1> >(Eigen::MatrixBase<Eigen::Matrix<double,-1,3,0,-1,3> > const &,Eigen::MatrixBase<Eigen::Matrix<int,-1,3,0,-1,3> > const &,Eigen::PlainObjectBase<Eigen::Matrix<double,-1,1,0,-1,1> > &);
  118. template void igl::volume<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<double, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  119. template void igl::volume<class Eigen::Matrix<double, -1, -1, 1, -1, -1>,class Eigen::Matrix<int, -1, -1, 0, -1, -1>,class Eigen::Matrix<double, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, -1, 1, -1, -1> > const &,class Eigen::MatrixBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &,class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1> > &);
  120. template void igl::volume<class Eigen::Matrix<double, -1, 3, 0, -1, 3>, class Eigen::Matrix<int, -1, 4, 0, -1, 4>, class Eigen::Matrix<double, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, 4, 0, -1, 4> > const&, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  121. template void igl::volume<class Eigen::Matrix<double, -1, 3, 1, -1, 3>, class Eigen::Matrix<int, -1, 3, 1, -1, 3>, class Eigen::Matrix<double, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, class Eigen::MatrixBase<class Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, class Eigen::PlainObjectBase<class Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  122. #endif