118 const typename GridType::BBoxType&,
128 using KeyType = GridType::CellCoord;
137 template<
typename QueryValueType>
153 template<
typename QueryValueType>
155 std::function<
typename GridType::ScalarType(
158 typename GridType::ScalarType)>;
160 bool cellEmpty(
const KeyType&
k)
const
162 auto p = derived()->valuesInCell(
k);
163 return p.first ==
p.second;
166 std::size_t countInCell(
const KeyType&
k)
const
168 auto p = derived()->valuesInCell(
k);
169 return std::distance(
p.first,
p.second);
195 typename GridType::PointType
p;
206 bmin = GridType::cell(
bb.min());
207 bmax = GridType::cell(
bb.max());
213 if (mIntersectsFun) {
214 for (
const auto& cell : GridType::cells(
bmin,
bmax)) {
217 ins |= derived()->insertInCell(cell, v);
222 for (
const auto& cell : GridType::cells(
bmin,
bmax)) {
223 ins |= derived()->insertInCell(cell, v);
238 template<
typename ObjIterator>
258 return insert(std::ranges::begin(
r), std::ranges::end(
r));
261 bool erase(
const ValueType& v)
270 typename GridType::PointType
p;
280 bmin = GridType::cell(bb.min);
281 bmax = GridType::cell(bb.max);
285 for (
const auto& cell : GridType::cells(bmin, bmax)) {
286 found |= derived()->eraseInCell(cell, v);
293 bool eraseAllInCell(
const KeyType& k)
296 auto& p = derived()->valuesInCell(k);
298 for (
auto it = p.first; it != p.second; ++it) {
299 res |= derived()->eraseInCell(k, it->second);
305 uint countInSphere(
const Sphere<typename GridType::ScalarType>& s)
const
307 return valuesInSphere(s).size();
312 auto valuesInSphere(
const Sphere<typename GridType::ScalarType>& s)
const
314 using Iter = DerivedGrid::ConstIterator;
315 using IterSet = std::set<Iter, IterComparator<Iter>>;
322 std::vector<Iter> resVec;
325 KeyType first = GridType::cell(s.center() - s.radius());
326 KeyType last = GridType::cell(s.center() + s.radius());
329 for (
const KeyType& c : GridType::cells(first, last)) {
331 const auto& p = derived()->valuesInCell(c);
333 for (
auto it = p.first; it != p.second; ++it) {
335 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
336 valuesSet.insert(it);
339 resVec.push_back(it);
347 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
348 resVec = std::vector<Iter>(valuesSet.begin(), valuesSet.end());
353 void eraseInSphere(
const Sphere<typename GridType::ScalarType>& s)
356 KeyType first = GridType::cell(s.center() - s.radius());
357 KeyType last = GridType::cell(s.center() + s.radius());
360 for (
const KeyType& c : GridType::cells(first, last)) {
362 const auto& p = derived()->valuesInCell(c);
364 for (
auto it = p.first; it != p.second; ++it) {
366 eraseInCell(it->first, it->second);
373 template<
typename QueryValueType>
375 const QueryValueType& qv,
377 typename GridType::ScalarType& dist)
const
379 using ScalarType = GridType::ScalarType;
380 using PointType = GridType::PointType;
381 using ResType = DerivedGrid::ConstIterator;
383 using QVT = RemoveCVRefAndPointer<QueryValueType>;
385 ResType result = derived()->end();
388 typename GridType::ScalarType maxDist = dist;
390 const ScalarType cellDiagonal = GridType::cellDiagonal();
393 typename GridType::BBoxType bb =
boundingBox(*qvv);
395 ScalarType centerDist = cellDiagonal;
396 PointType center = bb.center();
402 Boxui currentIntervalBox;
403 Boxui lastIntervalBox = currentIntervalBox;
405 currentIntervalBox.add(GridType::cell(bb.min()));
407 currentIntervalBox.add(GridType::cell(bb.max()));
410 ScalarType tmp = cellDiagonal;
420 if (result != derived()->end()) {
433 lastIntervalBox = currentIntervalBox;
434 currentIntervalBox.add(GridType::cell(center - centerDist));
435 currentIntervalBox.add(GridType::cell(center + centerDist));
444 end = result != derived()->end();
445 end |= (centerDist > maxDist);
447 (center - centerDist < GridType::min() &&
448 center + centerDist > GridType::max());
452 centerDist += cellDiagonal;
456 if (result != derived()->end()) {
459 currentIntervalBox.add(GridType::cell(center - dist));
460 currentIntervalBox.add(GridType::cell(center + dist));
467 if (r != derived()->end()) {
476 template<
typename QueryValueType>
478 const QueryValueType& qv,
480 typename GridType::ScalarType& dist)
const
482 QueryBoundedDistFunction<QueryValueType> boundDistFun =
483 [&](
const QueryValueType& q,
484 const RemoveCVRefAndPointer<ValueType>& v,
485 typename GridType::ScalarType) {
489 dist = std::numeric_limits<typename GridType::ScalarType>::max();
491 return closestValue(qv, boundDistFun, dist);
494 template<
typename QueryValueType>
496 const QueryValueType& qv,
499 typename GridType::ScalarType maxDist =
500 std::numeric_limits<typename GridType::ScalarType>::max();
504 template<
typename QueryValueType>
506 const QueryValueType& qv,
507 typename GridType::ScalarType& dist)
const
511 RemoveCVRefAndPointer<ValueType>,
512 typename GridType::ScalarType>();
513 return closestValue(qv, f, dist);
516 template<
typename QueryValueType>
517 auto closestValue(
const QueryValueType& qv)
const
521 RemoveCVRefAndPointer<ValueType>,
522 typename GridType::ScalarType>();
523 typename GridType::ScalarType maxDist =
524 std::numeric_limits<typename GridType::ScalarType>::max();
525 return closestValue(qv, f, maxDist);
528 template<
typename QueryValueType>
530 const QueryValueType& qv,
534 using ResType = std::vector<typename DerivedGrid::ConstIterator>;
536 using KClosestPairType = std::pair<
537 typename GridType::ScalarType,
538 typename DerivedGrid::ConstIterator>;
539 using KClosestSet = std::
540 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
544 KClosestSet set = valuesInCellNeighborhood(qv, n,
distFunction, ignore);
546 auto it = set.size() >= n ? std::next(set.begin(), n - 1) : set.end();
549 if (it != set.end()) {
550 using QVT = RemoveCVRefAndPointer<QueryValueType>;
554 typename GridType::BBoxType bb =
boundingBox(*qvv);
559 bb.min() -= it->first;
560 bb.max() += it->first;
563 Boxui currentIntervalBox;
565 currentIntervalBox.add(GridType::cell(bb.min()));
567 currentIntervalBox.add(GridType::cell(bb.max()));
570 for (
const KeyType& c : GridType::cells(
571 currentIntervalBox.
min(), currentIntervalBox.
max())) {
572 if (!ignore.isInside(c)) {
574 const auto& p = derived()->valuesInCell(c);
576 for (
auto it = p.first; it != p.second; ++it) {
578 set.insert(std::make_pair(tmp, it));
587 uint retNValues = std::min((uint) set.size(), n);
588 vec.reserve(retNValues);
590 for (uint i = 0; i < retNValues; i++) {
591 vec.push_back(it->second);
597 template<
typename QueryValueType>
598 auto kClosestValues(
const QueryValueType& qv, uint n)
const
603 distFunction<QueryValueType, RemoveCVRefAndPointer<ValueType>>();
604 return kClosestValues(qv, n, f);
624 const GridType&
grid,
626 GridType(
grid), mIntersectsFun(intersects)
643 template<Po
intConcept Po
intType>
645 const PointType&
min,
646 const PointType&
max,
647 const KeyType&
sizes,
649 GridType(
min,
max,
sizes), mIntersectsFun(intersects)
664 template<
typename BoxType>
667 const KeyType&
sizes,
669 GridType(
bbox,
sizes), mIntersectsFun(intersects)
693 template<
typename ObjIterator>
698 mIntersectsFun(intersects)
700 using ScalarType = GridType::ScalarType;
701 using BBoxType = GridType::BBoxType;
702 using CellCoord = GridType::CellCoord;
740 AbstractGrid(std::ranges::begin(
r), std::ranges::end(
r), intersects)
753 template<
typename Iter>
758 return i1->second <
i2->second;
762 template<
typename Pair>
765 bool operator()(
const Pair& p1,
const Pair&
p2)
const
767 if (p1.first ==
p2.first) {
768 return p1.second->second <
p2.second->second;
770 return p1.first <
p2.first;
787 template<
typename Iterator>
792 using PointType = GridType::PointType;
816 template<
typename QueryValueType>
819 typename GridType::ScalarType& dist,
824 using ResType = DerivedGrid::ConstIterator;
828 for (
const KeyType& c :
830 if (!
ignore.isInsideStrict(c)) {
832 const auto&
p = derived()->valuesInCell(c);
834 for (
auto it =
p.first;
it !=
p.second; ++
it) {
847 template<
typename QueryValueType>
848 auto valuesInCellNeighborhood(
856 typename GridType::ScalarType,
857 typename DerivedGrid::ConstIterator>;
859 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
878 for (
const KeyType& c : GridType::cells(
880 if (!
ignore.isInside(c)) {
881 const auto&
p = derived()->valuesInCell(c);
884 for (
auto it =
p.first;
it !=
p.second; ++
it) {
891 ignore = currentIntervalBox;
892 for (uint i = 0; i < currentIntervalBox.min().DIM; ++i) {
893 if (currentIntervalBox.min()(i) != 0)
894 currentIntervalBox.min()(i)--;
895 if (currentIntervalBox.max()(i) !=
896 GridType::cellNumber(i) - 1)
897 currentIntervalBox.max()(i)++;