VTK-m  2.0
FlyingEdgesPass1.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_pass1_h
14 #define vtk_m_worklet_contour_flyingedges_pass1_h
15 
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace flying_edges
24 {
25 
26 /*
27 * Understanding Pass1 in general
28 *
29 * PASS 1: Process all of the voxel edges that compose each row. Determine the
30 * edges case classification, count the number of edge intersections, and
31 * figure out where intersections along the row begins and ends
32 * (i.e., gather information for computational trimming).
33 *
34 * So in general the algorithm selects a primary axis to stride ( X or Y).
35 * It does this by forming a plane along the other two axes and marching
36 * over the sum/primary axis.
37 *
38 * So for SumXAxis, this means that we form a YZ plane and march the
39 * X axis along each point. As we march we are looking at the X axis edge
40 * that is formed by the current and next point.
41 *
42 * So for SumYAxis, this means that we form a XZ plane and march the
43 * Y axis along each point. As we march we are looking at the Y axis edge
44 * that is formed by the current and next point.
45 *
46 */
47 
48 template <typename Device, typename WholeEdgeField>
49 inline VTKM_EXEC void write_edge(Device,
50  vtkm::Id write_index,
51  WholeEdgeField& edges,
52  vtkm::UInt8 edgeCase)
53 {
54  edges.Set(write_index, edgeCase);
55 }
56 
57 template <typename WholeEdgeField>
58 inline VTKM_EXEC void write_edge(vtkm::cont::DeviceAdapterTagCuda,
59  vtkm::Id write_index,
60  WholeEdgeField& edges,
61  vtkm::UInt8 edgeCase)
62 {
63  if (edgeCase != FlyingEdges3D::Below)
64  {
65  edges.Set(write_index, edgeCase);
66  }
67 }
68 
69 template <typename T>
71 {
74 
76  ComputePass1(T value, const vtkm::Id3& pdims)
77  : PointDims(pdims)
78  , IsoValue(value)
79  {
80  }
81 
82  using ControlSignature = void(CellSetIn,
83  FieldOut axis_sum,
84  FieldOut axis_min,
85  FieldOut axis_max,
86  WholeArrayInOut edgeData,
87  WholeArrayIn data);
88  using ExecutionSignature = void(ThreadIndices, _2, _3, _4, _5, _6, Device);
89  using InputDomain = _1;
90 
91  template <typename ThreadIndices,
92  typename WholeEdgeField,
93  typename WholeDataField,
94  typename Device>
95  VTKM_EXEC void operator()(const ThreadIndices& threadIndices,
96  vtkm::Id3& axis_sum,
97  vtkm::Id& axis_min,
98  vtkm::Id& axis_max,
99  WholeEdgeField& edges,
100  const WholeDataField& field,
101  Device device) const
102  {
103  using AxisToSum = typename select_AxisToSum<Device>::type;
104 
105  const vtkm::Id3 ijk = compute_ijk(AxisToSum{}, threadIndices.GetInputIndex3D());
106  const vtkm::Id3 dims = this->PointDims;
107  const vtkm::Id startPos = compute_start(AxisToSum{}, ijk, dims);
108  const vtkm::Id offset = compute_inc(AxisToSum{}, dims);
109 
110  const T value = this->IsoValue;
111  axis_min = this->PointDims[AxisToSum::xindex];
112  axis_max = 0;
113  T s1 = field.Get(startPos);
114  T s0 = s1;
115  axis_sum = { 0, 0, 0 };
116  const vtkm::Id end = this->PointDims[AxisToSum::xindex] - 1;
117  for (vtkm::Id i = 0; i < end; ++i)
118  {
119  s0 = s1;
120  s1 = field.Get(startPos + (offset * (i + 1)));
121 
123  if (s0 >= value)
124  {
125  edgeCase = FlyingEdges3D::LeftAbove;
126  }
127  if (s1 >= value)
128  {
129  edgeCase |= FlyingEdges3D::RightAbove;
130  }
131 
132  write_edge(device, startPos + (offset * i), edges, edgeCase);
133 
134  if (edgeCase == FlyingEdges3D::LeftAbove || edgeCase == FlyingEdges3D::RightAbove)
135  {
136  axis_sum[AxisToSum::xindex] += 1; // increment number of intersections along axis
137  axis_max = i + 1;
138  if (axis_min == (end + 1))
139  {
140  axis_min = i;
141  }
142  }
143  }
144  write_edge(device, startPos + (offset * end), edges, FlyingEdges3D::Below);
145  }
146 };
147 
149 {
150  template <typename DeviceAdapterTag, typename T, typename StorageTagField, typename... Args>
151  VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
152  const ComputePass1<T>& worklet,
155  vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
156  Args&&... args) const
157  {
158  vtkm::cont::Invoker invoke(device);
159  metaDataMesh2D = make_metaDataMesh2D(SumXAxis{}, worklet.PointDims);
160 
161  invoke(worklet, metaDataMesh2D, std::forward<Args>(args)..., edgeCases, inputField);
162  return true;
163  }
164 
165  template <typename DeviceAdapterTag, typename T, typename StorageTagField, typename... Args>
166  VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
167  const ComputePass1<T>& worklet,
170  vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
171  Args&&... args) const
172  {
173  vtkm::cont::Invoker invoke(device);
174  metaDataMesh2D = make_metaDataMesh2D(SumYAxis{}, worklet.PointDims);
175 
176  edgeCases.Fill(static_cast<vtkm::UInt8>(FlyingEdges3D::Below));
177  invoke(worklet, metaDataMesh2D, std::forward<Args>(args)..., edgeCases, inputField);
178  return true;
179  }
180 
181  template <typename DeviceAdapterTag, typename... Args>
182  VTKM_CONT bool operator()(DeviceAdapterTag device, Args&&... args) const
183  {
184  return this->LaunchXAxis(device, std::forward<Args>(args)...);
185  }
186 
187  template <typename... Args>
188  VTKM_CONT bool operator()(vtkm::cont::DeviceAdapterTagCuda device, Args&&... args) const
189  {
190  return this->LaunchYAxis(device, std::forward<Args>(args)...);
191  }
192 
193  template <typename... Args>
194  VTKM_CONT bool operator()(vtkm::cont::DeviceAdapterTagKokkos device, Args&&... args) const
195  {
196  return this->LaunchYAxis(device, std::forward<Args>(args)...);
197  }
198 };
199 }
200 }
201 }
202 
203 
204 #endif
vtkm::worklet::flying_edges::compute_ijk
VTKM_EXEC vtkm::Id3 compute_ijk(SumXAxis, const vtkm::Id3 &executionSpaceIJK)
Definition: FlyingEdgesHelpers.h:96
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
vtkm::worklet::flying_edges::ComputePass1::ControlSignature
void(CellSetIn, FieldOut axis_sum, FieldOut axis_min, FieldOut axis_max, WholeArrayInOut edgeData, WholeArrayIn data) ControlSignature
Definition: FlyingEdgesPass1.h:87
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::flying_edges::FlyingEdges3D::Below
@ Below
Definition: FlyingEdgesHelpers.h:37
vtkm::worklet::flying_edges::compute_start
VTKM_EXEC vtkm::Id compute_start(SumXAxis, const vtkm::Id3 &ijk, const vtkm::Id3 &dims)
Definition: FlyingEdgesHelpers.h:131
vtkm::cont::CellSetStructured
Definition: CastAndCall.h:32
vtkm::worklet::flying_edges::FlyingEdges3D::RightAbove
@ RightAbove
Definition: FlyingEdgesHelpers.h:40
FlyingEdgesHelpers.h
vtkm::worklet::flying_edges::launchComputePass1
Definition: FlyingEdgesPass1.h:148
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::flying_edges::SumXAxis
Definition: FlyingEdgesHelpers.h:51
vtkm::worklet::flying_edges::ComputePass1::ComputePass1
ComputePass1(T value, const vtkm::Id3 &pdims)
Definition: FlyingEdgesPass1.h:76
vtkm::cont::ArrayHandle::Fill
VTKM_CONT void Fill(const ValueType &fillValue, vtkm::Id startIndex, vtkm::Id endIndex, vtkm::cont::Token &token) const
Fills the array with a given value.
Definition: ArrayHandle.h:530
vtkm::worklet::flying_edges::ComputePass1::ExecutionSignature
void(ThreadIndices, _2, _3, _4, _5, _6, Device) ExecutionSignature
Definition: FlyingEdgesPass1.h:88
vtkm::worklet::WorkletVisitPointsWithCells
Base class for worklets that map from Cells to Points.
Definition: WorkletMapTopology.h:274
vtkm::cont::Invoker
Allows launching any worklet without a dispatcher.
Definition: Invoker.h:41
vtkm::worklet::flying_edges::compute_inc
VTKM_EXEC vtkm::Id compute_inc(SumXAxis, const vtkm::Id3 &)
Definition: FlyingEdgesHelpers.h:174
vtkm::exec::arg::ThreadIndices
The ExecutionSignature tag to use to get the thread indices.
Definition: ThreadIndices.h:41
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::flying_edges::write_edge
VTKM_EXEC void write_edge(Device, vtkm::Id write_index, WholeEdgeField &edges, vtkm::UInt8 edgeCase)
Definition: FlyingEdgesPass1.h:49
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::worklet::flying_edges::ComputePass1::InputDomain
_1 InputDomain
Definition: FlyingEdgesPass1.h:89
vtkm::worklet::flying_edges::launchComputePass1::operator()
VTKM_CONT bool operator()(vtkm::cont::DeviceAdapterTagCuda device, Args &&... args) const
Definition: FlyingEdgesPass1.h:188
vtkm::worklet::flying_edges::make_metaDataMesh2D
vtkm::cont::CellSetStructured< 2 > make_metaDataMesh2D(SumXAxis, const vtkm::Id3 &pdims)
Definition: FlyingEdgesHelpers.h:81
vtkm::Vec< vtkm::Id, 3 >
vtkm::worklet::flying_edges::launchComputePass1::LaunchYAxis
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device, const ComputePass1< T > &worklet, const vtkm::cont::ArrayHandle< T, StorageTagField > &inputField, vtkm::cont::ArrayHandle< vtkm::UInt8 > &edgeCases, vtkm::cont::CellSetStructured< 2 > &metaDataMesh2D, Args &&... args) const
Definition: FlyingEdgesPass1.h:166
vtkm::worklet::flying_edges::SumYAxis
Definition: FlyingEdgesHelpers.h:57
vtkm::worklet::flying_edges::launchComputePass1::operator()
VTKM_CONT bool operator()(vtkm::cont::DeviceAdapterTagKokkos device, Args &&... args) const
Definition: FlyingEdgesPass1.h:194
vtkm::worklet::flying_edges::launchComputePass1::operator()
VTKM_CONT bool operator()(DeviceAdapterTag device, Args &&... args) const
Definition: FlyingEdgesPass1.h:182
vtkm::worklet::flying_edges::FlyingEdges3D::LeftAbove
@ LeftAbove
Definition: FlyingEdgesHelpers.h:39
WorkletMapTopology.h
vtkm::worklet::flying_edges::ComputePass1
Definition: FlyingEdgesPass1.h:70
vtkm::worklet::flying_edges::ComputePass1::operator()
VTKM_EXEC void operator()(const ThreadIndices &threadIndices, vtkm::Id3 &axis_sum, vtkm::Id &axis_min, vtkm::Id &axis_max, WholeEdgeField &edges, const WholeDataField &field, Device device) const
Definition: FlyingEdgesPass1.h:95
vtkm::worklet::flying_edges::launchComputePass1::LaunchXAxis
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device, const ComputePass1< T > &worklet, const vtkm::cont::ArrayHandle< T, StorageTagField > &inputField, vtkm::cont::ArrayHandle< vtkm::UInt8 > &edgeCases, vtkm::cont::CellSetStructured< 2 > &metaDataMesh2D, Args &&... args) const
Definition: FlyingEdgesPass1.h:151
vtkm::worklet::flying_edges::ComputePass1::IsoValue
T IsoValue
Definition: FlyingEdgesPass1.h:73
vtkm::worklet::flying_edges::ComputePass1::ComputePass1
ComputePass1()
Definition: FlyingEdgesPass1.h:75
vtkm::worklet::flying_edges::ComputePass1::PointDims
vtkm::Id3 PointDims
Definition: FlyingEdgesPass1.h:72