VTK-m  2.0
worklet/StreamSurface.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_filter_flow_worklet_streamsurface_h
11 #define vtk_m_filter_flow_worklet_streamsurface_h
12 
18 
19 namespace vtkm
20 {
21 namespace worklet
22 {
23 namespace flow
24 {
25 
27 {
28 public:
29  //Helper worklet to count various things in each polyline.
31  {
32  public:
33  VTKM_CONT
35 
36  using ControlSignature = void(CellSetIn, WholeArrayInOut invalidCell, FieldOut ptsPerPolyline);
37  using ExecutionSignature = void(CellShape shapeType,
38  PointCount numPoints,
39  _2 isValid,
40  _3 ptsPerPolyline);
41  using InputDomain = _1;
42 
43  template <typename CellShapeTag, typename InValidType>
44  VTKM_EXEC void operator()(const CellShapeTag& shapeType,
45  const vtkm::IdComponent& numPoints,
46  InValidType& invalidCell,
47  vtkm::Id& ptsPerPolyline) const
48  {
49  // We only support polylines that contain 2 or more points.
50  if (shapeType.Id == vtkm::CELL_SHAPE_POLY_LINE && numPoints > 1)
51  ptsPerPolyline = numPoints;
52  else
53  {
54  invalidCell.Set(0, 1);
55  ptsPerPolyline = 0;
56  }
57  }
58 
59  private:
60  };
61 
62  //Helper worklet to determine number of triangles for each pair of polylines
64  {
65  public:
66  VTKM_CONT
68 
69  using ControlSignature = void(FieldIn numPts0, FieldIn numPts1, FieldOut outConnCount);
70  using ExecutionSignature = void(_1 numPts0, _2 numPts1, _3 outConnCount);
71  using InputDomain = _1;
72 
73  VTKM_EXEC void operator()(const vtkm::Id& numPts0,
74  const vtkm::Id& numPts1,
75  vtkm::Id& outConnCount) const
76  {
77  if (numPts0 == numPts1)
78  outConnCount = (numPts0 - 1) * 2 * 3;
79  else if (numPts1 < numPts0)
80  outConnCount = (numPts0 - 1) * 2 * 3 + (numPts1 - numPts0) * 3;
81  else
82  outConnCount = (numPts1 - 1) * 2 * 3 + (numPts0 - numPts1) * 3;
83  }
84 
85  private:
86  };
87 
88  //Helper worklet to generate the stream surface cells
90  {
91  public:
92  VTKM_CONT
94 
95  using ControlSignature = void(FieldIn numPts0,
96  FieldIn numPts1,
97  FieldIn offset0,
98  FieldIn offset1,
99  FieldIn connOffset,
100  WholeArrayOut outConn);
101  using ExecutionSignature =
102  void(_1 numPts0, _2 numPts1, _3 ptOffset0, _4 offset1, _5 connOffset, _6 outConn);
103  using InputDomain = _1;
104 
105  template <typename OutConnType>
106  VTKM_EXEC void operator()(const vtkm::Id& numPts0,
107  const vtkm::Id& numPts1,
108  const vtkm::Id& offset0,
109  const vtkm::Id& offset1,
110  const vtkm::Id& connOffset,
111  OutConnType& outConn) const
112  {
113  vtkm::Id idx0 = 0, idx1 = 0;
114  vtkm::Id nextToLastIdx0 = numPts0 - 1;
115  vtkm::Id nextToLastIdx1 = numPts1 - 1;
116  vtkm::Id outIdx = connOffset;
117 
118  //There could be different numbers of points in the pairs of polylines.
119  //Create pairs of triangles as far as possible.
120 
121  /* polyline0 polyline1
122  *
123  * idx0 + 1 x----------- x idx1 + 1
124  * | \ |
125  * | \ Tri2 |
126  * | \ |
127  * | \ |
128  * | Tri1 \ |
129  * | \|
130  * idx0 + 0 x ---------- x idx1 + 0
131  *
132  */
133  while (idx0 < nextToLastIdx0 && idx1 < nextToLastIdx1)
134  {
135  //Tri 1
136  outConn.Set(outIdx + 0, offset0 + idx0 + 0);
137  outConn.Set(outIdx + 1, offset1 + idx1 + 0);
138  outConn.Set(outIdx + 2, offset0 + idx0 + 1);
139 
140  //Tri 2
141  outConn.Set(outIdx + 3, offset0 + idx0 + 1);
142  outConn.Set(outIdx + 4, offset1 + idx1 + 0);
143  outConn.Set(outIdx + 5, offset1 + idx1 + 1);
144 
145  idx0++;
146  idx1++;
147  outIdx += 6;
148  }
149 
150  // Same number of points in both polylines. We are done.
151  if (numPts0 == numPts1)
152  return;
153 
154  //If we have more points in one polyline, create a triangle fan
155  //to complete the triangulation.
156  //polyline0 is at the end, polyline1 still has more points.
157  /* polyline0 polyline1
158  *
159  * x idx1 + 1
160  * /|
161  * / |
162  * / |
163  * / |
164  * / Tri |
165  * / |
166  * idx0 + 0 x ---------- x idx1 + 0
167  *
168  */
169  if (idx0 == nextToLastIdx0 && idx1 < nextToLastIdx1)
170  {
171  while (idx1 < nextToLastIdx1)
172  {
173  outConn.Set(outIdx + 0, offset0 + idx0 + 0);
174  outConn.Set(outIdx + 1, offset1 + idx1 + 0);
175  outConn.Set(outIdx + 2, offset1 + idx1 + 1);
176  idx1++;
177  outIdx += 3;
178  }
179  }
180 
181  //polyline1 is at the end, polyline0 still has more points.
182  /* polyline0 polyline1
183  *
184  * idx0 + 1 x
185  * | \
186  * | \
187  * | \
188  * | \
189  * | Tri \
190  * | \
191  * idx0 + 0 x ---------- x idx1 + 0
192  *
193  */
194  else
195  {
196  while (idx0 < nextToLastIdx0)
197  {
198  outConn.Set(outIdx + 0, offset0 + idx0 + 0);
199  outConn.Set(outIdx + 1, offset1 + idx1 + 0);
200  outConn.Set(outIdx + 2, offset0 + idx0 + 1);
201  idx0++;
202  outIdx += 3;
203  }
204  }
205  }
206 
207  private:
208  };
209 
210  VTKM_CONT
212 
213  VTKM_CONT
214  void Run(const vtkm::cont::CoordinateSystem& coords,
215  const vtkm::cont::UnknownCellSet& cellset,
218  {
219  using ExplCoordsType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
220 
221  if (!(coords.GetData().IsType<ExplCoordsType>() &&
224  {
225  throw vtkm::cont::ErrorBadValue("Stream surface requires polyline data.");
226  }
227 
228  //Count number of polylines and make sure we ONLY have polylines
229  vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, invalidCell;
231 
232  //We only care if there are ANY non-polyline cells. So use a one element array.
233  //Any non-polyline cell will set the value to 1. No need to worry about race conditions
234  //as the outcasts will all set it to the same value.
235  invalidCell.Allocate(1);
236  invalidCell.WritePortal().Set(0, 0);
237  countInvoker.Invoke(cellset, invalidCell, ptsPerPolyline);
238 
239  if (invalidCell.ReadPortal().Get(0) == 1)
240  throw vtkm::cont::ErrorBadValue("Stream surface requires only polyline data.");
241 
242  vtkm::Id numPolylines = cellset.GetNumberOfCells();
243 
244  //Compute polyline offsets
245  vtkm::cont::ArrayHandle<vtkm::Id> polylineOffset;
246  vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylineOffset);
247 
248  auto ptsPerPolyline0 = vtkm::cont::make_ArrayHandleView(ptsPerPolyline, 0, numPolylines - 1);
249  auto ptsPerPolyline1 = vtkm::cont::make_ArrayHandleView(ptsPerPolyline, 1, numPolylines - 1);
250 
251  //Count the number of triangles to be generated
252  vtkm::cont::ArrayHandle<vtkm::Id> triangleConnCount, triangleConnOffset;
254  countTriInvoker.Invoke(ptsPerPolyline0, ptsPerPolyline1, triangleConnCount);
255  vtkm::cont::Algorithm::ScanExclusive(triangleConnCount, triangleConnOffset);
256 
257  //Surface points are same as input points.
258  newPoints = coords.GetData().AsArrayHandle<ExplCoordsType>();
259 
260  //Create surface triangles
261  vtkm::Id numConnIds = vtkm::cont::Algorithm::Reduce(triangleConnCount, vtkm::Id(0));
262  vtkm::cont::ArrayHandle<vtkm::Id> newConnectivity;
263  newConnectivity.Allocate(numConnIds);
265 
266  genCellsDisp.Invoke(ptsPerPolyline0,
267  ptsPerPolyline1,
268  vtkm::cont::make_ArrayHandleView(polylineOffset, 0, numPolylines - 1),
269  vtkm::cont::make_ArrayHandleView(polylineOffset, 1, numPolylines - 1),
270  triangleConnOffset,
271  newConnectivity);
272  newCells.Fill(numConnIds, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);
273  }
274 
275 private:
276 };
277 
278 }
279 }
280 } //vtkm::worklet::flow
281 
282 #endif // vtk_m_filter_flow_worklet_streamsurface_h
vtkm::worklet::flow::StreamSurface::GenerateCells
Definition: worklet/StreamSurface.h:89
vtkm::worklet::flow::StreamSurface::GenerateCells::ControlSignature
void(FieldIn numPts0, FieldIn numPts1, FieldIn offset0, FieldIn offset1, FieldIn connOffset, WholeArrayOut outConn) ControlSignature
Definition: worklet/StreamSurface.h:100
vtkm::worklet::flow::StreamSurface::CountPolylines::CountPolylines
VTKM_CONT CountPolylines()
Definition: worklet/StreamSurface.h:34
vtkm::worklet::flow::StreamSurface::CountTriangleConn::ControlSignature
void(FieldIn numPts0, FieldIn numPts1, FieldOut outConnCount) ControlSignature
Definition: worklet/StreamSurface.h:69
vtkm::cont::ArrayHandle< vtkm::Vec3f >
vtkm::worklet::flow::StreamSurface::CountPolylines::operator()
VTKM_EXEC void operator()(const CellShapeTag &shapeType, const vtkm::IdComponent &numPoints, InValidType &invalidCell, vtkm::Id &ptsPerPolyline) const
Definition: worklet/StreamSurface.h:44
vtkm::worklet::flow::StreamSurface::CountTriangleConn::operator()
VTKM_EXEC void operator()(const vtkm::Id &numPts0, const vtkm::Id &numPts1, vtkm::Id &outConnCount) const
Definition: worklet/StreamSurface.h:73
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::flow::StreamSurface::Run
VTKM_CONT void Run(const vtkm::cont::CoordinateSystem &coords, const vtkm::cont::UnknownCellSet &cellset, vtkm::cont::ArrayHandle< vtkm::Vec3f > &newPoints, vtkm::cont::CellSetSingleType<> &newCells)
Definition: worklet/StreamSurface.h:214
vtkm::worklet::flow::StreamSurface::CountPolylines::ControlSignature
void(CellSetIn, WholeArrayInOut invalidCell, FieldOut ptsPerPolyline) ControlSignature
Definition: worklet/StreamSurface.h:36
vtkm::worklet::flow::StreamSurface::CountTriangleConn::InputDomain
_1 InputDomain
Definition: worklet/StreamSurface.h:71
vtkm::cont::make_ArrayHandleView
ArrayHandleView< ArrayHandleType > make_ArrayHandleView(const ArrayHandleType &array, vtkm::Id startIndex, vtkm::Id numValues)
Definition: ArrayHandleView.h:222
WorkletMapField.h
CellSetExplicit.h
vtkm::cont::UnknownCellSet::CanConvert
VTKM_CONT bool CanConvert() const
Returns true if this cell set can be retrieved as the given type.
Definition: UnknownCellSet.h:161
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::WorkletMapField::FieldOut
A control signature tag for output fields.
Definition: WorkletMapField.h:60
vtkm::worklet::WorkletVisitCellsWithPoints::PointCount
IncidentElementCount PointCount
Definition: WorkletMapTopology.h:267
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::CellSetSingleType
Definition: CastAndCall.h:34
vtkm::worklet::flow::StreamSurface::GenerateCells::operator()
VTKM_EXEC void operator()(const vtkm::Id &numPts0, const vtkm::Id &numPts1, const vtkm::Id &offset0, const vtkm::Id &offset1, const vtkm::Id &connOffset, OutConnType &outConn) const
Definition: worklet/StreamSurface.h:106
vtkm::cont::UnknownCellSet
A CellSet of an unknown type.
Definition: UnknownCellSet.h:48
ArrayHandleView.h
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::cont::CoordinateSystem
Definition: CoordinateSystem.h:25
vtkm::worklet::flow::StreamSurface::GenerateCells::ExecutionSignature
void(_1 numPts0, _2 numPts1, _3 ptOffset0, _4 offset1, _5 connOffset, _6 outConn) ExecutionSignature
Definition: worklet/StreamSurface.h:102
vtkm::worklet::flow::StreamSurface::CountPolylines::ExecutionSignature
void(CellShape shapeType, PointCount numPoints, _2 isValid, _3 ptsPerPolyline) ExecutionSignature
Definition: worklet/StreamSurface.h:40
vtkm::worklet::flow::StreamSurface::CountTriangleConn::CountTriangleConn
VTKM_CONT CountTriangleConn()
Definition: worklet/StreamSurface.h:67
vtkm::worklet::DispatcherMapField
Dispatcher for worklets that inherit from WorkletMapField.
Definition: DispatcherMapField.h:25
vtkm::worklet::flow::StreamSurface
Definition: worklet/StreamSurface.h:26
vtkm::CELL_SHAPE_POLY_LINE
@ CELL_SHAPE_POLY_LINE
Definition: CellShape.h:40
vtkm::worklet::DispatcherMapTopology
Dispatcher for worklets that inherit from WorkletMapTopology.
Definition: DispatcherMapTopology.h:31
vtkm::worklet::WorkletMapField::FieldIn
A control signature tag for input fields.
Definition: WorkletMapField.h:49
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::flow::StreamSurface::CountPolylines::InputDomain
_1 InputDomain
Definition: worklet/StreamSurface.h:41
vtkm::worklet::WorkletVisitCellsWithPoints
Base class for worklets that map from Points to Cells.
Definition: WorkletMapTopology.h:255
vtkm::worklet::flow::StreamSurface::CountTriangleConn::ExecutionSignature
void(_1 numPts0, _2 numPts1, _3 outConnCount) ExecutionSignature
Definition: worklet/StreamSurface.h:70
vtkm::worklet::flow::StreamSurface::CountTriangleConn
Definition: worklet/StreamSurface.h:63
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::flow::StreamSurface::GenerateCells::InputDomain
_1 InputDomain
Definition: worklet/StreamSurface.h:103
vtkm::cont::ArrayHandle::WritePortal
VTKM_CONT WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:435
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
Definition: CellShape.h:41
vtkm::cont::ErrorBadValue
This class is thrown when a VTKm function or method encounters an invalid value that inhibits progres...
Definition: ErrorBadValue.h:25
vtkm::cont::Algorithm::Reduce
static VTKM_CONT U Reduce(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, U initialValue)
Definition: Algorithm.h:656
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::CellSetExplicit
Definition: CastAndCall.h:36
vtkm::worklet::flow::StreamSurface::GenerateCells::GenerateCells
VTKM_CONT GenerateCells()
Definition: worklet/StreamSurface.h:93
vtkm::worklet::flow::StreamSurface::CountPolylines
Definition: worklet/StreamSurface.h:30
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
DispatcherMapTopology.h
WorkletMapTopology.h
vtkm::cont::CoordinateSystem::GetData
VTKM_CONT vtkm::cont::UncertainArrayHandle< vtkm::TypeListFieldVec3, VTKM_DEFAULT_STORAGE_LIST > GetData() const
vtkm::cont::UnknownCellSet::GetNumberOfCells
VTKM_CONT vtkm::Id GetNumberOfCells() const
Definition: UnknownCellSet.h:111
vtkm::worklet::WorkletMapField
Base class for worklets that do a simple mapping of field arrays.
Definition: WorkletMapField.h:38
vtkm::worklet::flow::StreamSurface::StreamSurface
VTKM_CONT StreamSurface()
Definition: worklet/StreamSurface.h:211