VTK-m  2.0
FlyingEdgesHelpers.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_helpers_h
14 #define vtk_m_worklet_contour_flyingedges_helpers_h
15 
16 #include <vtkm/Types.h>
17 
20 
23 
24 namespace vtkm
25 {
26 namespace worklet
27 {
28 namespace flying_edges
29 {
30 
32 {
33 public:
34  // Edge case table values.
35  enum EdgeClass
36  {
37  Below = 0, // below isovalue
38  Above = 1, // above isovalue
39  LeftAbove = 1, // left vertex is above isovalue
40  RightAbove = 2, // right vertex is above isovalue
41  BothAbove = 3 // entire edge is above isovalue
42  };
43  enum CellClass
44  {
45  Interior = 0,
48  };
49 };
50 
51 struct SumXAxis
52 {
53  static constexpr vtkm::Id xindex = 0;
54  static constexpr vtkm::Id yindex = 1;
55  static constexpr vtkm::Id zindex = 2;
56 };
57 struct SumYAxis
58 {
59  static constexpr vtkm::Id xindex = 1;
60  static constexpr vtkm::Id yindex = 0;
61  static constexpr vtkm::Id zindex = 2;
62 };
63 
64 template <typename Device>
66 {
67  using type = SumXAxis;
68 };
69 
70 template <>
71 struct select_AxisToSum<vtkm::cont::DeviceAdapterTagCuda>
72 {
73  using type = SumYAxis;
74 };
75 template <>
76 struct select_AxisToSum<vtkm::cont::DeviceAdapterTagKokkos>
77 {
78  using type = SumYAxis;
79 };
80 
82 {
84  metaDataMesh.SetPointDimensions(vtkm::Id2{ pdims[1], pdims[2] });
85  return metaDataMesh;
86 }
87 
89 {
91  metaDataMesh.SetPointDimensions(vtkm::Id2{ pdims[0], pdims[2] });
92  return metaDataMesh;
93 }
94 
95 
96 VTKM_EXEC inline vtkm::Id3 compute_ijk(SumXAxis, const vtkm::Id3& executionSpaceIJK)
97 {
98  return vtkm::Id3{ 0, executionSpaceIJK[0], executionSpaceIJK[1] };
99 }
100 VTKM_EXEC inline vtkm::Id3 compute_ijk(SumYAxis, const vtkm::Id3& executionSpaceIJK)
101 {
102  return vtkm::Id3{ executionSpaceIJK[0], 0, executionSpaceIJK[1] };
103 }
104 
105 
107  const vtkm::Id3& executionSpacePDims,
108  vtkm::Id numOfXPoints)
109 {
110  return vtkm::Id3{ numOfXPoints - 1, executionSpacePDims[0] - 1, executionSpacePDims[1] - 1 };
111 }
113  const vtkm::Id3& executionSpacePDims,
114  vtkm::Id numOfYPoints)
115 {
116  return vtkm::Id3{ executionSpacePDims[0] - 1, numOfYPoints - 1, executionSpacePDims[1] - 1 };
117 }
119  const vtkm::Id3& executionSpacePDims,
120  vtkm::Id numOfXPoints)
121 {
122  return vtkm::Id3{ numOfXPoints, executionSpacePDims[0], executionSpacePDims[1] };
123 }
125  const vtkm::Id3& executionSpacePDims,
126  vtkm::Id numOfYPoints)
127 {
128  return vtkm::Id3{ executionSpacePDims[0], numOfYPoints, executionSpacePDims[1] };
129 }
130 
131 VTKM_EXEC inline vtkm::Id compute_start(SumXAxis, const vtkm::Id3& ijk, const vtkm::Id3& dims)
132 {
133  return (dims[0] * ijk[1]) + ((dims[0] * dims[1]) * ijk[2]);
134 }
135 VTKM_EXEC inline vtkm::Id compute_start(SumYAxis, const vtkm::Id3& ijk, const vtkm::Id3& dims)
136 {
137  return ijk[0] + ((dims[0] * dims[1]) * ijk[2]);
138 }
139 
141  const vtkm::Id3& ijk,
142  const vtkm::Id3& pdims)
143 {
144  //Optimized form of
145  // return vtkm::Id4 { compute_start(sx, ijk, pdims),
146  // compute_start(sx, ijk + vtkm::Id3{ 0, 1, 0 }, pdims),
147  // compute_start(sx, ijk + vtkm::Id3{ 0, 0, 1 }, pdims),
148  // compute_start(sx, ijk + vtkm::Id3{ 0, 1, 1 }, pdims) };
149  const auto sliceSize = (pdims[0] * pdims[1]);
150  const auto rowPos = (pdims[0] * ijk[1]);
151  return vtkm::Id4{ rowPos + (sliceSize * ijk[2]),
152  rowPos + pdims[0] + (sliceSize * ijk[2]),
153  rowPos + (sliceSize * (ijk[2] + 1)),
154  rowPos + pdims[0] + (sliceSize * (ijk[2] + 1)) };
155 }
157  const vtkm::Id3& ijk,
158  const vtkm::Id3& pdims)
159 {
160  //Optimized form of
161  // return vtkm::Id4{ compute_start(sy, ijk, pdims),
162  // compute_start(sy, ijk + vtkm::Id3{ 1, 0, 0 }, pdims),
163  // compute_start(sy, ijk + vtkm::Id3{ 0, 0, 1 }, pdims),
164  // compute_start(sy, ijk + vtkm::Id3{ 1, 0, 1 }, pdims) };
165  const auto sliceSize = (pdims[0] * pdims[1]);
166  return vtkm::Id4{ ijk[0] + (sliceSize * ijk[2]),
167  ijk[0] + 1 + (sliceSize * ijk[2]),
168  ijk[0] + (sliceSize * (ijk[2] + 1)),
169  ijk[0] + 1 + (sliceSize * (ijk[2] + 1)) };
170 }
171 
172 
173 
175 {
176  return 1;
177 }
179 {
180  return dims[0];
181 }
182 
183 //----------------------------------------------------------------------------
184 template <typename WholeEdgeField>
185 VTKM_EXEC inline vtkm::UInt8 getEdgeCase(const WholeEdgeField& edges,
186  const vtkm::Id4& startPos,
187  vtkm::Id inc)
188 {
189  vtkm::UInt8 e0 = edges.Get(startPos[0] + inc);
190  vtkm::UInt8 e1 = edges.Get(startPos[1] + inc);
191  vtkm::UInt8 e2 = edges.Get(startPos[2] + inc);
192  vtkm::UInt8 e3 = edges.Get(startPos[3] + inc);
193  return static_cast<vtkm::UInt8>(e0 | (e1 << 2) | (e2 << 4) | (e3 << 6));
194 }
195 
196 
197 //----------------------------------------------------------------------------
198 
199 template <typename WholeEdgeField, typename FieldInPointId>
200 VTKM_EXEC inline bool computeTrimBounds(vtkm::Id rightMax,
201  const WholeEdgeField& edges,
202  const FieldInPointId& axis_mins,
203  const FieldInPointId& axis_maxs,
204  const vtkm::Id4& startPos,
205  vtkm::Id inc,
206  vtkm::Id& left,
207  vtkm::Id& right)
208 {
209  // find adjusted trim values.
210  left = vtkm::Min(axis_mins[0], axis_mins[1]);
211  left = vtkm::Min(left, axis_mins[2]);
212  left = vtkm::Min(left, axis_mins[3]);
213 
214  right = vtkm::Max(axis_maxs[0], axis_maxs[1]);
215  right = vtkm::Max(right, axis_maxs[2]);
216  right = vtkm::Max(right, axis_maxs[3]);
217 
218  // The trim edges may need adjustment if the contour travels between rows
219  // of edges (without intersecting these edges). This means checking
220  // whether the trim faces at (left,right) made up of the edges intersect
221  // the contour.
222  if (left > rightMax && right == 0)
223  {
224  //verify that we have nothing to generate and early terminate.
225  bool mins_same = (axis_mins[0] == axis_mins[1] && axis_mins[0] == axis_mins[2] &&
226  axis_mins[0] == axis_mins[3]);
227  bool maxs_same = (axis_maxs[0] == axis_maxs[1] && axis_maxs[0] == axis_maxs[2] &&
228  axis_maxs[0] == axis_maxs[3]);
229 
230  left = 0;
231  right = rightMax;
232  if (mins_same && maxs_same)
233  {
234  vtkm::UInt8 e0 = edges.Get(startPos[0]);
235  vtkm::UInt8 e1 = edges.Get(startPos[1]);
236  vtkm::UInt8 e2 = edges.Get(startPos[2]);
237  vtkm::UInt8 e3 = edges.Get(startPos[3]);
238  if (e0 == e1 && e1 == e2 && e2 == e3)
239  {
240  //We have nothing to process in this row
241  return false;
242  }
243  }
244  }
245  else
246  {
247 
248  vtkm::UInt8 e0 = edges.Get(startPos[0] + (left * inc));
249  vtkm::UInt8 e1 = edges.Get(startPos[1] + (left * inc));
250  vtkm::UInt8 e2 = edges.Get(startPos[2] + (left * inc));
251  vtkm::UInt8 e3 = edges.Get(startPos[3] + (left * inc));
252  if ((e0 & 0x1) != (e1 & 0x1) || (e1 & 0x1) != (e2 & 0x1) || (e2 & 0x1) != (e3 & 0x1))
253  {
254  left = 0;
255  }
256 
257  e0 = edges.Get(startPos[0] + (right * inc));
258  e1 = edges.Get(startPos[1] + (right * inc));
259  e2 = edges.Get(startPos[2] + (right * inc));
260  e3 = edges.Get(startPos[3] + (right * inc));
261  if ((e0 & 0x2) != (e1 & 0x2) || (e1 & 0x2) != (e2 & 0x2) || (e2 & 0x2) != (e3 & 0x2))
262  {
263  right = rightMax;
264  }
265  }
266 
267  return true;
268 }
269 }
270 }
271 }
272 #endif
vtkm::worklet::flying_edges::FlyingEdges3D
Definition: FlyingEdgesHelpers.h:31
vtkm::worklet::flying_edges::compute_ijk
VTKM_EXEC vtkm::Id3 compute_ijk(SumXAxis, const vtkm::Id3 &executionSpaceIJK)
Definition: FlyingEdgesHelpers.h:96
vtkm::worklet::flying_edges::SumYAxis::yindex
static constexpr vtkm::Id yindex
Definition: FlyingEdgesHelpers.h:60
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
Types.h
vtkm::worklet::flying_edges::compute_neighbor_starts
VTKM_EXEC vtkm::Id4 compute_neighbor_starts(SumXAxis, const vtkm::Id3 &ijk, const vtkm::Id3 &pdims)
Definition: FlyingEdgesHelpers.h:140
vtkm::worklet::flying_edges::FlyingEdges3D::MaxBoundary
@ MaxBoundary
Definition: FlyingEdgesHelpers.h:47
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::Above
@ Above
Definition: FlyingEdgesHelpers.h:38
vtkm::worklet::flying_edges::FlyingEdges3D::RightAbove
@ RightAbove
Definition: FlyingEdgesHelpers.h:40
DeviceAdapterTag.h
vtkm::worklet::flying_edges::computeTrimBounds
VTKM_EXEC bool computeTrimBounds(vtkm::Id rightMax, const WholeEdgeField &edges, const FieldInPointId &axis_mins, const FieldInPointId &axis_maxs, const vtkm::Id4 &startPos, vtkm::Id inc, vtkm::Id &left, vtkm::Id &right)
Definition: FlyingEdgesHelpers.h:200
DeviceAdapterTagKokkos.h
vtkm::worklet::flying_edges::FlyingEdges3D::Interior
@ Interior
Definition: FlyingEdgesHelpers.h:45
vtkm::worklet::flying_edges::FlyingEdges3D::EdgeClass
EdgeClass
Definition: FlyingEdgesHelpers.h:35
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
DeviceAdapterTagCuda.h
vtkm::worklet::flying_edges::SumXAxis
Definition: FlyingEdgesHelpers.h:51
vtkm::worklet::flying_edges::select_AxisToSum
Definition: FlyingEdgesHelpers.h:65
vtkm::worklet::flying_edges::SumXAxis::xindex
static constexpr vtkm::Id xindex
Definition: FlyingEdgesHelpers.h:53
vtkm::worklet::flying_edges::SumXAxis::zindex
static constexpr vtkm::Id zindex
Definition: FlyingEdgesHelpers.h:55
vtkm::worklet::flying_edges::compute_inc
VTKM_EXEC vtkm::Id compute_inc(SumXAxis, const vtkm::Id3 &)
Definition: FlyingEdgesHelpers.h:174
vtkm::worklet::flying_edges::FlyingEdges3D::BothAbove
@ BothAbove
Definition: FlyingEdgesHelpers.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::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::worklet::flying_edges::compute_cdims
VTKM_EXEC vtkm::Id3 compute_cdims(SumXAxis, const vtkm::Id3 &executionSpacePDims, vtkm::Id numOfXPoints)
Definition: FlyingEdgesHelpers.h:106
vtkm::worklet::flying_edges::SumXAxis::yindex
static constexpr vtkm::Id yindex
Definition: FlyingEdgesHelpers.h:54
vtkm::worklet::flying_edges::make_metaDataMesh2D
vtkm::cont::CellSetStructured< 2 > make_metaDataMesh2D(SumXAxis, const vtkm::Id3 &pdims)
Definition: FlyingEdgesHelpers.h:81
vtkm::worklet::flying_edges::SumYAxis::zindex
static constexpr vtkm::Id zindex
Definition: FlyingEdgesHelpers.h:61
vtkm::Vec< vtkm::Id, 3 >
vtkm::cont::CellSetStructured::SetPointDimensions
void SetPointDimensions(SchedulingRangeType dimensions)
Definition: CellSetStructured.h:49
vtkm::worklet::flying_edges::SumYAxis::xindex
static constexpr vtkm::Id xindex
Definition: FlyingEdgesHelpers.h:59
vtkm::worklet::flying_edges::SumYAxis
Definition: FlyingEdgesHelpers.h:57
CellSetStructured.h
vtkm::worklet::flying_edges::FlyingEdges3D::LeftAbove
@ LeftAbove
Definition: FlyingEdgesHelpers.h:39
vtkm::worklet::flying_edges::FlyingEdges3D::MinBoundary
@ MinBoundary
Definition: FlyingEdgesHelpers.h:46
vtkm::worklet::flying_edges::FlyingEdges3D::CellClass
CellClass
Definition: FlyingEdgesHelpers.h:43
vtkm::worklet::flying_edges::compute_pdims
VTKM_EXEC vtkm::Id3 compute_pdims(SumXAxis, const vtkm::Id3 &executionSpacePDims, vtkm::Id numOfXPoints)
Definition: FlyingEdgesHelpers.h:118