116 const typename GridType::BBoxType&,
126 using KeyType = GridType::CellPos;
135 template<
typename QueryValueType>
151 template<
typename QueryValueType>
153 std::function<
typename GridType::ScalarType(
156 typename GridType::ScalarType)>;
158 bool cellEmpty(
const KeyType&
k)
const
160 auto p = derived()->valuesInCell(
k);
161 return p.first ==
p.second;
164 std::size_t countInCell(
const KeyType&
k)
const
166 auto p = derived()->valuesInCell(
k);
167 return std::distance(
p.first,
p.second);
193 typename GridType::PointType
p;
211 if (mIntersectsFun) {
212 for (
const auto& cell : GridType::cells(
bmin,
bmax)) {
215 ins |= derived()->insertInCell(cell, v);
220 for (
const auto& cell : GridType::cells(
bmin,
bmax)) {
221 ins |= derived()->insertInCell(cell, v);
236 template<
typename ObjIterator>
256 return insert(std::ranges::begin(
r), std::ranges::end(
r));
259 bool erase(
const ValueType& v)
268 typename GridType::PointType
p;
278 bmin = GridType::cell(bb.min);
279 bmax = GridType::cell(bb.max);
283 for (
const auto& cell : GridType::cells(bmin, bmax)) {
284 found |= derived()->eraseInCell(cell, v);
291 bool eraseAllInCell(
const KeyType& k)
294 auto& p = derived()->valuesInCell(k);
296 for (
auto it = p.first; it != p.second; ++it) {
297 res |= derived()->eraseInCell(k, it->second);
303 uint countInSphere(
const Sphere<typename GridType::ScalarType>& s)
const
305 return valuesInSphere(s).
size();
310 auto valuesInSphere(
const Sphere<typename GridType::ScalarType>& s)
const
312 using Iter = DerivedGrid::ConstIterator;
313 using IterSet = std::set<Iter, IterComparator<Iter>>;
320 std::vector<Iter> resVec;
323 KeyType first = GridType::cell(s.center() - s.radius());
324 KeyType last = GridType::cell(s.center() + s.radius());
327 for (
const KeyType& c : GridType::cells(first, last)) {
329 const auto& p = derived()->valuesInCell(c);
331 for (
auto it = p.first; it != p.second; ++it) {
333 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
334 valuesSet.insert(it);
337 resVec.push_back(it);
345 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
346 resVec = std::vector<Iter>(valuesSet.begin(), valuesSet.end());
351 void eraseInSphere(
const Sphere<typename GridType::ScalarType>& s)
354 KeyType first = GridType::cell(s.center() - s.radius());
355 KeyType last = GridType::cell(s.center() + s.radius());
358 for (
const KeyType& c : GridType::cells(first, last)) {
360 const auto& p = derived()->valuesInCell(c);
362 for (
auto it = p.first; it != p.second; ++it) {
364 eraseInCell(it->first, it->second);
371 template<
typename QueryValueType>
373 const QueryValueType& qv,
375 typename GridType::ScalarType& dist)
const
377 using ScalarType = GridType::ScalarType;
378 using PointType = GridType::PointType;
379 using ResType = DerivedGrid::ConstIterator;
381 using QVT = RemoveCVRefAndPointer<QueryValueType>;
383 ResType result = derived()->end();
386 typename GridType::ScalarType maxDist = dist;
388 const ScalarType cellDiagonal = GridType::cellDiagonal();
391 typename GridType::BBoxType bb =
boundingBox(*qvv);
393 ScalarType centerDist = cellDiagonal;
394 PointType center = bb.center();
400 Boxui currentIntervalBox;
401 Boxui lastIntervalBox = currentIntervalBox;
403 currentIntervalBox.
add(GridType::cell(bb.min()));
405 currentIntervalBox.
add(GridType::cell(bb.max()));
408 ScalarType tmp = cellDiagonal;
418 if (result != derived()->end()) {
431 lastIntervalBox = currentIntervalBox;
432 currentIntervalBox.add(GridType::cell(center - centerDist));
433 currentIntervalBox.add(GridType::cell(center + centerDist));
442 end = result != derived()->end();
443 end |= (centerDist > maxDist);
445 (center - centerDist < GridType::min() &&
446 center + centerDist > GridType::max());
450 centerDist += cellDiagonal;
454 if (result != derived()->end()) {
457 currentIntervalBox.
add(GridType::cell(center - dist));
458 currentIntervalBox.
add(GridType::cell(center + dist));
465 if (r != derived()->end()) {
474 template<
typename QueryValueType>
476 const QueryValueType& qv,
478 typename GridType::ScalarType& dist)
const
480 QueryBoundedDistFunction<QueryValueType> boundDistFun =
481 [&](
const QueryValueType& q,
482 const RemoveCVRefAndPointer<ValueType>& v,
483 typename GridType::ScalarType) {
487 dist = std::numeric_limits<typename GridType::ScalarType>::max();
489 return closestValue(qv, boundDistFun, dist);
492 template<
typename QueryValueType>
494 const QueryValueType& qv,
497 typename GridType::ScalarType maxDist =
498 std::numeric_limits<typename GridType::ScalarType>::max();
502 template<
typename QueryValueType>
504 const QueryValueType& qv,
505 typename GridType::ScalarType& dist)
const
509 RemoveCVRefAndPointer<ValueType>,
510 typename GridType::ScalarType>();
511 return closestValue(qv, f, dist);
514 template<
typename QueryValueType>
515 auto closestValue(
const QueryValueType& qv)
const
519 RemoveCVRefAndPointer<ValueType>,
520 typename GridType::ScalarType>();
521 typename GridType::ScalarType maxDist =
522 std::numeric_limits<typename GridType::ScalarType>::max();
523 return closestValue(qv, f, maxDist);
526 template<
typename QueryValueType>
528 const QueryValueType& qv,
532 using ResType = std::vector<typename DerivedGrid::ConstIterator>;
534 using KClosestPairType = std::pair<
535 typename GridType::ScalarType,
536 typename DerivedGrid::ConstIterator>;
537 using KClosestSet = std::
538 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
542 KClosestSet set = valuesInCellNeighborhood(qv, n,
distFunction, ignore);
544 auto it = set.size() >= n ? std::next(set.begin(), n - 1) : set.end();
547 if (it != set.end()) {
548 using QVT = RemoveCVRefAndPointer<QueryValueType>;
552 typename GridType::BBoxType bb =
boundingBox(*qvv);
557 bb.min() -= it->first;
558 bb.max() += it->first;
561 Boxui currentIntervalBox;
563 currentIntervalBox.
add(GridType::cell(bb.min()));
565 currentIntervalBox.
add(GridType::cell(bb.max()));
568 for (
const KeyType& c : GridType::cells(
569 currentIntervalBox.
min(), currentIntervalBox.
max())) {
570 if (!ignore.isInside(c)) {
572 const auto& p = derived()->valuesInCell(c);
574 for (
auto it = p.first; it != p.second; ++it) {
576 set.insert(std::make_pair(tmp, it));
585 uint retNValues = std::min((uint) set.size(), n);
586 vec.reserve(retNValues);
588 for (uint i = 0; i < retNValues; i++) {
589 vec.push_back(it->second);
595 template<
typename QueryValueType>
596 auto kClosestValues(
const QueryValueType& qv, uint n)
const
601 distFunction<QueryValueType, RemoveCVRefAndPointer<ValueType>>();
602 return kClosestValues(qv, n, f);
622 const GridType&
grid,
624 GridType(
grid), mIntersectsFun(intersects)
641 template<Po
intConcept Po
intType>
643 const PointType&
min,
644 const PointType&
max,
645 const KeyType&
sizes,
647 GridType(
min,
max,
sizes), mIntersectsFun(intersects)
662 template<
typename BoxType>
665 const KeyType&
sizes,
667 GridType(
bbox,
sizes), mIntersectsFun(intersects)
691 template<
typename ObjIterator>
696 mIntersectsFun(intersects)
698 using ScalarType = GridType::ScalarType;
699 using BBoxType = GridType::BBoxType;
700 using CellPos = GridType::CellPos;
738 AbstractGrid(std::ranges::begin(
r), std::ranges::end(
r), intersects)
751 template<
typename Iter>
756 return i1->second <
i2->second;
760 template<
typename Pair>
763 bool operator()(
const Pair& p1,
const Pair&
p2)
const
765 if (p1.first ==
p2.first) {
766 return p1.second->second <
p2.second->second;
768 return p1.first <
p2.first;
785 template<
typename Iterator>
790 using PointType = GridType::PointType;
800 p = &(
vv->position());
814 template<
typename QueryValueType>
817 typename GridType::ScalarType& dist,
822 using ResType = DerivedGrid::ConstIterator;
826 for (
const KeyType& c :
830 const auto&
p = derived()->valuesInCell(c);
832 for (
auto it =
p.first;
it !=
p.second; ++
it) {
845 template<
typename QueryValueType>
846 auto valuesInCellNeighborhood(
854 typename GridType::ScalarType,
855 typename DerivedGrid::ConstIterator>;
857 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
876 for (
const KeyType& c : GridType::cells(
879 const auto&
p = derived()->valuesInCell(c);
882 for (
auto it =
p.first;
it !=
p.second; ++
it) {
889 ignore = currentIntervalBox;
890 for (uint i = 0; i < currentIntervalBox.min().DIM; ++i) {
891 if (currentIntervalBox.min()(i) != 0)
892 currentIntervalBox.
min()(i)--;
893 if (currentIntervalBox.max()(i) !=
894 GridType::cellNumber(i) - 1)
895 currentIntervalBox.max()(i)++;