readBF.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <alecjacobson@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. #include "readBF.h"
  9. #include "list_to_matrix.h"
  10. #include <vector>
  11. #include <cstdio>
  12. #include <fstream>
  13. #include <cassert>
  14. #include <functional>
  15. template <
  16. typename DerivedWI,
  17. typename DerivedP,
  18. typename DerivedO>
  19. IGL_INLINE bool igl::readBF(
  20. const std::string & filename,
  21. Eigen::PlainObjectBase<DerivedWI> & WI,
  22. Eigen::PlainObjectBase<DerivedP> & P,
  23. Eigen::PlainObjectBase<DerivedO> & O)
  24. {
  25. using namespace std;
  26. ifstream is(filename);
  27. if(!is.is_open())
  28. {
  29. return false;
  30. }
  31. string line;
  32. std::vector<typename DerivedWI::Scalar> vWI;
  33. std::vector<typename DerivedP::Scalar> vP;
  34. std::vector<std::vector<typename DerivedO::Scalar> > vO;
  35. while(getline(is, line))
  36. {
  37. int wi,p;
  38. double cx,cy,cz;
  39. if(sscanf(line.c_str(), "%d %d %lg %lg %lg",&wi,&p,&cx,&cy,&cz) != 5)
  40. {
  41. return false;
  42. }
  43. vWI.push_back(wi);
  44. vP.push_back(p);
  45. vO.push_back({cx,cy,cz});
  46. }
  47. list_to_matrix(vWI,WI);
  48. list_to_matrix(vP,P);
  49. list_to_matrix(vO,O);
  50. return true;
  51. }
  52. template <
  53. typename DerivedWI,
  54. typename DerivedbfP,
  55. typename DerivedO,
  56. typename DerivedC,
  57. typename DerivedBE,
  58. typename DerivedP>
  59. IGL_INLINE bool igl::readBF(
  60. const std::string & filename,
  61. Eigen::PlainObjectBase<DerivedWI> & WI,
  62. Eigen::PlainObjectBase<DerivedbfP> & bfP,
  63. Eigen::PlainObjectBase<DerivedO> & offsets,
  64. Eigen::PlainObjectBase<DerivedC> & C,
  65. Eigen::PlainObjectBase<DerivedBE> & BE,
  66. Eigen::PlainObjectBase<DerivedP> & P)
  67. {
  68. using namespace Eigen;
  69. using namespace std;
  70. if(!readBF(filename,WI,bfP,offsets))
  71. {
  72. return false;
  73. }
  74. C.resize(WI.rows(),3);
  75. vector<bool> computed(C.rows(),false);
  76. // better not be cycles in bfP
  77. std::function<Eigen::RowVector3d(const int)> locate_tip;
  78. locate_tip =
  79. [&offsets,&computed,&bfP,&locate_tip,&C](const int w)->Eigen::RowVector3d
  80. {
  81. if(w<0) return Eigen::RowVector3d(0,0,0);
  82. if(computed[w]) return C.row(w);
  83. computed[w] = true;
  84. return C.row(w) = locate_tip(bfP(w)) + offsets.row(w);
  85. };
  86. int num_roots = (bfP.array() == -1).count();
  87. BE.resize(WI.rows()-num_roots,2);
  88. P.resize(BE.rows());
  89. for(int c = 0;c<C.rows();c++)
  90. {
  91. locate_tip(c);
  92. assert(c>=0);
  93. // weight associated with this bone
  94. const int wi = WI(c);
  95. if(wi >= 0)
  96. {
  97. // index into C
  98. const int p = bfP(c);
  99. assert(p >= 0 && "No weights for roots allowed");
  100. // index into BE
  101. const int pwi = WI(p);
  102. P(wi) = pwi;
  103. BE(wi,0) = p;
  104. BE(wi,1) = c;
  105. }
  106. }
  107. return true;
  108. }
  109. #ifdef IGL_STATIC_LIBRARY
  110. template bool igl::readBF<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  111. #endif