VTK-m  2.0
FlyingEdgesPass4Common.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_pass4_common_h
14 #define vtk_m_worklet_contour_flyingedges_pass4_common_h
15 
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace flying_edges
24 {
25 
27 {
28  return vtkm::Id3{ 1, dims[0], (dims[0] * dims[1]) };
29 }
30 
32 {
33  return cellId + 1;
34 }
36  vtkm::Id cellId,
37  vtkm::Id y_point_axis_inc)
38 {
39  return cellId + (y_point_axis_inc - 1);
40 }
41 
42 VTKM_EXEC inline bool case_includes_axes(vtkm::UInt8 const* const edgeUses)
43 {
44  return (edgeUses[0] != 0 || edgeUses[4] != 0 || edgeUses[8] != 0);
45 }
46 
47 template <typename WholeConnField, typename WholeCellIdField>
48 VTKM_EXEC inline void generate_tris(vtkm::Id inputCellId,
49  vtkm::UInt8 edgeCase,
50  vtkm::UInt8 numTris,
51  vtkm::Id* edgeIds,
52  vtkm::Id& triId,
53  const WholeConnField& conn,
54  const WholeCellIdField& cellIds)
55 {
56  auto* edges = data::GetTriEdgeCases(edgeCase);
57  vtkm::Id edgeIndex = 1;
58  vtkm::Id index = static_cast<vtkm::Id>(triId) * 3;
59  for (vtkm::UInt8 i = 0; i < numTris; ++i)
60  {
61  cellIds.Set(triId + i, inputCellId);
62 
63  //This keeps the same winding for the triangles that marching cells
64  //produced. By keeping the winding the same we make sure
65  //that 'fast' normals are consistent with the marching
66  //cells version
67  conn.Set(index, edgeIds[edges[edgeIndex]]);
68  conn.Set(index + 1, edgeIds[edges[edgeIndex + 2]]);
69  conn.Set(index + 2, edgeIds[edges[edgeIndex + 1]]);
70  index += 3;
71  edgeIndex += 3;
72  }
73  triId += numTris;
74 }
75 
76 
77 // Helper function to set up the point ids on voxel edges.
78 //----------------------------------------------------------------------------
79 template <typename AxisToSum, typename FieldInPointId3>
80 VTKM_EXEC inline void init_voxelIds(AxisToSum,
81  vtkm::Id writeOffset,
82  vtkm::UInt8 edgeCase,
83  const FieldInPointId3& axis_sums,
84  vtkm::Id* edgeIds)
85 {
86  auto* edgeUses = data::GetEdgeUses(edgeCase);
87  edgeIds[0] = writeOffset + axis_sums[0][AxisToSum::xindex]; // x-edges
88  edgeIds[1] = writeOffset + axis_sums[1][AxisToSum::xindex];
89  edgeIds[2] = writeOffset + axis_sums[3][AxisToSum::xindex];
90  edgeIds[3] = writeOffset + axis_sums[2][AxisToSum::xindex];
91  edgeIds[4] = writeOffset + axis_sums[0][AxisToSum::yindex]; // y-edges
92  edgeIds[5] = edgeIds[4] + edgeUses[4];
93  edgeIds[6] = writeOffset + axis_sums[3][AxisToSum::yindex];
94  edgeIds[7] = edgeIds[6] + edgeUses[6];
95  edgeIds[8] = writeOffset + axis_sums[0][AxisToSum::zindex]; // z-edges
96  edgeIds[9] = edgeIds[8] + edgeUses[8];
97  edgeIds[10] = writeOffset + axis_sums[1][AxisToSum::zindex];
98  edgeIds[11] = edgeIds[10] + edgeUses[10];
99 }
100 
101 // Helper function to advance the point ids along voxel rows.
102 //----------------------------------------------------------------------------
103 VTKM_EXEC inline void advance_voxelIds(vtkm::UInt8 const* const edgeUses, vtkm::Id* edgeIds)
104 {
105  edgeIds[0] += edgeUses[0]; // x-edges
106  edgeIds[1] += edgeUses[1];
107  edgeIds[2] += edgeUses[2];
108  edgeIds[3] += edgeUses[3];
109  edgeIds[4] += edgeUses[4]; // y-edges
110  edgeIds[5] = edgeIds[4] + edgeUses[5];
111  edgeIds[6] += edgeUses[6];
112  edgeIds[7] = edgeIds[6] + edgeUses[7];
113  edgeIds[8] += edgeUses[8]; // z-edges
114  edgeIds[9] = edgeIds[8] + edgeUses[9];
115  edgeIds[10] += edgeUses[10];
116  edgeIds[11] = edgeIds[10] + edgeUses[11];
117 }
118 
119 //----------------------------------------------------------------------------
121 {
128  bool hasWork = true;
129 
130  template <typename AxisToSum,
131  typename ThreadIndices,
132  typename WholeSumField,
133  typename FieldInPointId,
134  typename WholeEdgeField>
136  const vtkm::Id3& pdims,
137  const ThreadIndices& threadIndices,
138  const WholeSumField& vtkmNotUsed(axis_sums),
139  const FieldInPointId& axis_mins,
140  const FieldInPointId& axis_maxs,
141  const WholeEdgeField& edges)
142  {
143  ijk = compute_ijk(AxisToSum{}, threadIndices.GetInputIndex3D());
144 
145  startPos = compute_neighbor_starts(AxisToSum{}, ijk, pdims);
146  axis_inc = compute_inc(AxisToSum{}, pdims);
147 
148  // Compute the subset (start and end) of the row that we need
149  // to iterate to generate triangles for the iso-surface
151  pdims[AxisToSum::xindex] - 1, edges, axis_mins, axis_maxs, startPos, axis_inc, left, right);
152  hasWork = hasWork && left != right;
153  if (!hasWork)
154  {
155  return;
156  }
157 
158 
159  cellId = compute_start(AxisToSum{}, ijk, pdims - vtkm::Id3{ 1, 1, 1 });
160 
161  //update our ijk
162  ijk[AxisToSum::xindex] = left;
163 
167 
168  if (ijk[AxisToSum::xindex] < 1)
169  {
170  boundaryStatus[AxisToSum::xindex] += FlyingEdges3D::MinBoundary;
171  }
172  if (ijk[AxisToSum::xindex] >= (pdims[AxisToSum::xindex] - 2))
173  {
174  boundaryStatus[AxisToSum::xindex] += FlyingEdges3D::MaxBoundary;
175  }
176  if (ijk[AxisToSum::yindex] < 1)
177  {
178  boundaryStatus[AxisToSum::yindex] += FlyingEdges3D::MinBoundary;
179  }
180  if (ijk[AxisToSum::yindex] >= (pdims[AxisToSum::yindex] - 2))
181  {
182  boundaryStatus[AxisToSum::yindex] += FlyingEdges3D::MaxBoundary;
183  }
184  if (ijk[AxisToSum::zindex] < 1)
185  {
186  boundaryStatus[AxisToSum::zindex] += FlyingEdges3D::MinBoundary;
187  }
188  if (ijk[AxisToSum::zindex] >= (pdims[AxisToSum::zindex] - 2))
189  {
190  boundaryStatus[AxisToSum::zindex] += FlyingEdges3D::MaxBoundary;
191  }
192  }
193 
194  template <typename AxisToSum>
195  VTKM_EXEC inline void increment(AxisToSum, const vtkm::Id3& pdims)
196  {
197  //compute what the current cellId is
198  cellId = increment_cellId(AxisToSum{}, cellId, axis_inc);
199 
200  //compute what the current ijk is
201  ijk[AxisToSum::xindex]++;
202 
203  // compute what the current boundary state is
204  // can never be on the MinBoundary after we increment
205  if (ijk[AxisToSum::xindex] >= (pdims[AxisToSum::xindex] - 2))
206  {
207  boundaryStatus[AxisToSum::xindex] = FlyingEdges3D::MaxBoundary;
208  }
209  else
210  {
211  boundaryStatus[AxisToSum::xindex] = FlyingEdges3D::Interior;
212  }
213  }
214 };
215 
216 // Helper function to state if a boundary object refers to a location that
217 // is fully inside ( not on a boundary )
218 //----------------------------------------------------------------------------
219 VTKM_EXEC inline bool fully_interior(const vtkm::Vec<vtkm::UInt8, 3>& boundaryStatus)
220 {
221  return boundaryStatus[0] == FlyingEdges3D::Interior &&
222  boundaryStatus[1] == FlyingEdges3D::Interior && boundaryStatus[2] == FlyingEdges3D::Interior;
223 }
224 }
225 }
226 }
227 #endif
vtkm::worklet::flying_edges::Pass4TrimState::cellId
vtkm::Id cellId
Definition: FlyingEdgesPass4Common.h:125
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::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::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::Pass4TrimState::boundaryStatus
vtkm::Vec< vtkm::UInt8, 3 > boundaryStatus
Definition: FlyingEdgesPass4Common.h:127
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::Pass4TrimState::left
vtkm::Id left
Definition: FlyingEdgesPass4Common.h:122
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::worklet::flying_edges::compute_incs3d
VTKM_EXEC vtkm::Id3 compute_incs3d(const vtkm::Id3 &dims)
Definition: FlyingEdgesPass4Common.h:26
vtkm::worklet::flying_edges::Pass4TrimState::axis_inc
vtkm::Id axis_inc
Definition: FlyingEdgesPass4Common.h:126
FlyingEdgesHelpers.h
vtkm::worklet::flying_edges::Pass4TrimState::hasWork
bool hasWork
Definition: FlyingEdgesPass4Common.h:128
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::FlyingEdges3D::Interior
@ Interior
Definition: FlyingEdgesHelpers.h:45
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::Pass4TrimState::ijk
vtkm::Id3 ijk
Definition: FlyingEdgesPass4Common.h:123
vtkm::worklet::flying_edges::SumXAxis
Definition: FlyingEdgesHelpers.h:51
vtkm::worklet::flying_edges::increment_cellId
constexpr VTKM_EXEC vtkm::Id increment_cellId(SumXAxis, vtkm::Id cellId, vtkm::Id)
Definition: FlyingEdgesPass4Common.h:31
vtkm::worklet::flying_edges::Pass4TrimState::increment
VTKM_EXEC void increment(AxisToSum, const vtkm::Id3 &pdims)
Definition: FlyingEdgesPass4Common.h:195
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::Pass4TrimState::Pass4TrimState
VTKM_EXEC Pass4TrimState(AxisToSum, const vtkm::Id3 &pdims, const ThreadIndices &threadIndices, const WholeSumField &vtkmNotUsed(axis_sums), const FieldInPointId &axis_mins, const FieldInPointId &axis_maxs, const WholeEdgeField &edges)
Definition: FlyingEdgesPass4Common.h:135
vtkm::worklet::flying_edges::compute_inc
VTKM_EXEC vtkm::Id compute_inc(SumXAxis, const vtkm::Id3 &)
Definition: FlyingEdgesHelpers.h:174
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::worklet::flying_edges::advance_voxelIds
VTKM_EXEC void advance_voxelIds(vtkm::UInt8 const *const edgeUses, vtkm::Id *edgeIds)
Definition: FlyingEdgesPass4Common.h:103
vtkm::worklet::flying_edges::data::GetTriEdgeCases
VTKM_EXEC vtkm::UInt8 const * GetTriEdgeCases(vtkm::UInt8 edgecase)
Definition: FlyingEdgesTables.h:116
vtkm::Vec< vtkm::Id, 3 >
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::Pass4TrimState::right
vtkm::Id right
Definition: FlyingEdgesPass4Common.h:122
vtkm::worklet::flying_edges::Pass4TrimState::startPos
vtkm::Id4 startPos
Definition: FlyingEdgesPass4Common.h:124
vtkm::worklet::flying_edges::FlyingEdges3D::MinBoundary
@ MinBoundary
Definition: FlyingEdgesHelpers.h:46