// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "random_points_on_mesh.h" #include "doublearea.h" #include "cumsum.h" #include "histc.h" #include #include template IGL_INLINE void igl::random_points_on_mesh( const int n, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, Eigen::PlainObjectBase & B, Eigen::PlainObjectBase & FI) { using namespace Eigen; using namespace std; typedef typename DerivedV::Scalar Scalar; typedef Matrix VectorXs; VectorXs A; doublearea(V,F,A); // Should be traingle mesh. Although Turk's method 1 generalizes... assert(F.cols() == 3); VectorXs C; VectorXs A0(A.size()+1); A0(0) = 0; A0.bottomRightCorner(A.size(),1) = A; // Even faster would be to use the "Alias Table Method" cumsum(A0,1,C); const Scalar Cmax = C(C.size()-1); assert(Cmax > 0 && "Total surface area should be positive"); // Why is this more accurate than `C /= C(C.size()-1)` ? for(int i = 0;i= 0); assert(R.maxCoeff() <= 1); histc(R,C,FI); FI = FI.array().min(F.rows() - 1); // fix the bin when R(i) == 1 exactly const VectorXs S = (VectorXs::Random(n,1).array() + 1.)/2.; const VectorXs T = (VectorXs::Random(n,1).array() + 1.)/2.; B.resize(n,3); B.col(0) = 1.-T.array().sqrt(); B.col(1) = (1.-S.array()) * T.array().sqrt(); B.col(2) = S.array() * T.array().sqrt(); } template < typename DerivedV, typename DerivedF, typename DerivedB, typename DerivedFI, typename DerivedX> IGL_INLINE void igl::random_points_on_mesh( const int n, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, Eigen::PlainObjectBase & B, Eigen::PlainObjectBase & FI, Eigen::PlainObjectBase & X) { random_points_on_mesh(n,V,F,B,FI); X = DerivedX::Zero(B.rows(),V.cols()); for(int x = 0;x IGL_INLINE void igl::random_points_on_mesh( const int n, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, Eigen::SparseMatrix & B, Eigen::PlainObjectBase & FI) { using namespace Eigen; using namespace std; Matrix BC; random_points_on_mesh(n,V,F,BC,FI); vector > BIJV; BIJV.reserve(n*3); for(int s = 0;s= 0); const int v = F(FI(s),c); BIJV.push_back(Triplet(s,v,BC(s,c))); } } B.resize(n,V.rows()); B.reserve(n*3); B.setFromTriplets(BIJV.begin(),BIJV.end()); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::random_points_on_mesh, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::random_points_on_mesh, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::random_points_on_mesh, Eigen::Matrix, float, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&, Eigen::PlainObjectBase >&); template void igl::random_points_on_mesh, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::random_points_on_mesh, Eigen::Matrix, double, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&, Eigen::PlainObjectBase >&); template void igl::random_points_on_mesh, Eigen::Matrix, double, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&, Eigen::PlainObjectBase >&); #endif