| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -16,6 +16,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "blobtree.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "quaternion.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "factorial.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "minimalPrimitive.hpp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <memory> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					namespace algoim::organizer | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -226,13 +227,13 @@ void compositePower(const std::vector<xarray<real, 3>>& powers, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace detail
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual void print() = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class Primitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     virtual void print() = 0;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual real eval(const uvector3&) { return 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     virtual real eval(const uvector3&) { return 0; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					real evalPower(const xarray<real, N>& phi, const uvector<real, N>& x) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -481,18 +482,18 @@ bool isInsideBernsteins(const std::vector<tensor3>& tensors, const uvector3& p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bool isInsidePower(const tensor3& t, const uvector3& p) { return evalPower(t, p) < 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class FRep : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					private: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::function<real(uvector3)> f; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class FRep : public Primitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// private:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     std::function<real(uvector3)> f;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "FRep" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     void print() override { std::cout << "FRep" << std::endl; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(const uvector3& p) override { return f(p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     real eval(const uvector3& p) override { return f(p); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    FRep(std::function<real(uvector3)> f_) : f(f_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     FRep(std::function<real(uvector3)> f_) : f(f_) {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					enum PrimitiveType { Sphere, Cylinder, Cone, Mesh, BRep }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -698,63 +699,13 @@ public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class AABB | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3 min = uvector3(std::numeric_limits<real>::max()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3 max = uvector3(std::numeric_limits<real>::lowest()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB()       = default; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB(const uvector3& min_, const uvector3& max_) : min(min_), max(max_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void extend(const uvector3& p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (int i = 0; i < 3; ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            min(i) = std::min(min(i), p(i)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            max(i) = std::max(max(i), p(i)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void extend(const AABB& aabb) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (int i = 0; i < 3; ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            min(i) = std::min(min(i), aabb.min(i)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            max(i) = std::max(max(i), aabb.max(i)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3 center() const { return (min + max) / 2; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3 size() const { return max - min; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real volume() const { return prod(size()); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bool intersect(const AABB& aabb) const | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (int i = 0; i < 3; ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (min(i) > aabb.max(i) || max(i) < aabb.min(i)) { return false; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void normalize(const uvector3& scale, const uvector3& boundaryMin) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        min = (min - boundaryMin) / scale; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        max = (max - boundaryMin) / scale; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct VisiblePrimitiveRep { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<tensor3> tensors; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB                 aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    organizer::BlobTree  subBlobTree; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct MinimalPrimitiveRep { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    tensor3 tensor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB    aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// hesai
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct Scene { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::vector<CompleteTensorRep> polys;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::vector<VisiblePrimitiveRep> visiblePrimitives;
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -763,66 +714,6 @@ struct Scene { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB                             boundary; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void upwardGeneratingNodes(std::vector<int>&    levelLeftBook, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                           organizer::BlobTree& tree, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                           int                  level, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                           int                  primitiveIdx, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                           bool                 isFinal) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    assert(level <= levelLeftBook.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (level == levelLeftBook.size()) { levelLeftBook.emplace_back(-1); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (levelLeftBook[level] != -1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // 右节点
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (level == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            tree.primitiveNodeIdx[primitiveIdx] = tree.structure.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            tree.structure.emplace_back(organizer::Blob{1, 0, 0, 0, 0, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            tree.structure.emplace_back(organizer::Blob{0, organizer::OP_INTERSECTION, 0, 0, 0, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // upwards
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tree.structure[levelLeftBook[level]].ancestor = tree.structure.size() - levelLeftBook[level]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        levelLeftBook[level]                          = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        upwardGeneratingNodes(levelLeftBook, tree, level + 1, primitiveIdx, isFinal); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (isFinal) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 不会再有同层的其它右节点了。因此该节点应作为右节点与更高层的左节点组合
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (level == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.primitiveNodeIdx[primitiveIdx] = tree.structure.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.structure.emplace_back(organizer::Blob{1, 0, 0, 0, 0, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.structure.emplace_back(organizer::Blob{0, organizer::OP_INTERSECTION, 0, 0, 0, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // upwards
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 向上寻找第一个有记录的左节点
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            int i = level + 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (i == levelLeftBook.size()) return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (; i < levelLeftBook.size(); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (levelLeftBook[i] != -1) break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            assert(i < levelLeftBook.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            tree.structure[levelLeftBook[i]].ancestor = tree.structure.size() - levelLeftBook[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            levelLeftBook[level]                      = -1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            upwardGeneratingNodes(levelLeftBook, tree, i + 1, primitiveIdx, isFinal); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // 左节点
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            levelLeftBook[level] = tree.structure.size(); // 标记左节点的位置
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (level == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.primitiveNodeIdx[primitiveIdx] = tree.structure.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.structure.emplace_back(organizer::Blob{1, 0, 0, 0, 1, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                tree.structure.emplace_back(organizer::Blob{0, organizer::OP_INTERSECTION, 0, 0, 1, 0}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void buildNearBalancedBlobTree(organizer::BlobTree& tree, int leafSize) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<int> levelLeftBook; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    tree.primitiveNodeIdx.resize(leafSize); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int i = 0; i < leafSize; ++i) { upwardGeneratingNodes(levelLeftBook, tree, 0, i, i == leafSize - 1); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void makeMesh(const MeshDesc& mesh, VisiblePrimitiveRep& visiblePrimitive) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    assert(visiblePrimitive.tensors.size() == mesh.indexInclusiveScan.size()); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -987,6 +878,50 @@ void makeCone(const ConeDesc& coneDesc, VisiblePrimitiveRep& visiblePrimitive) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    buildNearBalancedBlobTree(visiblePrimitive.subBlobTree, 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void mergeSubtree2Leaf(BlobTree&                               blobTree, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       std::vector<MinimalPrimitiveRep>&       minimalReps, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const std::vector<VisiblePrimitiveRep>& visiblePrimitiveReps) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<int> realLeafIndices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int i = 0; i < blobTree.structure.size(); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int oldAncestor = blobTree.structure[i].ancestor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (int j = visiblePrimitiveReps.size() - 1; blobTree.primitiveNodeIdx[j] > i; --j) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (blobTree.structure[i].isLeft && oldAncestor + i > blobTree.primitiveNodeIdx[j]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                blobTree.structure[i].ancestor += std::max(int(visiblePrimitiveReps[j].subBlobTree.structure.size()) - 1, 0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int i = 0; i < visiblePrimitiveReps.size(); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int originLeafIdx   = blobTree.primitiveNodeIdx[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int subBlobTreeSize = visiblePrimitiveReps[i].subBlobTree.structure.size(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (visiblePrimitiveReps[i].tensors.size() != 1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (int j = i + 1; j < visiblePrimitiveReps.size(); ++j) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                blobTree.primitiveNodeIdx[j] += std::max(int(subBlobTreeSize) - 1, 0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            blobTree.structure[originLeafIdx].isPrimitive = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            blobTree.structure[originLeafIdx].nodeOp      = visiblePrimitiveReps[i].subBlobTree.structure.back().nodeOp; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            blobTree.structure.insert(blobTree.structure.begin() + originLeafIdx, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                      visiblePrimitiveReps[i].subBlobTree.structure.begin(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                      visiblePrimitiveReps[i].subBlobTree.structure.end() - 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            realLeafIndices.reserve(realLeafIndices.size() + visiblePrimitiveReps[i].subBlobTree.primitiveNodeIdx.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto primitiveIdx : visiblePrimitiveReps[i].subBlobTree.primitiveNodeIdx) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                realLeafIndices.push_back(primitiveIdx + originLeafIdx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            minimalReps.reserve(minimalReps.size() + visiblePrimitiveReps[i].tensors.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            const auto& aabb = visiblePrimitiveReps[i].aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (const auto& tensor : visiblePrimitiveReps[i].tensors) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                minimalReps.emplace_back(MinimalPrimitiveRep{tensor, aabb}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            blobTree.structure[originLeafIdx].isPrimitive = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            realLeafIndices.push_back(originLeafIdx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            minimalReps.emplace_back(MinimalPrimitiveRep{visiblePrimitiveReps[i].tensors[0], visiblePrimitiveReps[i].aabb}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    blobTree.primitiveNodeIdx = realLeafIndices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors, AABB& aabb)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     uvector3 ext(1 + mesh.indexInclusiveScan.size());
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -1135,32 +1070,5 @@ void makeCone(const ConeDesc& coneDesc, VisiblePrimitiveRep& visiblePrimitive) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     AABB                 aabb;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const int CHILD_NUM = 8; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct OcTreeNode { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<int> polyIntersectIndices; // 同一poly会出现在不同node的polyIndices中
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::vector<int> polyFullyContainedIndices; // 完全包含该node的poly, 同样会出现在不同node的polyIndices中
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::array<int, CHILD_NUM> children;        // octree
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    AABB             aabb; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    organizer::BlobTree blobTree; // 部分遍历过的octree,那些不属于该node的primitive的out信息已经在该blobtree种尽可能地向上传递
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Node() { children.fill(-1); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    OcTreeNode() = default; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    OcTreeNode(const uvector3& min_, const uvector3& max_, const organizer::BlobTree& blobTree_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        : aabb(min_, max_), blobTree(blobTree_) {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    OcTreeNode(const AABB& aabb_, const organizer::BlobTree& blobTree_) : aabb(aabb_), blobTree(blobTree_) {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // 深拷贝
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    OcTreeNode(const OcTreeNode& node) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        : polyIntersectIndices(node.polyIntersectIndices), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          // polyFullyContainedIndices(node.polyFullyContainedIndices),
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          aabb(node.aabb), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          blobTree(node.blobTree) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int a = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int b = 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace algoim::organizer
 |