| 
						
						
							
								
							
						
						
					 | 
					@ -108,14 +108,19 @@ AABB getOneEightCellAABB(const AABB& fatherAABB, const uvector<int, 3> side, int | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} // namespace detail
 | 
					 | 
					 | 
					} // namespace detail
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					bool keepQuadraturePoint(const Scene& scene, const OcTreeNode& ocTreeNode, const uvector3& originPt) | 
					 | 
					 | 
					bool keepQuadraturePoint(const std::vector<tensor3>& tensors, const OcTreeNode& ocTreeNode, const uvector3& point) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // 只需要考虑intersect polys,不用考虑fully contained polys
 | 
					 | 
					 | 
					    // 只需要考虑intersect polys,不用考虑fully contained polys
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const auto& polyIntersectIndices = ocTreeNode.polyIntersectIndices; | 
					 | 
					 | 
					    const auto& polyIntersectIndices = ocTreeNode.polyIntersectIndices; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    assert(tensors.size() == polyIntersectIndices.size()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (polyIntersectIndices.size() == 0) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        assert(ocTreeNode.blobTree.structure.back().inOut != NODE_IN_OUT_UNKNOWN); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return ocTreeNode.blobTree.structure.back().inOut; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    std::vector<bool> primitiveInOuts(polyIntersectIndices.size()); | 
					 | 
					 | 
					    std::vector<bool> primitiveInOuts(polyIntersectIndices.size()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (int i = 0; i < ocTreeNode.polyIntersectIndices.size(); ++i) { | 
					 | 
					 | 
					    for (int i = 0; i < ocTreeNode.polyIntersectIndices.size(); ++i) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        // primitiveInOuts[i] = isInsidePowers(scene.polys[polyIntersectIndices[i]].rawPower, originPt);
 | 
					 | 
					 | 
					        // primitiveInOuts[i] = isInsidePowers(scene.polys[polyIntersectIndices[i]].rawPower, originPt);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        primitiveInOuts[i] = isInsideBernstein(scene.tensors[polyIntersectIndices[i]], originPt); | 
					 | 
					 | 
					        primitiveInOuts[i] = isInsideBernstein(tensors[i], point); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // 这里blobTree是拷贝传参
 | 
					 | 
					 | 
					    // 这里blobTree是拷贝传参
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    auto blobTree = ocTreeNode.blobTree; | 
					 | 
					 | 
					    auto blobTree = ocTreeNode.blobTree; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -188,7 +193,7 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    uvector3 nodeMid = node.aabb.center(); | 
					 | 
					 | 
					    uvector3 nodeMid = node.aabb.center(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (int i = 0; i < polyIntersectIndices.size(); ++i) { | 
					 | 
					 | 
					    for (int i = 0; i < polyIntersectIndices.size(); ++i) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        const int       polyIntersectIndex = polyIntersectIndices[i]; | 
					 | 
					 | 
					        const int       polyIntersectIndex = polyIntersectIndices[i]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        const auto&     poly               = scene.tensors[polyIntersectIndex]; | 
					 | 
					 | 
					        const auto&     poly               = scene.minimalReps[polyIntersectIndex].tensor; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        uvector<int, 3> mark(0, 0, 0); | 
					 | 
					 | 
					        uvector<int, 3> mark(0, 0, 0); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for (int faceAxis = 0; faceAxis < 3; ++faceAxis) { | 
					 | 
					 | 
					        for (int faceAxis = 0; faceAxis < 3; ++faceAxis) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            real    centerPlane = nodeMid(faceAxis); | 
					 | 
					 | 
					            real    centerPlane = nodeMid(faceAxis); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -296,7 +301,7 @@ void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector<OcTre | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        int bbb = 1; | 
					 | 
					 | 
					        int bbb = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices; | 
					 | 
					 | 
					    const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    if (polyIntersectIndices.size() <= 5) { | 
					 | 
					 | 
					    if (polyIntersectIndices.size() <= 3) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        leaves.emplace_back(node); | 
					 | 
					 | 
					        leaves.emplace_back(node); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        return; | 
					 | 
					 | 
					        return; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -326,21 +331,21 @@ void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector<OcTre | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    uvector3 nodeMid = node.aabb.center(); | 
					 | 
					 | 
					    uvector3 nodeMid = node.aabb.center(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (int i = 0; i < polyIntersectIndices.size(); ++i) { | 
					 | 
					 | 
					    for (int i = 0; i < polyIntersectIndices.size(); ++i) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        const int   polyIntersectIndex = polyIntersectIndices[i]; | 
					 | 
					 | 
					        const int   polyIntersectIndex = polyIntersectIndices[i]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        const auto& poly               = scene.tensors[polyIntersectIndex]; | 
					 | 
					 | 
					        const auto& minimalRep         = scene.minimalReps[polyIntersectIndex]; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        subIdx                         = 0; | 
					 | 
					 | 
					        subIdx                         = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for (MultiLoop<3> j(0, 2); ~j; ++j, ++subIdx) { | 
					 | 
					 | 
					        for (MultiLoop<3> j(0, 2); ~j; ++j, ++subIdx) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            // if (!poly.aabb.intersect(subNodes[subIdx].aabb)) {
 | 
					 | 
					 | 
					            if (!minimalRep.aabb.intersect(subNodes[subIdx].aabb)) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            //     // out of the subcell
 | 
					 | 
					 | 
					                // out of the subcell
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            //     organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
 | 
					 | 
					 | 
					                organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            //     continue;
 | 
					 | 
					 | 
					                continue; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            // }
 | 
					 | 
					 | 
					            } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            if (subIdx == 1) { | 
					 | 
					 | 
					            if (subIdx == 1) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                int aaa = 1; | 
					 | 
					 | 
					                int aaa = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                int bbb = 1; | 
					 | 
					 | 
					                int bbb = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            tensor3 subcellPoly(nullptr, poly.ext()); | 
					 | 
					 | 
					            tensor3 subcellPoly(nullptr, minimalRep.tensor.ext()); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            algoim_spark_alloc(real, subcellPoly); | 
					 | 
					 | 
					            algoim_spark_alloc(real, subcellPoly); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            bernstein::deCasteljau(poly, subNodes[subIdx].aabb.min, subNodes[subIdx].aabb.max, subcellPoly); | 
					 | 
					 | 
					            bernstein::deCasteljau(minimalRep.tensor, subNodes[subIdx].aabb.min, subNodes[subIdx].aabb.max, subcellPoly); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            int sign = bernstein::uniformSign(subcellPoly); | 
					 | 
					 | 
					            int sign = bernstein::uniformSign(subcellPoly); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (sign == 1) { | 
					 | 
					 | 
					            if (sign == 1) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); | 
					 | 
					 | 
					                organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -458,18 +463,36 @@ void basicTask(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitives, in | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					BasicTaskRes basicTask(const Scene& scene, const OcTreeNode& node, int q = 10) | 
					 | 
					 | 
					BasicTaskRes basicTask(const Scene& scene, const OcTreeNode& node, int q = 10) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					{ | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (node.polyIntersectIndices.size() == 0) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        assert(node.blobTree.structure.back().inOut != NODE_IN_OUT_UNKNOWN); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (node.blobTree.structure.back().inOut == NODE_IN) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            return {node.aabb.volume(), 0}; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            return {0, 0}; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    auto                           integrand = [](const uvector<real, 3>& x) { return 1.0; }; | 
					 | 
					 | 
					    auto                           integrand = [](const uvector<real, 3>& x) { return 1.0; }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    real                           volume = 0., surf = 0.; | 
					 | 
					 | 
					    real                           volume = 0., surf = 0.; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    auto                           range = node.aabb.size(); | 
					 | 
					 | 
					    auto                           range = node.aabb.size(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    ImplicitPolyQuadrature<3> ipquad(scene.tensors, node.polyIntersectIndices); | 
					 | 
					 | 
					    std::vector<tensor3>           phis; // phis using subcell as [0,1]^3
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    std::vector<SparkStack<real>*> phiStacks; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (int i = 0; i < node.polyIntersectIndices.size(); i++) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        const auto& polyWithinScene = scene.minimalReps[node.polyIntersectIndices[i]].tensor; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        phis.emplace_back(tensor3(nullptr, polyWithinScene.ext())); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        phiStacks.emplace_back(algoim_spark_alloc_heap(real, phis.back())); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        bernstein::deCasteljau(polyWithinScene, node.aabb.min, node.aabb.max, phis.back()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    // ImplicitPolyQuadrature<3> ipquad(scene.minimalReps, node.polyIntersectIndices);
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    ImplicitPolyQuadrature<3> ipquad(phis); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) { | 
					 | 
					 | 
					    ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        auto realX = x * range + node.aabb.min; | 
					 | 
					 | 
					        auto realX = x * range + node.aabb.min; // 这里realX应该是最原始空间下的点?不过因为算体积,所以不影响
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        if (keepQuadraturePoint(scene, node, realX)) { volume += w * integrand(realX); } | 
					 | 
					 | 
					        if (keepQuadraturePoint(phis, node, x)) { volume += w * integrand(realX); } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					    }); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    ipquad.integrate_surf(AutoMixed, q, [&](const uvector<real, 3>& x, real w, const uvector<real, 3>& wn) { | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        volume += w * integrand(x * range + node.aabb.min); | 
					 | 
					 | 
					    for (auto& p : phiStacks) delete p; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    }); | 
					 | 
					 | 
					    return {volume * node.aabb.volume(), surf}; | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					    return {volume, surf}; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitives, | 
					 | 
					 | 
					void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitives, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -513,7 +536,7 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            visiblePrimitiveReps[i].aabb.normalize(range, xmin); | 
					 | 
					 | 
					            visiblePrimitiveReps[i].aabb.normalize(range, xmin); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } else if (auto pt = std::dynamic_pointer_cast<CylinderDesc>(primitives[i])) { | 
					 | 
					 | 
					        } else if (auto pt = std::dynamic_pointer_cast<CylinderDesc>(primitives[i])) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            visiblePrimitiveReps[i].tensors = {tensor3(nullptr, 3), tensor3(nullptr, 2), tensor3(nullptr, 2)}; | 
					 | 
					 | 
					            visiblePrimitiveReps[i].tensors = {tensor3(nullptr, 3), tensor3(nullptr, 3), tensor3(nullptr, 3)}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            auto& tensors                   = visiblePrimitiveReps[i].tensors; | 
					 | 
					 | 
					            auto& tensors                   = visiblePrimitiveReps[i].tensors; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            tensors[0].ext_(pt->alignAxis)  = 1; | 
					 | 
					 | 
					            tensors[0].ext_(pt->alignAxis)  = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            algoimSparkAllocHeapVector(tensorStacks, tensors); | 
					 | 
					 | 
					            algoimSparkAllocHeapVector(tensorStacks, tensors); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -526,7 +549,7 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            visiblePrimitiveReps[i].aabb.normalize(range, xmin); | 
					 | 
					 | 
					            visiblePrimitiveReps[i].aabb.normalize(range, xmin); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } else if (auto pt = std::dynamic_pointer_cast<ConeDesc>(primitives[i])) { | 
					 | 
					 | 
					        } else if (auto pt = std::dynamic_pointer_cast<ConeDesc>(primitives[i])) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            visiblePrimitiveReps[i].tensors = {tensor3(nullptr, 3), tensor3(nullptr, 2), tensor3(nullptr, 2)}; | 
					 | 
					 | 
					            visiblePrimitiveReps[i].tensors = {tensor3(nullptr, 3), tensor3(nullptr, 3), tensor3(nullptr, 3)}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            auto& tensors                   = visiblePrimitiveReps[i].tensors; | 
					 | 
					 | 
					            auto& tensors                   = visiblePrimitiveReps[i].tensors; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            algoimSparkAllocHeapVector(tensorStacks, tensors); | 
					 | 
					 | 
					            algoimSparkAllocHeapVector(tensorStacks, tensors); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -542,7 +565,7 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::vector<tensor3> realPrimitives; | 
					 | 
					 | 
					    std::vector<MinimalPrimitiveRep> minimalReps; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    /*** merge subtrees to main tree ***/ | 
					 | 
					 | 
					    /*** merge subtrees to main tree ***/ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    std::vector<int>                 realLeafIndices; | 
					 | 
					 | 
					    std::vector<int>                 realLeafIndices; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (int i = 0; i < visiblePrimitiveReps.size() - 1; ++i) { | 
					 | 
					 | 
					    for (int i = 0; i < visiblePrimitiveReps.size() - 1; ++i) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -574,26 +597,33 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            for (auto primitiveIdx : visiblePrimitiveReps[i].subBlobTree.primitiveNodeIdx) { | 
					 | 
					 | 
					            for (auto primitiveIdx : visiblePrimitiveReps[i].subBlobTree.primitiveNodeIdx) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                realLeafIndices.push_back(primitiveIdx + originLeafIdx); | 
					 | 
					 | 
					                realLeafIndices.push_back(primitiveIdx + originLeafIdx); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					
 | 
					 | 
					 | 
					            minimalReps.reserve(minimalReps.size() + visiblePrimitiveReps[i].tensors.size()); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            realPrimitives.insert(realPrimitives.end(), visiblePrimitiveReps[i].tensors.begin(), | 
					 | 
					 | 
					            const auto& aabb = visiblePrimitiveReps[i].aabb; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                  visiblePrimitiveReps[i].tensors.end()); | 
					 | 
					 | 
					            for (const auto& tensor : visiblePrimitiveReps[i].tensors) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                minimalReps.emplace_back(MinimalPrimitiveRep{tensor, aabb}); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } else { | 
					 | 
					 | 
					        } else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            blobTree.structure[originLeafIdx].isPrimitive = true; | 
					 | 
					 | 
					            blobTree.structure[originLeafIdx].isPrimitive = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            realLeafIndices.push_back(originLeafIdx); | 
					 | 
					 | 
					            realLeafIndices.push_back(originLeafIdx); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            realPrimitives.emplace_back(visiblePrimitiveReps[i].tensors[0]); | 
					 | 
					 | 
					            minimalReps.emplace_back(MinimalPrimitiveRep{visiblePrimitiveReps[i].tensors[0], visiblePrimitiveReps[i].aabb}); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    blobTree.primitiveNodeIdx = realLeafIndices; | 
					 | 
					 | 
					    blobTree.primitiveNodeIdx = realLeafIndices; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    /*** merge subtrees to main tree ***/ | 
					 | 
					 | 
					    /*** merge subtrees to main tree ***/ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    Scene      scene{realPrimitives, AABB(xmin, xmax)}; | 
					 | 
					 | 
					    Scene      scene{minimalReps, AABB(xmin, xmax)}; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    OcTreeNode rootNode(0, 1, blobTree); | 
					 | 
					 | 
					    OcTreeNode rootNode(0, 1, blobTree); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    for (int i = 0; i < realPrimitives.size(); ++i) { rootNode.polyIntersectIndices.emplace_back(i); } | 
					 | 
					 | 
					    for (int i = 0; i < minimalReps.size(); ++i) { rootNode.polyIntersectIndices.emplace_back(i); } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    int cnt = 1; | 
					 | 
					 | 
					    int cnt = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    buildOcTreeV0(scene, rootNode, leaves, 1, cnt); | 
					 | 
					 | 
					    buildOcTreeV0(scene, rootNode, leaves, 1, cnt); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    basicTask(scene, leaves[14], q); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    int i = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (const auto& leaf : leaves) { | 
					 | 
					 | 
					    for (const auto& leaf : leaves) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        auto basicRes = basicTask(scene, leaf, q); | 
					 | 
					 | 
					        auto basicRes = basicTask(scene, leaf, q); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        volume        += basicRes.volume * prod(leaf.aabb.max - leaf.aabb.min); | 
					 | 
					 | 
					        if (std::isinf(basicRes.volume)) { std::cout << "inf volume when solving leaf: " << i << std::endl; } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        volume += basicRes.volume; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        std::cout << "Solved leaves: " << ++i << "/" << leaves.size() << std::endl; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    volume *= prod(xmax - xmin); | 
					 | 
					 | 
					    volume *= prod(xmax - xmin); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |