VTK-m  2.0
FlyingEdgesPass2.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_pass2_h
14 #define vtk_m_worklet_contour_flyingedges_pass2_h
15 
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace flying_edges
24 {
25 
27 {
29 
31  explicit ComputePass2(const vtkm::Id3& pdims)
32  : PointDims(pdims)
33  {
34  }
35 
36  using ControlSignature = void(CellSetIn,
37  WholeArrayInOut axis_sums,
38  FieldInPoint axis_mins,
39  FieldInPoint axis_maxs,
40  FieldOutCell cell_tri_count,
41  WholeArrayIn edgeData);
42  using ExecutionSignature = void(ThreadIndices, _2, _3, _4, _5, _6, Device);
43  using InputDomain = _1;
44 
45  template <typename ThreadIndices,
46  typename WholeSumField,
47  typename FieldInPointId,
48  typename WholeEdgeField,
49  typename Device>
50  VTKM_EXEC void operator()(const ThreadIndices& threadIndices,
51  const WholeSumField& axis_sums,
52  const FieldInPointId& axis_mins,
53  const FieldInPointId& axis_maxs,
54  vtkm::Int32& cell_tri_count,
55  const WholeEdgeField& edges,
56  Device) const
57  {
58  using AxisToSum = typename select_AxisToSum<Device>::type;
59 
60  // Pass 2. Traverse all cells in the meta data plane. This allows us to
61  // easily grab the four edge cases bounding this voxel-row
62  const vtkm::Id3 ijk = compute_ijk(AxisToSum{}, threadIndices.GetInputIndex3D());
63  const vtkm::Id3 pdims = this->PointDims;
64 
65  const vtkm::Id4 startPos = compute_neighbor_starts(AxisToSum{}, ijk, pdims);
66  const vtkm::Id axis_inc = compute_inc(AxisToSum{}, pdims);
67 
68  // Compute the subset (start and end) of the row that we need
69  // to iterate to generate triangles for the iso-surface
70  vtkm::Id left, right;
71  bool hasWork = computeTrimBounds(
72  pdims[AxisToSum::xindex] - 1, edges, axis_mins, axis_maxs, startPos, axis_inc, left, right);
73  if (!hasWork)
74  {
75  return;
76  }
77 
78  vtkm::Vec<bool, 3> onBoundary(false, false, false); //updated in for-loop
79  onBoundary[AxisToSum::yindex] = (ijk[AxisToSum::yindex] >= (pdims[AxisToSum::yindex] - 2));
80  onBoundary[AxisToSum::zindex] = (ijk[AxisToSum::zindex] >= (pdims[AxisToSum::zindex] - 2));
81 
82  cell_tri_count = 0;
83  vtkm::Id3 sums = axis_sums.Get(threadIndices.GetIndicesIncident()[0]);
84  vtkm::Id3 adj_row_sum(0, 0, 0);
85  vtkm::Id3 adj_col_sum(0, 0, 0);
86  if (onBoundary[AxisToSum::yindex])
87  {
88  adj_row_sum = axis_sums.Get(threadIndices.GetIndicesIncident()[1]);
89  }
90  if (onBoundary[AxisToSum::zindex])
91  {
92  adj_col_sum = axis_sums.Get(threadIndices.GetIndicesIncident()[3]);
93  }
94 
95  for (vtkm::Id i = left; i < right; ++i) // run along the trimmed voxels
96  {
97  vtkm::UInt8 edgeCase = getEdgeCase(edges, startPos, (axis_inc * i));
98  vtkm::UInt8 numTris = data::GetNumberOfPrimitives(edgeCase);
99  if (numTris > 0)
100  {
101  cell_tri_count += numTris;
102 
103  // Count the number of y- and z-points to be generated. Pass# 1 counted
104  // the number of x-intersections along the x-edges. Now we count all
105  // intersections on the y- and z-voxel axes.
106  auto* edgeUses = data::GetEdgeUses(edgeCase);
107 
108  onBoundary[AxisToSum::xindex] = (i >= (pdims[AxisToSum::xindex] - 2));
109 
110  // row axes edge always counted
111  sums[AxisToSum::yindex] += edgeUses[4];
112  // col axes edge always counted
113  sums[AxisToSum::zindex] += edgeUses[8];
114 
115  // handle boundary
116  this->CountBoundaryEdgeUses(
117  AxisToSum{}, onBoundary, edgeUses, sums, adj_row_sum, adj_col_sum);
118  }
119  }
120 
121  axis_sums.Set(threadIndices.GetIndicesIncident()[0], sums);
122  if (onBoundary[AxisToSum::yindex])
123  {
124  axis_sums.Set(threadIndices.GetIndicesIncident()[1], adj_row_sum);
125  }
126  if (onBoundary[AxisToSum::zindex])
127  {
128  axis_sums.Set(threadIndices.GetIndicesIncident()[3], adj_col_sum);
129  }
130  }
131 
132  //----------------------------------------------------------------------------
133  // Count intersections along voxel axes. When traversing the volume across
134  // edges, the voxel axes on the boundary may be undefined near boundaries
135  // (because there are no fully-formed cells). Thus the voxel axes on the
136  // boundary are treated specially.
137  //
138  // Only on these boundaries do we write to the metaData of our neighbor
139  // as it is safe as those
140  template <typename AxisToSum>
141  VTKM_EXEC inline void CountBoundaryEdgeUses(AxisToSum,
142  vtkm::Vec<bool, 3> onBoundary,
143  vtkm::UInt8 const* const edgeUses,
144  vtkm::Id3& sums,
145  vtkm::Id3& adj_row_sum,
146  vtkm::Id3& adj_col_sum) const
147  {
148  if (onBoundary[AxisToSum::xindex]) //+x boundary
149  {
150  sums[AxisToSum::yindex] += edgeUses[5];
151  sums[AxisToSum::zindex] += edgeUses[9];
152  if (onBoundary[AxisToSum::yindex]) //+x +y
153  {
154  adj_row_sum[AxisToSum::zindex] += edgeUses[11];
155  }
156  if (onBoundary[AxisToSum::zindex]) //+x +z
157  {
158  adj_col_sum[AxisToSum::yindex] += edgeUses[7];
159  }
160  }
161  if (onBoundary[AxisToSum::yindex]) //+y boundary
162  {
163  adj_row_sum[AxisToSum::zindex] += edgeUses[10];
164  }
165  if (onBoundary[AxisToSum::zindex]) //+z boundary
166  {
167  adj_col_sum[AxisToSum::yindex] += edgeUses[6];
168  }
169  }
170 };
171 }
172 }
173 }
174 
175 #endif
vtkm::worklet::flying_edges::compute_ijk
VTKM_EXEC vtkm::Id3 compute_ijk(SumXAxis, const vtkm::Id3 &executionSpaceIJK)
Definition: FlyingEdgesHelpers.h:96
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm::worklet::flying_edges::ComputePass2::ComputePass2
ComputePass2(const vtkm::Id3 &pdims)
Definition: FlyingEdgesPass2.h:31
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::compute_neighbor_starts
VTKM_EXEC vtkm::Id4 compute_neighbor_starts(SumXAxis, const vtkm::Id3 &ijk, const vtkm::Id3 &pdims)
Definition: FlyingEdgesHelpers.h:140
FlyingEdgesHelpers.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
vtkm::worklet::flying_edges::ComputePass2::PointDims
vtkm::Id3 PointDims
Definition: FlyingEdgesPass2.h:28
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::data::GetNumberOfPrimitives
VTKM_EXEC vtkm::UInt8 GetNumberOfPrimitives(vtkm::UInt8 edgecase)
Definition: FlyingEdgesTables.h:26
vtkm::worklet::flying_edges::ComputePass2::ComputePass2
ComputePass2()
Definition: FlyingEdgesPass2.h:30
vtkm::worklet::flying_edges::ComputePass2::ExecutionSignature
void(ThreadIndices, _2, _3, _4, _5, _6, Device) ExecutionSignature
Definition: FlyingEdgesPass2.h:42
vtkm::worklet::flying_edges::ComputePass2::InputDomain
_1 InputDomain
Definition: FlyingEdgesPass2.h:43
vtkm::worklet::WorkletVisitCellsWithPoints
Base class for worklets that map from Points to Cells.
Definition: WorkletMapTopology.h:255
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::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::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::worklet::flying_edges::ComputePass2
Definition: FlyingEdgesPass2.h:26
vtkm::worklet::flying_edges::ComputePass2::ControlSignature
void(CellSetIn, WholeArrayInOut axis_sums, FieldInPoint axis_mins, FieldInPoint axis_maxs, FieldOutCell cell_tri_count, WholeArrayIn edgeData) ControlSignature
Definition: FlyingEdgesPass2.h:41
vtkm::Vec< vtkm::Id, 3 >
FlyingEdgesTables.h
vtkm::Int32
int32_t Int32
Definition: Types.h:160
vtkm::worklet::flying_edges::ComputePass2::operator()
VTKM_EXEC void operator()(const ThreadIndices &threadIndices, const WholeSumField &axis_sums, const FieldInPointId &axis_mins, const FieldInPointId &axis_maxs, vtkm::Int32 &cell_tri_count, const WholeEdgeField &edges, Device) const
Definition: FlyingEdgesPass2.h:50
vtkm::worklet::WorkletVisitCellsWithPoints::FieldOutCell
FieldOut FieldOutCell
Definition: WorkletMapTopology.h:263
vtkm::worklet::flying_edges::ComputePass2::CountBoundaryEdgeUses
VTKM_EXEC void CountBoundaryEdgeUses(AxisToSum, vtkm::Vec< bool, 3 > onBoundary, vtkm::UInt8 const *const edgeUses, vtkm::Id3 &sums, vtkm::Id3 &adj_row_sum, vtkm::Id3 &adj_col_sum) const
Definition: FlyingEdgesPass2.h:141