random_points_on_mesh.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "random_points_on_mesh.h"
  9. #include "doublearea.h"
  10. #include "cumsum.h"
  11. #include "histc.h"
  12. #include <iostream>
  13. #include <cassert>
  14. template <typename DerivedV, typename DerivedF, typename DerivedB, typename DerivedFI>
  15. IGL_INLINE void igl::random_points_on_mesh(
  16. const int n,
  17. const Eigen::PlainObjectBase<DerivedV > & V,
  18. const Eigen::PlainObjectBase<DerivedF > & F,
  19. Eigen::PlainObjectBase<DerivedB > & B,
  20. Eigen::PlainObjectBase<DerivedFI > & FI)
  21. {
  22. using namespace Eigen;
  23. using namespace std;
  24. typedef typename DerivedV::Scalar Scalar;
  25. typedef Matrix<Scalar,Dynamic,1> VectorXs;
  26. VectorXs A;
  27. doublearea(V,F,A);
  28. A /= A.array().sum();
  29. // Should be traingle mesh. Although Turk's method 1 generalizes...
  30. assert(F.cols() == 3);
  31. VectorXs C;
  32. VectorXs A0(A.size()+1);
  33. A0(0) = 0;
  34. A0.bottomRightCorner(A.size(),1) = A;
  35. // Even faster would be to use the "Alias Table Method"
  36. cumsum(A0,1,C);
  37. const VectorXs R = (VectorXs::Random(n,1).array() + 1.)/2.;
  38. assert(R.minCoeff() >= 0);
  39. assert(R.maxCoeff() <= 1);
  40. histc(R,C,FI);
  41. const VectorXs S = (VectorXs::Random(n,1).array() + 1.)/2.;
  42. const VectorXs T = (VectorXs::Random(n,1).array() + 1.)/2.;
  43. B.resize(n,3);
  44. B.col(0) = 1.-T.array().sqrt();
  45. B.col(1) = (1.-S.array()) * T.array().sqrt();
  46. B.col(2) = S.array() * T.array().sqrt();
  47. }
  48. template <typename DerivedV, typename DerivedF, typename ScalarB, typename DerivedFI>
  49. IGL_INLINE void igl::random_points_on_mesh(
  50. const int n,
  51. const Eigen::PlainObjectBase<DerivedV > & V,
  52. const Eigen::PlainObjectBase<DerivedF > & F,
  53. Eigen::SparseMatrix<ScalarB > & B,
  54. Eigen::PlainObjectBase<DerivedFI > & FI)
  55. {
  56. using namespace Eigen;
  57. using namespace std;
  58. Matrix<ScalarB,Dynamic,3> BC;
  59. random_points_on_mesh(n,V,F,BC,FI);
  60. vector<Triplet<ScalarB> > BIJV;
  61. BIJV.reserve(n*3);
  62. for(int s = 0;s<n;s++)
  63. {
  64. for(int c = 0;c<3;c++)
  65. {
  66. assert(FI(s) < F.rows());
  67. assert(FI(s) >= 0);
  68. const int v = F(FI(s),c);
  69. BIJV.push_back(Triplet<ScalarB>(s,v,BC(s,c)));
  70. }
  71. }
  72. B.resize(n,V.rows());
  73. B.reserve(n*3);
  74. B.setFromTriplets(BIJV.begin(),BIJV.end());
  75. }
  76. #ifdef IGL_STATIC_LIBRARY
  77. // Explicit template instantiation
  78. template void igl::random_points_on_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  79. template void igl::random_points_on_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::SparseMatrix<double, 0, int>&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  80. #endif