Skip to content

Commit 90c3ab3

Browse files
committed
Fixed depth morton ID in box solution
1 parent dd61d7d commit 90c3ab3

File tree

1 file changed

+37
-65
lines changed

1 file changed

+37
-65
lines changed

octree.h

Lines changed: 37 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,30 +1347,6 @@ namespace OrthoTree
13471347
LocationID m_childFlag;
13481348
};
13491349

1350-
1351-
class ChildCheckerVariableDepth
1352-
{
1353-
public:
1354-
inline constexpr ChildCheckerVariableDepth(depth_t examinedLevel, depth_t maxDepthNo, DepthAndLocationID const& depthAndLocation) noexcept
1355-
: m_examinedDepthID(maxDepthNo - examinedLevel)
1356-
, m_childID(GetLocationIDOnExaminedLevel(depthAndLocation.LocID, depthAndLocation.DepthID - m_examinedDepthID) & m_mask)
1357-
{}
1358-
1359-
inline constexpr ChildID GetChildID() const noexcept { return CastMortonIDToChildID(m_childID); }
1360-
1361-
inline constexpr bool Test(DepthAndLocationID const& depthAndLocation) const noexcept
1362-
{
1363-
assert(m_examinedDepthID <= depthAndLocation.DepthID);
1364-
auto const locationIDOnExaminationLevel = GetLocationIDOnExaminedLevel(depthAndLocation.LocID, depthAndLocation.DepthID - m_examinedDepthID);
1365-
return (locationIDOnExaminationLevel & m_mask) == m_childID;
1366-
}
1367-
1368-
private:
1369-
static constexpr LocationID m_mask = CHILD_NO - 1;
1370-
depth_t m_examinedDepthID;
1371-
LocationID m_childID;
1372-
};
1373-
13741350
class ChildKeyGenerator
13751351
{
13761352
public:
@@ -1384,18 +1360,10 @@ namespace OrthoTree
13841360
NodeID m_parentFlag;
13851361
};
13861362

1387-
class GridConverter
1363+
static inline constexpr NodeID GetHashAtDepth(auto&& location, depth_t maxDepthNo) noexcept
13881364
{
1389-
public:
1390-
explicit GridConverter(depth_t examinedLevel)
1391-
: m_shift(examinedLevel * DIMENSION_NO)
1392-
{}
1393-
1394-
LocationID GetLocationID(DimArray<GridID> const& gridID) const noexcept { return Encode(gridID) >> m_shift; }
1395-
1396-
private:
1397-
UnderlyingInt m_shift;
1398-
};
1365+
return (NodeID{ 1 } << (location.DepthID * DIMENSION_NO)) | (location.LocID >> ((maxDepthNo - location.DepthID) * DIMENSION_NO));
1366+
}
13991367

