Viskores  1.0
exec/PointLocatorSparseGrid.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_exec_PointLocatorSparseGrid_h
19 #define viskores_exec_PointLocatorSparseGrid_h
20 
22 
24 
25 namespace viskores
26 {
27 namespace exec
28 {
29 
36 class VISKORES_ALWAYS_EXPORT PointLocatorSparseGrid
37 {
38 public:
39  using CoordPortalType =
40  typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
42 
43 
45  const viskores::Vec3f& max,
46  const viskores::Id3& dims,
47  const CoordPortalType& coords,
48  const IdPortalType& pointIds,
49  const IdPortalType& cellLower,
50  const IdPortalType& cellUpper)
51  : Min(min)
52  , Dims(dims)
53  , Dxdydz((max - Min) / Dims)
54  , Coords(coords)
55  , PointIds(pointIds)
56  , CellLower(cellLower)
57  , CellUpper(cellUpper)
58  {
59  }
60 
72  viskores::Id& nearestNeighborId,
73  viskores::FloatDefault& distance2) const
74  {
75  //std::cout << "FindNeareastNeighbor: " << queryPoint << std::endl;
76  viskores::Id3 ijk = (queryPoint - this->Min) / this->Dxdydz;
77  ijk = viskores::Max(ijk, viskores::Id3(0));
78  ijk = viskores::Min(ijk, this->Dims - viskores::Id3(1));
79 
80  nearestNeighborId = -1;
81  distance2 = viskores::Infinity<viskores::FloatDefault>();
82 
83  this->FindInCell(queryPoint, ijk, nearestNeighborId, distance2);
84 
85  // TODO: This might stop looking before the absolute nearest neighbor is found.
86  viskores::Id maxLevel =
87  viskores::Max(viskores::Max(this->Dims[0], this->Dims[1]), this->Dims[2]);
88  viskores::Id level;
89  for (level = 1; (nearestNeighborId < 0) && (level < maxLevel); ++level)
90  {
91  this->FindInBox(queryPoint, ijk, level, nearestNeighborId, distance2);
92  }
93 
94  // Search one more level out. This is still not guaranteed to find the closest point
95  // in all cases (past level 2), but it will catch most cases where the closest point
96  // is just on the other side of a cell boundary.
97  this->FindInBox(queryPoint, ijk, level, nearestNeighborId, distance2);
98  }
99 
100 private:
104 
106 
110 
111  VISKORES_EXEC void FindInCell(const viskores::Vec3f& queryPoint,
112  const viskores::Id3& ijk,
113  viskores::Id& nearestNeighborId,
114  viskores::FloatDefault& nearestDistance2) const
115  {
116  viskores::Id cellId =
117  ijk[0] + (ijk[1] * this->Dims[0]) + (ijk[2] * this->Dims[0] * this->Dims[1]);
118  viskores::Id lower = this->CellLower.Get(cellId);
119  viskores::Id upper = this->CellUpper.Get(cellId);
120  for (viskores::Id index = lower; index < upper; index++)
121  {
122  viskores::Id pointid = this->PointIds.Get(index);
123  viskores::Vec3f point = this->Coords.Get(pointid);
124  viskores::FloatDefault distance2 = viskores::MagnitudeSquared(point - queryPoint);
125  if (distance2 < nearestDistance2)
126  {
127  nearestNeighborId = pointid;
128  nearestDistance2 = distance2;
129  }
130  }
131  }
132 
133  VISKORES_EXEC void FindInBox(const viskores::Vec3f& queryPoint,
134  const viskores::Id3& boxCenter,
135  viskores::Id level,
136  viskores::Id& nearestNeighborId,
137  viskores::FloatDefault& nearestDistance2) const
138  {
139  if ((boxCenter[0] - level) >= 0)
140  {
141  this->FindInXPlane(queryPoint,
142  boxCenter - viskores::Id3(level, 0, 0),
143  level,
144  nearestNeighborId,
145  nearestDistance2);
146  }
147  if ((boxCenter[0] + level) < this->Dims[0])
148  {
149  this->FindInXPlane(queryPoint,
150  boxCenter + viskores::Id3(level, 0, 0),
151  level,
152  nearestNeighborId,
153  nearestDistance2);
154  }
155 
156  if ((boxCenter[1] - level) >= 0)
157  {
158  this->FindInYPlane(queryPoint,
159  boxCenter - viskores::Id3(0, level, 0),
160  level,
161  nearestNeighborId,
162  nearestDistance2);
163  }
164  if ((boxCenter[1] + level) < this->Dims[1])
165  {
166  this->FindInYPlane(queryPoint,
167  boxCenter + viskores::Id3(0, level, 0),
168  level,
169  nearestNeighborId,
170  nearestDistance2);
171  }
172 
173  if ((boxCenter[2] - level) >= 0)
174  {
175  this->FindInZPlane(queryPoint,
176  boxCenter - viskores::Id3(0, 0, level),
177  level,
178  nearestNeighborId,
179  nearestDistance2);
180  }
181  if ((boxCenter[2] + level) < this->Dims[2])
182  {
183  this->FindInZPlane(queryPoint,
184  boxCenter + viskores::Id3(0, 0, level),
185  level,
186  nearestNeighborId,
187  nearestDistance2);
188  }
189  }
190 
191  VISKORES_EXEC void FindInPlane(const viskores::Vec3f& queryPoint,
192  const viskores::Id3& planeCenter,
193  const viskores::Id3& div,
194  const viskores::Id3& mod,
195  const viskores::Id3& origin,
196  viskores::Id numInPlane,
197  viskores::Id& nearestNeighborId,
198  viskores::FloatDefault& nearestDistance2) const
199  {
200  for (viskores::Id index = 0; index < numInPlane; ++index)
201  {
202  viskores::Id3 ijk = planeCenter + viskores::Id3(index) / div +
203  viskores::Id3(index % mod[0], index % mod[1], index % mod[2]) + origin;
204  if ((ijk[0] >= 0) && (ijk[0] < this->Dims[0]) && (ijk[1] >= 0) && (ijk[1] < this->Dims[1]) &&
205  (ijk[2] >= 0) && (ijk[2] < this->Dims[2]))
206  {
207  this->FindInCell(queryPoint, ijk, nearestNeighborId, nearestDistance2);
208  }
209  }
210  }
211 
213  const viskores::Id3& planeCenter,
214  viskores::Id level,
215  viskores::Id& nearestNeighborId,
216  viskores::FloatDefault& nearestDistance2) const
217  {
218  viskores::Id yWidth = (2 * level) + 1;
219  viskores::Id zWidth = (2 * level) + 1;
220  viskores::Id3 div = { yWidth * zWidth, yWidth * zWidth, yWidth };
221  viskores::Id3 mod = { 1, yWidth, 1 };
222  viskores::Id3 origin = { 0, -level, -level };
223  viskores::Id numInPlane = yWidth * zWidth;
224  this->FindInPlane(
225  queryPoint, planeCenter, div, mod, origin, numInPlane, nearestNeighborId, nearestDistance2);
226  }
227 
229  viskores::Id3 planeCenter,
230  viskores::Id level,
231  viskores::Id& nearestNeighborId,
232  viskores::FloatDefault& nearestDistance2) const
233  {
234  viskores::Id xWidth = (2 * level) - 1;
235  viskores::Id zWidth = (2 * level) + 1;
236  viskores::Id3 div = { xWidth * zWidth, xWidth * zWidth, xWidth };
237  viskores::Id3 mod = { xWidth, 1, 1 };
238  viskores::Id3 origin = { -level + 1, 0, -level };
239  viskores::Id numInPlane = xWidth * zWidth;
240  this->FindInPlane(
241  queryPoint, planeCenter, div, mod, origin, numInPlane, nearestNeighborId, nearestDistance2);
242  }
243 
245  viskores::Id3 planeCenter,
246  viskores::Id level,
247  viskores::Id& nearestNeighborId,
248  viskores::FloatDefault& nearestDistance2) const
249  {
250  viskores::Id xWidth = (2 * level) - 1;
251  viskores::Id yWidth = (2 * level) - 1;
252  viskores::Id3 div = { xWidth * yWidth, xWidth, xWidth * yWidth };
253  viskores::Id3 mod = { xWidth, 1, 1 };
254  viskores::Id3 origin = { -level + 1, -level + 1, 0 };
255  viskores::Id numInPlane = xWidth * yWidth;
256  this->FindInPlane(
257  queryPoint, planeCenter, div, mod, origin, numInPlane, nearestNeighborId, nearestDistance2);
258  }
259 };
260 
261 } // viskores::exec
262 } // viskores
263 
264 #endif // viskores_exec_PointLocatorSparseGrid_h
viskores::exec::PointLocatorSparseGrid::Min
viskores::Vec3f Min
Definition: exec/PointLocatorSparseGrid.h:101
viskores::exec::PointLocatorSparseGrid::CellUpper
IdPortalType CellUpper
Definition: exec/PointLocatorSparseGrid.h:109
viskores::exec::PointLocatorSparseGrid::IdPortalType
typename viskores::cont::ArrayHandle< viskores::Id >::ReadPortalType IdPortalType
Definition: exec/PointLocatorSparseGrid.h:41
viskores::exec::PointLocatorSparseGrid::FindInCell
void FindInCell(const viskores::Vec3f &queryPoint, const viskores::Id3 &ijk, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:111
viskores::cont::ArrayHandle::ReadPortalType
typename StorageType::ReadPortalType ReadPortalType
The type of portal used when accessing data in a read-only mode.
Definition: ArrayHandle.h:325
viskores::exec::PointLocatorSparseGrid::CellLower
IdPortalType CellLower
Definition: exec/PointLocatorSparseGrid.h:108
CoordinateSystem.h
VectorAnalysis.h
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores::exec::PointLocatorSparseGrid::CoordPortalType
typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType CoordPortalType
Definition: exec/PointLocatorSparseGrid.h:40
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::exec::PointLocatorSparseGrid::FindInZPlane
void FindInZPlane(const viskores::Vec3f &queryPoint, viskores::Id3 planeCenter, viskores::Id level, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:244
viskores::exec::PointLocatorSparseGrid::PointLocatorSparseGrid
PointLocatorSparseGrid(const viskores::Vec3f &min, const viskores::Vec3f &max, const viskores::Id3 &dims, const CoordPortalType &coords, const IdPortalType &pointIds, const IdPortalType &cellLower, const IdPortalType &cellUpper)
Definition: exec/PointLocatorSparseGrid.h:44
viskores::exec::PointLocatorSparseGrid::PointIds
IdPortalType PointIds
Definition: exec/PointLocatorSparseGrid.h:107
viskores::Id3
viskores::Vec< viskores::Id, 3 > Id3
Id3 corresponds to a 3-dimensional index for 3d arrays.
Definition: Types.h:1053
viskores::exec::PointLocatorSparseGrid::FindNearestNeighbor
void FindNearestNeighbor(const viskores::Vec3f &queryPoint, viskores::Id &nearestNeighborId, viskores::FloatDefault &distance2) const
Nearest neighbor search using a Uniform Grid.
Definition: exec/PointLocatorSparseGrid.h:71
viskores::exec::PointLocatorSparseGrid
Structure for locating point.
Definition: exec/PointLocatorSparseGrid.h:36
viskores::exec::PointLocatorSparseGrid::FindInPlane
void FindInPlane(const viskores::Vec3f &queryPoint, const viskores::Id3 &planeCenter, const viskores::Id3 &div, const viskores::Id3 &mod, const viskores::Id3 &origin, viskores::Id numInPlane, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:191
viskores::FloatDefault
viskores::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:244
viskores::exec::PointLocatorSparseGrid::FindInBox
void FindInBox(const viskores::Vec3f &queryPoint, const viskores::Id3 &boxCenter, viskores::Id level, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:133
viskores::exec::PointLocatorSparseGrid::Dims
viskores::Id3 Dims
Definition: exec/PointLocatorSparseGrid.h:102
viskores::exec::PointLocatorSparseGrid::FindInYPlane
void FindInYPlane(const viskores::Vec3f &queryPoint, viskores::Id3 planeCenter, viskores::Id level, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:228
viskores::MagnitudeSquared
detail::FloatingPointReturnType< T >::Type MagnitudeSquared(const T &x)
Returns the square of the magnitude of a vector.
Definition: VectorAnalysis.h:72
viskores::exec::PointLocatorSparseGrid::FindInXPlane
void FindInXPlane(const viskores::Vec3f &queryPoint, const viskores::Id3 &planeCenter, viskores::Id level, viskores::Id &nearestNeighborId, viskores::FloatDefault &nearestDistance2) const
Definition: exec/PointLocatorSparseGrid.h:212
viskores::Vec< viskores::FloatDefault, 3 >
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59
viskores::exec::PointLocatorSparseGrid::Coords
CoordPortalType Coords
Definition: exec/PointLocatorSparseGrid.h:105
viskores::exec::PointLocatorSparseGrid::Dxdydz
viskores::Vec3f Dxdydz
Definition: exec/PointLocatorSparseGrid.h:103