1 #include "objects/finders/IncrementalFinder.h"
2 
3 NAMESPACE_SPH_BEGIN
4 
addPoint(const Vector & p)5 IncrementalFinder::Handle IncrementalFinder::addPoint(const Vector& p) {
6     const Indices idxs = floor(p / cellSize);
7     Cell& cell = map[idxs];
8     cell.push(p);
9     count++;
10     return Handle(idxs, cell.size() - 1, {});
11 }
12 
addPoints(ArrayView<const Vector> points)13 void IncrementalFinder::addPoints(ArrayView<const Vector> points) {
14     for (const Vector& p : points) {
15         this->addPoint(p);
16     }
17 }
18 
point(const Handle & handle) const19 Vector IncrementalFinder::point(const Handle& handle) const {
20     return map.at(handle.coords())[handle.index()];
21 }
22 
array() const23 Array<Vector> IncrementalFinder::array() const {
24     Array<Vector> result;
25     for (const auto& cell : map) {
26         for (const Vector& p : cell.second) {
27             result.push(p);
28         }
29     }
30     return result;
31 }
32 
size() const33 Size IncrementalFinder::size() const {
34     return count;
35 }
36 
getNeighCnt(const Vector & center,const Float radius) const37 Size IncrementalFinder::getNeighCnt(const Vector& center, const Float radius) const {
38     Size count = 0;
39     this->findAll(center, radius, [&count](const Handle& UNUSED(handle)) { //
40         ++count;
41     });
42     return count;
43 }
44 
findAll(const Vector & center,const Float radius,Array<Handle> & handles) const45 void IncrementalFinder::findAll(const Vector& center, const Float radius, Array<Handle>& handles) const {
46     handles.clear();
47     this->findAll(center, radius, [&handles](const Handle& handle) { //
48         handles.push(handle);
49     });
50 }
51 
findAll(const Vector & center,const Float radius,Array<Vector> & neighs) const52 void IncrementalFinder::findAll(const Vector& center, const Float radius, Array<Vector>& neighs) const {
53     neighs.clear();
54     this->findAll(center, radius, [this, &neighs](const Handle& handle) { //
55         neighs.push(point(handle));
56     });
57 }
58 
59 
60 template <typename TAdd>
findAll(const Vector & center,const Float radius,const TAdd & add) const61 void IncrementalFinder::findAll(const Vector& center, const Float radius, const TAdd& add) const {
62     const Sphere search(center, radius);
63     const Indices idxs0 = floor(center / cellSize);
64 
65     Indices left = idxs0;
66     Indices right = idxs0;
67     for (Size i = 0; i < 3; ++i) {
68         Indices next = idxs0;
69         while (true) {
70             next[i]++;
71             if (search.overlaps(cellBox(next))) {
72                 right[i] = next[i];
73             } else {
74                 break;
75             }
76         }
77 
78         next = idxs0;
79         while (true) {
80             next[i]--;
81             if (search.overlaps(cellBox(next))) {
82                 left[i] = next[i];
83             } else {
84                 break;
85             }
86         }
87     }
88 
89     for (int z = left[2]; z <= right[2]; ++z) {
90         for (int y = left[1]; y <= right[1]; ++y) {
91             for (int x = left[0]; x <= right[0]; ++x) {
92                 const Indices idxs(x, y, z);
93                 const auto iter = map.find(idxs);
94                 if (iter == map.end()) {
95                     continue;
96                 }
97 
98                 for (Size i = 0; i < iter->second.size(); ++i) {
99                     const Vector& p = iter->second[i];
100                     const Float distSqr = getSqrLength(p - center);
101                     if (distSqr < sqr(radius)) {
102                         add(Handle(idxs, i, {}));
103                     }
104                 }
105             }
106         }
107     }
108 }
109 
110 NAMESPACE_SPH_END
111