VTK-m  2.0
worklet/SplitSharpEdges.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_SplitSharpEdges_h
11 #define vtk_m_worklet_SplitSharpEdges_h
12 
14 
15 #include <vtkm/cont/Algorithm.h>
16 #include <vtkm/cont/ArrayCopy.h>
19 #include <vtkm/cont/Invoker.h>
20 #include <vtkm/exec/CellEdge.h>
21 
22 #include <vtkm/Bitset.h>
23 #include <vtkm/CellTraits.h>
24 #include <vtkm/TypeTraits.h>
25 #include <vtkm/VectorAnalysis.h>
26 
27 namespace vtkm
28 {
29 namespace worklet
30 {
31 
32 namespace internal
33 {
34 // Given a cell and a point on the cell, find the two edges that are
35 // associated with this point in canonical index
36 template <typename PointFromCellSetType>
37 VTKM_EXEC vtkm::ErrorCode FindRelatedEdges(const vtkm::Id& pointIndex,
38  const vtkm::Id& cellIndexG,
39  const PointFromCellSetType& pFromCellSet,
40  vtkm::Id2& edge0G,
41  vtkm::Id2& edge1G)
42 {
43  typename PointFromCellSetType::CellShapeTag cellShape = pFromCellSet.GetCellShape(cellIndexG);
44  typename PointFromCellSetType::IndicesType cellConnections = pFromCellSet.GetIndices(cellIndexG);
45  vtkm::IdComponent numPointsInCell = pFromCellSet.GetNumberOfIndices(cellIndexG);
46  vtkm::IdComponent numEdges;
47  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeNumberOfEdges(numPointsInCell, cellShape, numEdges));
48  vtkm::IdComponent edgeIndex = -1;
49  // Find the two edges with the pointIndex
50  while (true)
51  {
52  ++edgeIndex;
53  if (edgeIndex >= numEdges)
54  {
55  // Bad cell. Could not find two incident edges.
57  }
58  vtkm::IdComponent2 localEdgeIndices;
59  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeLocalIndex(
60  numPointsInCell, 0, edgeIndex, cellShape, localEdgeIndices[0]));
61  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeLocalIndex(
62  numPointsInCell, 1, edgeIndex, cellShape, localEdgeIndices[1]));
63  vtkm::Id2 canonicalEdgeId(cellConnections[localEdgeIndices[0]],
64  cellConnections[localEdgeIndices[1]]);
65  if (canonicalEdgeId[0] == pointIndex || canonicalEdgeId[1] == pointIndex)
66  { // Assign value to edge0 first
67  if ((edge0G[0] == -1) && (edge0G[1] == -1))
68  {
69  edge0G = canonicalEdgeId;
70  }
71  else
72  {
73  edge1G = canonicalEdgeId;
74  break;
75  }
76  }
77  }
79 }
80 
81 // TODO: We should replace this expensive lookup with a WholeCellSetIn<Edge, Cell> map.
82 // Given an edge on a cell, it would find the neighboring
83 // cell of this edge in local index. If it's a non manifold edge, -1 would be returned.
84 template <typename PointFromCellSetType, typename IncidentCellVecType>
85 VTKM_EXEC int FindNeighborCellInLocalIndex(const vtkm::Id2& eOI,
86  const PointFromCellSetType& pFromCellSet,
87  const IncidentCellVecType& incidentCells,
88  const vtkm::Id currentCellLocalIndex)
89 {
90  int neighboringCellIndex = -1;
91  vtkm::IdComponent numberOfIncidentCells = incidentCells.GetNumberOfComponents();
92  size_t neighboringCellsCount = 0;
93  for (vtkm::IdComponent incidentCellIndex = 0; incidentCellIndex < numberOfIncidentCells;
94  incidentCellIndex++)
95  {
96  if (currentCellLocalIndex == incidentCellIndex)
97  {
98  continue; // No need to check the current interested cell
99  }
100  vtkm::Id cellIndexG = incidentCells[incidentCellIndex]; // Global cell index
101  typename PointFromCellSetType::CellShapeTag cellShape = pFromCellSet.GetCellShape(cellIndexG);
102  typename PointFromCellSetType::IndicesType cellConnections =
103  pFromCellSet.GetIndices(cellIndexG);
104  vtkm::IdComponent numPointsInCell = pFromCellSet.GetNumberOfIndices(cellIndexG);
105  vtkm::IdComponent numEdges;
106  vtkm::exec::CellEdgeNumberOfEdges(numPointsInCell, cellShape, numEdges);
107  vtkm::IdComponent edgeIndex = -1;
108  // Check if this cell has edge of interest
109  while (true)
110  {
111  ++edgeIndex;
112  if (edgeIndex >= numEdges)
113  {
114  break;
115  }
116  vtkm::IdComponent2 localEdgeIndices;
117  vtkm::exec::CellEdgeLocalIndex(numPointsInCell, 0, edgeIndex, cellShape, localEdgeIndices[0]);
118  vtkm::exec::CellEdgeLocalIndex(numPointsInCell, 1, edgeIndex, cellShape, localEdgeIndices[1]);
119  vtkm::Id2 canonicalEdgeId(cellConnections[localEdgeIndices[0]],
120  cellConnections[localEdgeIndices[1]]);
121  if ((canonicalEdgeId[0] == eOI[0] && canonicalEdgeId[1] == eOI[1]) ||
122  (canonicalEdgeId[0] == eOI[1] && canonicalEdgeId[1] == eOI[0]))
123  {
124  neighboringCellIndex = incidentCellIndex;
125  neighboringCellsCount++;
126  break;
127  }
128  }
129  }
130  return neighboringCellIndex;
131 }
132 
133 // Generalized logic for finding what 'regions' own the connected cells.
134 template <typename IncidentCellVecType, typename PointFromCellSetType, typename FaceNormalVecType>
135 VTKM_EXEC bool FindConnectedCellOwnerships(vtkm::FloatDefault cosFeatureAngle,
136  const IncidentCellVecType& incidentCells,
137  vtkm::Id pointIndex,
138  const PointFromCellSetType& pFromCellSet,
139  const FaceNormalVecType& faceNormals,
140  vtkm::Id visitedCellsRegionIndex[64],
141  vtkm::Id& regionIndex)
142 {
143  const vtkm::IdComponent numberOfIncidentCells = incidentCells.GetNumberOfComponents();
144  VTKM_ASSERT(numberOfIncidentCells < 64);
145  if (numberOfIncidentCells <= 1)
146  {
147  return false; // Not enough cells to compare
148  }
149  // Initialize a global cell mask to avoid confusion. globalCellIndex->status
150  // 0 means not visited yet 1 means visited.
151  vtkm::Bitset<vtkm::UInt64> visitedCells;
152  // Reallocate memory for visitedCellsGroup if needed
153 
154  // Loop through each cell
155  for (vtkm::IdComponent incidentCellIndex = 0; incidentCellIndex < numberOfIncidentCells;
156  incidentCellIndex++)
157  {
158  vtkm::Id cellIndexG = incidentCells[incidentCellIndex]; // cell index in global order
159  // If not visited
160  if (!visitedCells.test(incidentCellIndex))
161  {
162  // Mark the cell and track the region
163  visitedCells.set(incidentCellIndex);
164  visitedCellsRegionIndex[incidentCellIndex] = regionIndex;
165 
166  // Find two edges containing the current point in canonial index
167  vtkm::Id2 edge0G(-1, -1), edge1G(-1, -1);
168  internal::FindRelatedEdges(pointIndex, cellIndexG, pFromCellSet, edge0G, edge1G);
169  // Grow the area along each edge
170  for (size_t i = 0; i < 2; i++)
171  { // Reset these two values for each grow operation
172  vtkm::Id2 currentEdgeG = i == 0 ? edge0G : edge1G;
173  vtkm::IdComponent currentTestingCellIndex = incidentCellIndex;
174  while (currentTestingCellIndex >= 0)
175  {
176  // Find the neighbor cell of the current cell edge in local index
177  int neighboringCellIndexQuery = internal::FindNeighborCellInLocalIndex(
178  currentEdgeG, pFromCellSet, incidentCells, currentTestingCellIndex);
179  // The edge should be manifold and the neighboring cell should
180  // have not been visited
181  if (neighboringCellIndexQuery != -1 && !visitedCells.test(neighboringCellIndexQuery))
182  {
183  vtkm::IdComponent neighborCellIndex =
184  static_cast<vtkm::IdComponent>(neighboringCellIndexQuery);
185  // Try to grow the area if the feature angle between current neighbor
186  auto thisNormal = faceNormals[currentTestingCellIndex];
187  //neighborNormal
188  auto neighborNormal = faceNormals[neighborCellIndex];
189  // Try to grow the area
190  if (vtkm::dot(thisNormal, neighborNormal) > cosFeatureAngle)
191  { // No need to split.
192  visitedCells.set(neighborCellIndex);
193 
194  // Mark the region visited
195  visitedCellsRegionIndex[neighborCellIndex] = regionIndex;
196 
197  // Move to examine next cell
198  currentTestingCellIndex = neighborCellIndex;
199  vtkm::Id2 neighborCellEdge0G(-1, -1), neighborCellEdge1G(-1, -1);
200  internal::FindRelatedEdges(pointIndex,
201  incidentCells[currentTestingCellIndex],
202  pFromCellSet,
203  neighborCellEdge0G,
204  neighborCellEdge1G);
205  // Update currentEdgeG
206  if ((currentEdgeG == neighborCellEdge0G) ||
207  currentEdgeG == vtkm::Id2(neighborCellEdge0G[1], neighborCellEdge0G[0]))
208  {
209  currentEdgeG = neighborCellEdge1G;
210  }
211  else
212  {
213  currentEdgeG = neighborCellEdge0G;
214  }
215  }
216  else
217  {
218  currentTestingCellIndex = -1;
219  }
220  }
221  else
222  {
223  currentTestingCellIndex =
224  -1; // Either seperated by previous visit, boundary or non-manifold
225  }
226  // cells is smaller than the thresold and the nighboring cell has not been visited
227  }
228  }
229  regionIndex++;
230  }
231  }
232  return true;
233 }
234 
235 } // internal namespace
236 
237 // Split sharp manifold edges where the feature angle between the
238 // adjacent surfaces are larger than the threshold value
240 {
241 public:
242  // This worklet would calculate the needed space for splitting sharp edges.
243  // For each point, it would have two values as numberOfNewPoint(how many
244  // times this point needs to be duplicated) and numberOfCellsNeedsUpdate
245  // (how many neighboring cells need to update connectivity).
246  // For example, Given a unit cube and feature angle
247  // as 89 degree, each point would be duplicated twice and there are two cells
248  // need connectivity update. There is no guarantee on which cell would get which
249  // new point.
251  {
252  public:
254  : CosFeatureAngle(cosfeatureAngle)
255  {
256  }
257  using ControlSignature = void(CellSetIn intputCells,
258  WholeCellSetIn<Cell, Point>, // Query points from cell
259  FieldInCell faceNormals,
260  FieldOutPoint newPointNum,
261  FieldOutPoint cellNum);
262  using ExecutionSignature = void(CellIndices incidentCells,
263  InputIndex pointIndex,
264  _2 pFromCellSet,
265  _3 faceNormals,
266  _4 newPointNum,
267  _5 cellNum);
268  using InputDomain = _1;
269 
270  template <typename IncidentCellVecType,
271  typename PointFromCellSetType,
272  typename FaceNormalVecType>
273  VTKM_EXEC void operator()(const IncidentCellVecType& incidentCells,
274  vtkm::Id pointIndex,
275  const PointFromCellSetType& pFromCellSet,
276  const FaceNormalVecType& faceNormals,
277  vtkm::Id& newPointNum,
278  vtkm::Id& cellNum) const
279  {
280  vtkm::Id regionIndex = 0;
281  vtkm::Id visitedCellsRegionIndex[64] = { 0 };
282  const bool foundConnections = internal::FindConnectedCellOwnerships(this->CosFeatureAngle,
283  incidentCells,
284  pointIndex,
285  pFromCellSet,
286  faceNormals,
287  visitedCellsRegionIndex,
288  regionIndex);
289  if (!foundConnections)
290  {
291  newPointNum = 0;
292  cellNum = 0;
293  }
294  else
295  {
296  // For each new region you need a new point
297  vtkm::Id numberOfCellsNeedUpdate = 0;
298  const vtkm::IdComponent size = incidentCells.GetNumberOfComponents();
299  for (vtkm::IdComponent i = 0; i < size; i++)
300  {
301  if (visitedCellsRegionIndex[i] > 0)
302  {
303  numberOfCellsNeedUpdate++;
304  }
305  }
306  newPointNum = regionIndex - 1;
307  cellNum = numberOfCellsNeedUpdate;
308  }
309  }
310 
311  private:
312  vtkm::FloatDefault CosFeatureAngle; // Cos value of the feature angle
313  };
314 
315  // This worklet split the sharp edges and populate the
316  // cellTopologyUpdateTuples as (cellGlobalId, oldPointId, newPointId).
318  {
319  public:
320  SplitSharpEdge(vtkm::FloatDefault cosfeatureAngle, vtkm::Id numberOfOldPoints)
321  : CosFeatureAngle(cosfeatureAngle)
322  , NumberOfOldPoints(numberOfOldPoints)
323  {
324  }
325  using ControlSignature = void(CellSetIn intputCells,
326  WholeCellSetIn<Cell, Point>, // Query points from cell
327  FieldInCell faceNormals,
328  FieldInPoint newPointStartingIndex,
329  FieldInPoint pointCellsStartingIndex,
330  WholeArrayOut cellTopologyUpdateTuples);
331  using ExecutionSignature = void(CellIndices incidentCells,
332  InputIndex pointIndex,
333  _2 pFromCellSet,
334  _3 faceNormals,
335  _4 newPointStartingIndex,
336  _5 pointCellsStartingIndex,
337  _6 cellTopologyUpdateTuples);
338  using InputDomain = _1;
339 
340  template <typename IncidentCellVecType,
341  typename PointFromCellSetType,
342  typename FaceNormalVecType,
343  typename CellTopologyUpdateTuples>
344  VTKM_EXEC void operator()(const IncidentCellVecType& incidentCells,
345  vtkm::Id pointIndex,
346  const PointFromCellSetType& pFromCellSet,
347  const FaceNormalVecType& faceNormals,
348  const vtkm::Id& newPointStartingIndex,
349  const vtkm::Id& pointCellsStartingIndex,
350  CellTopologyUpdateTuples& cellTopologyUpdateTuples) const
351  {
352  vtkm::Id regionIndex = 0;
353  vtkm::Id visitedCellsRegionIndex[64] = { 0 };
354  const bool foundConnections = internal::FindConnectedCellOwnerships(this->CosFeatureAngle,
355  incidentCells,
356  pointIndex,
357  pFromCellSet,
358  faceNormals,
359  visitedCellsRegionIndex,
360  regionIndex);
361  if (foundConnections)
362  {
363  // For each new region you need a new point
364  // Initialize the offset in the global cellTopologyUpdateTuples;
365  vtkm::Id cellTopologyUpdateTuplesIndex = pointCellsStartingIndex;
366  const vtkm::IdComponent size = incidentCells.GetNumberOfComponents();
367  for (vtkm::Id i = 0; i < size; i++)
368  {
369  if (visitedCellsRegionIndex[i])
370  { // New region generated. Need to update the topology
371  vtkm::Id replacementPointId =
372  NumberOfOldPoints + newPointStartingIndex + visitedCellsRegionIndex[i] - 1;
373  vtkm::Id globalCellId = incidentCells[static_cast<vtkm::IdComponent>(i)];
374  // (cellGlobalIndex, oldPointId, replacementPointId)
375  vtkm::Id3 tuple = vtkm::make_Vec(globalCellId, pointIndex, replacementPointId);
376  cellTopologyUpdateTuples.Set(cellTopologyUpdateTuplesIndex, tuple);
377  cellTopologyUpdateTuplesIndex++;
378  }
379  }
380  }
381  }
382 
383  private:
384  vtkm::FloatDefault CosFeatureAngle; // Cos value of the feature angle
386  };
387 
388  template <typename CellSetType,
389  typename FaceNormalsType,
390  typename CoordsComType,
391  typename CoordsInStorageType,
392  typename CoordsOutStorageType,
393  typename NewCellSetType>
394  void Run(
395  const CellSetType& oldCellset,
396  const vtkm::FloatDefault featureAngle,
397  const FaceNormalsType& faceNormals,
398  const vtkm::cont::ArrayHandle<vtkm::Vec<CoordsComType, 3>, CoordsInStorageType>& oldCoords,
399  vtkm::cont::ArrayHandle<vtkm::Vec<CoordsComType, 3>, CoordsOutStorageType>& newCoords,
400  NewCellSetType& newCellset)
401  {
402  vtkm::cont::Invoker invoke;
403 
404  const vtkm::FloatDefault featureAngleR =
405  featureAngle / static_cast<vtkm::FloatDefault>(180.0) * vtkm::Pi<vtkm::FloatDefault>();
406 
407  //Launch the first kernel that computes which points need to be split
408  vtkm::cont::ArrayHandle<vtkm::Id> newPointNums, cellNeedUpdateNums;
409  ClassifyPoint classifyPoint(vtkm::Cos(featureAngleR));
410  invoke(classifyPoint, oldCellset, oldCellset, faceNormals, newPointNums, cellNeedUpdateNums);
411  VTKM_ASSERT(newPointNums.GetNumberOfValues() == oldCoords.GetNumberOfValues());
412 
413  //Compute relevant information from cellNeedUpdateNums so we can release
414  //that memory asap
415  vtkm::cont::ArrayHandle<vtkm::Id> pointCellsStartingIndexs;
416  vtkm::cont::Algorithm::ScanExclusive(cellNeedUpdateNums, pointCellsStartingIndexs);
417 
418  const vtkm::Id cellsNeedUpdateNum =
419  vtkm::cont::Algorithm::Reduce(cellNeedUpdateNums, vtkm::Id(0));
420  cellNeedUpdateNums.ReleaseResources();
421 
422 
423  //Compute the mapping of new points to old points. This is required for
424  //processing additional point fields
425  const vtkm::Id totalNewPointsNum = vtkm::cont::Algorithm::Reduce(newPointNums, vtkm::Id(0));
426  this->NewPointsIdArray.Allocate(oldCoords.GetNumberOfValues() + totalNewPointsNum);
428  vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), oldCoords.GetNumberOfValues()),
429  0,
430  oldCoords.GetNumberOfValues(),
431  this->NewPointsIdArray,
432  0);
433  auto newPointsIdArrayPortal = this->NewPointsIdArray.WritePortal();
434 
435  // Fill the new point coordinate system with all the existing values
436  newCoords.Allocate(oldCoords.GetNumberOfValues() + totalNewPointsNum);
437  vtkm::cont::Algorithm::CopySubRange(oldCoords, 0, oldCoords.GetNumberOfValues(), newCoords);
438 
439  if (totalNewPointsNum > 0)
440  { //only if we have new points do we need add any of the new
441  //coordinate locations
442  vtkm::Id newCoordsIndex = oldCoords.GetNumberOfValues();
443  auto oldCoordsPortal = oldCoords.ReadPortal();
444  auto newCoordsPortal = newCoords.WritePortal();
445  auto newPointNumsPortal = newPointNums.WritePortal();
446  for (vtkm::Id i = 0; i < oldCoords.GetNumberOfValues(); i++)
447  { // Find out for each new point, how many times it should be added
448  for (vtkm::Id j = 0; j < newPointNumsPortal.Get(i); j++)
449  {
450  newPointsIdArrayPortal.Set(newCoordsIndex, i);
451  newCoordsPortal.Set(newCoordsIndex++, oldCoordsPortal.Get(i));
452  }
453  }
454  }
455 
456  // Allocate the size for the updateCellTopologyArray
457  vtkm::cont::ArrayHandle<vtkm::Id3> cellTopologyUpdateTuples;
458  cellTopologyUpdateTuples.Allocate(cellsNeedUpdateNum);
459 
460  vtkm::cont::ArrayHandle<vtkm::Id> newpointStartingIndexs;
461  vtkm::cont::Algorithm::ScanExclusive(newPointNums, newpointStartingIndexs);
462  newPointNums.ReleaseResources();
463 
464 
465  SplitSharpEdge splitSharpEdge(vtkm::Cos(featureAngleR), oldCoords.GetNumberOfValues());
466  invoke(splitSharpEdge,
467  oldCellset,
468  oldCellset,
469  faceNormals,
470  newpointStartingIndexs,
471  pointCellsStartingIndexs,
472  cellTopologyUpdateTuples);
473  auto ctutPortal = cellTopologyUpdateTuples.ReadPortal();
474  vtkm::cont::printSummary_ArrayHandle(cellTopologyUpdateTuples, std::cout);
475 
476 
477  // Create the new cellset
478  CellDeepCopy::Run(oldCellset, newCellset, this->NewPointsIdArray.GetNumberOfValues());
479  // FIXME: Since the non const get array function is not in CellSetExplict.h,
480  // here I just get a non-const copy of the array handle.
481  auto connectivityArrayHandle = newCellset.GetConnectivityArray(vtkm::TopologyElementTagCell(),
483  auto connectivityArrayHandleP = connectivityArrayHandle.WritePortal();
484  auto offsetArrayHandle =
485  newCellset.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
486  auto offsetArrayHandleP = offsetArrayHandle.WritePortal();
487  for (vtkm::Id i = 0; i < cellTopologyUpdateTuples.GetNumberOfValues(); i++)
488  {
489  vtkm::Id cellId(ctutPortal.Get(i)[0]), oldPointId(ctutPortal.Get(i)[1]),
490  newPointId(ctutPortal.Get(i)[2]);
491  vtkm::Id bound = (cellId + 1 == offsetArrayHandle.GetNumberOfValues())
492  ? connectivityArrayHandle.GetNumberOfValues()
493  : offsetArrayHandleP.Get(cellId + 1);
494  vtkm::Id k = 0;
495  for (vtkm::Id j = offsetArrayHandleP.Get(cellId); j < bound; j++, k++)
496  {
497  if (connectivityArrayHandleP.Get(j) == oldPointId)
498  {
499  connectivityArrayHandleP.Set(j, newPointId);
500  }
501  }
502  }
503  }
504 
506 
507 private:
509 };
510 }
511 } // vtkm::worklet
512 
513 #endif // vtk_m_worklet_SplitSharpEdges_h
vtkm::TopologyElementTagPoint
A tag used to identify the point elements in a topology.
Definition: TopologyElementTag.h:34
vtkm::Bitset
A bitmap to serve different needs.
Definition: Bitset.h:28
Bitset.h
vtkm::worklet::SplitSharpEdges::SplitSharpEdge
Definition: worklet/SplitSharpEdges.h:317
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
Manages an array-worth of data.
Definition: ArrayHandle.h:283
vtkm::ErrorCode
ErrorCode
Definition: ErrorCode.h:19
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::SplitSharpEdge
SplitSharpEdge(vtkm::FloatDefault cosfeatureAngle, vtkm::Id numberOfOldPoints)
Definition: worklet/SplitSharpEdges.h:320
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
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::worklet::SplitSharpEdges::ClassifyPoint
Definition: worklet/SplitSharpEdges.h:250
vtkm::worklet::SplitSharpEdges
Definition: worklet/SplitSharpEdges.h:239
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::WorkletVisitPointsWithCells::FieldInCell
FieldInIncident FieldInCell
Definition: WorkletMapTopology.h:278
vtkm::Bitset::test
VTKM_EXEC_CONT bool test(vtkm::Id bitIndex) const
Definition: Bitset.h:53
vtkm::cont::make_ArrayHandleCounting
VTKM_CONT vtkm::cont::ArrayHandleCounting< CountingValueType > make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
A convenience function for creating an ArrayHandleCounting.
Definition: ArrayHandleCounting.h:151
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::worklet::SplitSharpEdges::ClassifyPoint::ExecutionSignature
void(CellIndices incidentCells, InputIndex pointIndex, _2 pFromCellSet, _3 faceNormals, _4 newPointNum, _5 cellNum) ExecutionSignature
Definition: worklet/SplitSharpEdges.h:267
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::InputDomain
_1 InputDomain
Definition: worklet/SplitSharpEdges.h:338
vtkm::cont::printSummary_ArrayHandle
VTKM_NEVER_EXPORT VTKM_CONT void printSummary_ArrayHandle(const vtkm::cont::ArrayHandle< T, StorageT > &array, std::ostream &out, bool full=false)
Definition: ArrayHandle.h:789
vtkm::ErrorCode::Success
@ Success
vtkm::cont::Algorithm::CopySubRange
static VTKM_CONT bool CopySubRange(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::Id inputStartIndex, vtkm::Id numberOfElementsToCopy, vtkm::cont::ArrayHandle< U, COut > &output, vtkm::Id outputIndex=0)
Definition: Algorithm.h:472
vtkm::worklet::SplitSharpEdges::ClassifyPoint::operator()
VTKM_EXEC void operator()(const IncidentCellVecType &incidentCells, vtkm::Id pointIndex, const PointFromCellSetType &pFromCellSet, const FaceNormalVecType &faceNormals, vtkm::Id &newPointNum, vtkm::Id &cellNum) const
Definition: worklet/SplitSharpEdges.h:273
vtkm::ErrorCode::MalformedCellDetected
@ MalformedCellDetected
vtkm::worklet::SplitSharpEdges::GetNewPointsIdArray
vtkm::cont::ArrayHandle< vtkm::Id > GetNewPointsIdArray() const
Definition: worklet/SplitSharpEdges.h:505
Invoker.h
vtkm::worklet::SplitSharpEdges::ClassifyPoint::InputDomain
_1 InputDomain
Definition: worklet/SplitSharpEdges.h:268
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::ExecutionSignature
void(CellIndices incidentCells, InputIndex pointIndex, _2 pFromCellSet, _3 faceNormals, _4 newPointStartingIndex, _5 pointCellsStartingIndex, _6 cellTopologyUpdateTuples) ExecutionSignature
Definition: worklet/SplitSharpEdges.h:337
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayCopy.h
CellDeepCopy.h
vtkm::worklet::SplitSharpEdges::ClassifyPoint::ClassifyPoint
ClassifyPoint(vtkm::FloatDefault cosfeatureAngle)
Definition: worklet/SplitSharpEdges.h:253
VectorAnalysis.h
TypeTraits.h
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::NumberOfOldPoints
vtkm::Id NumberOfOldPoints
Definition: worklet/SplitSharpEdges.h:385
vtkm::worklet::WorkletVisitPointsWithCells
Base class for worklets that map from Cells to Points.
Definition: WorkletMapTopology.h:274
ArrayHandlePermutation.h
Algorithm.h
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::ControlSignature
void(CellSetIn intputCells, WholeCellSetIn< Cell, Point >, FieldInCell faceNormals, FieldInPoint newPointStartingIndex, FieldInPoint pointCellsStartingIndex, WholeArrayOut cellTopologyUpdateTuples) ControlSignature
Definition: worklet/SplitSharpEdges.h:330
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::SplitSharpEdges::ClassifyPoint::ControlSignature
void(CellSetIn intputCells, WholeCellSetIn< Cell, Point >, FieldInCell faceNormals, FieldOutPoint newPointNum, FieldOutPoint cellNum) ControlSignature
Definition: worklet/SplitSharpEdges.h:261
vtkm::cont::Invoker
Allows launching any worklet without a dispatcher.
Definition: Invoker.h:41
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::make_Vec
constexpr VTKM_EXEC_CONT vtkm::Vec< T, vtkm::IdComponent(sizeof...(Ts)+1)> make_Vec(T value0, Ts &&... args)
Initializes and returns a Vec containing all the arguments.
Definition: Types.h:1212
vtkm::worklet::SplitSharpEdges::Run
void Run(const CellSetType &oldCellset, const vtkm::FloatDefault featureAngle, const FaceNormalsType &faceNormals, const vtkm::cont::ArrayHandle< vtkm::Vec< CoordsComType, 3 >, CoordsInStorageType > &oldCoords, vtkm::cont::ArrayHandle< vtkm::Vec< CoordsComType, 3 >, CoordsOutStorageType > &newCoords, NewCellSetType &newCellset)
Definition: worklet/SplitSharpEdges.h:394
vtkm::worklet::CellDeepCopy::Run
static VTKM_CONT void Run(const InCellSetType &inCellSet, vtkm::cont::CellSetExplicit< ShapeStorage, ConnectivityStorage, OffsetsStorage > &outCellSet, vtkm::Id numberOfPoints)
Definition: CellDeepCopy.h:68
vtkm::worklet::WorkletVisitPointsWithCells::CellIndices
IncidentElementIndices CellIndices
Definition: WorkletMapTopology.h:288
vtkm::worklet::WorkletVisitPointsWithCells::FieldInPoint
FieldInVisit FieldInPoint
Definition: WorkletMapTopology.h:280
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
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::WorkletVisitPointsWithCells::FieldOutPoint
FieldOut FieldOutPoint
Definition: WorkletMapTopology.h:282
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::Bitset::set
VTKM_EXEC_CONT void set(vtkm::Id bitIndex)
Definition: Bitset.h:30
ArrayHandleCounting.h
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:111
vtkm::worklet::SplitSharpEdges::ClassifyPoint::CosFeatureAngle
vtkm::FloatDefault CosFeatureAngle
Definition: worklet/SplitSharpEdges.h:312
CellEdge.h
vtkm::TopologyElementTagCell
A tag used to identify the cell elements in a topology.
Definition: TopologyElementTag.h:24
CellTraits.h
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::operator()
VTKM_EXEC void operator()(const IncidentCellVecType &incidentCells, vtkm::Id pointIndex, const PointFromCellSetType &pFromCellSet, const FaceNormalVecType &faceNormals, const vtkm::Id &newPointStartingIndex, const vtkm::Id &pointCellsStartingIndex, CellTopologyUpdateTuples &cellTopologyUpdateTuples) const
Definition: worklet/SplitSharpEdges.h:344
vtkm::worklet::SplitSharpEdges::SplitSharpEdge::CosFeatureAngle
vtkm::FloatDefault CosFeatureAngle
Definition: worklet/SplitSharpEdges.h:384
vtkm::worklet::SplitSharpEdges::NewPointsIdArray
vtkm::cont::ArrayHandle< vtkm::Id > NewPointsIdArray
Definition: worklet/SplitSharpEdges.h:508
vtkm::exec::arg::InputIndex
The ExecutionSignature tag to use to get the input index.
Definition: InputIndex.h:42
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559