VTK-m  2.0
worklet/Tube.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_worklet_tube_h
11 #define vtk_m_worklet_tube_h
12 
13 #include <typeinfo>
14 #include <vtkm/VectorAnalysis.h>
15 #include <vtkm/cont/Algorithm.h>
18 #include <vtkm/cont/DataSet.h>
24 
25 namespace vtkm
26 {
27 namespace worklet
28 {
29 
30 class Tube
31 {
32 public:
33  //Helper worklet to count various things in each polyline.
35  {
36  public:
37  VTKM_CONT
38  CountSegments(const bool& capping, const vtkm::Id& n)
39  : Capping(capping)
40  , NumSides(n)
41  , NumVertsPerCell(3)
42  {
43  }
44 
45  using ControlSignature = void(CellSetIn cellset,
46  WholeArrayIn pointCoords,
47  FieldOut nonIncidentPtsPerPolyline,
48  FieldOut ptsPerPolyline,
49  FieldOut ptsPerTube,
50  FieldOut numTubeConnIds,
51  FieldOut validCell);
52  using ExecutionSignature = void(CellShape shapeType,
53  PointCount numPoints,
54  PointIndices ptIndices,
55  _2 inPts,
56  _3 nonIncidentPtsPerPolyline,
57  _4 ptsPerPolyline,
58  _5 ptsPerTube,
59  _6 numTubeConnIds,
60  _7 validCell);
61  using InputDomain = _1;
62 
63  template <typename CellShapeTag, typename PointIndexType, typename InPointsType>
64  VTKM_EXEC void operator()(const CellShapeTag& shapeType,
65  const vtkm::IdComponent& numPoints,
66  const PointIndexType& ptIndices,
67  const InPointsType& inPts,
68  vtkm::IdComponent& nonIncidentPtsPerPolyline,
69  vtkm::Id& ptsPerPolyline,
70  vtkm::Id& ptsPerTube,
71  vtkm::Id& numTubeConnIds,
72  vtkm::Id& validCell) const
73  {
74  // We only support polylines that contain 2 or more points.
75  vtkm::IdComponent numNonCoincidentPoints = 1;
76  vtkm::Vec3f p = inPts.Get(ptIndices[0]);
77 
78  validCell = 0;
79  for (int i = 1; i < numPoints; ++i)
80  {
81  vtkm::Vec3f pNext = inPts.Get(ptIndices[i]);
82  if (vtkm::Magnitude(pNext - p) > vtkm::Epsilon<vtkm::FloatDefault>())
83  {
84  numNonCoincidentPoints++;
85  p = pNext;
86  validCell = 1;
87  }
88  }
89 
90  if (shapeType.Id == vtkm::CELL_SHAPE_POLY_LINE && numNonCoincidentPoints > 1)
91  {
92  ptsPerPolyline = numPoints;
93  nonIncidentPtsPerPolyline = numNonCoincidentPoints;
94  ptsPerTube = this->NumSides * numNonCoincidentPoints;
95  // (two tris per segment) X (numSides) X numVertsPerCell
96  numTubeConnIds = (numNonCoincidentPoints - 1) * 2 * this->NumSides * this->NumVertsPerCell;
97 
98  //Capping adds center vertex in middle of cap, plus NumSides triangles for cap.
99  if (this->Capping)
100  {
101  ptsPerTube += 2;
102  numTubeConnIds += (2 * this->NumSides * this->NumVertsPerCell);
103  }
104  }
105  else
106  {
107  validCell = 0;
108  ptsPerPolyline = 0;
109  nonIncidentPtsPerPolyline = 0;
110  ptsPerTube = 0;
111  numTubeConnIds = 0;
112  }
113  }
114 
115  private:
116  bool Capping;
119  };
120 
121  //Helper worklet to generate normals at each point in the polyline.
123  {
124  static constexpr vtkm::FloatDefault vecMagnitudeEps = static_cast<vtkm::FloatDefault>(1e-3);
125 
126  public:
127  VTKM_CONT
129  : DefaultNorm(0, 0, 1)
130  {
131  }
132 
133  using ControlSignature = void(CellSetIn cellset,
134  WholeArrayIn pointCoords,
135  FieldInCell polylineOffset,
136  WholeArrayOut newNormals);
137  using ExecutionSignature = void(CellShape shapeType,
138  PointCount numPoints,
139  PointIndices ptIndices,
140  _2 inPts,
141  _3 polylineOffset,
142  _4 outNormals);
143  using InputDomain = _1;
145  VTKM_CONT
147  {
148  return ScatterType(validCell);
149  }
150 
151  template <typename InPointsType, typename PointIndexType>
152  VTKM_EXEC vtkm::IdComponent FindValidSegment(const InPointsType& inPts,
153  const PointIndexType& ptIndices,
154  const vtkm::IdComponent& numPoints,
155  vtkm::IdComponent start) const
156  {
157  auto ps = inPts.Get(ptIndices[start]);
158  vtkm::IdComponent end = start + 1;
159  while (end < numPoints)
160  {
161  auto pe = inPts.Get(ptIndices[end]);
162  if (vtkm::Magnitude(pe - ps) > vtkm::Epsilon<vtkm::FloatDefault>())
163  return end - 1;
164  end++;
165  }
166 
167  return numPoints;
168  }
169 
170  template <typename CellShapeTag,
171  typename PointIndexType,
172  typename InPointsType,
173  typename OutNormalType>
174  VTKM_EXEC void operator()(const CellShapeTag& shapeType,
175  const vtkm::IdComponent& numPoints,
176  const PointIndexType& ptIndices,
177  const InPointsType& inPts,
178  const vtkm::Id& polylineOffset,
179  OutNormalType& outNormals) const
180  {
181  //Ignore non-polyline and polyline with less than 2 points.
182  if (shapeType.Id != vtkm::CELL_SHAPE_POLY_LINE || numPoints < 2)
183  return;
184  else
185  {
186  //The following follows the VTK implementation in:
187  //vtkPolyLine::GenerateSlidingNormals
188  vtkm::Vec3f sPrev, sNext, normal, p0, p1;
189  vtkm::IdComponent sNextId = FindValidSegment(inPts, ptIndices, numPoints, 0);
190 
191  if (sNextId != numPoints) // at least one valid segment
192  {
193  p0 = inPts.Get(ptIndices[sNextId]);
194  p1 = inPts.Get(ptIndices[sNextId + 1]);
195  sPrev = vtkm::Normal(p1 - p0);
196  }
197  else // no valid segments. Set everything to the default normal.
198  {
199  for (vtkm::Id i = 0; i < numPoints; i++)
200  outNormals.Set(polylineOffset + i, this->DefaultNorm);
201  return;
202  }
203 
204  // find the next valid, non-parallel segment
205  while (++sNextId < numPoints)
206  {
207  sNextId = FindValidSegment(inPts, ptIndices, numPoints, sNextId);
208  if (sNextId != numPoints)
209  {
210  p0 = inPts.Get(ptIndices[sNextId]);
211  p1 = inPts.Get(ptIndices[sNextId + 1]);
212  sNext = vtkm::Normal(p1 - p0);
213 
214  // now the starting normal should simply be the cross product
215  // in the following if statement we check for the case where
216  // the two segments are parallel, in which case, continue searching
217  // for the next valid segment
218  auto n = vtkm::Cross(sPrev, sNext);
220  {
221  normal = n;
222  sPrev = sNext;
223  break;
224  }
225  }
226  }
227 
228  //only one valid segment...
229  if (sNextId >= numPoints)
230  {
231  for (vtkm::IdComponent j = 0; j < 3; j++)
232  if (sPrev[j] != 0)
233  {
234  normal[(j + 2) % 3] = 0;
235  normal[(j + 1) % 3] = 1;
236  normal[j] = -sPrev[(j + 1) % 3] / sPrev[j];
237  break;
238  }
239  }
240 
241  vtkm::Normalize(normal);
242  vtkm::Id lastNormalId = 0;
243  while (++sNextId < numPoints)
244  {
245  sNextId = FindValidSegment(inPts, ptIndices, numPoints, sNextId);
246  if (sNextId == numPoints)
247  break;
248 
249  p0 = inPts.Get(ptIndices[sNextId]);
250  p1 = inPts.Get(ptIndices[sNextId + 1]);
251  sNext = vtkm::Normal(p1 - p0);
252 
253  auto q = vtkm::Cross(sNext, sPrev);
254 
255  if (vtkm::Magnitude(q) <= vtkm::Epsilon<vtkm::FloatDefault>()) //can't use this segment
256  continue;
257  vtkm::Normalize(q);
258 
259  vtkm::FloatDefault f1 = vtkm::Dot(q, normal);
260  vtkm::FloatDefault f2 = 1 - (f1 * f1);
261  if (f2 > 0)
262  f2 = vtkm::Sqrt(f2);
263  else
264  f2 = 0;
265 
266  auto c = vtkm::Normal(sNext + sPrev);
267  auto w = vtkm::Cross(c, q);
268  c = vtkm::Cross(sPrev, q);
269  if ((vtkm::Dot(normal, c) * vtkm::Dot(w, c)) < 0)
270  f2 = -f2;
271 
272  for (vtkm::Id i = lastNormalId; i < sNextId; i++)
273  outNormals.Set(polylineOffset + i, normal);
274  lastNormalId = sNextId;
275  sPrev = sNext;
276  normal = (f1 * q) + (f2 * w);
277  }
278 
279  for (vtkm::Id i = lastNormalId; i < numPoints; i++)
280  outNormals.Set(polylineOffset + i, normal);
281  }
282  }
283 
284  private:
286  };
287 
288  //Helper worklet to generate the tube points
290  {
291  public:
292  VTKM_CONT
293  GeneratePoints(const bool& capping, const vtkm::Id& n, const vtkm::FloatDefault& r)
294  : Capping(capping)
295  , NumSides(n)
296  , Radius(r)
297  , Theta(2 * static_cast<vtkm::FloatDefault>(vtkm::Pi()) / static_cast<vtkm::FloatDefault>(n))
298  {
299  }
300 
301  using ControlSignature = void(CellSetIn cellset,
302  WholeArrayIn pointCoords,
303  WholeArrayIn normals,
304  FieldInCell numNonCoincidentPts,
305  FieldInCell tubePointOffsets,
306  FieldInCell polylineOffset,
307  WholeArrayOut newPointCoords,
308  WholeArrayOut outPointSrcIdx);
309  using ExecutionSignature = void(CellShape shapeType,
310  PointCount numPoints,
311  PointIndices ptIndices,
312  _2 inPts,
313  _3 inNormals,
314  _4 numNonCoincidentPts,
315  _5 tubePointOffsets,
316  _6 polylineOffset,
317  _7 outPts,
318  _8 outPointSrcIdx);
319  using InputDomain = _1;
321  VTKM_CONT
323  {
324  return ScatterType(validCell);
325  }
326 
327  template <typename CellShapeTag,
328  typename PointIndexType,
329  typename InPointsType,
330  typename InNormalsType,
331  typename OutPointsType,
332  typename OutPointSrcIdxType>
333  VTKM_EXEC void operator()(const CellShapeTag& shapeType,
334  const vtkm::IdComponent& numPoints,
335  const PointIndexType& ptIndices,
336  const InPointsType& inPts,
337  const InNormalsType& inNormals,
338  const vtkm::Id& numNonCoincidentPts,
339  const vtkm::Id& tubePointOffsets,
340  const vtkm::Id& polylineOffset,
341  OutPointsType& outPts,
342  OutPointSrcIdxType& outPointSrcIdx) const
343  {
344  if (shapeType.Id != vtkm::CELL_SHAPE_POLY_LINE || numNonCoincidentPts < 2)
345  return;
346  else
347  {
348  vtkm::Id outIdx = tubePointOffsets;
349  vtkm::Id pIdx = ptIndices[0];
350  vtkm::Id pNextIdx =
351  ptIndices[this->FindNextNonCoincidentPointIndex(ptIndices, inPts, 0, numPoints)];
352  vtkm::Vec3f p = inPts.Get(pIdx);
353  vtkm::Vec3f pNext = inPts.Get(pNextIdx);
354  vtkm::Vec3f sNext = pNext - p;
355  vtkm::Vec3f sPrev = sNext;
356  vtkm::FloatDefault eps = vtkm::Epsilon<vtkm::FloatDefault>();
357 
358  //Add the start cap vertex. This is just a point at the center of the tube (on the polyline).
359  if (this->Capping)
360  {
361  outPts.Set(outIdx, p);
362  outPointSrcIdx.Set(outIdx, pIdx);
363  outIdx++;
364  }
365 
366  vtkm::IdComponent j = 0;
367  while (j < numPoints)
368  {
369  vtkm::IdComponent jNext =
370  this->FindNextNonCoincidentPointIndex(ptIndices, inPts, j, numPoints);
371  if (j == 0) //first point
372  {
373  //Variables initialized before loop started.
374  }
375  else if (jNext == numPoints) //last point
376  {
377  sPrev = sNext;
378  p = pNext;
379  pIdx = pNextIdx;
380  }
381  else
382  {
383  p = pNext;
384  pIdx = pNextIdx;
385  pNextIdx = ptIndices[jNext];
386  pNext = inPts.Get(pNextIdx);
387  sPrev = sNext;
388  sNext = pNext - p;
389  }
390  vtkm::Vec3f n = inNormals.Get(polylineOffset + j);
391 
392  vtkm::Normalize(sNext);
393  auto s = (sPrev + sNext) / 2.;
394  if (vtkm::Magnitude(s) <= eps)
395  s = vtkm::Cross(sPrev, n);
396  vtkm::Normalize(s);
397 
398  auto w = vtkm::Cross(s, n);
399  //Bad normal
400  if (vtkm::Magnitude(w) <= eps)
401  this->RaiseError("Bad normal in Tube worklet.");
402  vtkm::Normalize(w);
403 
404  //create orthogonal coordinate system.
405  auto nP = vtkm::Cross(w, s);
406  vtkm::Normalize(nP);
407 
408  //this only implements the 'sides share vertices' line 476
409  vtkm::Vec3f normal;
410  for (vtkm::IdComponent k = 0; k < this->NumSides; k++)
411  {
412  vtkm::FloatDefault angle = static_cast<vtkm::FloatDefault>(k) * this->Theta;
413  vtkm::FloatDefault cosValue = vtkm::Cos(angle);
414  vtkm::FloatDefault sinValue = vtkm::Sin(angle);
415  normal = w * cosValue + nP * sinValue;
416  auto newPt = p + this->Radius * normal;
417  outPts.Set(outIdx, newPt);
418  outPointSrcIdx.Set(outIdx, pIdx);
419  outIdx++;
420  }
421 
422  j = jNext;
423  }
424 
425  //Add the end cap vertex. This is just a point at the center of the tube (on the polyline).
426  if (this->Capping)
427  {
428  outPts.Set(outIdx, p);
429  outPointSrcIdx.Set(outIdx, pIdx);
430  outIdx++;
431  }
432  }
433  }
434 
435  template <typename PointIndexType, typename InPointsType>
437  const InPointsType& inPts,
438  vtkm::IdComponent start,
439  vtkm::IdComponent numPoints) const
440  {
441  vtkm::Id pIdx = ptIndices[start];
442  vtkm::Id pNextIdx;
443  vtkm::Float32 eps = vtkm::Epsilon<vtkm::FloatDefault>();
444  for (vtkm::IdComponent i = start + 1; i < numPoints; ++i)
445  {
446  pNextIdx = ptIndices[i];
447  vtkm::FloatDefault pNext = vtkm::Magnitude(inPts.Get(pIdx) - inPts.Get(pNextIdx));
448  if (pNext > eps)
449  {
450  return i;
451  }
452  }
453 
454  return numPoints;
455  }
456 
457  private:
458  bool Capping;
462  };
463 
464  //Helper worklet to generate the tube cells
466  {
467  public:
468  VTKM_CONT
469  GenerateCells(const bool& capping, const vtkm::Id& n)
470  : Capping(capping)
471  , NumSides(n)
472  {
473  }
474 
475  using ControlSignature = void(CellSetIn cellset,
476  FieldInCell ptsPerPolyline,
477  FieldInCell tubePointOffsets,
478  FieldInCell tubeConnOffsets,
479  WholeArrayOut outConnectivity,
480  WholeArrayOut outCellSrcIdx);
481  using ExecutionSignature = void(CellShape shapeType,
482  InputIndex inCellIndex,
483  _2 ptsPerPolyline,
484  _3 tubePointOffset,
485  _4 tubeConnOffsets,
486  _5 outConn,
487  _6 outCellSrcIdx);
488  using InputDomain = _1;
489 
490  template <typename CellShapeTag, typename OutConnType, typename OutCellSrcIdxType>
491  VTKM_EXEC void operator()(const CellShapeTag& shapeType,
492  vtkm::Id inCellIndex,
493  const vtkm::IdComponent& numPoints,
494  const vtkm::Id& tubePointOffset,
495  const vtkm::Id& tubeConnOffset,
496  OutConnType& outConn,
497  OutCellSrcIdxType& outCellSrcIdx) const
498  {
499  if (shapeType.Id != vtkm::CELL_SHAPE_POLY_LINE || numPoints < 2)
500  return;
501  else
502  {
503  vtkm::Id outIdx = tubeConnOffset;
504  vtkm::Id tubePtOffset = (this->Capping ? tubePointOffset + 1 : tubePointOffset);
505  for (vtkm::IdComponent i = 0; i < numPoints - 1; i++)
506  {
507  for (vtkm::Id j = 0; j < this->NumSides; j++)
508  {
509  //Triangle 1: verts 0,1,2
510  outConn.Set(outIdx + 0, tubePtOffset + i * this->NumSides + j);
511  outConn.Set(outIdx + 1, tubePtOffset + i * this->NumSides + (j + 1) % this->NumSides);
512  outConn.Set(outIdx + 2,
513  tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
514  outCellSrcIdx.Set(outIdx / 3, inCellIndex);
515  outIdx += 3;
516 
517  //Triangle 2: verts 0,2,3
518  outConn.Set(outIdx + 0, tubePtOffset + i * this->NumSides + j);
519  outConn.Set(outIdx + 1,
520  tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
521  outConn.Set(outIdx + 2, tubePtOffset + (i + 1) * this->NumSides + j);
522  outCellSrcIdx.Set(outIdx / 3, inCellIndex);
523  outIdx += 3;
524  }
525  }
526 
527  if (this->Capping)
528  {
529  //start cap triangles
530  vtkm::Id startCenterPt = 0 + tubePointOffset;
531  for (vtkm::Id j = 0; j < this->NumSides; j++)
532  {
533  outConn.Set(outIdx + 0, startCenterPt);
534  outConn.Set(outIdx + 1, startCenterPt + 1 + j);
535  outConn.Set(outIdx + 2, startCenterPt + 1 + ((j + 1) % this->NumSides));
536  outCellSrcIdx.Set(outIdx / 3, inCellIndex);
537  outIdx += 3;
538  }
539 
540  //end cap triangles
541  vtkm::Id endCenterPt = (tubePointOffset + 1) + (numPoints * this->NumSides);
542  vtkm::Id endOffsetPt = endCenterPt - this->NumSides;
543 
544  for (vtkm::Id j = 0; j < this->NumSides; j++)
545  {
546  outConn.Set(outIdx + 0, endCenterPt);
547  outConn.Set(outIdx + 1, endOffsetPt + j);
548  outConn.Set(outIdx + 2, endOffsetPt + ((j + 1) % this->NumSides));
549  outCellSrcIdx.Set(outIdx / 3, inCellIndex);
550  outIdx += 3;
551  }
552  }
553  }
554  }
555 
556  private:
557  bool Capping;
559  };
560 
561 
563  {
564  public:
565  using ControlSignature = void(FieldIn sourceIdx, WholeArrayIn sourceArray, FieldOut output);
566  using ExecutionSignature = void(_1 sourceIdx, _2 sourceArray, _3 output);
567  using InputDomain = _1;
568 
569  VTKM_CONT
570  MapField() {}
571 
572  template <typename SourceArrayType, typename T>
573  VTKM_EXEC void operator()(const vtkm::Id& sourceIdx,
574  const SourceArrayType& sourceArray,
575  T& output) const
576  {
577  output = sourceArray.Get(sourceIdx);
578  }
579  };
580 
581  VTKM_CONT
583  : Capping(false)
584  , NumSides(0)
585  , Radius(0)
586  {
587  }
588 
589  VTKM_CONT
590  Tube(const bool& capping, const vtkm::Id& n, const vtkm::FloatDefault& r)
591  : Capping(capping)
592  , NumSides(n)
593  , Radius(r)
594  {
595  }
596 
597  VTKM_CONT
598  void SetCapping(bool v) { this->Capping = v; }
599  VTKM_CONT
600  void SetNumberOfSides(vtkm::Id n) { this->NumSides = n; }
601  VTKM_CONT
602  void SetRadius(vtkm::FloatDefault r) { this->Radius = r; }
603 
604  template <typename Storage>
606  const vtkm::cont::UnknownCellSet& cellset,
609  {
610  using NormalsType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
611 
612  if (!cellset.CanConvert<vtkm::cont::CellSetExplicit<>>() &&
614  {
615  throw vtkm::cont::ErrorBadValue("Tube filter only supported for polyline data.");
616  }
617 
618  //Count number of polyline pts, tube pts and tube cells
619  vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, validCell;
620  vtkm::cont::ArrayHandle<vtkm::IdComponent> nonIncidentPtsPerPolyline;
621  CountSegments countSegs(this->Capping, this->NumSides);
623  countInvoker.Invoke(cellset,
624  coords,
625  nonIncidentPtsPerPolyline,
626  ptsPerPolyline,
627  ptsPerTube,
628  numTubeConnIds,
629  validCell);
630 
631  vtkm::Id totalPolylinePts = vtkm::cont::Algorithm::Reduce(ptsPerPolyline, vtkm::Id(0));
632  if (totalPolylinePts == 0)
633  throw vtkm::cont::ErrorBadValue("Tube filter only supported for polyline data.");
634  vtkm::Id totalTubePts = vtkm::cont::Algorithm::Reduce(ptsPerTube, vtkm::Id(0));
635  vtkm::Id totalTubeConnIds = vtkm::cont::Algorithm::Reduce(numTubeConnIds, vtkm::Id(0));
636  //All cells are triangles, so cell count is simple to compute.
637  vtkm::Id totalTubeCells = totalTubeConnIds / 3;
638 
639  vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, nonIncidentPolylinePtOffset,
640  tubePointOffsets, tubeConnOffsets;
641  vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylinePtOffset);
643  vtkm::cont::make_ArrayHandleCast<vtkm::Id>(nonIncidentPtsPerPolyline),
644  nonIncidentPolylinePtOffset);
645  vtkm::cont::Algorithm::ScanExclusive(ptsPerTube, tubePointOffsets);
646  vtkm::cont::Algorithm::ScanExclusive(numTubeConnIds, tubeConnOffsets);
647 
648  //Generate normals at each point on all polylines
649  NormalsType normals;
650  normals.Allocate(totalPolylinePts);
652  GenerateNormals::MakeScatter(validCell));
653  genNormalsDisp.Invoke(cellset, coords, polylinePtOffset, normals);
654 
655  //Generate the tube points
656  newPoints.Allocate(totalTubePts);
657  this->OutputPointSourceIndex.Allocate(totalTubePts);
658  GeneratePoints genPts(this->Capping, this->NumSides, this->Radius);
660  genPts, GeneratePoints::MakeScatter(validCell));
661  genPtsDisp.Invoke(cellset,
662  coords,
663  normals,
664  nonIncidentPtsPerPolyline,
665  tubePointOffsets,
666  polylinePtOffset,
667  newPoints,
668  this->OutputPointSourceIndex);
669 
670  //Generate tube cells
671  vtkm::cont::ArrayHandle<vtkm::Id> newConnectivity;
672  newConnectivity.Allocate(totalTubeConnIds);
673  this->OutputCellSourceIndex.Allocate(totalTubeCells);
674  GenerateCells genCells(this->Capping, this->NumSides);
676  genCellsDisp.Invoke(cellset,
677  nonIncidentPtsPerPolyline,
678  tubePointOffsets,
679  tubeConnOffsets,
680  newConnectivity,
681  this->OutputCellSourceIndex);
682  newCells.Fill(totalTubePts, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);
683  }
684 
686  {
687  return this->OutputCellSourceIndex;
688  }
690  {
691  return this->OutputPointSourceIndex;
692  }
693 
694 private:
695  bool Capping;
700 };
701 }
702 }
703 
704 #endif // vtk_m_worklet_tube_h
vtkm::worklet::Tube::GeneratePoints::Capping
bool Capping
Definition: worklet/Tube.h:458
vtkm::Sqrt
VTKM_EXEC_CONT vtkm::Float32 Sqrt(vtkm::Float32 x)
Compute the square root of x.
Definition: Math.h:958
vtkm::worklet::Tube::GetOutputPointSourceIndex
vtkm::cont::ArrayHandle< vtkm::Id > GetOutputPointSourceIndex() const
Definition: worklet/Tube.h:689
vtkm::worklet::Tube::GeneratePoints::GeneratePoints
VTKM_CONT GeneratePoints(const bool &capping, const vtkm::Id &n, const vtkm::FloatDefault &r)
Definition: worklet/Tube.h:293
vtkm::cont::ArrayHandle< vtkm::Id >
vtkm::worklet::Tube::NumSides
vtkm::Id NumSides
Definition: worklet/Tube.h:696
vtkm::worklet::Tube::GenerateNormals::ExecutionSignature
void(CellShape shapeType, PointCount numPoints, PointIndices ptIndices, _2 inPts, _3 polylineOffset, _4 outNormals) ExecutionSignature
Definition: worklet/Tube.h:142
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::Cos
VTKM_EXEC_CONT vtkm::Float32 Cos(vtkm::Float32 x)
Compute the cosine of x.
Definition: Math.h:269
ArrayHandleCast.h
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::worklet::Tube::CountSegments::NumSides
vtkm::Id NumSides
Definition: worklet/Tube.h:117
vtkm::worklet::Tube::GeneratePoints::ExecutionSignature
void(CellShape shapeType, PointCount numPoints, PointIndices ptIndices, _2 inPts, _3 inNormals, _4 numNonCoincidentPts, _5 tubePointOffsets, _6 polylineOffset, _7 outPts, _8 outPointSrcIdx) ExecutionSignature
Definition: worklet/Tube.h:318
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::Tube
Definition: worklet/Tube.h:30
UnknownCellSet.h
vtkm::worklet::WorkletVisitCellsWithPoints::PointCount
IncidentElementCount PointCount
Definition: WorkletMapTopology.h:267
vtkm::Normalize
VTKM_EXEC_CONT void Normalize(T &x)
Changes a vector to be normal.
Definition: VectorAnalysis.h:168
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::worklet::Tube::MapField::InputDomain
_1 InputDomain
Definition: worklet/Tube.h:567
vtkm::worklet::Tube::GeneratePoints
Definition: worklet/Tube.h:289
vtkm::worklet::Tube::GenerateCells::ExecutionSignature
void(CellShape shapeType, InputIndex inCellIndex, _2 ptsPerPolyline, _3 tubePointOffset, _4 tubeConnOffsets, _5 outConn, _6 outCellSrcIdx) ExecutionSignature
Definition: worklet/Tube.h:487
vtkm::Magnitude
VTKM_EXEC_CONT detail::FloatingPointReturnType< T >::Type Magnitude(const T &x)
Returns the magnitude of a vector.
Definition: VectorAnalysis.h:100
vtkm::worklet::Tube::CountSegments::ControlSignature
void(CellSetIn cellset, WholeArrayIn pointCoords, FieldOut nonIncidentPtsPerPolyline, FieldOut ptsPerPolyline, FieldOut ptsPerTube, FieldOut numTubeConnIds, FieldOut validCell) ControlSignature
Definition: worklet/Tube.h:51
vtkm::cont::CellSetSingleType
Definition: CastAndCall.h:34
vtkm::worklet::Tube::GenerateCells
Definition: worklet/Tube.h:465
vtkm::worklet::Tube::SetNumberOfSides
VTKM_CONT void SetNumberOfSides(vtkm::Id n)
Definition: worklet/Tube.h:600
vtkm::cont::UnknownCellSet
A CellSet of an unknown type.
Definition: UnknownCellSet.h:48
vtkm::worklet::WorkletVisitCellsWithPoints::PointIndices
IncidentElementIndices PointIndices
Definition: WorkletMapTopology.h:269
vtkm::worklet::Tube::MapField::MapField
VTKM_CONT MapField()
Definition: worklet/Tube.h:570
vtkm::Sin
VTKM_EXEC_CONT vtkm::Float32 Sin(vtkm::Float32 x)
Compute the sine of x.
Definition: Math.h:210
vtkm::worklet::Tube::GeneratePoints::ControlSignature
void(CellSetIn cellset, WholeArrayIn pointCoords, WholeArrayIn normals, FieldInCell numNonCoincidentPts, FieldInCell tubePointOffsets, FieldInCell polylineOffset, WholeArrayOut newPointCoords, WholeArrayOut outPointSrcIdx) ControlSignature
Definition: worklet/Tube.h:308
vtkm::worklet::Tube::GenerateNormals::InputDomain
_1 InputDomain
Definition: worklet/Tube.h:143
vtkm::worklet::Tube::GenerateCells::InputDomain
_1 InputDomain
Definition: worklet/Tube.h:488
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::Tube::SetCapping
VTKM_CONT void SetCapping(bool v)
Definition: worklet/Tube.h:598
vtkm::worklet::Tube::GenerateNormals
Definition: worklet/Tube.h:122
ScatterCounting.h
vtkm::Normal
VTKM_EXEC_CONT T Normal(const T &x)
Returns a normalized version of the given vector.
Definition: VectorAnalysis.h:157
vtkm::worklet::Tube::GenerateNormals::ControlSignature
void(CellSetIn cellset, WholeArrayIn pointCoords, FieldInCell polylineOffset, WholeArrayOut newNormals) ControlSignature
Definition: worklet/Tube.h:136
VectorAnalysis.h
vtkm::worklet::Tube::GenerateNormals::operator()
VTKM_EXEC void operator()(const CellShapeTag &shapeType, const vtkm::IdComponent &numPoints, const PointIndexType &ptIndices, const InPointsType &inPts, const vtkm::Id &polylineOffset, OutNormalType &outNormals) const
Definition: worklet/Tube.h:174
vtkm::worklet::Tube::GeneratePoints::FindNextNonCoincidentPointIndex
VTKM_EXEC vtkm::IdComponent FindNextNonCoincidentPointIndex(const PointIndexType &ptIndices, const InPointsType &inPts, vtkm::IdComponent start, vtkm::IdComponent numPoints) const
Definition: worklet/Tube.h:436
vtkm::worklet::Tube::Run
VTKM_CONT void Run(const vtkm::cont::ArrayHandle< vtkm::Vec3f, Storage > &coords, const vtkm::cont::UnknownCellSet &cellset, vtkm::cont::ArrayHandle< vtkm::Vec3f > &newPoints, vtkm::cont::CellSetSingleType<> &newCells)
Definition: worklet/Tube.h:605
vtkm::worklet::ScatterCounting
A scatter that maps input to some numbers of output.
Definition: ScatterCounting.h:44
vtkm::worklet::Tube::GenerateNormals::MakeScatter
static VTKM_CONT ScatterType MakeScatter(const vtkm::cont::ArrayHandle< vtkm::Id > &validCell)
Definition: worklet/Tube.h:146
vtkm::worklet::Tube::Tube
VTKM_CONT Tube()
Definition: worklet/Tube.h:582
vtkm::worklet::Tube::Radius
vtkm::FloatDefault Radius
Definition: worklet/Tube.h:697
vtkm::worklet::Tube::GeneratePoints::ScatterType
vtkm::worklet::ScatterCounting ScatterType
Definition: worklet/Tube.h:320
vtkm::worklet::Tube::GenerateCells::operator()
VTKM_EXEC void operator()(const CellShapeTag &shapeType, vtkm::Id inCellIndex, const vtkm::IdComponent &numPoints, const vtkm::Id &tubePointOffset, const vtkm::Id &tubeConnOffset, OutConnType &outConn, OutCellSrcIdxType &outCellSrcIdx) const
Definition: worklet/Tube.h:491
Algorithm.h
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::Cross
VTKM_EXEC_CONT vtkm::Vec< typename detail::FloatingPointReturnType< T >::Type, 3 > Cross(const vtkm::Vec< T, 3 > &x, const vtkm::Vec< T, 3 > &y)
Find the cross product of two vectors.
Definition: VectorAnalysis.h:177
vtkm::worklet::WorkletVisitCellsWithPoints
Base class for worklets that map from Points to Cells.
Definition: WorkletMapTopology.h:255
vtkm::worklet::Tube::CountSegments::CountSegments
VTKM_CONT CountSegments(const bool &capping, const vtkm::Id &n)
Definition: worklet/Tube.h:38
vtkm::worklet::Tube::SetRadius
VTKM_CONT void SetRadius(vtkm::FloatDefault r)
Definition: worklet/Tube.h:602
vtkm::worklet::Tube::GenerateNormals::DefaultNorm
vtkm::Vec3f DefaultNorm
Definition: worklet/Tube.h:285
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::Tube::Capping
bool Capping
Definition: worklet/Tube.h:695
vtkm::worklet::Tube::GenerateCells::Capping
bool Capping
Definition: worklet/Tube.h:557
vtkm::worklet::Tube::GeneratePoints::NumSides
vtkm::Id NumSides
Definition: worklet/Tube.h:459
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
Definition: CellShape.h:41
vtkm::worklet::Tube::CountSegments::InputDomain
_1 InputDomain
Definition: worklet/Tube.h:61
vtkm::worklet::Tube::MapField
Definition: worklet/Tube.h:562
vtkm::worklet::Tube::GenerateNormals::vecMagnitudeEps
static constexpr vtkm::FloatDefault vecMagnitudeEps
Definition: worklet/Tube.h:124
vtkm::worklet::Tube::MapField::ExecutionSignature
void(_1 sourceIdx, _2 sourceArray, _3 output) ExecutionSignature
Definition: worklet/Tube.h:566
vtkm::worklet::Tube::GeneratePoints::Theta
vtkm::FloatDefault Theta
Definition: worklet/Tube.h:461
vtkm::worklet::Tube::MapField::operator()
VTKM_EXEC void operator()(const vtkm::Id &sourceIdx, const SourceArrayType &sourceArray, T &output) const
Definition: worklet/Tube.h:573
vtkm::Vec< vtkm::FloatDefault, 3 >
vtkm::worklet::Tube::GeneratePoints::MakeScatter
static VTKM_CONT ScatterType MakeScatter(const vtkm::cont::ArrayHandle< vtkm::Id > &validCell)
Definition: worklet/Tube.h:322
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
vtkm::worklet::Tube::CountSegments::NumVertsPerCell
vtkm::Id NumVertsPerCell
Definition: worklet/Tube.h:118
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::worklet::Tube::GeneratePoints::InputDomain
_1 InputDomain
Definition: worklet/Tube.h:319
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::worklet::Tube::CountSegments::ExecutionSignature
void(CellShape shapeType, PointCount numPoints, PointIndices ptIndices, _2 inPts, _3 nonIncidentPtsPerPolyline, _4 ptsPerPolyline, _5 ptsPerTube, _6 numTubeConnIds, _7 validCell) ExecutionSignature
Definition: worklet/Tube.h:60
vtkm::cont::CellSetExplicit
Definition: CastAndCall.h:36
vtkm::Float32
float Float32
Definition: Types.h:154
vtkm::worklet::Tube::CountSegments::operator()
VTKM_EXEC void operator()(const CellShapeTag &shapeType, const vtkm::IdComponent &numPoints, const PointIndexType &ptIndices, const InPointsType &inPts, vtkm::IdComponent &nonIncidentPtsPerPolyline, vtkm::Id &ptsPerPolyline, vtkm::Id &ptsPerTube, vtkm::Id &numTubeConnIds, vtkm::Id &validCell) const
Definition: worklet/Tube.h:64
vtkm::worklet::Tube::CountSegments
Definition: worklet/Tube.h:34
vtkm::worklet::Tube::GeneratePoints::Radius
vtkm::FloatDefault Radius
Definition: worklet/Tube.h:460
vtkm::worklet::Tube::GenerateCells::NumSides
vtkm::Id NumSides
Definition: worklet/Tube.h:558
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::Tube::GenerateNormals::ScatterType
vtkm::worklet::ScatterCounting ScatterType
Definition: worklet/Tube.h:144
DispatcherMapTopology.h
vtkm::worklet::Tube::MapField::ControlSignature
void(FieldIn sourceIdx, WholeArrayIn sourceArray, FieldOut output) ControlSignature
Definition: worklet/Tube.h:565
WorkletMapTopology.h
vtkm::worklet::Tube::GenerateNormals::GenerateNormals
VTKM_CONT GenerateNormals()
Definition: worklet/Tube.h:128
vtkm::worklet::Tube::GenerateNormals::FindValidSegment
VTKM_EXEC vtkm::IdComponent FindValidSegment(const InPointsType &inPts, const PointIndexType &ptIndices, const vtkm::IdComponent &numPoints, vtkm::IdComponent start) const
Definition: worklet/Tube.h:152
vtkm::worklet::Tube::OutputPointSourceIndex
vtkm::cont::ArrayHandle< vtkm::Id > OutputPointSourceIndex
Definition: worklet/Tube.h:699
vtkm::worklet::Tube::GenerateCells::GenerateCells
VTKM_CONT GenerateCells(const bool &capping, const vtkm::Id &n)
Definition: worklet/Tube.h:469
vtkm::exec::arg::InputIndex
The ExecutionSignature tag to use to get the input index.
Definition: InputIndex.h:42
vtkm::worklet::Tube::Tube
VTKM_CONT Tube(const bool &capping, const vtkm::Id &n, const vtkm::FloatDefault &r)
Definition: worklet/Tube.h:590
DataSet.h
vtkm::worklet::WorkletVisitCellsWithPoints::FieldInCell
FieldInVisit FieldInCell
Definition: WorkletMapTopology.h:261
vtkm::worklet::Tube::GeneratePoints::operator()
VTKM_EXEC void operator()(const CellShapeTag &shapeType, const vtkm::IdComponent &numPoints, const PointIndexType &ptIndices, const InPointsType &inPts, const InNormalsType &inNormals, const vtkm::Id &numNonCoincidentPts, const vtkm::Id &tubePointOffsets, const vtkm::Id &polylineOffset, OutPointsType &outPts, OutPointSrcIdxType &outPointSrcIdx) const
Definition: worklet/Tube.h:333
vtkm::exec::FunctorBase::RaiseError
VTKM_EXEC void RaiseError(const char *message) const
Definition: FunctorBase.h:40
vtkm::worklet::WorkletMapField
Base class for worklets that do a simple mapping of field arrays.
Definition: WorkletMapField.h:38
vtkm::worklet::Tube::CountSegments::Capping
bool Capping
Definition: worklet/Tube.h:116
vtkm::worklet::Tube::GenerateCells::ControlSignature
void(CellSetIn cellset, FieldInCell ptsPerPolyline, FieldInCell tubePointOffsets, FieldInCell tubeConnOffsets, WholeArrayOut outConnectivity, WholeArrayOut outCellSrcIdx) ControlSignature
Definition: worklet/Tube.h:480
vtkm::worklet::Tube::OutputCellSourceIndex
vtkm::cont::ArrayHandle< vtkm::Id > OutputCellSourceIndex
Definition: worklet/Tube.h:698
vtkm::worklet::Tube::GetOutputCellSourceIndex
vtkm::cont::ArrayHandle< vtkm::Id > GetOutputCellSourceIndex() const
Definition: worklet/Tube.h:685