void build() { /* we reset the allocator when the mesh size changed */ if (mesh && mesh->numPrimitivesChanged) { bvh->alloc.clear(); } /* skip build for empty scene */ const size_t numOriginalPrimitives = mesh ? mesh->size() : scene->getNumPrimitives<Mesh,false>(); if (numOriginalPrimitives == 0) { prims0.clear(); bvh->clear(); return; } double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::BVH" + toString(N) + "BuilderFastSpatialSAH"); /* create primref array */ const size_t numSplitPrimitives = max(numOriginalPrimitives,size_t(splitFactor*numOriginalPrimitives)); prims0.resize(numSplitPrimitives); PrimInfo pinfo = mesh ? createPrimRefArray(mesh,prims0,bvh->scene->progressInterface) : createPrimRefArray(scene,Mesh::geom_type,false,prims0,bvh->scene->progressInterface); Splitter splitter(scene); /* enable os_malloc for two level build */ if (mesh) bvh->alloc.setOSallocation(true); const size_t node_bytes = pinfo.size()*sizeof(typename BVH::AlignedNode)/(4*N); const size_t leaf_bytes = size_t(1.2*Primitive::blocks(pinfo.size())*sizeof(Primitive)); bvh->alloc.init_estimate(node_bytes+leaf_bytes); settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,pinfo.size(),node_bytes+leaf_bytes); settings.branchingFactor = N; settings.maxDepth = BVH::maxBuildDepthLeaf; NodeRef root = BVHBuilderBinnedFastSpatialSAH::build<NodeRef>( typename BVH::CreateAlloc(bvh), typename BVH::AlignedNode::Create2(), typename BVH::AlignedNode::Set2(), CreateLeafSpatial<N,Primitive>(bvh), splitter, bvh->scene->progressInterface, prims0.data(), numSplitPrimitives, pinfo,settings); bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size()); bvh->layoutLargeNodes(size_t(pinfo.size()*0.005f)); /* clear temporary data for static geometry */ if (scene && scene->isStaticAccel()) { prims0.clear(); bvh->shrink(); } bvh->cleanup(); bvh->postBuild(t0); }
void build(size_t, size_t) { /* progress monitor */ auto progress = [&] (size_t dn) { bvh->scene->progressMonitor(dn); }; auto virtualprogress = BuildProgressMonitorFromClosure(progress); /* fast path for empty BVH */ const size_t numPrimitives = scene->getNumPrimitives<BezierCurves,1>(); if (numPrimitives == 0) { prims.clear(); bvh->set(BVH::emptyNode,empty,0); return; } double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "BuilderHairSAH"); //profile(1,5,numPrimitives,[&] (ProfileTimer& timer) { /* create primref array */ bvh->alloc.init_estimate(numPrimitives*sizeof(Primitive)); prims.resize(numPrimitives); const PrimInfo pinfo = createBezierRefArray<1>(scene,prims,virtualprogress); /* build hierarchy */ typename BVH::NodeRef root = bvh_obb_builder_binned_sah<N> ( [&] () { return bvh->alloc.threadLocal2(); }, [&] (const PrimInfo* children, const size_t numChildren, HeuristicArrayBinningSAH<BezierPrim> alignedHeuristic, FastAllocator::ThreadLocal2* alloc) -> Node* { Node* node = (Node*) alloc->alloc0.malloc(sizeof(Node),16); node->clear(); for (size_t i=0; i<numChildren; i++) node->set(i,children[i].geomBounds); return node; }, [&] (const PrimInfo* children, const size_t numChildren, UnalignedHeuristicArrayBinningSAH<BezierPrim> unalignedHeuristic, FastAllocator::ThreadLocal2* alloc) -> UnalignedNode* { UnalignedNode* node = (UnalignedNode*) alloc->alloc0.malloc(sizeof(UnalignedNode),16); node->clear(); for (size_t i=0; i<numChildren; i++) { const LinearSpace3fa space = unalignedHeuristic.computeAlignedSpace(children[i]); const PrimInfo sinfo = unalignedHeuristic.computePrimInfo(children[i],space); node->set(i,OBBox3fa(space,sinfo.geomBounds)); } return node; }, [&] (size_t depth, const PrimInfo& pinfo, FastAllocator::ThreadLocal2* alloc) -> NodeRef { size_t items = pinfo.size(); size_t start = pinfo.begin; Primitive* accel = (Primitive*) alloc->alloc1.malloc(items*sizeof(Primitive)); NodeRef node = bvh->encodeLeaf((char*)accel,items); for (size_t i=0; i<items; i++) { accel[i].fill(prims.data(),start,pinfo.end,bvh->scene,false); } return node; }, progress, prims.data(),pinfo,N,BVH::maxBuildDepthLeaf,1,1,BVH::maxLeafBlocks); bvh->set(root,pinfo.geomBounds,pinfo.size()); //}); /* clear temporary data for static geometry */ if (scene->isStatic()) { prims.clear(); bvh->shrink(); } bvh->cleanup(); bvh->postBuild(t0); }