131 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2009-2021 Intel Corporation
 | |
| // SPDX-License-Identifier: Apache-2.0
 | |
| 
 | |
| #include "../builders/bvh_builder_hair.h"
 | |
| #include "../builders/primrefgen.h"
 | |
| 
 | |
| #include "../geometry/pointi.h"
 | |
| #include "../geometry/linei.h"
 | |
| #include "../geometry/curveNi.h"
 | |
| #include "../geometry/curveNv.h"
 | |
| 
 | |
| #if defined(EMBREE_GEOMETRY_CURVE) || defined(EMBREE_GEOMETRY_POINT)
 | |
| 
 | |
| namespace embree
 | |
| {
 | |
|   namespace isa
 | |
|   {
 | |
|     template<int N, typename CurvePrimitive, typename LinePrimitive, typename PointPrimitive>
 | |
|     struct BVHNHairBuilderSAH : public Builder
 | |
|     {
 | |
|       typedef BVHN<N> BVH;
 | |
|       typedef typename BVH::NodeRef NodeRef;
 | |
| 
 | |
|       BVH* bvh;
 | |
|       Scene* scene;
 | |
|       mvector<PrimRef> prims;
 | |
|       BVHBuilderHair::Settings settings;
 | |
| 
 | |
|       BVHNHairBuilderSAH (BVH* bvh, Scene* scene)
 | |
|         : bvh(bvh), scene(scene), prims(scene->device,0) {}
 | |
|       
 | |
|       void build() 
 | |
|       {
 | |
|         /* if we use the primrefarray for allocations we have to take it back from the BVH */
 | |
|         if (settings.finished_range_threshold != size_t(inf))
 | |
|           bvh->alloc.unshare(prims);
 | |
| 
 | |
|         /* fast path for empty BVH */
 | |
|         const size_t numPrimitives = scene->getNumPrimitives(Geometry::MTY_CURVES,false);
 | |
|         if (numPrimitives == 0) {
 | |
|           bvh->clear();
 | |
|           prims.clear();
 | |
|           return;
 | |
|         }
 | |
| 
 | |
|         double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "HairBuilderSAH");
 | |
| 
 | |
|         /* create primref array */
 | |
|         prims.resize(numPrimitives);
 | |
|         const PrimInfo pinfo = createPrimRefArray(scene,Geometry::MTY_CURVES,false,numPrimitives,prims,scene->progressInterface);
 | |
| 
 | |
|         /* estimate acceleration structure size */
 | |
|         const size_t node_bytes = pinfo.size()*sizeof(typename BVH::OBBNode)/(4*N);
 | |
|         const size_t leaf_bytes = CurvePrimitive::bytes(pinfo.size());
 | |
|         bvh->alloc.init_estimate(node_bytes+leaf_bytes);
 | |
|         
 | |
|         /* builder settings */
 | |
|         settings.branchingFactor = N;
 | |
|         settings.maxDepth = BVH::maxBuildDepthLeaf;
 | |
|         settings.logBlockSize = bsf(CurvePrimitive::max_size());
 | |
|         settings.minLeafSize = CurvePrimitive::max_size();
 | |
|         settings.maxLeafSize = CurvePrimitive::max_size();
 | |
|         settings.finished_range_threshold = numPrimitives/1000;
 | |
|         if (settings.finished_range_threshold < 1000)
 | |
|           settings.finished_range_threshold = inf;
 | |
| 
 | |
|         /* creates a leaf node */
 | |
|         auto createLeaf = [&] (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) -> NodeRef {
 | |
|           
 | |
|           if (set.size() == 0)
 | |
|             return BVH::emptyNode;
 | |
| 
 | |
|           const unsigned int geomID0 = prims[set.begin()].geomID();
 | |
|           if (scene->get(geomID0)->getTypeMask() & Geometry::MTY_POINTS)
 | |
|             return PointPrimitive::createLeaf(bvh,prims,set,alloc);
 | |
|           else if (scene->get(geomID0)->getCurveBasis() == Geometry::GTY_BASIS_LINEAR)
 | |
|             return LinePrimitive::createLeaf(bvh,prims,set,alloc);
 | |
|           else
 | |
|             return CurvePrimitive::createLeaf(bvh,prims,set,alloc);
 | |
|         };
 | |
|         
 | |
|         auto reportFinishedRange = [&] (const range<size_t>& range) -> void
 | |
|           {
 | |
|             PrimRef* begin = prims.data()+range.begin();
 | |
|             PrimRef* end   = prims.data()+range.end(); // FIXME: extended end for spatial split builder!!!!!
 | |
|             size_t bytes = (size_t)end - (size_t)begin;
 | |
|             bvh->alloc.addBlock(begin,bytes);
 | |
|           };
 | |
|           
 | |
|         /* build hierarchy */
 | |
|         typename BVH::NodeRef root = BVHBuilderHair::build<NodeRef>
 | |
|           (typename BVH::CreateAlloc(bvh),
 | |
|            typename BVH::AABBNode::Create(),
 | |
|            typename BVH::AABBNode::Set(),
 | |
|            typename BVH::OBBNode::Create(),
 | |
|            typename BVH::OBBNode::Set(),
 | |
|            createLeaf,scene->progressInterface,
 | |
|            reportFinishedRange,
 | |
|            scene,prims.data(),pinfo,settings);
 | |
|         
 | |
|         bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());
 | |
|         
 | |
|         /* if we allocated using the primrefarray we have to keep it alive */
 | |
|         if (settings.finished_range_threshold != size_t(inf))
 | |
|           bvh->alloc.share(prims);
 | |
|         
 | |
|         /* clear temporary data for static geometry */
 | |
|         if (scene->isStaticAccel()) {
 | |
|           prims.clear();
 | |
|         }
 | |
|         bvh->cleanup();
 | |
|         bvh->postBuild(t0);
 | |
|       }
 | |
| 
 | |
|       void clear() {
 | |
|         prims.clear();
 | |
|       }
 | |
|     };
 | |
|     
 | |
|     /*! entry functions for the builder */
 | |
|     Builder* BVH4Curve4vBuilder_OBB_New   (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Curve4v,Line4i,Point4i>((BVH4*)bvh,scene); }
 | |
|     Builder* BVH4Curve4iBuilder_OBB_New   (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Curve4i,Line4i,Point4i>((BVH4*)bvh,scene); }
 | |
| 
 | |
| #if defined(__AVX__)
 | |
|     Builder* BVH8Curve8vBuilder_OBB_New   (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<8,Curve8v,Line8i,Point8i>((BVH8*)bvh,scene); }
 | |
|     Builder* BVH4Curve8iBuilder_OBB_New   (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Curve8i,Line8i,Point8i>((BVH4*)bvh,scene); }
 | |
| #endif
 | |
| 
 | |
|   }
 | |
| }
 | |
| #endif
 |