VTK-m  2.0
FlyingEdgesPass4Y.h
Go to the documentation of this file.
1 
2 //============================================================================
3 // Copyright (c) Kitware, Inc.
4 // All rights reserved.
5 // See LICENSE.txt for details.
6 //
7 // This software is distributed WITHOUT ANY WARRANTY; without even
8 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 // PURPOSE. See the above copyright notice for more information.
10 //============================================================================
11 
12 
13 #ifndef vtk_m_worklet_contour_flyingedges_pass4y_h
14 #define vtk_m_worklet_contour_flyingedges_pass4y_h
15 
16 
19 
20 #include <vtkm/VectorAnalysis.h>
22 
23 namespace vtkm
24 {
25 namespace worklet
26 {
27 namespace flying_edges
28 {
29 
30 
31 template <typename T>
33 {
34 
36 
38 
41 
43  ComputePass4Y(T value,
44  const vtkm::Id3& pdims,
45  vtkm::Id multiContourCellOffset,
46  vtkm::Id multiContourPointOffset)
47  : PointDims(pdims)
48  , IsoValue(value)
49  , CellWriteOffset(multiContourCellOffset)
50  , PointWriteOffset(multiContourPointOffset)
51  {
52  }
53 
54  using ControlSignature = void(CellSetIn,
55  FieldInPoint axis_sums,
56  FieldInPoint axis_mins,
57  FieldInPoint axis_maxs,
58  WholeArrayIn cell_tri_count,
59  WholeArrayIn edgeData,
60  WholeArrayIn data,
61  WholeArrayOut connectivity,
62  WholeArrayOut edgeIds,
63  WholeArrayOut weights,
64  WholeArrayOut inputCellIds);
65  using ExecutionSignature =
66  void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, WorkIndex);
67 
68  template <typename ThreadIndices,
69  typename FieldInPointId3,
70  typename FieldInPointId,
71  typename WholeTriField,
72  typename WholeEdgeField,
73  typename WholeDataField,
74  typename WholeConnField,
75  typename WholeEdgeIdField,
76  typename WholeWeightField,
77  typename WholeCellIdField>
78  VTKM_EXEC void operator()(const ThreadIndices& threadIndices,
79  const FieldInPointId3& axis_sums,
80  const FieldInPointId& axis_mins,
81  const FieldInPointId& axis_maxs,
82  const WholeTriField& cellTriCount,
83  const WholeEdgeField& edges,
84  const WholeDataField& field,
85  const WholeConnField& conn,
86  const WholeEdgeIdField& interpolatedEdgeIds,
87  const WholeWeightField& weights,
88  const WholeCellIdField& inputCellIds,
89  vtkm::Id oidx) const
90  {
91  using AxisToSum = SumYAxis;
92 
93  //This works as cellTriCount was computed with ScanExtended
94  //and therefore has one more entry than the number of cells
95  vtkm::Id cell_tri_offset = cellTriCount.Get(oidx);
96  vtkm::Id next_tri_offset = cellTriCount.Get(oidx + 1);
97  if (cell_tri_offset == next_tri_offset)
98  { //we produce nothing
99  return;
100  }
101  cell_tri_offset += this->CellWriteOffset;
102 
103  Pass4TrimState state(
104  AxisToSum{}, this->PointDims, threadIndices, axis_sums, axis_mins, axis_maxs, edges);
105  if (!state.hasWork)
106  {
107  return;
108  }
109 
110  const vtkm::Id3 pdims = this->PointDims;
111  const vtkm::Id3 increments = compute_incs3d(pdims);
112  vtkm::Id edgeIds[12];
113 
114  auto edgeCase = getEdgeCase(edges, state.startPos, (state.axis_inc * state.left));
115  init_voxelIds(AxisToSum{}, this->PointWriteOffset, edgeCase, axis_sums, edgeIds);
116  for (vtkm::Id i = state.left; i < state.right; ++i) // run along the trimmed voxels
117  {
118  edgeCase = getEdgeCase(edges, state.startPos, (state.axis_inc * i));
119  vtkm::UInt8 numTris = data::GetNumberOfPrimitives(edgeCase);
120  if (numTris > 0)
121  {
122  // Start by generating triangles for this case
124  state.cellId, edgeCase, numTris, edgeIds, cell_tri_offset, conn, inputCellIds);
125 
126  // Now generate edgeIds and weights along voxel axes if needed. Remember to take
127  // boundary into account.
128  auto* edgeUses = data::GetEdgeUses(edgeCase);
129  if (!fully_interior(state.boundaryStatus) || case_includes_axes(edgeUses))
130  {
131  this->Generate(state.boundaryStatus,
132  field,
133  interpolatedEdgeIds,
134  weights,
135  state.startPos,
136  increments,
137  (state.axis_inc * i),
138  edgeUses,
139  edgeIds);
140  }
141  advance_voxelIds(edgeUses, edgeIds);
142  }
143  state.increment(AxisToSum{}, pdims);
144  }
145  }
146 
147  //----------------------------------------------------------------------------
148  template <typename WholeDataField, typename WholeIEdgeField, typename WholeWeightField>
149  VTKM_EXEC inline void Generate(const vtkm::Vec<vtkm::UInt8, 3>& boundaryStatus,
150  const WholeDataField& field,
151  const WholeIEdgeField& interpolatedEdgeIds,
152  const WholeWeightField& weights,
153  const vtkm::Id4& startPos,
154  const vtkm::Id3& incs,
155  vtkm::Id offset,
156  vtkm::UInt8 const* const edgeUses,
157  vtkm::Id* edgeIds) const
158  {
159  using AxisToSum = SumYAxis;
160 
161  vtkm::Id2 pos(startPos[0] + offset, 0);
162  {
163  auto s0 = field.Get(pos[0]);
164 
165  //EdgesUses 0,4,8 work for Y axis
166  if (edgeUses[0])
167  { // edgesUses[0] == i axes edge
168  auto writeIndex = edgeIds[0];
169  pos[1] = startPos[0] + offset + incs[AxisToSum::xindex];
170  auto s1 = field.Get(pos[1]);
171  T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
172 
173  interpolatedEdgeIds.Set(writeIndex, pos);
174  weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
175  }
176  if (edgeUses[4])
177  { // edgesUses[4] == j axes edge
178  auto writeIndex = edgeIds[4];
179  pos[1] = startPos[1] + offset;
180  auto s1 = field.Get(pos[1]);
181  T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
182 
183  interpolatedEdgeIds.Set(writeIndex, pos);
184  weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
185  }
186  if (edgeUses[8])
187  { // edgesUses[8] == k axes edge
188  auto writeIndex = edgeIds[8];
189  pos[1] = startPos[2] + offset;
190  auto s1 = field.Get(pos[1]);
191  T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
192 
193  interpolatedEdgeIds.Set(writeIndex, pos);
194  weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
195  }
196  }
197 
198  // On the boundary cells special work has to be done to cover the partial
199  // cell axes. These are boundary situations where the voxel axes is not
200  // fully formed. These situations occur on the +x,+y,+z volume
201  // boundaries. The other cases such as interior, or -x,-y,-z boundaries fall through
202  // which is expected
203  //
204  // clang-format off
205  const bool onX = boundaryStatus[AxisToSum::xindex] & FlyingEdges3D::MaxBoundary;
206  const bool onY = boundaryStatus[AxisToSum::yindex] & FlyingEdges3D::MaxBoundary;
207  const bool onZ = boundaryStatus[AxisToSum::zindex] & FlyingEdges3D::MaxBoundary;
208  if (onX) //+x boundary
209  {
210  this->InterpolateEdge(pos[0], incs, 5, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
211  this->InterpolateEdge(pos[0], incs, 9, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
212  if (onY) //+x +y
213  {
214  this->InterpolateEdge(pos[0], incs, 11, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
215  }
216  if (onZ) //+x +z
217  {
218  this->InterpolateEdge(pos[0], incs, 7, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
219  }
220  }
221  if (onY) //+y boundary
222  {
223  this->InterpolateEdge(pos[0], incs, 1, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
224  this->InterpolateEdge(pos[0], incs, 10, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
225  if (onZ) //+y +z boundary
226  {
227  this->InterpolateEdge(pos[0], incs, 3, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
228  }
229  }
230  if (onZ) //+z boundary
231  {
232  this->InterpolateEdge(pos[0], incs, 2, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
233  this->InterpolateEdge(pos[0], incs, 6, edgeUses, edgeIds, field, interpolatedEdgeIds, weights);
234  }
235  // clang-format on
236  }
237 
238  // Indicate whether voxel axes need processing for this case.
239  //----------------------------------------------------------------------------
240  template <typename WholeField, typename WholeIEdgeField, typename WholeWeightField>
241  VTKM_EXEC inline void InterpolateEdge(vtkm::Id currentIdx,
242  const vtkm::Id3& incs,
243  vtkm::Id edgeNum,
244  vtkm::UInt8 const* const edgeUses,
245  vtkm::Id* edgeIds,
246  const WholeField& field,
247  const WholeIEdgeField& interpolatedEdgeIds,
248  const WholeWeightField& weights) const
249  {
250  using AxisToSum = SumYAxis;
251 
252  // if this edge is not used then get out
253  if (!edgeUses[edgeNum])
254  {
255  return;
256  }
257  const vtkm::Id writeIndex = edgeIds[edgeNum];
258 
259  // build the edge information
261 
262  vtkm::Id3 offsets1 = data::GetVertOffsets(AxisToSum{}, verts[0]);
263  vtkm::Id3 offsets2 = data::GetVertOffsets(AxisToSum{}, verts[1]);
264 
265  vtkm::Id2 iEdge(currentIdx + vtkm::Dot(offsets1, incs), currentIdx + vtkm::Dot(offsets2, incs));
266 
267  interpolatedEdgeIds.Set(writeIndex, iEdge);
268 
269  auto s0 = field.Get(iEdge[0]);
270  auto s1 = field.Get(iEdge[1]);
271  T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
272  weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
273  }
274 };
275 
276 template <typename T>
278 {
279 
280  vtkm::internal::ArrayPortalUniformPointCoordinates Coordinates;
282 
284  ComputePass5Y(const vtkm::Id3& pdims,
285  const vtkm::Vec3f& origin,
286  const vtkm::Vec3f& spacing,
287  vtkm::Id normalWriteOffset,
288  bool generateNormals)
289  : Coordinates(pdims, origin, spacing)
290  , NormalWriteOffset(normalWriteOffset)
291  {
292  if (!generateNormals)
293  {
294  this->NormalWriteOffset = -1;
295  }
296  }
297 
298  using ControlSignature = void(FieldIn interpEdgeIds,
299  FieldIn interpWeight,
300  FieldOut points,
301  WholeArrayIn field,
302  WholeArrayOut normals);
303  using ExecutionSignature = void(_1, _2, _3, _4, _5, WorkIndex);
304 
305  template <typename PT, typename WholeInputField, typename WholeNormalField>
306  VTKM_EXEC void operator()(const vtkm::Id2& interpEdgeIds,
307  vtkm::FloatDefault weight,
308  vtkm::Vec<PT, 3>& outPoint,
309  const WholeInputField& field,
310  WholeNormalField& normals,
311  vtkm::Id oidx) const
312  {
313  {
314  vtkm::Vec3f point1 = this->Coordinates.Get(interpEdgeIds[0]);
315  vtkm::Vec3f point2 = this->Coordinates.Get(interpEdgeIds[1]);
316  outPoint = vtkm::Lerp(point1, point2, weight);
317  }
318 
319  //NormalWriteOffset of -1 means no normals
320  if (this->NormalWriteOffset >= 0)
321  {
322  vtkm::Vec<T, 3> g0, g1;
323  const vtkm::Id3& dims = this->Coordinates.GetDimensions();
324  vtkm::Id3 ijk{ interpEdgeIds[0] % dims[0],
325  (interpEdgeIds[0] / dims[0]) % dims[1],
326  interpEdgeIds[0] / (dims[0] * dims[1]) };
327 
329  vtkm::exec::BoundaryState boundary(ijk, dims);
331  coord_neighborhood(this->Coordinates, boundary);
332 
333  vtkm::exec::FieldNeighborhood<WholeInputField> field_neighborhood(field, boundary);
334 
335 
336  //compute the gradient at point 1
337  gradient(boundary, coord_neighborhood, field_neighborhood, g0);
338 
339  //compute the gradient at point 2. This optimization can be optimized
340  boundary.IJK = vtkm::Id3{ interpEdgeIds[1] % dims[0],
341  (interpEdgeIds[1] / dims[0]) % dims[1],
342  interpEdgeIds[1] / (dims[0] * dims[1]) };
343  gradient(boundary, coord_neighborhood, field_neighborhood, g1);
344 
345  vtkm::Vec3f n = vtkm::Lerp(g0, g1, weight);
346  const auto mag2 = vtkm::MagnitudeSquared(n);
347  if (mag2 > 0.)
348  {
349  n = n * vtkm::RSqrt(mag2);
350  }
351  normals.Set(this->NormalWriteOffset + oidx, n);
352  }
353  }
354 };
355 }
356 }
357 }
358 #endif
vtkm::worklet::flying_edges::ComputePass5Y::ComputePass5Y
ComputePass5Y(const vtkm::Id3 &pdims, const vtkm::Vec3f &origin, const vtkm::Vec3f &spacing, vtkm::Id normalWriteOffset, bool generateNormals)
Definition: FlyingEdgesPass4Y.h:284
vtkm::worklet::flying_edges::ComputePass5Y::ExecutionSignature
void(_1, _2, _3, _4, _5, WorkIndex) ExecutionSignature
Definition: FlyingEdgesPass4Y.h:303
vtkm::worklet::flying_edges::ComputePass5Y::Coordinates
vtkm::internal::ArrayPortalUniformPointCoordinates Coordinates
Definition: FlyingEdgesPass4Y.h:280
vtkm::exec::BoundaryState
Provides a neighborhood's placement with respect to the mesh's boundary.
Definition: BoundaryState.h:31
vtkm::worklet::flying_edges::generate_tris
VTKM_EXEC void generate_tris(vtkm::Id inputCellId, vtkm::UInt8 edgeCase, vtkm::UInt8 numTris, vtkm::Id *edgeIds, vtkm::Id &triId, const WholeConnField &conn, const WholeCellIdField &cellIds)
Definition: FlyingEdgesPass4Common.h:48
vtkm::MagnitudeSquared
VTKM_EXEC_CONT detail::FloatingPointReturnType< T >::Type MagnitudeSquared(const T &x)
Returns the square of the magnitude of a vector.
Definition: VectorAnalysis.h:64
vtkm::worklet::flying_edges::case_includes_axes
VTKM_EXEC bool case_includes_axes(vtkm::UInt8 const *const edgeUses)
Definition: FlyingEdgesPass4Common.h:42
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm::worklet::flying_edges::data::GetEdgeUses
VTKM_EXEC vtkm::UInt8 const * GetEdgeUses(vtkm::UInt8 edgecase)
Definition: FlyingEdgesTables.h:42
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::flying_edges::ComputePass4Y::CellWriteOffset
vtkm::Id CellWriteOffset
Definition: FlyingEdgesPass4Y.h:39
vtkm::worklet::flying_edges::ComputePass5Y::ControlSignature
void(FieldIn interpEdgeIds, FieldIn interpWeight, FieldOut points, WholeArrayIn field, WholeArrayOut normals) ControlSignature
Definition: FlyingEdgesPass4Y.h:302
vtkm::worklet::flying_edges::FlyingEdges3D::MaxBoundary
@ MaxBoundary
Definition: FlyingEdgesHelpers.h:47
vtkm::worklet::flying_edges::compute_incs3d
VTKM_EXEC vtkm::Id3 compute_incs3d(const vtkm::Id3 &dims)
Definition: FlyingEdgesPass4Common.h:26
vtkm::worklet::flying_edges::data::GetVertMap
VTKM_EXEC vtkm::Vec< vtkm::UInt8, 2 > GetVertMap(vtkm::Id index)
Definition: FlyingEdgesTables.h:381
FlyingEdgesHelpers.h
vtkm::exec::BoundaryState::IJK
vtkm::Id3 IJK
Definition: BoundaryState.h:260
vtkm::worklet::flying_edges::Pass4TrimState
Definition: FlyingEdgesPass4Common.h:120
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::flying_edges::ComputePass4Y::PointWriteOffset
vtkm::Id PointWriteOffset
Definition: FlyingEdgesPass4Y.h:40
VectorAnalysis.h
vtkm::worklet::flying_edges::data::GetNumberOfPrimitives
VTKM_EXEC vtkm::UInt8 GetNumberOfPrimitives(vtkm::UInt8 edgecase)
Definition: FlyingEdgesTables.h:26
vtkm::worklet::flying_edges::ComputePass4Y::Generate
VTKM_EXEC void Generate(const vtkm::Vec< vtkm::UInt8, 3 > &boundaryStatus, const WholeDataField &field, const WholeIEdgeField &interpolatedEdgeIds, const WholeWeightField &weights, const vtkm::Id4 &startPos, const vtkm::Id3 &incs, vtkm::Id offset, vtkm::UInt8 const *const edgeUses, vtkm::Id *edgeIds) const
Definition: FlyingEdgesPass4Y.h:149
vtkm::worklet::flying_edges::ComputePass5Y
Definition: FlyingEdgesPass4Y.h:277
vtkm::worklet::flying_edges::fully_interior
VTKM_EXEC bool fully_interior(const vtkm::Vec< vtkm::UInt8, 3 > &boundaryStatus)
Definition: FlyingEdgesPass4Common.h:219
vtkm::worklet::flying_edges::ComputePass4Y::ComputePass4Y
ComputePass4Y(T value, const vtkm::Id3 &pdims, vtkm::Id multiContourCellOffset, vtkm::Id multiContourPointOffset)
Definition: FlyingEdgesPass4Y.h:43
vtkm::worklet::flying_edges::ComputePass4Y::PointDims
vtkm::Id3 PointDims
Definition: FlyingEdgesPass4Y.h:35
vtkm::worklet::flying_edges::data::GetVertOffsets
VTKM_EXEC vtkm::Id3 GetVertOffsets(SumXAxis, vtkm::UInt8 index)
Definition: FlyingEdgesTables.h:391
vtkm::worklet::flying_edges::ComputePass5Y::NormalWriteOffset
vtkm::Id NormalWriteOffset
Definition: FlyingEdgesPass4Y.h:281
vtkm::worklet::flying_edges::ComputePass5Y::ComputePass5Y
ComputePass5Y()
Definition: FlyingEdgesPass4Y.h:283
vtkm::worklet::WorkletVisitCellsWithPoints
Base class for worklets that map from Points to Cells.
Definition: WorkletMapTopology.h:255
vtkm::exec::arg::ThreadIndices
The ExecutionSignature tag to use to get the thread indices.
Definition: ThreadIndices.h:41
vtkm::worklet::flying_edges::getEdgeCase
VTKM_EXEC vtkm::UInt8 getEdgeCase(const WholeEdgeField &edges, const vtkm::Id4 &startPos, vtkm::Id inc)
Definition: FlyingEdgesHelpers.h:185
vtkm::worklet::WorkletVisitCellsWithPoints::FieldInPoint
FieldInIncident FieldInPoint
Definition: WorkletMapTopology.h:259
vtkm::worklet::flying_edges::ComputePass4Y::operator()
VTKM_EXEC void operator()(const ThreadIndices &threadIndices, const FieldInPointId3 &axis_sums, const FieldInPointId &axis_mins, const FieldInPointId &axis_maxs, const WholeTriField &cellTriCount, const WholeEdgeField &edges, const WholeDataField &field, const WholeConnField &conn, const WholeEdgeIdField &interpolatedEdgeIds, const WholeWeightField &weights, const WholeCellIdField &inputCellIds, vtkm::Id oidx) const
Definition: FlyingEdgesPass4Y.h:78
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::worklet::flying_edges::ComputePass5Y::operator()
VTKM_EXEC void operator()(const vtkm::Id2 &interpEdgeIds, vtkm::FloatDefault weight, vtkm::Vec< PT, 3 > &outPoint, const WholeInputField &field, WholeNormalField &normals, vtkm::Id oidx) const
Definition: FlyingEdgesPass4Y.h:306
vtkm::worklet::flying_edges::ComputePass4Y::IsoValue
T IsoValue
Definition: FlyingEdgesPass4Y.h:37
vtkm::Lerp
VTKM_EXEC_CONT ValueType Lerp(const ValueType &value0, const ValueType &value1, const WeightType &weight)
Returns the linear interpolation of two values based on weight.
Definition: VectorAnalysis.h:32
vtkm::worklet::flying_edges::ComputePass4Y::InterpolateEdge
VTKM_EXEC void InterpolateEdge(vtkm::Id currentIdx, const vtkm::Id3 &incs, vtkm::Id edgeNum, vtkm::UInt8 const *const edgeUses, vtkm::Id *edgeIds, const WholeField &field, const WholeIEdgeField &interpolatedEdgeIds, const WholeWeightField &weights) const
Definition: FlyingEdgesPass4Y.h:241
vtkm::worklet::flying_edges::ComputePass4Y::ControlSignature
void(CellSetIn, FieldInPoint axis_sums, FieldInPoint axis_mins, FieldInPoint axis_maxs, WholeArrayIn cell_tri_count, WholeArrayIn edgeData, WholeArrayIn data, WholeArrayOut connectivity, WholeArrayOut edgeIds, WholeArrayOut weights, WholeArrayOut inputCellIds) ControlSignature
Definition: FlyingEdgesPass4Y.h:64
vtkm::worklet::flying_edges::advance_voxelIds
VTKM_EXEC void advance_voxelIds(vtkm::UInt8 const *const edgeUses, vtkm::Id *edgeIds)
Definition: FlyingEdgesPass4Common.h:103
vtkm::Vec< T, 3 >
Definition: Types.h:975
vtkm::Vec< vtkm::Id, 3 >
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
FlyingEdgesTables.h
vtkm::worklet::flying_edges::SumYAxis
Definition: FlyingEdgesHelpers.h:57
vtkm::worklet::flying_edges::init_voxelIds
VTKM_EXEC void init_voxelIds(AxisToSum, vtkm::Id writeOffset, vtkm::UInt8 edgeCase, const FieldInPointId3 &axis_sums, vtkm::Id *edgeIds)
Definition: FlyingEdgesPass4Common.h:80
vtkm::worklet::flying_edges::ComputePass4Y::ComputePass4Y
ComputePass4Y()
Definition: FlyingEdgesPass4Y.h:42
vtkm::worklet::flying_edges::ComputePass4Y
Definition: FlyingEdgesPass4Y.h:32
vtkm::worklet::flying_edges::ComputePass4Y::ExecutionSignature
void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, WorkIndex) ExecutionSignature
Definition: FlyingEdgesPass4Y.h:66
vtkm::exec::FieldNeighborhood
Retrieves field values from a neighborhood.
Definition: FieldNeighborhood.h:36
vtkm::worklet::gradient::StructuredPointGradient
Definition: StructuredPointGradient.h:25
StructuredPointGradient.h
vtkm::worklet::WorkletMapField
Base class for worklets that do a simple mapping of field arrays.
Definition: WorkletMapField.h:38
vtkm::exec::arg::WorkIndex
The ExecutionSignature tag to use to get the work index.
Definition: WorkIndex.h:39