@@ -3105,86 +3105,59 @@ namespace OrthoTree
31053105 this ->template Create <false >(*this , points, maxDepthNoIn, std::move (boxSpaceOptional), maxElementNoInNode);
31063106 }
31073107
3108- public: // Create
3109- // Create
3110- template <bool IS_PARALLEL_EXEC = false >
3111- static void Create (
3112- OrthoTreePoint& tree,
3113- TContainer const & points,
3114- std::optional<depth_t > maxDepthNoIn = std::nullopt ,
3115- std::optional<TBox> boxSpaceOptional = std::nullopt ,
3116- std::size_t maxElementNoInNode = DEFAULT_MAX_ELEMENT) noexcept
3108+ private:
3109+ struct Location
31173110 {
3118- auto const boxSpace = boxSpaceOptional.has_value () ? IGM::GetBoxAD (*boxSpaceOptional) : IGM::GetBoxOfPointsAD (points);
3119- auto const pointNo = points.size ();
3120-
3121- auto const maxDepthNo = (!maxDepthNoIn || maxDepthNoIn == depth_t {}) ? Base::EstimateMaxDepth (pointNo, maxElementNoInNode) : *maxDepthNoIn;
3122- tree.InitBase (boxSpace, maxDepthNo, maxElementNoInNode);
3123- if (points.empty ())
3124- return ;
3125-
3126- // Calculate and sort the Morton location ids
3127-
3128- struct Location
3129- {
3130- TEntityID EntityID;
3131- MortonLocationID LocationID;
3132- };
3133- auto locations = std::vector<Location>(pointNo);
3134- EXEC_POL_DEF (ept); // GCC 11.3
3135- std::transform (EXEC_POL_ADD (ept) points.begin (), points.end (), locations.begin (), [&](auto const & point) {
3136- return Location{ detail::getKeyPart (points, point), tree.GetLocationID (detail::getValuePart (point)) };
3137- });
3111+ TEntityID EntityID;
3112+ MortonLocationID LocationID;
3113+ };
31383114
3115+ // Build the tree in depth-first order
3116+ template <bool IS_PARALLEL_EXEC = false >
3117+ inline constexpr void BuildTree (std::vector<Location>& locations) noexcept
3118+ {
31393119 if constexpr (IS_PARALLEL_EXEC)
31403120 {
31413121 EXEC_POL_DEF (eps); // GCC 11.3
31423122 std::sort (EXEC_POL_ADD (eps) locations.begin (), locations.end (), [&](auto const & l, auto const & r) { return l.LocationID < r.LocationID ; });
31433123 }
31443124
3145- // Build the tree in depth-first order
3146-
31473125 struct NodeStackData
31483126 {
31493127 std::pair<MortonNodeID, Node> NodeInstance;
31503128 typename std::vector<Location>::iterator EndLocationIt;
31513129 };
31523130 std::array<NodeStackData, SI::MAX_THEORETICAL_DEPTH> nodeStack;
3153- nodeStack[0 ] = NodeStackData{ *tree. m_nodes .find (SI::GetRootKey ()), locations.end () };
3154- tree. m_nodes .clear (); // Root will be inserted again via the nodeStack, unspecified behavior
3131+ nodeStack[0 ] = NodeStackData{ *this -> m_nodes .find (SI::GetRootKey ()), locations.end () };
3132+ this -> m_nodes .clear (); // Root will be inserted again via the nodeStack, unspecified behavior
31553133
31563134 auto beginLocationIt = locations.begin ();
31573135 auto constexpr exitDepthID = depth_t (-1 );
31583136 for (depth_t depthID = 0 ; depthID != exitDepthID;)
31593137 {
31603138 auto & [node, endLocationIt] = nodeStack[depthID];
31613139 std::size_t const elementNo = std::distance (beginLocationIt, endLocationIt);
3162- if (elementNo == 0 )
3163- {
3164- tree.m_nodes .emplace (std::move (node));
3165- --depthID;
3166- continue ;
3167- }
3168-
3169- if ((elementNo < tree.m_maxElementNo && !node.second .IsAnyChildExist ()) || depthID == maxDepthNo)
3140+ if ((0 < elementNo && elementNo < this ->m_maxElementNo && !node.second .IsAnyChildExist ()) || depthID == this ->m_maxDepthNo )
31703141 {
31713142 auto & entityIDs = node.second .GetEntities ();
31723143 entityIDs.resize (elementNo);
3173-
31743144 LOOPIVDEP
31753145 for (std::size_t i = 0 ; i < elementNo; ++i)
31763146 {
31773147 entityIDs[i] = beginLocationIt->EntityID ;
31783148 ++beginLocationIt;
31793149 }
3150+ }
31803151
3181- tree.m_nodes .emplace (std::move (node));
3152+ if (beginLocationIt == endLocationIt)
3153+ {
3154+ this ->m_nodes .emplace (std::move (node));
31823155 --depthID;
31833156 continue ;
31843157 }
31853158
31863159 ++depthID;
3187- auto const examinedLevel = tree. GetDepthMax () - depthID;
3160+ auto const examinedLevel = this -> GetDepthMax () - depthID;
31883161 auto const keyGenerator = typename SI::ChildKeyGenerator (node.first );
31893162 auto const childChecker = typename SI::ChildCheckerFixedDepth (examinedLevel, beginLocationIt->LocationID );
31903163 auto childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID (examinedLevel));
@@ -3202,10 +3175,40 @@ namespace OrthoTree
32023175 }
32033176
32043177 nodeStack[depthID].NodeInstance .first = std::move (childKey);
3205- nodeStack[depthID].NodeInstance .second = tree. CreateChild (node.second , childKey);
3178+ nodeStack[depthID].NodeInstance .second = this -> CreateChild (node.second , childKey);
32063179 }
32073180 }
32083181
3182+ public: // Create
3183+ // Create
3184+ template <bool IS_PARALLEL_EXEC = false >
3185+ static void Create (
3186+ OrthoTreePoint& tree,
3187+ TContainer const & points,
3188+ std::optional<depth_t > maxDepthNoIn = std::nullopt ,
3189+ std::optional<TBox> boxSpaceOptional = std::nullopt ,
3190+ std::size_t maxElementNoInNode = DEFAULT_MAX_ELEMENT) noexcept
3191+ {
3192+ auto const boxSpace = boxSpaceOptional.has_value () ? IGM::GetBoxAD (*boxSpaceOptional) : IGM::GetBoxOfPointsAD (points);
3193+ auto const pointNo = points.size ();
3194+
3195+ auto const maxDepthNo = (!maxDepthNoIn || maxDepthNoIn == depth_t {}) ? Base::EstimateMaxDepth (pointNo, maxElementNoInNode) : *maxDepthNoIn;
3196+ tree.InitBase (boxSpace, maxDepthNo, maxElementNoInNode);
3197+ if (points.empty ())
3198+ return ;
3199+
3200+ detail::reserve (tree.m_nodes , Base::EstimateNodeNumber (pointNo, maxDepthNo, maxElementNoInNode));
3201+
3202+ // Calculate and sort the Morton location ids
3203+ auto locations = std::vector<Location>(pointNo);
3204+ EXEC_POL_DEF (ept); // GCC 11.3
3205+ std::transform (EXEC_POL_ADD (ept) points.begin (), points.end (), locations.begin (), [&](auto const & point) {
3206+ return Location{ detail::getKeyPart (points, point), tree.GetLocationID (detail::getValuePart (point)) };
3207+ });
3208+
3209+ tree.template BuildTree <IS_PARALLEL_EXEC>(locations);
3210+ }
3211+
32093212 public: // Edit functions
32103213 // Insert entity into the tree with node rebalancing
32113214 bool InsertWithRebalancing (TEntityID newEntityID, TVector const & newPoint, TContainer const & points) noexcept
0 commit comments