14001368
static inline constexpr NodeID GetHash(auto&& location) noexcept
14011369
{
@@ -1738,9 +1706,24 @@ namespace OrthoTree
17381706
static inline constexpr DepthAndLocationID GetDepthAndLocationID(depth_t maxDepthNo, std::array<LocationID, 2> const& locationIDRange) noexcept
17391707
{
17401708
auto dl = DepthAndLocationID{ maxDepthNo, locationIDRange[0] };
1709+
if (locationIDRange[0] != locationIDRange[1])
1710+
{
1711+
depth_t levelID = 0;
1712+
if constexpr (false)
1713+
{
1714+
auto const differentBitNo = std::bit_width(locationIDRange[0] ^ locationIDRange[1]);
1715+
levelID = (differentBitNo + DIMENSION_NO - 1) / DIMENSION_NO;
1716+
}
1717+
else
1718+
{
1719+
for (auto diffLocationFlag = locationIDRange[0] ^ locationIDRange[1]; diffLocationFlag != 0; diffLocationFlag >>= DIMENSION_NO)
1720+
++levelID;
1721+
}
17411722

1742-
for (auto diffLocationFlag = locationIDRange[0] ^ locationIDRange[1]; IsValidKey(diffLocationFlag); diffLocationFlag >>= DIMENSION_NO, --dl.DepthID)
1743-
dl.LocID = GetParentGridID(dl.LocID);
1723+
dl.DepthID -= levelID;
1724+
dl.LocID >>= levelID * DIMENSION_NO;
1725+
dl.LocID <<= levelID * DIMENSION_NO;
1726+
}
17441727

17451728
return dl;
17461729
}
@@ -1757,23 +1740,13 @@ namespace OrthoTree
17571740

17581741
static inline constexpr NodeID GetNodeID(depth_t maxDepthNo, std::array<LocationID, 2> const& locationIDRange) noexcept
17591742
{
1760-
return GetHash(GetDepthAndLocationID(maxDepthNo, locationIDRange));
1743+
return GetHashAtDepth(GetDepthAndLocationID(maxDepthNo, locationIDRange), maxDepthNo);
17611744
}
17621745

17631746
static inline constexpr auto IsLess(DepthAndLocationID const& leftLocation, DepthAndLocationID const& rightLocation) noexcept
17641747
{
1765-
if (leftLocation.DepthID == rightLocation.DepthID)
1766-
return leftLocation.LocID < rightLocation.LocID;
1767-
else if (leftLocation.DepthID < rightLocation.DepthID)
1768-
{
1769-
auto const locationIDRight = GetLocationIDOnExaminedLevel(rightLocation.LocID, rightLocation.DepthID - leftLocation.DepthID);
1770-
return leftLocation.LocID <= locationIDRight;
1771-
}
1772-
else
1773-
{
1774-
auto const locationIDLeft = GetLocationIDOnExaminedLevel(leftLocation.LocID, leftLocation.DepthID - rightLocation.DepthID);
1775-
return locationIDLeft < rightLocation.LocID;
1776-
}
1748+
return (leftLocation.LocID < rightLocation.LocID) ||
1749+
((leftLocation.LocID == rightLocation.LocID) && (leftLocation.DepthID < rightLocation.DepthID));
17771750
}
17781751
};
17791752
} // namespace detail
@@ -2169,22 +2142,22 @@ namespace OrthoTree
21692142
auto parentEntities = std::vector<TEntityID>{}; // Box entities could be stuck in the parent node.
21702143
for (auto const entityID : GetNodeEntities(parentNode))
21712144
{
2172-
auto const [depthID, locationID] = this->GetDepthAndLocationID(detail::at(geometryCollection, entityID));
2173-
if (depthID <= parentDepth)
2145+
auto depthAndLocation = this->GetDepthAndLocationID(detail::at(geometryCollection, entityID));
2146+
if (depthAndLocation.DepthID <= parentDepth)
21742147
{
21752148
parentEntities.emplace_back(entityID);
21762149
continue;
21772150
}
21782151

21792152
// i-th entity should be moved to a child node
21802153

2181-
auto const childID = SI::GetChildIDByDepth(parentDepth, depthID, locationID);
2154+
auto const childID = SI::GetChildIDByDepth(parentDepth, m_maxDepthNo, depthAndLocation.LocID);
21822155
auto const childNodeKey = childGenerator.GetChildNodeKey(childID);
21832156
if (parentNode.HasChild(childNodeKey))
21842157
{
2185-
auto const entitiyNodeKey_ = SI::GetHash(depthID, locationID);
2158+
auto const entitiyNodeKey_ = SI::GetHashAtDepth(depthAndLocation, m_maxDepthNo);
21862159
auto const [parentNodeKey_, parentDepthID_] = FindSmallestNodeKeyWithDepth(entitiyNodeKey_);
2187-
InsertWithRebalancingBase<false>(parentNodeKey_, parentDepthID_, entitiyNodeKey_, depthID, entityID, geometryCollection);
2160+
InsertWithRebalancingBase<false>(parentNodeKey_, parentDepthID_, entitiyNodeKey_, depthAndLocation.DepthID, entityID, geometryCollection);
21882161
}
21892162
else
21902163
{
@@ -2565,7 +2538,7 @@ namespace OrthoTree
25652538
template<bool HANDLE_OUT_OF_TREE_GEOMETRY = false>
25662539
MortonNodeID GetNodeID(TBox const& box) const noexcept
25672540
{
2568-
return SI::GetHash(this->GetDepthAndLocationID<HANDLE_OUT_OF_TREE_GEOMETRY>(box));
2541+
return SI::GetHashAtDepth(this->GetDepthAndLocationID<HANDLE_OUT_OF_TREE_GEOMETRY>(box), m_maxDepthNo);
25692542
}
25702543

25712544
// Find smallest node which contains the box
@@ -2801,7 +2774,7 @@ namespace OrthoTree
28012774
return foundNodes;
28022775
}
28032776

2804-
auto const rangeKey = SI::GetHash(this->GetDepthAndLocationID<!IS_BOX_TYPE, TBoxRange>(range));
2777+
auto const rangeKey = SI::GetHashAtDepth(this->GetDepthAndLocationID<!IS_BOX_TYPE, TBoxRange>(range), m_maxDepthNo);
28052778
auto smallestNodeKey = this->FindSmallestNodeKey(rangeKey);
28062779
if (!SI::IsValidKey(smallestNodeKey))
28072780
{
@@ -3552,12 +3525,12 @@ namespace OrthoTree
35523525
auto const keyGenerator = typename SI::ChildKeyGenerator(parentKey);
35533526
while (beginLocationIterator != endLocationIterator)
35543527
{
3555-
auto const childChecker = typename SI::ChildCheckerVariableDepth(remainingDepthNo, this->m_maxDepthNo, beginLocationIterator->DepthAndLocation);
3528+
auto const childChecker = typename SI::ChildCheckerFixedDepth(remainingDepthNo, beginLocationIterator->DepthAndLocation.LocID);
35563529
auto const actualEndLocationIterator = std::partition_point(beginLocationIterator, endLocationIterator, [&](auto const& location) {
3557-
return childChecker.Test(location.DepthAndLocation);
3530+
return childChecker.Test(location.DepthAndLocation.LocID);
35583531
});
35593532

3560-
auto const childKey = keyGenerator.GetChildNodeKey(childChecker.GetChildID());
3533+
auto const childKey = keyGenerator.GetChildNodeKey(childChecker.GetChildID(remainingDepthNo));
35613534

35623535
parentNode.AddChild(childKey);
35633536
auto& nodeChild = this->CreateChild(parentNode, childKey);
@@ -3595,11 +3568,10 @@ namespace OrthoTree
35953568
Base::template ConstructGridIDListRecursively<DIMENSION_NO>(gridStepNo, gridBoundaries, temporaryGridID, gridIDs);
35963569

35973570
auto const boxNo = gridIDs.size();
3598-
auto const gridGenerator = typename SI::GridConverter(remainingDepthNo);
35993571

36003572
// First element into locationID
36013573
location.DepthAndLocation.DepthID = depthID;
3602-
location.DepthAndLocation.LocID = gridGenerator.GetLocationID(gridIDs[0]);
3574+
location.DepthAndLocation.LocID = SI::Encode(gridIDs[0]);
36033575
auto const entityID = location.EntityID;
36043576

36053577
auto const additionalBoxNo = boxNo - 1;
@@ -3612,7 +3584,7 @@ namespace OrthoTree
36123584
auto& location = additionalLocations.at(locationNo + iBox);
36133585
location.EntityID = entityID;
36143586
location.DepthAndLocation.DepthID = depthID;
3615-
location.DepthAndLocation.LocID = gridGenerator.GetLocationID(gridIDs[iBox + 1]);
3587+
location.DepthAndLocation.LocID = SI::Encode(gridIDs[iBox + 1]);
36163588
}
36173589
}
36183590

@@ -3738,7 +3710,7 @@ namespace OrthoTree
37383710

37393711
for (auto const& location : locations)
37403712
{
3741-
auto const entityNodeKey = SI::GetHash(location.DepthAndLocation);
3713+
auto const entityNodeKey = SI::GetHashAtDepth(location.DepthAndLocation, this->GetDepthMax());
37423714
auto const parentNodeKey = this->FindSmallestNodeKey(entityNodeKey);
37433715

37443716
if (!this->template InsertWithRebalancingBase<SPLIT_DEPTH_INCREASEMENT == 0>(
@@ -3765,7 +3737,7 @@ namespace OrthoTree
37653737

37663738
for (auto const& location : locations)
37673739
{
3768-
auto const entityNodeKey = SI::GetHash(location.DepthAndLocation);
3740+
auto const entityNodeKey = SI::GetHashAtDepth(location.DepthAndLocation, this->GetDepthMax());
37693741
if (!this->template InsertWithoutRebalancingBase<SPLIT_DEPTH_INCREASEMENT == 0>(smallestNodeKey, entityNodeKey, newEntityID, doInsertToLeaf))
37703742
return false;
37713743
}

0 commit comments

Comments
 (0)