Viskores  1.0
exec/CellLocatorUniformBins.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_CellLocatorUniformBins_h
19 #define viskores_exec_CellLocatorUniformBins_h
20 
23 
27 
30 #include <viskores/VecTraits.h>
31 
32 namespace viskores
33 {
34 namespace exec
35 {
36 
37 //--------------------------------------------------------------------
38 
48 template <typename CellStructureType>
49 class VISKORES_ALWAYS_EXPORT CellLocatorUniformBins
50 {
51  template <typename T>
53 
54  using CoordsPortalType =
55  typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
56 
59  using CellIdReadPortal =
61  CellIdOffsetArrayType>::ReadPortalType;
62 
63 public:
64  template <typename CellSetType>
66  const viskores::Id3& cellDims,
67  const viskores::Vec3f& origin,
68  const viskores::Vec3f& maxPoint,
69  const viskores::Vec3f& invSpacing,
70  const viskores::Id3& maxCellIds,
72  cellIds,
73  const CellSetType& cellSet,
76  viskores::cont::Token& token)
77  : CellDims(cellDims)
78  , Origin(origin)
79  , MaxPoint(maxPoint)
80  , InvSpacing(invSpacing)
81  , MaxCellIds(maxCellIds)
82  , CellIds(cellIds.PrepareForInput(device, token))
83  , CellSet(cellSet.PrepareForInput(device,
86  token))
87  , Coords(coords.GetDataAsMultiplexer().PrepareForInput(device, token))
88  {
89  }
90 
92  struct LastCell
93  {
94  viskores::Id CellId = -1;
95  viskores::Id BinIdx = -1;
96  };
97 
100  viskores::Id& cellId,
101  viskores::Vec3f& parametric) const
102  {
103  LastCell lastCell;
104  return this->FindCellImpl(point, cellId, parametric, lastCell);
105  }
106 
109  viskores::Id& cellId,
110  viskores::Vec3f& parametric,
111  LastCell& lastCell) const
112  {
113  viskores::Id binIdx = this->FindBinIdx(point);
114 
115  if (binIdx == -1)
116  {
117  lastCell.CellId = -1;
118  lastCell.BinIdx = -1;
119  cellId = -1;
121  }
122  //See if the point is still in the same bin.
123  else if (binIdx == lastCell.BinIdx && this->LastCellValid(lastCell))
124  {
125  viskores::Vec3f pc;
126  //Check the last cell first.
127  if (this->PointInCell(point, lastCell.CellId, pc))
128  {
129  parametric = pc;
130  cellId = lastCell.CellId;
132  }
133  //Otherwise, check cells in the bin, but skip lastCell.CellId
134  else if (this->PointInBin(point, lastCell.BinIdx, cellId, pc, lastCell.CellId))
135  {
136  parametric = pc;
138  }
139  }
140  //if cell still not found, drop to the general find cell below.
141 
142  //LastCell not initialized, or not in the same bin: do a full test.
143  //Since already computed the binIdx, re-use it.
144  return this->FindCellImpl(point, cellId, parametric, lastCell, binIdx);
145  }
146 
147  VISKORES_DEPRECATED(1.6, "Locators are no longer pointers. Use . operator.")
148  VISKORES_EXEC CellLocatorUniformBins* operator->() { return this; }
149  VISKORES_DEPRECATED(1.6, "Locators are no longer pointers. Use . operator.")
150  VISKORES_EXEC const CellLocatorUniformBins* operator->() const { return this; }
151 
152 private:
154  {
155  if (!this->IsInside(point))
156  return -1;
157 
158  viskores::Vec3f temp;
159  temp = point - this->Origin;
160  temp = temp * this->InvSpacing;
161 
162  //make sure that if we border the upper edge, we sample the correct cell
163  viskores::Id3 logicalCell = viskores::Min(viskores::Id3(temp), this->MaxCellIds);
164 
165  viskores::Id binIdx =
166  (logicalCell[2] * this->CellDims[1] + logicalCell[1]) * this->CellDims[0] + logicalCell[0];
167 
168  return binIdx;
169  }
170 
171  VISKORES_EXEC bool LastCellValid(const LastCell& lastCell) const
172  {
173  return lastCell.BinIdx >= 0 && lastCell.BinIdx < this->CellIds.GetNumberOfValues() &&
174  lastCell.CellId >= 0 && lastCell.CellId < this->CellSet.GetNumberOfElements();
175  }
176 
177  VISKORES_EXEC bool IsInside(const viskores::Vec3f& point) const
178  {
179  if (point[0] < this->Origin[0] || point[0] > this->MaxPoint[0])
180  return false;
181  if (point[1] < this->Origin[1] || point[1] > this->MaxPoint[1])
182  return false;
183  if (point[2] < this->Origin[2] || point[2] > this->MaxPoint[2])
184  return false;
185 
186  return true;
187  }
188 
191  viskores::Id& cellId,
192  viskores::Vec3f& parametric,
193  LastCell& lastCell,
194  viskores::Id ptBinIdx = -1) const
195  {
196  lastCell.CellId = -1;
197  lastCell.BinIdx = -1;
198 
199  //if ptBinIdx is set, use it. Otherwise, compute the bin idx.
200  viskores::Id binIdx = -1;
201  if (ptBinIdx == -1)
202  binIdx = this->FindBinIdx(point);
203  else
204  binIdx = ptBinIdx;
205 
206  //point not in a bin. return not found.
207  if (binIdx == -1)
208  {
209  cellId = -1;
211  }
212 
213  //search cells in the bin.
214  viskores::Vec3f pc;
215  if (this->PointInBin(point, binIdx, cellId, pc))
216  {
217  parametric = pc;
218  lastCell.CellId = cellId;
219  lastCell.BinIdx = binIdx;
221  }
222 
224  }
225 
226  template <typename PointsVecType>
227  VISKORES_EXEC viskores::Bounds ComputeCellBounds(const PointsVecType& points) const
228  {
230 
231  viskores::Bounds bounds;
232  for (viskores::IdComponent i = 0; i < numPoints; ++i)
233  bounds.Include(points[i]);
234 
235  return bounds;
236  }
237 
238  // TODO: This function may return false positives for non 3D cells as the
239  // tests are done on the projection of the point on the cell. Extra checks
240  // should be added to test if the point actually falls on the cell.
241  template <typename CellShapeTag, typename CoordsType>
243  CellShapeTag cellShape,
244  CoordsType cellPoints,
245  viskores::Vec3f& parametricCoordinates,
246  bool& inside) const
247  {
248  auto bounds = this->ComputeCellBounds(cellPoints);
249  if (bounds.Contains(point))
250  {
251  VISKORES_RETURN_ON_ERROR(viskores::exec::WorldCoordinatesToParametricCoordinates(
252  cellPoints, point, cellShape, parametricCoordinates));
253  inside = viskores::exec::CellInside(parametricCoordinates, cellShape);
254  }
255  else
256  {
257  inside = false;
258  }
259  // Return success error code even point is not inside this cell
261  }
262 
264  bool PointInBin(const viskores::Vec3f& point,
265  const viskores::Id& binIdx,
266  viskores::Id& cellId,
267  viskores::Vec3f& parametric,
268  const viskores::Id& skipCellId = -1) const
269  {
270  auto binIds = this->CellIds.Get(binIdx);
271 
272  viskores::Vec3f pc;
273  for (viskores::IdComponent i = 0; i < binIds.GetNumberOfComponents(); i++)
274  {
275  viskores::Id cid = binIds[i];
276  if (cid != skipCellId && this->PointInCell(point, cid, pc))
277  {
278  cellId = cid;
279  parametric = pc;
280  return true;
281  }
282  }
283 
284  return false;
285  }
286 
288  bool PointInCell(const viskores::Vec3f& point,
289  const viskores::Id& cid,
290  viskores::Vec3f& parametric) const
291  {
292  auto indices = this->CellSet.GetIndices(cid);
293  auto pts = viskores::make_VecFromPortalPermute(&indices, this->Coords);
294  viskores::Vec3f pc;
295  bool inside;
296  auto status = this->PointInsideCell(point, this->CellSet.GetCellShape(cid), pts, pc, inside);
297  if (status == viskores::ErrorCode::Success && inside)
298  {
299  parametric = pc;
300  return true;
301  }
302 
303  return false;
304  }
305 
311 
313 
314  CellStructureType CellSet;
316 };
317 
318 }
319 } // viskores::exec
320 
321 #endif //viskores_exec_CellLocatorUniformBins_h
viskores::exec::CellLocatorUniformBins::MaxCellIds
viskores::Id3 MaxCellIds
Definition: exec/CellLocatorUniformBins.h:310
viskores::exec::CellLocatorUniformBins::Origin
viskores::Vec3f Origin
Definition: exec/CellLocatorUniformBins.h:307
ArrayHandle.h
viskores::exec::CellLocatorUniformBins::PointInsideCell
viskores::ErrorCode PointInsideCell(viskores::Vec3f point, CellShapeTag cellShape, CoordsType cellPoints, viskores::Vec3f &parametricCoordinates, bool &inside) const
Definition: exec/CellLocatorUniformBins.h:242
viskores::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:32
viskores::exec::CellLocatorUniformBins::ComputeCellBounds
viskores::Bounds ComputeCellBounds(const PointsVecType &points) const
Definition: exec/CellLocatorUniformBins.h:227
viskores::Bounds
Represent an axis-aligned 3D bounds in space.
Definition: Bounds.h:37
viskores::exec::CellLocatorUniformBins::CellIdReadPortal
typename viskores::cont::ArrayHandleGroupVecVariable< CellIdArrayType, CellIdOffsetArrayType >::ReadPortalType CellIdReadPortal
Definition: exec/CellLocatorUniformBins.h:61
viskores::exec::CellLocatorUniformBins::MaxPoint
viskores::Vec3f MaxPoint
Definition: exec/CellLocatorUniformBins.h:308
viskores::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:36
viskores::cont::ArrayHandle< viskores::Id >
viskores::cont::CoordinateSystem
Manages a coordinate system for a DataSet.
Definition: CoordinateSystem.h:38
viskores::exec::CellLocatorUniformBins::FindCell
viskores::ErrorCode FindCell(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric) const
Locate the cell containing the provided point.
Definition: exec/CellLocatorUniformBins.h:99
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::CellLocatorUniformBins::FindCellImpl
viskores::ErrorCode FindCellImpl(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric, LastCell &lastCell, viskores::Id ptBinIdx=-1) const
Definition: exec/CellLocatorUniformBins.h:190
viskores::exec::CellLocatorUniformBins
Structure for locating cells.
Definition: exec/CellLocatorUniformBins.h:49
CoordinateSystem.h
VecFromPortalPermute.h
viskores::exec::CellLocatorUniformBins::LastCell
Structure capturing the location of a cell in the search structure.
Definition: exec/CellLocatorUniformBins.h:92
viskores::exec::CellLocatorUniformBins::IsInside
bool IsInside(const viskores::Vec3f &point) const
Definition: exec/CellLocatorUniformBins.h:177
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_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores::exec::CellLocatorUniformBins::LastCell::BinIdx
viskores::Id BinIdx
Definition: exec/CellLocatorUniformBins.h:95
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
VISKORES_DEPRECATED
#define VISKORES_DEPRECATED(...)
Definition: Deprecated.h:156
viskores::exec::CellLocatorUniformBins::FindBinIdx
viskores::Id FindBinIdx(const viskores::Vec3f &point) const
Definition: exec/CellLocatorUniformBins.h:153
viskores::exec::CellLocatorUniformBins::PointInCell
bool PointInCell(const viskores::Vec3f &point, const viskores::Id &cid, viskores::Vec3f &parametric) const
Definition: exec/CellLocatorUniformBins.h:288
viskores::exec::CellLocatorUniformBins::FindCell
viskores::ErrorCode FindCell(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric, LastCell &lastCell) const
Locate the cell containing the provided point.
Definition: exec/CellLocatorUniformBins.h:108
viskores::exec::CellLocatorUniformBins::Coords
CoordsPortalType Coords
Definition: exec/CellLocatorUniformBins.h:315
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::exec::CellLocatorUniformBins::PointInBin
bool PointInBin(const viskores::Vec3f &point, const viskores::Id &binIdx, viskores::Id &cellId, viskores::Vec3f &parametric, const viskores::Id &skipCellId=-1) const
Definition: exec/CellLocatorUniformBins.h:264
viskores::exec::CellLocatorUniformBins::CellDims
viskores::Id3 CellDims
Definition: exec/CellLocatorUniformBins.h:306
viskores::ErrorCode::CellNotFound
@ CellNotFound
A cell matching some given criteria could not be found.
viskores::exec::CellLocatorUniformBins::InvSpacing
viskores::Vec3f InvSpacing
Definition: exec/CellLocatorUniformBins.h:309
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::Bounds::Include
void Include(const viskores::Vec< T, 3 > &point)
Expand bounds to include a point.
Definition: Bounds.h:203
viskores::exec::CellLocatorUniformBins::ReadPortal
typename viskores::cont::ArrayHandle< T >::ReadPortalType ReadPortal
Definition: exec/CellLocatorUniformBins.h:52
viskores::exec::CellLocatorUniformBins::LastCellValid
bool LastCellValid(const LastCell &lastCell) const
Definition: exec/CellLocatorUniformBins.h:171
viskores::exec::CellLocatorUniformBins::CellSet
CellStructureType CellSet
Definition: exec/CellLocatorUniformBins.h:314
viskores::exec::CellLocatorUniformBins::LastCell::CellId
viskores::Id CellId
Definition: exec/CellLocatorUniformBins.h:94
ArrayHandleGroupVecVariable.h
viskores::exec::CellLocatorUniformBins::CellIds
CellIdReadPortal CellIds
Definition: exec/CellLocatorUniformBins.h:312
viskores::cont::ArrayHandleGroupVecVariable
Fancy array handle that groups values into vectors of different sizes.
Definition: ArrayHandleGroupVecVariable.h:279
ParametricCoordinates.h
viskores::Vec< viskores::Id, 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::CellLocatorUniformBins::CellLocatorUniformBins
CellLocatorUniformBins(const viskores::Id3 &cellDims, const viskores::Vec3f &origin, const viskores::Vec3f &maxPoint, const viskores::Vec3f &invSpacing, const viskores::Id3 &maxCellIds, const viskores::cont::ArrayHandleGroupVecVariable< CellIdArrayType, CellIdOffsetArrayType > &cellIds, const CellSetType &cellSet, const viskores::cont::CoordinateSystem &coords, viskores::cont::DeviceAdapterId device, viskores::cont::Token &token)
Definition: exec/CellLocatorUniformBins.h:65
viskores::exec::CellLocatorUniformBins::CoordsPortalType
typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType CoordsPortalType
Definition: exec/CellLocatorUniformBins.h:55
TopologyElementTag.h