VTK-m  2.0
FlyingEdges.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 #ifndef vtk_m_worklet_contour_flyingedges_h
13 #define vtk_m_worklet_contour_flyingedges_h
14 
19 
20 #include <vtkm/cont/Algorithm.h>
22 #include <vtkm/cont/Invoker.h>
23 
24 namespace vtkm
25 {
26 namespace worklet
27 {
28 namespace flying_edges
29 {
30 
31 namespace detail
32 {
33 template <typename T, typename S>
34 vtkm::Id extend_by(vtkm::cont::ArrayHandle<T, S>& handle, vtkm::Id size)
35 {
36  vtkm::Id oldLen = handle.GetNumberOfValues();
37  handle.Allocate(oldLen + size, vtkm::CopyFlag::On);
38  return oldLen;
39 }
40 }
41 
42 //----------------------------------------------------------------------------
43 template <typename ValueType,
44  typename StorageTagField,
45  typename StorageTagVertices,
46  typename StorageTagNormals,
47  typename CoordinateType,
48  typename NormalType>
51  const vtkm::cont::ArrayHandleUniformPointCoordinates& coordinateSystem,
52  const std::vector<ValueType>& isovalues,
54  vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& points,
55  vtkm::cont::ArrayHandle<vtkm::Vec<NormalType, 3>, StorageTagNormals>& normals,
57 {
58  vtkm::cont::Invoker invoke;
59 
60  vtkm::Vec3f origin, spacing;
61  { //extract out the origin and spacing as these are needed for Pass4 to properly
62  //interpolate the new points
63  auto portal = coordinateSystem.ReadPortal();
64  origin = portal.GetOrigin();
65  spacing = portal.GetSpacing();
66  }
67  auto pdims = cells.GetPointDimensions();
68 
70  edgeCases.Allocate(coordinateSystem.GetNumberOfValues());
71 
72  vtkm::cont::CellSetStructured<2> metaDataMesh2D;
73  vtkm::cont::ArrayHandle<vtkm::Id> metaDataLinearSums; //per point of metaDataMesh
74  vtkm::cont::ArrayHandle<vtkm::Id> metaDataMin; //per point of metaDataMesh
75  vtkm::cont::ArrayHandle<vtkm::Id> metaDataMax; //per point of metaDataMesh
76  vtkm::cont::ArrayHandle<vtkm::Int32> metaDataNumTris; //per cell of metaDataMesh
77 
78  auto metaDataSums = vtkm::cont::make_ArrayHandleGroupVec<3>(metaDataLinearSums);
79 
80  // Since sharedState can be re-used between invocations of contour,
81  // we need to make sure we reset the size of the Interpolation
82  // arrays so we don't execute Pass5 over an array that is too large
83  sharedState.InterpolationEdgeIds.ReleaseResources();
85  sharedState.CellIdMap.ReleaseResources();
86 
87  vtkm::cont::ArrayHandle<vtkm::Id> triangle_topology;
88  for (std::size_t i = 0; i < isovalues.size(); ++i)
89  {
90  auto multiContourCellOffset = sharedState.CellIdMap.GetNumberOfValues();
91  auto multiContourPointOffset = sharedState.InterpolationWeights.GetNumberOfValues();
92  ValueType isoval = isovalues[i];
93 
94  //----------------------------------------------------------------------------
95  // PASS 1: Process all of the voxel edges that compose each row. Determine the
96  // edges case classification, count the number of edge intersections, and
97  // figure out where intersections along the row begins and ends
98  // (i.e., gather information for computational trimming).
99  //
100  {
101  VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "FlyingEdges Pass1");
102 
103  // We have different logic for GPU's compared to Shared memory systems
104  // since this is the first touch of lots of the arrays, and will effect
105  // NUMA perf.
106  //
107  // Additionally GPU's does significantly better when you do an initial fill
108  // and write only non-below values
109  //
110  ComputePass1<ValueType> worklet1(isoval, pdims);
113  worklet1,
114  inputField,
115  edgeCases,
116  metaDataMesh2D,
117  metaDataSums,
118  metaDataMin,
119  metaDataMax);
120  }
121 
122  //----------------------------------------------------------------------------
123  // PASS 2: Process a single row of voxels/cells. Count the number of other
124  // axis intersections by topological reasoning from previous edge cases.
125  // Determine the number of primitives (i.e., triangles) generated from this
126  // row. Use computational trimming to reduce work.
127  {
128  VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "FlyingEdges Pass2");
129  ComputePass2 worklet2(pdims);
130  invoke(worklet2,
131  metaDataMesh2D,
132  metaDataSums,
133  metaDataMin,
134  metaDataMax,
135  metaDataNumTris,
136  edgeCases);
137  }
138 
139  //----------------------------------------------------------------------------
140  // PASS 3: Compute the number of points and triangles that each edge
141  // row needs to generate by using exclusive scans.
142  vtkm::cont::Algorithm::ScanExtended(metaDataNumTris, metaDataNumTris);
143  auto sumTris =
144  vtkm::cont::ArrayGetValue(metaDataNumTris.GetNumberOfValues() - 1, metaDataNumTris);
145  if (sumTris > 0)
146  {
147  detail::extend_by(triangle_topology, 3 * sumTris);
148  detail::extend_by(sharedState.CellIdMap, sumTris);
149 
150 
151  vtkm::Id newPointSize =
152  vtkm::cont::Algorithm::ScanExclusive(metaDataLinearSums, metaDataLinearSums);
153  detail::extend_by(sharedState.InterpolationEdgeIds, newPointSize);
154  detail::extend_by(sharedState.InterpolationWeights, newPointSize);
155 
156  //----------------------------------------------------------------------------
157  // PASS 4: Process voxel rows and generate topology, and interpolation state
158  {
159  VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "FlyingEdges Pass4");
160 
161  launchComputePass4 pass4(
162  pdims, origin, spacing, multiContourCellOffset, multiContourPointOffset);
163 
164  detail::extend_by(points, newPointSize);
165  if (sharedState.GenerateNormals)
166  {
167  detail::extend_by(normals, newPointSize);
168  }
169 
171  pass4,
172  newPointSize,
173  isoval,
174  inputField,
175  edgeCases,
176  metaDataMesh2D,
177  metaDataSums,
178  metaDataMin,
179  metaDataMax,
180  metaDataNumTris,
181  sharedState,
182  triangle_topology,
183  points,
184  normals);
185  }
186  }
187  }
188 
190  outputCells.Fill(points.GetNumberOfValues(), vtkm::CELL_SHAPE_TRIANGLE, 3, triangle_topology);
191  return outputCells;
192 }
193 
194 } //namespace flying_edges
195 }
196 }
197 
198 #endif
VTKM_LOG_SCOPE
#define VTKM_LOG_SCOPE(level,...)
Definition: Logging.h:265
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< T, S >
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::ArrayHandle::Allocate
VTKM_CONT void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:465
vtkm::worklet::contour::CommonState::InterpolationWeights
vtkm::cont::ArrayHandle< vtkm::FloatDefault > InterpolationWeights
Definition: CommonState.h:33
vtkm::cont::CellSetStructured< 3 >
vtkm::worklet::flying_edges::launchComputePass4
Definition: FlyingEdgesPass4.h:28
vtkm::worklet::contour::CommonState::GenerateNormals
bool GenerateNormals
Definition: CommonState.h:32
FlyingEdgesHelpers.h
vtkm::cont::CellSetSingleType
Definition: CastAndCall.h:34
vtkm::cont::ArrayGetValue
VTKM_CONT T ArrayGetValue(vtkm::Id id, const vtkm::cont::ArrayHandle< T, S > &data)
Obtain a small set of values from an ArrayHandle with minimal device transfers.
Definition: ArrayGetValues.h:264
vtkm::worklet::flying_edges::launchComputePass1
Definition: FlyingEdgesPass1.h:148
Invoker.h
vtkm::worklet::flying_edges::execute
vtkm::cont::CellSetSingleType execute(const vtkm::cont::CellSetStructured< 3 > &cells, const vtkm::cont::ArrayHandleUniformPointCoordinates &coordinateSystem, const std::vector< ValueType > &isovalues, const vtkm::cont::ArrayHandle< ValueType, StorageTagField > &inputField, vtkm::cont::ArrayHandle< vtkm::Vec< CoordinateType, 3 >, StorageTagVertices > &points, vtkm::cont::ArrayHandle< vtkm::Vec< NormalType, 3 >, StorageTagNormals > &normals, vtkm::worklet::contour::CommonState &sharedState)
Definition: FlyingEdges.h:49
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::cont::TryExecuteOnDevice
VTKM_CONT bool TryExecuteOnDevice(vtkm::cont::DeviceAdapterId devId, Functor &&functor)
Try to execute a functor on a specific device selected at runtime.
Definition: TryExecute.h:178
Algorithm.h
vtkm::cont::Algorithm::ScanExclusive
static VTKM_CONT T ScanExclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::cont::ArrayHandle< T, COut > &output)
Definition: Algorithm.h:816
vtkm::worklet::contour::CommonState
Definition: CommonState.h:24
vtkm::cont::Invoker
Allows launching any worklet without a dispatcher.
Definition: Invoker.h:41
vtkm::CopyFlag::On
@ On
ArrayHandleGroupVec.h
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
Definition: CellShape.h:41
FlyingEdgesPass1.h
vtkm::worklet::flying_edges::ComputePass2
Definition: FlyingEdgesPass2.h:26
vtkm::cont::CellSetStructured::GetPointDimensions
SchedulingRangeType GetPointDimensions() const
Definition: CellSetStructured.h:64
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::worklet::contour::CommonState::CellIdMap
vtkm::cont::ArrayHandle< vtkm::Id > CellIdMap
Definition: CommonState.h:35
vtkm::cont::ArrayHandleUniformPointCoordinates
ArrayHandleUniformPointCoordinates is a specialization of ArrayHandle.
Definition: ArrayHandleUniformPointCoordinates.h:45
vtkm::cont::ArrayHandle::ReadPortal
VTKM_CONT ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:414
vtkm::cont::Algorithm::ScanExtended
static VTKM_CONT void ScanExtended(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::cont::ArrayHandle< T, COut > &output)
Definition: Algorithm.h:901
FlyingEdgesPass2.h
vtkm::cont::Invoker::GetDevice
vtkm::cont::DeviceAdapterId GetDevice() const
Get the device adapter that this Invoker is bound too.
Definition: Invoker.h:123
vtkm::cont::CellSetSingleType::Fill
VTKM_CONT void Fill(vtkm::Id numPoints, vtkm::UInt8 shapeId, vtkm::IdComponent numberOfPointsPerCell, const vtkm::cont::ArrayHandle< vtkm::Id, ConnectivityStorageTag > &connectivity)
Definition: CellSetSingleType.h:186
vtkm::worklet::contour::CommonState::InterpolationEdgeIds
vtkm::cont::ArrayHandle< vtkm::Id2 > InterpolationEdgeIds
Definition: CommonState.h:34
vtkm::worklet::flying_edges::ComputePass1
Definition: FlyingEdgesPass1.h:70
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559
vtkm::cont::LogLevel::Perf
@ Perf
General timing data and algorithm flow information, such as filter execution, worklet dispatches,...
FlyingEdgesPass4.h