// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2015 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 "ambient_occlusion.h" #include "random_dir.h" #include "ray_mesh_intersect.h" #include "EPS.h" #include "Hit.h" #include "parallel_for.h" #include #include #include template < typename DerivedP, typename DerivedN, typename DerivedS > IGL_INLINE void igl::ambient_occlusion( const std::function< bool( const Eigen::Matrix &, const Eigen::Matrix &) > & shoot_ray, const Eigen::MatrixBase & P, const Eigen::MatrixBase & N, const int num_samples, Eigen::PlainObjectBase & S) { const int n = P.rows(); // Resize output S.resize(n,1); // Embree seems to be parallel when constructing but not when tracing rays typedef typename DerivedP::Scalar Scalar; typedef Eigen::Matrix Vector3N; const Eigen::Matrix D = random_dir_stratified(num_samples).cast(); const auto & inner = [&P,&N,&num_samples,&D,&S,&shoot_ray](const int p) { const Vector3N origin = P.row(p); const Vector3N normal = N.row(p); int num_hits = 0; for(int s = 0;s IGL_INLINE void igl::ambient_occlusion( const igl::AABB & aabb, const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & P, const Eigen::MatrixBase & N, const int num_samples, Eigen::PlainObjectBase & S) { typedef typename DerivedV::Scalar Scalar; using Vector3S = Eigen::Matrix; const auto & shoot_ray = [&aabb,&V,&F]( const Eigen::Matrix & _s, const Eigen::Matrix & dir)->bool { Vector3S s = _s+1e-4*dir; igl::Hit hit; return aabb.intersect_ray( V, F, s, dir, hit); }; return ambient_occlusion(shoot_ray,P,N,num_samples,S); } template < typename DerivedV, typename DerivedF, typename DerivedP, typename DerivedN, typename DerivedS > IGL_INLINE void igl::ambient_occlusion( const Eigen::MatrixBase & V, const Eigen::MatrixBase & F, const Eigen::MatrixBase & P, const Eigen::MatrixBase & N, const int num_samples, Eigen::PlainObjectBase & S) { typedef typename DerivedV::Scalar Scalar; using Vector3S = Eigen::Matrix; if(F.rows() < 100) { // Super naive const auto & shoot_ray = [&V,&F]( const Eigen::Matrix & _s, const Eigen::Matrix & dir)->bool { Vector3S s = _s+1e-4*dir; igl::Hit hit; return ray_mesh_intersect(s,dir,V,F,hit); }; return ambient_occlusion(shoot_ray,P,N,num_samples,S); } AABB aabb; aabb.init(V,F); return ambient_occlusion(aabb,V,F,P,N,num_samples,S); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix >(std::function const&, Eigen::Matrix const&)> const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix >(std::function const&, Eigen::Matrix const&)> const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix >(std::function const&, Eigen::Matrix const&)> const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix >(std::function const&, Eigen::Matrix const&)> const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix>(std::function::Scalar, 3, 1, 0, 3, 1> const&, Eigen::Matrix::Scalar, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, int, Eigen::PlainObjectBase>&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix>(std::function::Scalar, 3, 1, 0, 3, 1> const&, Eigen::Matrix::Scalar, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, int, Eigen::PlainObjectBase>&); template void igl::ambient_occlusion, Eigen::Matrix, Eigen::Matrix>(std::function::Scalar, 3, 1, 0, 3, 1> const&, Eigen::Matrix::Scalar, 3, 1, 0, 3, 1> const&)> const&, Eigen::MatrixBase> const&, Eigen::MatrixBase> const&, int, Eigen::PlainObjectBase>&); #endif