Viskores  1.0
exec/CellLocatorTwoLevel.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_CellLocatorTwoLevel_h
19 #define viskores_exec_CellLocatorTwoLevel_h
20 
23 
26 
27 #include <viskores/Math.h>
29 #include <viskores/Types.h>
31 #include <viskores/VecTraits.h>
32 
33 namespace viskores
34 {
35 namespace internal
36 {
37 namespace cl_uniform_bins
38 {
39 
40 using DimensionType = viskores::Int16;
41 using DimVec3 = viskores::Vec<DimensionType, 3>;
42 using FloatVec3 = viskores::Vec3f;
43 
44 struct Grid
45 {
46  DimVec3 Dimensions;
47  // Bug in CUDA 9.2 where having this gap for alignment was for some reason setting garbage
48  // in a union with other cell locators (or perhaps not properly copying data). This appears
49  // to be fixed by CUDA 10.2.
50  DimensionType Padding;
51  FloatVec3 Origin;
52  FloatVec3 BinSize;
53 };
54 
55 struct Bounds
56 {
57  FloatVec3 Min;
58  FloatVec3 Max;
59 };
60 
61 VISKORES_EXEC inline viskores::Id ComputeFlatIndex(const DimVec3& idx, const DimVec3 dim)
62 {
63  return idx[0] + (dim[0] * (idx[1] + (dim[1] * idx[2])));
64 }
65 
66 VISKORES_EXEC inline Grid ComputeLeafGrid(const DimVec3& idx,
67  const DimVec3& dim,
68  const Grid& l1Grid)
69 {
70  return { dim,
71  0,
72  l1Grid.Origin + (static_cast<FloatVec3>(idx) * l1Grid.BinSize),
73  l1Grid.BinSize / static_cast<FloatVec3>(dim) };
74 }
75 
76 template <typename PointsVecType>
77 VISKORES_EXEC inline Bounds ComputeCellBounds(const PointsVecType& points)
78 {
79  using CoordsType = typename viskores::VecTraits<PointsVecType>::ComponentType;
81 
82  CoordsType minp = points[0], maxp = points[0];
83  for (viskores::IdComponent i = 1; i < numPoints; ++i)
84  {
85  minp = viskores::Min(minp, points[i]);
86  maxp = viskores::Max(maxp, points[i]);
87  }
88 
89  return { FloatVec3(minp), FloatVec3(maxp) };
90 }
91 }
92 }
93 } // viskores::internal::cl_uniform_bins
94 
95 namespace viskores
96 {
97 namespace exec
98 {
99 
100 //--------------------------------------------------------------------
101 
111 template <typename CellStructureType>
112 class VISKORES_ALWAYS_EXPORT CellLocatorTwoLevel
113 {
114 private:
117 
118  template <typename T>
120 
121  using CoordsPortalType =
122  typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
123 
124  // TODO: This function may return false positives for non 3D cells as the
125  // tests are done on the projection of the point on the cell. Extra checks
126  // should be added to test if the point actually falls on the cell.
127  template <typename CellShapeTag, typename CoordsType>
129  CellShapeTag cellShape,
130  CoordsType cellPoints,
131  FloatVec3& parametricCoordinates,
132  bool& inside)
133  {
134  auto bounds = viskores::internal::cl_uniform_bins::ComputeCellBounds(cellPoints);
135  if (point[0] >= bounds.Min[0] && point[0] <= bounds.Max[0] && point[1] >= bounds.Min[1] &&
136  point[1] <= bounds.Max[1] && point[2] >= bounds.Min[2] && point[2] <= bounds.Max[2])
137  {
138  VISKORES_RETURN_ON_ERROR(viskores::exec::WorldCoordinatesToParametricCoordinates(
139  cellPoints, point, cellShape, parametricCoordinates));
140  inside = viskores::exec::CellInside(parametricCoordinates, cellShape);
141  }
142  else
143  {
144  inside = false;
145  }
146  // Return success error code even point is not inside this cell
148  }
149 
150 public:
151  template <typename CellSetType>
152  VISKORES_CONT CellLocatorTwoLevel(const viskores::internal::cl_uniform_bins::Grid& topLevelGrid,
153  const viskores::cont::ArrayHandle<DimVec3>& leafDimensions,
154  const viskores::cont::ArrayHandle<viskores::Id>& leafStartIndex,
155  const viskores::cont::ArrayHandle<viskores::Id>& cellStartIndex,
158  const CellSetType& cellSet,
159  const viskores::cont::CoordinateSystem& coords,
161  viskores::cont::Token& token)
162  : TopLevel(topLevelGrid)
163  , LeafDimensions(leafDimensions.PrepareForInput(device, token))
164  , LeafStartIndex(leafStartIndex.PrepareForInput(device, token))
165  , CellStartIndex(cellStartIndex.PrepareForInput(device, token))
166  , CellCount(cellCount.PrepareForInput(device, token))
167  , CellIds(cellIds.PrepareForInput(device, token))
168  , CellSet(cellSet.PrepareForInput(device,
171  token))
172  , Coords(coords.GetDataAsMultiplexer().PrepareForInput(device, token))
173  {
174  }
175 
177  struct LastCell
178  {
179  viskores::Id CellId = -1;
180  viskores::Id LeafIdx = -1;
181  };
182 
186  viskores::Id& cellId,
187  FloatVec3& parametric) const
188  {
189  LastCell lastCell;
190  return this->FindCellImpl(point, cellId, parametric, lastCell);
191  }
192 
196  viskores::Id& cellId,
197  FloatVec3& parametric,
198  LastCell& lastCell) const
199  {
200  viskores::Vec3f pc;
201  //See if point is inside the last cell.
202  if ((lastCell.CellId >= 0) && (lastCell.CellId < this->CellSet.GetNumberOfElements()) &&
203  this->PointInCell(point, lastCell.CellId, pc) == viskores::ErrorCode::Success)
204  {
205  parametric = pc;
206  cellId = lastCell.CellId;
208  }
209 
210  //See if it's in the last leaf.
211  if ((lastCell.LeafIdx >= 0) && (lastCell.LeafIdx < this->CellCount.GetNumberOfValues()) &&
212  this->PointInLeaf(point, lastCell.LeafIdx, cellId, pc) == viskores::ErrorCode::Success)
213  {
214  parametric = pc;
215  lastCell.CellId = cellId;
217  }
218 
219  //Call the full point search.
220  return this->FindCellImpl(point, cellId, parametric, lastCell);
221  }
222 
223 private:
226  const viskores::Id& cid,
227  viskores::Vec3f& parametric) const
228  {
229  auto indices = this->CellSet.GetIndices(cid);
230  auto pts = viskores::make_VecFromPortalPermute(&indices, this->Coords);
231  viskores::Vec3f pc;
232  bool inside;
233  auto status = PointInsideCell(point, this->CellSet.GetCellShape(cid), pts, pc, inside);
234  if (status == viskores::ErrorCode::Success && inside)
235  {
236  parametric = pc;
238  }
239 
241  }
242 
245  const viskores::Id& leafIdx,
246  viskores::Id& cellId,
247  FloatVec3& parametric) const
248  {
249  viskores::Id start = this->CellStartIndex.Get(leafIdx);
250  viskores::Id end = start + this->CellCount.Get(leafIdx);
251 
252  for (viskores::Id i = start; i < end; ++i)
253  {
254  viskores::Vec3f pc;
255 
256  viskores::Id cid = this->CellIds.Get(i);
257  if (this->PointInCell(point, cid, pc) == viskores::ErrorCode::Success)
258  {
259  cellId = cid;
260  parametric = pc;
262  }
263  }
264 
266  }
267 
268 
271  viskores::Id& cellId,
272  FloatVec3& parametric,
273  LastCell& lastCell) const
274  {
275  using namespace viskores::internal::cl_uniform_bins;
276 
277  cellId = -1;
278  lastCell.CellId = -1;
279  lastCell.LeafIdx = -1;
280 
281  DimVec3 binId3 = static_cast<DimVec3>((point - this->TopLevel.Origin) / this->TopLevel.BinSize);
282  if (binId3[0] >= 0 && binId3[0] < this->TopLevel.Dimensions[0] && binId3[1] >= 0 &&
283  binId3[1] < this->TopLevel.Dimensions[1] && binId3[2] >= 0 &&
284  binId3[2] < this->TopLevel.Dimensions[2])
285  {
286  viskores::Id binId = ComputeFlatIndex(binId3, this->TopLevel.Dimensions);
287 
288  auto ldim = this->LeafDimensions.Get(binId);
289  if (!ldim[0] || !ldim[1] || !ldim[2])
290  {
292  }
293 
294  auto leafGrid = ComputeLeafGrid(binId3, ldim, this->TopLevel);
295 
296  DimVec3 leafId3 = static_cast<DimVec3>((point - leafGrid.Origin) / leafGrid.BinSize);
297  // precision issues may cause leafId3 to be out of range so clamp it
298  leafId3 = viskores::Max(DimVec3(0), viskores::Min(ldim - DimVec3(1), leafId3));
299 
300  viskores::Id leafStart = this->LeafStartIndex.Get(binId);
301  viskores::Id leafIdx = leafStart + ComputeFlatIndex(leafId3, leafGrid.Dimensions);
302 
303  if (this->PointInLeaf(point, leafIdx, cellId, parametric) == viskores::ErrorCode::Success)
304  {
305  lastCell.CellId = cellId;
306  lastCell.LeafIdx = leafIdx;
308  }
309  }
310 
312  }
313 
314  viskores::internal::cl_uniform_bins::Grid TopLevel;
315 
318 
322 
323  CellStructureType CellSet;
325 };
326 }
327 } // viskores::exec
328 
329 #endif //viskores_exec_CellLocatorTwoLevel_h
viskores::exec::CellLocatorTwoLevel::Coords
CoordsPortalType Coords
Definition: exec/CellLocatorTwoLevel.h:324
viskores::exec::CellLocatorTwoLevel::CellSet
CellStructureType CellSet
Definition: exec/CellLocatorTwoLevel.h:323
ArrayHandle.h
viskores::exec::CellLocatorTwoLevel::ReadPortal
typename viskores::cont::ArrayHandle< T >::ReadPortalType ReadPortal
Definition: exec/CellLocatorTwoLevel.h:119
viskores::exec::CellLocatorTwoLevel::LeafStartIndex
ReadPortal< viskores::Id > LeafStartIndex
Definition: exec/CellLocatorTwoLevel.h:317
viskores::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:32
viskores::exec::CellLocatorTwoLevel::PointInCell
viskores::ErrorCode PointInCell(const viskores::Vec3f &point, const viskores::Id &cid, viskores::Vec3f &parametric) const
Definition: exec/CellLocatorTwoLevel.h:225
viskores::exec::CellLocatorTwoLevel
Structure for locating cells.
Definition: exec/CellLocatorTwoLevel.h:112
viskores::Int16
int16_t Int16
Base type to use for 16-bit signed integer numbers.
Definition: Types.h:181
Types.h
viskores::exec::CellLocatorTwoLevel::PointInsideCell
static viskores::ErrorCode PointInsideCell(FloatVec3 point, CellShapeTag cellShape, CoordsType cellPoints, FloatVec3 &parametricCoordinates, bool &inside)
Definition: exec/CellLocatorTwoLevel.h:128
viskores::exec::CellLocatorTwoLevel::CellStartIndex
ReadPortal< viskores::Id > CellStartIndex
Definition: exec/CellLocatorTwoLevel.h:319
viskores::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:36
viskores::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:313
viskores::exec::CellLocatorTwoLevel::LastCell::LeafIdx
viskores::Id LeafIdx
Definition: exec/CellLocatorTwoLevel.h:180
viskores::cont::CoordinateSystem
Manages a coordinate system for a DataSet.
Definition: CoordinateSystem.h:38
viskores::exec::CellLocatorTwoLevel::FindCellImpl
viskores::ErrorCode FindCellImpl(const FloatVec3 &point, viskores::Id &cellId, FloatVec3 &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorTwoLevel.h:270
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::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
viskores::exec::CellLocatorTwoLevel::CellCount
ReadPortal< viskores::Id > CellCount
Definition: exec/CellLocatorTwoLevel.h:320
CoordinateSystem.h
viskores::exec::CellLocatorTwoLevel::LastCell
Structure capturing the location of a cell in the search structure.
Definition: exec/CellLocatorTwoLevel.h:177
VecFromPortalPermute.h
viskores::exec::CellLocatorTwoLevel::FindCell
viskores::ErrorCode FindCell(const FloatVec3 &point, viskores::Id &cellId, FloatVec3 &parametric, LastCell &lastCell) const
Locate the cell containing the provided point.
Definition: exec/CellLocatorTwoLevel.h:195
viskores::TopologyElementTagPoint
A tag used to identify the point elements in a topology.
Definition: TopologyElementTag.h:42
VISKORES_RETURN_ON_ERROR
#define VISKORES_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:210
viskores::make_VecFromPortalPermute
VecFromPortalPermute< IndexVecType, PortalType > make_VecFromPortalPermute(const IndexVecType *index, const PortalType &portal)
Definition: VecFromPortalPermute.h:181
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores::exec::CellLocatorTwoLevel::FindCell
viskores::ErrorCode FindCell(const FloatVec3 &point, viskores::Id &cellId, FloatVec3 &parametric) const
Locate the cell containing the provided point.
Definition: exec/CellLocatorTwoLevel.h:185
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores::VecTraits::GetNumberOfComponents
static constexpr viskores::IdComponent GetNumberOfComponents(const T &)
Returns the number of components in the given vector.
Definition: VecTraits.h:102
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
CellInside.h
Math.h
viskores::exec::CellLocatorTwoLevel::CellLocatorTwoLevel
CellLocatorTwoLevel(const viskores::internal::cl_uniform_bins::Grid &topLevelGrid, const viskores::cont::ArrayHandle< DimVec3 > &leafDimensions, const viskores::cont::ArrayHandle< viskores::Id > &leafStartIndex, const viskores::cont::ArrayHandle< viskores::Id > &cellStartIndex, const viskores::cont::ArrayHandle< viskores::Id > &cellCount, const viskores::cont::ArrayHandle< viskores::Id > &cellIds, const CellSetType &cellSet, const viskores::cont::CoordinateSystem &coords, viskores::cont::DeviceAdapterId device, viskores::cont::Token &token)
Definition: exec/CellLocatorTwoLevel.h:152
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::ErrorCode::CellNotFound
@ CellNotFound
A cell matching some given criteria could not be found.
viskores::exec::CellLocatorTwoLevel::CoordsPortalType
typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType CoordsPortalType
Definition: exec/CellLocatorTwoLevel.h:122
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::exec::CellLocatorTwoLevel::TopLevel
viskores::internal::cl_uniform_bins::Grid TopLevel
Definition: exec/CellLocatorTwoLevel.h:314
viskores::VecTraits::ComponentType
T ComponentType
Type of the components in the vector.
Definition: VecTraits.h:79
viskores::exec::CellLocatorTwoLevel::LeafDimensions
ReadPortal< DimVec3 > LeafDimensions
Definition: exec/CellLocatorTwoLevel.h:316
viskores::exec::CellLocatorTwoLevel::CellIds
ReadPortal< viskores::Id > CellIds
Definition: exec/CellLocatorTwoLevel.h:321
viskores::exec::CellLocatorTwoLevel::LastCell::CellId
viskores::Id CellId
Definition: exec/CellLocatorTwoLevel.h:179
ParametricCoordinates.h
viskores::Vec< DimensionType, 3 >
viskores::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:43
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59
VecTraits.h
viskores::exec::CellLocatorTwoLevel::PointInLeaf
viskores::ErrorCode PointInLeaf(const FloatVec3 &point, const viskores::Id &leafIdx, viskores::Id &cellId, FloatVec3 &parametric) const
Definition: exec/CellLocatorTwoLevel.h:244
viskores::Vec3f
viskores::Vec< viskores::FloatDefault, 3 > Vec3f
Vec3f corresponds to a 3-dimensional vector of floating point values.
Definition: Types.h:1064
TopologyElementTag.h