Viskores  1.0
exec/CellLocatorBoundingIntervalHierarchy.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_CellLocatorBoundingIntervalHierarchy_h
19 #define viskores_exec_CellLocatorBoundingIntervalHierarchy_h
20 
27 
28 namespace viskores
29 {
30 namespace exec
31 {
32 
33 
34 
35 
37 {
38 #if defined(VISKORES_CLANG)
39 #pragma GCC diagnostic push
40 #pragma GCC diagnostic ignored "-Wnested-anon-types"
41 #endif // gcc || clang
45  union
46  {
47  struct
48  {
51  } Node;
52  struct
53  {
56  } Leaf;
57  };
58 #if defined(VISKORES_CLANG)
59 #pragma GCC diagnostic pop
60 #endif // gcc || clang
61 
64  : Dimension()
65  , ParentIndex()
66  , ChildIndex()
67  , Node{ 0, 0 }
68  {
69  }
70 }; // struct CellLocatorBoundingIntervalHierarchyNode
71 
81 template <typename CellSetType>
82 class VISKORES_ALWAYS_EXPORT CellLocatorBoundingIntervalHierarchy
83 {
84  using NodeArrayHandle =
87 
88 public:
91  const NodeArrayHandle& nodes,
92  const CellIdArrayHandle& cellIds,
93  const CellSetType& cellSet,
96  viskores::cont::Token& token)
97  : Nodes(nodes.PrepareForInput(device, token))
98  , CellIds(cellIds.PrepareForInput(device, token))
99  , CellSet(cellSet.PrepareForInput(device, VisitType(), IncidentType(), token))
100  , Coords(coords.PrepareForInput(device, token))
101  {
102  }
103 
105  struct LastCell
106  {
107  viskores::Id CellId = -1;
108  viskores::Id NodeIdx = -1;
109  };
110 
113  viskores::Id& cellId,
114  viskores::Vec3f& parametric) const
115  {
116  LastCell lastCell;
117  return this->FindCellImpl(point, cellId, parametric, lastCell);
118  }
119 
122  viskores::Id& cellId,
123  viskores::Vec3f& parametric,
124  LastCell& lastCell) const
125  {
126  cellId = -1;
127 
128  //Check the last cell.
129  if ((lastCell.CellId >= 0) && (lastCell.CellId < this->CellSet.GetNumberOfElements()))
130  {
131  if (this->PointInCell(point, lastCell.CellId, parametric) == viskores::ErrorCode::Success)
132  {
133  cellId = lastCell.CellId;
135  }
136  }
137 
138  //Check the last leaf node.
139  if ((lastCell.NodeIdx >= 0) && (lastCell.NodeIdx < this->Nodes.GetNumberOfValues()))
140  {
141  const auto& node = this->Nodes.Get(lastCell.NodeIdx);
142 
143  if (node.ChildIndex < 0)
144  {
145  VISKORES_RETURN_ON_ERROR(this->FindInLeaf(point, parametric, node, cellId));
146  if (cellId != -1)
147  {
148  lastCell.CellId = cellId;
150  }
151  }
152  }
153 
154  //No fastpath. Do a full search.
155  return this->FindCellImpl(point, cellId, parametric, lastCell);
156  }
157 
160  viskores::Id& cellId,
161  viskores::Vec3f& parametric,
162  LastCell& lastCell) const
163  {
164  cellId = -1;
165  viskores::Id nodeIndex = 0;
166  FindCellState state = FindCellState::EnterNode;
167 
168  while ((cellId < 0) && !((nodeIndex == 0) && (state == FindCellState::AscendFromNode)))
169  {
170  switch (state)
171  {
172  case FindCellState::EnterNode:
174  this->EnterNode(state, point, cellId, nodeIndex, parametric, lastCell));
175  break;
176  case FindCellState::AscendFromNode:
177  this->AscendFromNode(state, nodeIndex);
178  break;
179  case FindCellState::DescendLeftChild:
180  this->DescendLeftChild(state, point, nodeIndex);
181  break;
182  case FindCellState::DescendRightChild:
183  this->DescendRightChild(state, point, nodeIndex);
184  break;
185  }
186  }
187 
188  if (cellId >= 0)
189  {
191  }
192  else
193  {
195  }
196  }
197 
198 private:
199  enum struct FindCellState
200  {
201  EnterNode,
202  AscendFromNode,
203  DescendLeftChild,
204  DescendRightChild
205  };
206 
209  const viskores::Vec3f& point,
210  viskores::Id& cellId,
211  viskores::Id nodeIndex,
212  viskores::Vec3f& parametric,
213  LastCell& lastCell) const
214  {
215  VISKORES_ASSERT(state == FindCellState::EnterNode);
216 
218  this->Nodes.Get(nodeIndex);
219 
220  if (node.ChildIndex < 0)
221  {
222  // In a leaf node. Look for a containing cell.
223  VISKORES_RETURN_ON_ERROR(this->FindInLeaf(point, parametric, node, cellId));
224  state = FindCellState::AscendFromNode;
225  if (cellId != -1)
226  {
227  lastCell.CellId = cellId;
228  lastCell.NodeIdx = nodeIndex;
229  }
230  }
231  else
232  {
233  state = FindCellState::DescendLeftChild;
234  }
236  }
237 
239  void AscendFromNode(FindCellState& state, viskores::Id& nodeIndex) const
240  {
241  VISKORES_ASSERT(state == FindCellState::AscendFromNode);
242 
243  viskores::Id childNodeIndex = nodeIndex;
245  this->Nodes.Get(childNodeIndex);
246  nodeIndex = childNode.ParentIndex;
248  this->Nodes.Get(nodeIndex);
249 
250  if (parentNode.ChildIndex == childNodeIndex)
251  {
252  // Ascending from left child. Descend into the right child.
253  state = FindCellState::DescendRightChild;
254  }
255  else
256  {
257  VISKORES_ASSERT(parentNode.ChildIndex + 1 == childNodeIndex);
258  // Ascending from right child. Ascend again. (Don't need to change state.)
259  }
260  }
261 
264  const viskores::Vec3f& point,
265  viskores::Id& nodeIndex) const
266  {
267  VISKORES_ASSERT(state == FindCellState::DescendLeftChild);
268 
270  this->Nodes.Get(nodeIndex);
271  const viskores::FloatDefault& coordinate = point[node.Dimension];
272  if (coordinate <= node.Node.LMax)
273  {
274  // Left child does contain the point. Do the actual descent.
275  nodeIndex = node.ChildIndex;
276  state = FindCellState::EnterNode;
277  }
278  else
279  {
280  // Left child does not contain the point. Skip to the right child.
281  state = FindCellState::DescendRightChild;
282  }
283  }
284 
287  const viskores::Vec3f& point,
288  viskores::Id& nodeIndex) const
289  {
290  VISKORES_ASSERT(state == FindCellState::DescendRightChild);
291 
293  this->Nodes.Get(nodeIndex);
294  const viskores::FloatDefault& coordinate = point[node.Dimension];
295  if (coordinate >= node.Node.RMin)
296  {
297  // Right child does contain the point. Do the actual descent.
298  nodeIndex = node.ChildIndex + 1;
299  state = FindCellState::EnterNode;
300  }
301  else
302  {
303  // Right child does not contain the point. Skip to ascent
304  state = FindCellState::AscendFromNode;
305  }
306  }
307 
309  const viskores::Vec3f& point,
310  viskores::Vec3f& parametric,
312  viskores::Id& containingCellId) const
313  {
314  for (viskores::Id i = node.Leaf.Start; i < node.Leaf.Start + node.Leaf.Size; ++i)
315  {
316  viskores::Id cellId = this->CellIds.Get(i);
317 
318  if (this->PointInCell(point, cellId, parametric) == viskores::ErrorCode::Success)
319  {
320  containingCellId = cellId;
322  }
323  }
324 
325  containingCellId = -1;
327  }
328 
329  // template <typename CoordsType, typename CellShapeTag>
331  viskores::Id& cellId,
332  viskores::Vec3f& parametric) const
333  {
334  using IndicesType = typename CellSetPortal::IndicesType;
335  IndicesType cellPointIndices = this->CellSet.GetIndices(cellId);
337  this->Coords);
338  auto cellShape = this->CellSet.GetCellShape(cellId);
339  bool isInside;
340  VISKORES_RETURN_ON_ERROR(IsPointInCell(point, parametric, cellShape, cellPoints, isInside));
341 
342  if (isInside && viskores::exec::CellInside(parametric, cellShape))
344 
346  }
347 
348  template <typename CoordsType, typename CellShapeTag>
350  viskores::Vec3f& parametric,
351  CellShapeTag cellShape,
352  const CoordsType& cellPoints,
353  bool& isInside)
354  {
355  isInside = false;
356  VISKORES_RETURN_ON_ERROR(viskores::exec::WorldCoordinatesToParametricCoordinates(
357  cellPoints, point, cellShape, parametric));
358  isInside = viskores::exec::CellInside(parametric, cellShape);
360  }
361 
365  using CellIdPortal = typename CellIdArrayHandle::ReadPortalType;
366  using CellSetPortal =
367  typename CellSetType::template ExecConnectivityType<VisitType, IncidentType>;
368  using CoordsPortal =
369  typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
370 
375 }; // class CellLocatorBoundingIntervalHierarchy
376 
377 } // namespace exec
378 
379 } // namespace viskores
380 
381 #endif //viskores_exec_CellLocatorBoundingIntervalHierarchy_h
viskores::exec::CellLocatorBoundingIntervalHierarchy::EnterNode
viskores::ErrorCode EnterNode(FindCellState &state, const viskores::Vec3f &point, viskores::Id &cellId, viskores::Id nodeIndex, viskores::Vec3f &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:208
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::ParentIndex
viskores::Id ParentIndex
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:43
viskores::exec::CellLocatorBoundingIntervalHierarchy::CellLocatorBoundingIntervalHierarchy
CellLocatorBoundingIntervalHierarchy(const NodeArrayHandle &nodes, const CellIdArrayHandle &cellIds, const CellSetType &cellSet, const viskores::cont::CoordinateSystem::MultiplexerArrayType &coords, viskores::cont::DeviceAdapterId device, viskores::cont::Token &token)
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:90
ArrayHandle.h
viskores::exec::CellLocatorBoundingIntervalHierarchyNode
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:36
viskores::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:32
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::Dimension
viskores::IdComponent Dimension
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:42
viskores::exec::CellLocatorBoundingIntervalHierarchy::LastCell::NodeIdx
viskores::Id NodeIdx
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:108
viskores::exec::CellLocatorBoundingIntervalHierarchy::LastCell::CellId
viskores::Id CellId
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:107
viskores::exec::CellLocatorBoundingIntervalHierarchy::CoordsPortal
typename viskores::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType CoordsPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:369
viskores::exec::CellLocatorBoundingIntervalHierarchy::FindInLeaf
viskores::ErrorCode FindInLeaf(const viskores::Vec3f &point, viskores::Vec3f &parametric, const viskores::exec::CellLocatorBoundingIntervalHierarchyNode &node, viskores::Id &containingCellId) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.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::exec::CellLocatorBoundingIntervalHierarchyNode >
viskores::exec::CellLocatorBoundingIntervalHierarchy::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/CellLocatorBoundingIntervalHierarchy.h:121
viskores::exec::CellLocatorBoundingIntervalHierarchy::IsPointInCell
static viskores::ErrorCode IsPointInCell(const viskores::Vec3f &point, viskores::Vec3f &parametric, CellShapeTag cellShape, const CoordsType &cellPoints, bool &isInside)
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:349
viskores::exec::CellLocatorBoundingIntervalHierarchy
Structure for locating cells.
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:82
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_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
CoordinateSystem.h
VecFromPortalPermute.h
viskores::TopologyElementTagPoint
A tag used to identify the point elements in a topology.
Definition: TopologyElementTag.h:42
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::Size
viskores::Id Size
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:55
VISKORES_RETURN_ON_ERROR
#define VISKORES_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:210
viskores::exec::CellLocatorBoundingIntervalHierarchy::LastCell
Structure capturing the location of a cell in the search structure.
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:105
viskores::exec::CellLocatorBoundingIntervalHierarchy::DescendRightChild
void DescendRightChild(FindCellState &state, const viskores::Vec3f &point, viskores::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:286
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores::exec::CellLocatorBoundingIntervalHierarchy::DescendLeftChild
void DescendLeftChild(FindCellState &state, const viskores::Vec3f &point, viskores::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:263
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::RMin
viskores::FloatDefault RMin
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:50
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::exec::CellLocatorBoundingIntervalHierarchy::FindCellState
FindCellState
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:199
CellInside.h
viskores::exec::CellLocatorBoundingIntervalHierarchy::FindCellImpl
viskores::ErrorCode FindCellImpl(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:159
viskores::VecFromPortalPermute
A short vector from an ArrayPortal and a vector of indices.
Definition: VecFromPortalPermute.h:36
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::Start
viskores::Id Start
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:54
VISKORES_ASSERT
#define VISKORES_ASSERT(condition)
Definition: Assert.h:51
viskores::cont::CoordinateSystem::MultiplexerArrayType
viskores::cont::ArrayHandleMultiplexerFromList< viskores::ListAppend< ArraysFloatDefault, ArraysFloatNonDefault > > MultiplexerArrayType
Definition: CoordinateSystem.h:109
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::ChildIndex
viskores::Id ChildIndex
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:44
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::CellLocatorBoundingIntervalHierarchyNode
CellLocatorBoundingIntervalHierarchyNode()
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:63
viskores::exec::CellLocatorBoundingIntervalHierarchy::Coords
CoordsPortal Coords
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:374
viskores::exec::CellLocatorBoundingIntervalHierarchy::CellIdPortal
typename CellIdArrayHandle::ReadPortalType CellIdPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:365
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::LMax
viskores::FloatDefault LMax
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:49
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::exec::CellLocatorBoundingIntervalHierarchy::Nodes
NodePortal Nodes
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:371
viskores::exec::CellLocatorBoundingIntervalHierarchy::CellIds
CellIdPortal CellIds
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:372
viskores::exec::CellLocatorBoundingIntervalHierarchy::PointInCell
viskores::ErrorCode PointInCell(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:330
viskores::ErrorCode::CellNotFound
@ CellNotFound
A cell matching some given criteria could not be found.
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::FloatDefault
viskores::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:244
viskores::exec::CellLocatorBoundingIntervalHierarchy::NodePortal
typename NodeArrayHandle::ReadPortalType NodePortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:364
viskores::exec::CellLocatorBoundingIntervalHierarchy::CellSet
CellSetPortal CellSet
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:373
viskores::exec::CellLocatorBoundingIntervalHierarchy::AscendFromNode
void AscendFromNode(FindCellState &state, viskores::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:239
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::Leaf
struct viskores::exec::CellLocatorBoundingIntervalHierarchyNode::@1::@4 Leaf
viskores::exec::CellLocatorBoundingIntervalHierarchyNode::Node
struct viskores::exec::CellLocatorBoundingIntervalHierarchyNode::@1::@3 Node
viskores::exec::CellLocatorBoundingIntervalHierarchy::CellSetPortal
typename CellSetType::template ExecConnectivityType< VisitType, IncidentType > CellSetPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:367
ParametricCoordinates.h
viskores::Vec< viskores::FloatDefault, 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
viskores::exec::CellLocatorBoundingIntervalHierarchy::FindCell
viskores::ErrorCode FindCell(const viskores::Vec3f &point, viskores::Id &cellId, viskores::Vec3f &parametric) const
Locate the cell containing the provided point.
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:112
TopologyElementTag.h