#include "orient_outward_ao.h" #include "per_face_normals.h" #include "barycenter.h" #include "doublearea.h" #include "matlab_format.h" #include "embree/ambient_occlusion.h" #include #include template < typename DerivedV, typename DerivedF, typename DerivedC, typename DerivedFF, typename DerivedI> IGL_INLINE void igl::orient_outward_ao( const Eigen::PlainObjectBase & V, const Eigen::PlainObjectBase & F, const Eigen::PlainObjectBase & C, const igl::EmbreeIntersector & ei, const int num_samples, Eigen::PlainObjectBase & FF, Eigen::PlainObjectBase & I) { using namespace Eigen; using namespace std; assert(C.rows() == F.rows()); assert(F.cols() == 3); assert(V.cols() == 3); // number of faces const int m = F.rows(); // number of patches const int num_cc = C.maxCoeff()+1; I.resize(num_cc); if(&FF != &F) { FF = F; } PlainObjectBase N; Matrix A; per_face_normals(V,F,N); doublearea(V,F,A); double minarea = A.minCoeff(); mt19937 engine; engine.seed(time(0)); vector ddist_probability(m); for (int f = 0; f < m; ++f) ddist_probability[f] = static_cast(A(f) * 100. / minarea); discrete_distribution ddist(dist_probability.begin(), dist_probability.end()); uniform_real_distribution rdist; VectorXi face_occluded_front(m, 0); VectorXi face_occluded_back (m, 0); #pragma omp parallel for for (int i = 0; i < num_samples; ++i) { int f = dist(engine); // select face with probability proportional to face area double t0 = rdist(engine); double t1 = rdist(engine); double t2 = rdist(engine); double t_sum = t0 + t1 + t2; t0 /= t_sum; t1 /= t_sum; t2 /= t_sum; RowVector3d p = t0 * V.row(F(f,0)) + t1 * V.row(F(f,1)) + t1 * V.row(F(f,2)); RowVector3d n = N.row(f); bool is_backside = rdist(engine) < 0.5; if (is_backside) n *= -1; Matrix S; ambient_occlusion(ei, p, n, 1, S); } // take area weighted average for(int c = 0;c, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif