mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			137 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // This file is part of libigl, a simple c++ geometry processing library.
 | |
| // 
 | |
| // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
 | |
| // 
 | |
| // 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 <functional>
 | |
| #include <vector>
 | |
| #include <algorithm>
 | |
| 
 | |
| template <
 | |
|   typename DerivedP,
 | |
|   typename DerivedN,
 | |
|   typename DerivedS >
 | |
| IGL_INLINE void igl::ambient_occlusion(
 | |
|   const std::function<
 | |
|     bool(
 | |
|       const Eigen::Vector3f&,
 | |
|       const Eigen::Vector3f&)
 | |
|       > & shoot_ray,
 | |
|   const Eigen::PlainObjectBase<DerivedP> & P,
 | |
|   const Eigen::PlainObjectBase<DerivedN> & N,
 | |
|   const int num_samples,
 | |
|   Eigen::PlainObjectBase<DerivedS> & S)
 | |
| {
 | |
|   using namespace Eigen;
 | |
|   const int n = P.rows();
 | |
|   // Resize output
 | |
|   S.resize(n,1);
 | |
|   // Embree seems to be parallel when constructing but not when tracing rays
 | |
|   const MatrixXf D = random_dir_stratified(num_samples).cast<float>();
 | |
| 
 | |
|   const auto & inner = [&P,&N,&num_samples,&D,&S,&shoot_ray](const int p)
 | |
|   {
 | |
|     const Vector3f origin = P.row(p).template cast<float>();
 | |
|     const Vector3f normal = N.row(p).template cast<float>();
 | |
|     int num_hits = 0;
 | |
|     for(int s = 0;s<num_samples;s++)
 | |
|     {
 | |
|       Vector3f d = D.row(s);
 | |
|       if(d.dot(normal) < 0)
 | |
|       {
 | |
|         // reverse ray
 | |
|         d *= -1;
 | |
|       }
 | |
|       if(shoot_ray(origin,d))
 | |
|       {
 | |
|         num_hits++;
 | |
|       }
 | |
|     }
 | |
|     S(p) = (double)num_hits/(double)num_samples;
 | |
|   };
 | |
|   parallel_for(n,inner,1000);
 | |
| }
 | |
| 
 | |
| template <
 | |
|   typename DerivedV,
 | |
|   int DIM,
 | |
|   typename DerivedF,
 | |
|   typename DerivedP,
 | |
|   typename DerivedN,
 | |
|   typename DerivedS >
 | |
| IGL_INLINE void igl::ambient_occlusion(
 | |
|   const igl::AABB<DerivedV,DIM> & aabb,
 | |
|   const Eigen::PlainObjectBase<DerivedV> & V,
 | |
|   const Eigen::PlainObjectBase<DerivedF> & F,
 | |
|   const Eigen::PlainObjectBase<DerivedP> & P,
 | |
|   const Eigen::PlainObjectBase<DerivedN> & N,
 | |
|   const int num_samples,
 | |
|   Eigen::PlainObjectBase<DerivedS> & S)
 | |
| {
 | |
|   const auto & shoot_ray = [&aabb,&V,&F](
 | |
|     const Eigen::Vector3f& _s,
 | |
|     const Eigen::Vector3f& dir)->bool
 | |
|   {
 | |
|     Eigen::Vector3f s = _s+1e-4*dir;
 | |
|     igl::Hit hit;
 | |
|     return aabb.intersect_ray(
 | |
|       V,
 | |
|       F,
 | |
|       s  .cast<typename DerivedV::Scalar>().eval(),
 | |
|       dir.cast<typename DerivedV::Scalar>().eval(),
 | |
|       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::PlainObjectBase<DerivedV> & V,
 | |
|   const Eigen::PlainObjectBase<DerivedF> & F,
 | |
|   const Eigen::PlainObjectBase<DerivedP> & P,
 | |
|   const Eigen::PlainObjectBase<DerivedN> & N,
 | |
|   const int num_samples,
 | |
|   Eigen::PlainObjectBase<DerivedS> & S)
 | |
| {
 | |
|   if(F.rows() < 100)
 | |
|   {
 | |
|     // Super naive
 | |
|     const auto & shoot_ray = [&V,&F](
 | |
|       const Eigen::Vector3f& _s,
 | |
|       const Eigen::Vector3f& dir)->bool
 | |
|     {
 | |
|       Eigen::Vector3f 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<DerivedV,3> aabb;
 | |
|   aabb.init(V,F);
 | |
|   return ambient_occlusion(aabb,V,F,P,N,num_samples,S);
 | |
| }
 | |
| 
 | |
| #ifdef IGL_STATIC_LIBRARY
 | |
| // Explicit template instantiation
 | |
| // generated by autoexplicit.sh
 | |
| template void igl::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 | |
| // generated by autoexplicit.sh
 | |
| template void igl::ambient_occlusion<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 | |
| // generated by autoexplicit.sh
 | |
| template void igl::ambient_occlusion<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 | |
| template void igl::ambient_occlusion<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::function<bool (Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
 | |
| #endif
 | 
