@@ -1891,7 +1891,7 @@ namespace OrthoTree
18911891 struct BoxDistance : ItemDistance
18921892 {
18931893 MortonNodeID NodeKey;
1894- std::vector<TEntityID> const * Entities ;
1894+ Node const * NodePtr ;
18951895 };
18961896
18971897
@@ -3273,7 +3273,7 @@ namespace OrthoTree
32733273 auto const nodeMinDistance = IGM::Size (IGM::GetBoxWallDistanceAD (searchPoint, centerPoint, halfSize));
32743274 if (nodeMinDistance < maxDistance)
32753275 {
3276- nodeMinDistances.push_back ({ { nodeMinDistance }, key, &node. Entities });
3276+ nodeMinDistances.push_back ({ { nodeMinDistance }, key, &node });
32773277 }
32783278 };
32793279
@@ -3334,7 +3334,7 @@ namespace OrthoTree
33343334 break ;
33353335 }
33363336
3337- CreateEntityDistance (* nodeDistance.Entities , searchPoint, points, neighborEntities, maxDistance);
3337+ CreateEntityDistance (nodeDistance.NodePtr -> Entities , searchPoint, points, neighborEntities, maxDistance);
33383338 farestEntityDistance = GetFarestDistance (neighborEntities, neighborNo);
33393339 }
33403340
@@ -4275,48 +4275,48 @@ namespace OrthoTree
42754275
42764276 void GetRayIntersectedFirstRecursive (
42774277 depth_t depthID,
4278- MortonNodeIDCR parentKey ,
4278+ Node const & parentNode ,
42794279 TContainer const & boxes,
42804280 TVector const & rayBasePoint,
42814281 TVector const & rayHeading,
42824282 TGeometry tolerance,
4283- std::multiset <EntityDistance>& foundEntities ) const noexcept
4283+ std::optional <EntityDistance>& foundEntity ) const noexcept
42844284 {
4285- auto const & node = this ->GetNode (parentKey);
4286-
4287- auto const maxExaminationDistance =
4288- foundEntities.empty () ? std::numeric_limits<typename IGM::Geometry>::infinity () : foundEntities.rbegin ()->Distance ;
4289- for (auto const entityID : node.Entities )
4285+ for (auto const entityID : parentNode.Entities )
42904286 {
42914287 auto const distance = AD::GetRayBoxDistance (detail::at (boxes, entityID), rayBasePoint, rayHeading, tolerance);
42924288 if (!distance)
42934289 continue ;
42944290
4295- auto const distance_ = IGM_Geometry (*distance);
4296- if (distance_ > maxExaminationDistance)
4297- continue ;
4298-
4299- foundEntities.insert ({ { distance_ }, entityID });
4291+ if (!foundEntity || foundEntity->Distance > *distance)
4292+ foundEntity = std::optional<EntityDistance>(std::in_place, EntityDistance{ { TGeometry (*distance) }, entityID });
43004293 }
43014294
43024295 ++depthID;
4303- auto nodeDistances = std::multiset<BoxDistance>();
43044296 auto const & halfSize = this ->GetNodeSize (depthID + 1 );
4305- for (MortonNodeIDCR childKey : node.GetChildren ())
4297+ auto nodeDistances = std::vector<BoxDistance>();
4298+ for (MortonNodeIDCR childKey : parentNode.GetChildren ())
43064299 {
43074300 auto const & nodeChild = this ->GetNode (childKey);
43084301 auto const distance = IGM::GetRayBoxDistanceAD (GetNodeCenterMacro (this , childKey, nodeChild), halfSize, rayBasePoint, rayHeading, tolerance);
43094302 if (!distance)
43104303 continue ;
43114304
4312- if (*distance > maxExaminationDistance )
4305+ if (foundEntity && *distance > foundEntity-> Distance )
43134306 continue ;
43144307
4315- nodeDistances.insert ({ { IGM_Geometry (distance.value ()) }, childKey, &nodeChild. Entities });
4308+ nodeDistances.push_back ({ { IGM_Geometry (distance.value ()) }, childKey, &nodeChild });
43164309 }
43174310
4311+ std::sort (nodeDistances.begin (), nodeDistances.end ());
4312+
43184313 for (auto const & nodeDistance : nodeDistances)
4319- GetRayIntersectedFirstRecursive (depthID, nodeDistance.NodeKey , boxes, rayBasePoint, rayHeading, tolerance, foundEntities);
4314+ {
4315+ if (foundEntity && nodeDistance.Distance - tolerance >= foundEntity->Distance )
4316+ break ;
4317+
4318+ GetRayIntersectedFirstRecursive (depthID, *nodeDistance.NodePtr , boxes, rayBasePoint, rayHeading, tolerance, foundEntity);
4319+ }
43204320 }
43214321
43224322
@@ -4358,21 +4358,21 @@ namespace OrthoTree
43584358 std::optional<TEntityID> RayIntersectedFirst (
43594359 TVector const & rayBasePoint, TVector const & rayHeading, TContainer const & boxes, TGeometry tolerance = {}) const noexcept
43604360 {
4361- auto const distance = IGM::GetRayBoxDistanceAD (
4362- GetNodeCenterMacro (this , SI::GetRootKey (), this -> GetNode ( SI::GetRootKey ()) ), this ->GetNodeSize (1 ), rayBasePoint, rayHeading, tolerance);
4361+ auto const & rootNode = this -> GetNode ( SI::GetRootKey ());
4362+ auto const distance = IGM::GetRayBoxDistanceAD ( GetNodeCenterMacro (this , SI::GetRootKey (), rootNode ), this ->GetNodeSize (1 ), rayBasePoint, rayHeading, tolerance);
43634363 if (!distance)
43644364 return std::nullopt ;
43654365
4366- auto foundEntities = std::multiset <EntityDistance>() ;
4367- GetRayIntersectedFirstRecursive (0 , SI::GetRootKey () , boxes, rayBasePoint, rayHeading, tolerance, foundEntities );
4368- if (foundEntities. empty () )
4366+ auto foundEntity = std::optional <EntityDistance>{} ;
4367+ GetRayIntersectedFirstRecursive (0 , rootNode , boxes, rayBasePoint, rayHeading, tolerance, foundEntity );
4368+ if (!foundEntity )
43694369 return std::nullopt ;
43704370
4371- return foundEntities. begin () ->EntityID ;
4371+ return foundEntity ->EntityID ;
43724372 }
43734373
43744374 // Get first box which is intersected by the ray
4375- inline std::optional<TEntityID> RayIntersectedFirst (TRay const & ray, TContainer const & boxes, TGeometry tolerance) const noexcept
4375+ inline std::optional<TEntityID> RayIntersectedFirst (TRay const & ray, TContainer const & boxes, TGeometry tolerance = {} ) const noexcept
43764376 {
43774377 return RayIntersectedFirst (ray.Origin , ray.Direction , boxes, tolerance);
43784378 }
0 commit comments