VTK-m  2.0
exec/CellLocatorBoundingIntervalHierarchy.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_exec_CellLocatorBoundingIntervalHierarchy_h
11 #define vtk_m_exec_CellLocatorBoundingIntervalHierarchy_h
12 
15 #include <vtkm/cont/ArrayHandle.h>
17 #include <vtkm/exec/CellInside.h>
19 
20 namespace vtkm
21 {
22 namespace exec
23 {
24 
25 
26 
27 
29 {
30 #if defined(VTKM_CLANG)
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wnested-anon-types"
33 #endif // gcc || clang
37  union {
38  struct
39  {
42  } Node;
43  struct
44  {
47  } Leaf;
48  };
49 #if defined(VTKM_CLANG)
50 #pragma GCC diagnostic pop
51 #endif // gcc || clang
52 
55  : Dimension()
56  , ParentIndex()
57  , ChildIndex()
58  , Node{ 0, 0 }
59  {
60  }
61 }; // struct CellLocatorBoundingIntervalHierarchyNode
62 
63 template <typename CellSetType>
65 {
66  using NodeArrayHandle =
69 
70 public:
71  VTKM_CONT
73  const NodeArrayHandle& nodes,
74  const CellIdArrayHandle& cellIds,
75  const CellSetType& cellSet,
78  vtkm::cont::Token& token)
79  : Nodes(nodes.PrepareForInput(device, token))
80  , CellIds(cellIds.PrepareForInput(device, token))
81  , CellSet(cellSet.PrepareForInput(device, VisitType(), IncidentType(), token))
82  , Coords(coords.PrepareForInput(device, token))
83  {
84  }
85 
86  struct LastCell
87  {
88  vtkm::Id CellId = -1;
89  vtkm::Id NodeIdx = -1;
90  };
91 
92  VTKM_EXEC
94  vtkm::Id& cellId,
95  vtkm::Vec3f& parametric) const
96  {
97  LastCell lastCell;
98  return this->FindCellImpl(point, cellId, parametric, lastCell);
99  }
100 
101  VTKM_EXEC
103  vtkm::Id& cellId,
104  vtkm::Vec3f& parametric,
105  LastCell& lastCell) const
106  {
107  cellId = -1;
108 
109  //Check the last cell.
110  if ((lastCell.CellId >= 0) && (lastCell.CellId < this->CellSet.GetNumberOfElements()))
111  {
112  if (this->PointInCell(point, lastCell.CellId, parametric) == vtkm::ErrorCode::Success)
113  {
114  cellId = lastCell.CellId;
116  }
117  }
118 
119  //Check the last leaf node.
120  if ((lastCell.NodeIdx >= 0) && (lastCell.NodeIdx < this->Nodes.GetNumberOfValues()))
121  {
122  const auto& node = this->Nodes.Get(lastCell.NodeIdx);
123 
124  if (node.ChildIndex < 0)
125  {
126  VTKM_RETURN_ON_ERROR(this->FindInLeaf(point, parametric, node, cellId));
127  if (cellId != -1)
128  {
129  lastCell.CellId = cellId;
131  }
132  }
133  }
134 
135  //No fastpath. Do a full search.
136  return this->FindCellImpl(point, cellId, parametric, lastCell);
137  }
138 
139  VTKM_EXEC
141  vtkm::Id& cellId,
142  vtkm::Vec3f& parametric,
143  LastCell& lastCell) const
144  {
145  cellId = -1;
146  vtkm::Id nodeIndex = 0;
147  FindCellState state = FindCellState::EnterNode;
148 
149  while ((cellId < 0) && !((nodeIndex == 0) && (state == FindCellState::AscendFromNode)))
150  {
151  switch (state)
152  {
153  case FindCellState::EnterNode:
155  this->EnterNode(state, point, cellId, nodeIndex, parametric, lastCell));
156  break;
157  case FindCellState::AscendFromNode:
158  this->AscendFromNode(state, nodeIndex);
159  break;
160  case FindCellState::DescendLeftChild:
161  this->DescendLeftChild(state, point, nodeIndex);
162  break;
163  case FindCellState::DescendRightChild:
164  this->DescendRightChild(state, point, nodeIndex);
165  break;
166  }
167  }
168 
169  if (cellId >= 0)
170  {
172  }
173  else
174  {
176  }
177  }
178 
179 private:
180  enum struct FindCellState
181  {
182  EnterNode,
183  AscendFromNode,
184  DescendLeftChild,
185  DescendRightChild
186  };
187 
188  VTKM_EXEC
190  const vtkm::Vec3f& point,
191  vtkm::Id& cellId,
192  vtkm::Id nodeIndex,
193  vtkm::Vec3f& parametric,
194  LastCell& lastCell) const
195  {
196  VTKM_ASSERT(state == FindCellState::EnterNode);
197 
198  const vtkm::exec::CellLocatorBoundingIntervalHierarchyNode& node = this->Nodes.Get(nodeIndex);
199 
200  if (node.ChildIndex < 0)
201  {
202  // In a leaf node. Look for a containing cell.
203  VTKM_RETURN_ON_ERROR(this->FindInLeaf(point, parametric, node, cellId));
204  state = FindCellState::AscendFromNode;
205  if (cellId != -1)
206  {
207  lastCell.CellId = cellId;
208  lastCell.NodeIdx = nodeIndex;
209  }
210  }
211  else
212  {
213  state = FindCellState::DescendLeftChild;
214  }
216  }
217 
218  VTKM_EXEC
219  void AscendFromNode(FindCellState& state, vtkm::Id& nodeIndex) const
220  {
221  VTKM_ASSERT(state == FindCellState::AscendFromNode);
222 
223  vtkm::Id childNodeIndex = nodeIndex;
225  this->Nodes.Get(childNodeIndex);
226  nodeIndex = childNode.ParentIndex;
228  this->Nodes.Get(nodeIndex);
229 
230  if (parentNode.ChildIndex == childNodeIndex)
231  {
232  // Ascending from left child. Descend into the right child.
233  state = FindCellState::DescendRightChild;
234  }
235  else
236  {
237  VTKM_ASSERT(parentNode.ChildIndex + 1 == childNodeIndex);
238  // Ascending from right child. Ascend again. (Don't need to change state.)
239  }
240  }
241 
242  VTKM_EXEC
243  void DescendLeftChild(FindCellState& state, const vtkm::Vec3f& point, vtkm::Id& nodeIndex) const
244  {
245  VTKM_ASSERT(state == FindCellState::DescendLeftChild);
246 
247  const vtkm::exec::CellLocatorBoundingIntervalHierarchyNode& node = this->Nodes.Get(nodeIndex);
248  const vtkm::FloatDefault& coordinate = point[node.Dimension];
249  if (coordinate <= node.Node.LMax)
250  {
251  // Left child does contain the point. Do the actual descent.
252  nodeIndex = node.ChildIndex;
253  state = FindCellState::EnterNode;
254  }
255  else
256  {
257  // Left child does not contain the point. Skip to the right child.
258  state = FindCellState::DescendRightChild;
259  }
260  }
261 
262  VTKM_EXEC
263  void DescendRightChild(FindCellState& state, const vtkm::Vec3f& point, vtkm::Id& nodeIndex) const
264  {
265  VTKM_ASSERT(state == FindCellState::DescendRightChild);
266 
267  const vtkm::exec::CellLocatorBoundingIntervalHierarchyNode& node = this->Nodes.Get(nodeIndex);
268  const vtkm::FloatDefault& coordinate = point[node.Dimension];
269  if (coordinate >= node.Node.RMin)
270  {
271  // Right child does contain the point. Do the actual descent.
272  nodeIndex = node.ChildIndex + 1;
273  state = FindCellState::EnterNode;
274  }
275  else
276  {
277  // Right child does not contain the point. Skip to ascent
278  state = FindCellState::AscendFromNode;
279  }
280  }
281 
283  const vtkm::Vec3f& point,
284  vtkm::Vec3f& parametric,
286  vtkm::Id& containingCellId) const
287  {
288  for (vtkm::Id i = node.Leaf.Start; i < node.Leaf.Start + node.Leaf.Size; ++i)
289  {
290  vtkm::Id cellId = this->CellIds.Get(i);
291 
292  if (this->PointInCell(point, cellId, parametric) == vtkm::ErrorCode::Success)
293  {
294  containingCellId = cellId;
296  }
297  }
298 
299  containingCellId = -1;
301  }
302 
303  // template <typename CoordsType, typename CellShapeTag>
305  vtkm::Id& cellId,
306  vtkm::Vec3f& parametric) const
307  {
308  using IndicesType = typename CellSetPortal::IndicesType;
309  IndicesType cellPointIndices = this->CellSet.GetIndices(cellId);
310  vtkm::VecFromPortalPermute<IndicesType, CoordsPortal> cellPoints(&cellPointIndices,
311  this->Coords);
312  auto cellShape = this->CellSet.GetCellShape(cellId);
313  bool isInside;
314  VTKM_RETURN_ON_ERROR(IsPointInCell(point, parametric, cellShape, cellPoints, isInside));
315 
316  if (isInside && vtkm::exec::CellInside(parametric, cellShape))
318 
320  }
321 
322  template <typename CoordsType, typename CellShapeTag>
324  vtkm::Vec3f& parametric,
325  CellShapeTag cellShape,
326  const CoordsType& cellPoints,
327  bool& isInside)
328  {
329  isInside = false;
330  VTKM_RETURN_ON_ERROR(vtkm::exec::WorldCoordinatesToParametricCoordinates(
331  cellPoints, point, cellShape, parametric));
332  isInside = vtkm::exec::CellInside(parametric, cellShape);
334  }
335 
339  using CellIdPortal = typename CellIdArrayHandle::ReadPortalType;
340  using CellSetPortal =
341  typename CellSetType::template ExecConnectivityType<VisitType, IncidentType>;
342  using CoordsPortal = typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
343 
348 }; // class CellLocatorBoundingIntervalHierarchy
349 
350 } // namespace exec
351 
352 } // namespace vtkm
353 
354 #endif //vtk_m_exec_CellLocatorBoundingIntervalHierarchy_h
vtkm::TopologyElementTagPoint
A tag used to identify the point elements in a topology.
Definition: TopologyElementTag.h:34
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:28
vtkm::cont::ArrayHandle< vtkm::exec::CellLocatorBoundingIntervalHierarchyNode >
ArrayHandle.h
vtkm::ErrorCode
ErrorCode
Definition: ErrorCode.h:19
vtkm::exec::CellLocatorBoundingIntervalHierarchy::NodePortal
typename NodeArrayHandle::ReadPortalType NodePortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:338
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm::exec::CellLocatorBoundingIntervalHierarchy
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:64
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
VTKM_EXEC_CONT
#define VTKM_EXEC_CONT
Definition: ExportMacros.h:52
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::ParentIndex
vtkm::Id ParentIndex
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:35
vtkm::ErrorCode::Success
@ Success
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::Dimension
vtkm::IdComponent Dimension
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:34
vtkm::exec::CellLocatorBoundingIntervalHierarchy::LastCell::NodeIdx
vtkm::Id NodeIdx
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:89
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::ChildIndex
vtkm::Id ChildIndex
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:36
CoordinateSystem.h
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::LMax
vtkm::FloatDefault LMax
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:40
vtkm::exec::CellLocatorBoundingIntervalHierarchy::EnterNode
VTKM_EXEC vtkm::ErrorCode EnterNode(FindCellState &state, const vtkm::Vec3f &point, vtkm::Id &cellId, vtkm::Id nodeIndex, vtkm::Vec3f &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:189
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CellSet
CellSetPortal CellSet
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:346
vtkm::cont::ArrayHandle::ReadPortalType
typename StorageType::ReadPortalType ReadPortalType
Definition: ArrayHandle.h:294
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CellLocatorBoundingIntervalHierarchy
VTKM_CONT CellLocatorBoundingIntervalHierarchy(const NodeArrayHandle &nodes, const CellIdArrayHandle &cellIds, const CellSetType &cellSet, const vtkm::cont::CoordinateSystem::MultiplexerArrayType &coords, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token)
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:72
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
VecFromPortalPermute.h
vtkm::exec::CellLocatorBoundingIntervalHierarchy::AscendFromNode
VTKM_EXEC void AscendFromNode(FindCellState &state, vtkm::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:219
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CoordsPortal
typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType CoordsPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:342
vtkm::exec::CellLocatorBoundingIntervalHierarchy::Nodes
NodePortal Nodes
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:344
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CellIds
CellIdPortal CellIds
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:345
vtkm::exec::CellLocatorBoundingIntervalHierarchy::FindCellState
FindCellState
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:180
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::exec::CellLocatorBoundingIntervalHierarchy::FindCell
VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f &point, vtkm::Id &cellId, vtkm::Vec3f &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:102
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CellSetPortal
typename CellSetType::template ExecConnectivityType< VisitType, IncidentType > CellSetPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:341
vtkm::cont::CoordinateSystem::MultiplexerArrayType
vtkm::cont::ArrayHandleMultiplexerFromList< vtkm::ListAppend< ArraysFloatDefault, ArraysFloatNonDefault > > MultiplexerArrayType
Definition: CoordinateSystem.h:95
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::Size
vtkm::Id Size
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:46
CellInside.h
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::RMin
vtkm::FloatDefault RMin
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:41
vtkm::exec::CellLocatorBoundingIntervalHierarchy::FindCell
VTKM_EXEC vtkm::ErrorCode FindCell(const vtkm::Vec3f &point, vtkm::Id &cellId, vtkm::Vec3f &parametric) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:93
vtkm::exec::CellLocatorBoundingIntervalHierarchy::FindInLeaf
VTKM_EXEC vtkm::ErrorCode FindInLeaf(const vtkm::Vec3f &point, vtkm::Vec3f &parametric, const vtkm::exec::CellLocatorBoundingIntervalHierarchyNode &node, vtkm::Id &containingCellId) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:282
vtkm::exec::CellLocatorBoundingIntervalHierarchy::LastCell
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:86
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::CellLocatorBoundingIntervalHierarchyNode
VTKM_EXEC_CONT CellLocatorBoundingIntervalHierarchyNode()
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:54
vtkm::exec::CellLocatorBoundingIntervalHierarchy::Coords
CoordsPortal Coords
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:347
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::Leaf
struct vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::@1::@4 Leaf
vtkm::exec::CellLocatorBoundingIntervalHierarchy::FindCellImpl
VTKM_EXEC vtkm::ErrorCode FindCellImpl(const vtkm::Vec3f &point, vtkm::Id &cellId, vtkm::Vec3f &parametric, LastCell &lastCell) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:140
vtkm::ErrorCode::CellNotFound
@ CellNotFound
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::Vec< vtkm::FloatDefault, 3 >
vtkm::exec::CellLocatorBoundingIntervalHierarchy::PointInCell
VTKM_EXEC vtkm::ErrorCode PointInCell(const vtkm::Vec3f &point, vtkm::Id &cellId, vtkm::Vec3f &parametric) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:304
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::Start
vtkm::Id Start
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:45
vtkm::exec::CellLocatorBoundingIntervalHierarchy::LastCell::CellId
vtkm::Id CellId
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:88
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:111
vtkm::exec::CellLocatorBoundingIntervalHierarchy::CellIdPortal
typename CellIdArrayHandle::ReadPortalType CellIdPortal
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:339
vtkm::exec::CellLocatorBoundingIntervalHierarchy::IsPointInCell
static VTKM_EXEC vtkm::ErrorCode IsPointInCell(const vtkm::Vec3f &point, vtkm::Vec3f &parametric, CellShapeTag cellShape, const CoordsType &cellPoints, bool &isInside)
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:323
vtkm::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:24
vtkm::exec::CellLocatorBoundingIntervalHierarchy::DescendRightChild
VTKM_EXEC void DescendRightChild(FindCellState &state, const vtkm::Vec3f &point, vtkm::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:263
VTKM_ALWAYS_EXPORT
#define VTKM_ALWAYS_EXPORT
Definition: ExportMacros.h:92
vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::Node
struct vtkm::exec::CellLocatorBoundingIntervalHierarchyNode::@1::@3 Node
ParametricCoordinates.h
vtkm::exec::CellLocatorBoundingIntervalHierarchy::DescendLeftChild
VTKM_EXEC void DescendLeftChild(FindCellState &state, const vtkm::Vec3f &point, vtkm::Id &nodeIndex) const
Definition: exec/CellLocatorBoundingIntervalHierarchy.h:243
TopologyElementTag.h
vtkm::VecFromPortalPermute
A short vector from an ArrayPortal and a vector of indices.
Definition: VecFromPortalPermute.h:28