4.7. Working with Cells

In the control environment, data is defined in mesh structures that comprise a set of finite cells. (See Section 2.4.2 (Cell Sets) for information on defining cell sets in the control environment.) When worklets that operate on cells are scheduled, these grid structures are broken into their independent cells, and that data is handed to the worklet. Thus, cell-based operations in the execution environment exclusively operate on independent cells.

Unlike some other libraries such as VTK, VTK‑m does not have a cell class that holds all the information pertaining to a cell of a particular type. Instead, VTK‑m provides tags or identifiers defining the cell shape, and companion data like coordinate and field information are held in separate structures. This organization is designed so a worklet may specify exactly what information it needs, and only that information will be loaded.

4.7.1. Cell Shape Tags and Ids

Cell shapes can be specified with either a tag (defined with a struct with a name like CellShapeTag*) or an enumerated identifier (defined with a constant number with a name like CELL_SHAPE_*). These shape tags and identifiers are defined in vtkm/CellShape.h and declared in the vtkm namespace (because they can be used in either the control or the execution environment). Figure 4.2 gives both the identifier and the tag names.

_images/CellConnections.png

Figure 4.2 Basic Cell Shapes.

struct CellShapeTagVertex
enumerator CELL_SHAPE_VERTEX

Vertex cells of a single point.

struct CellShapeTagLine
enumerator CELL_SHAPE_LINE

A line cell connecting two points.

struct CellShapeTagPolyLine
enumerator CELL_SHAPE_POLY_LINE

A sequence of line segments.

A polyline has 2 or more points, and the points are connected in order by line segments forming a piecewise linear curve.

struct CellShapeTagTriangle
enumerator CELL_SHAPE_TRIANGLE

A triangle.

struct CellShapeTagPolygon
enumerator CELL_SHAPE_POLYGON

A general polygon shape.

All polygons have points ordered in counterclockwise order around the front side. Some operations may be invalid if the polygon is not a convex shape.

struct CellShapeTagQuad
enumerator CELL_SHAPE_QUAD

A four-sided polygon.

struct CellShapeTagTetra
enumerator CELL_SHAPE_TETRA

A tetrahedron.

A tetrahedron is a 3D polyhedron with 4 points and 4 triangular faces.

struct CellShapeTagHexahedron
enumerator CELL_SHAPE_HEXAHEDRON

A hexahedron.

struct CellShapeTagWedge
enumerator CELL_SHAPE_WEDGE

A wedge.

Wedges are simple prisms that can be formed by extruding a triangle. They have 2 triangular faces and 3 quadrilateral faces.

struct CellShapeTagPyramid
enumerator CELL_SHAPE_PYRAMID

A pyramid with a quadrilateral base and four triangular faces.0.

In addition to the basic cell shapes, there is a special “empty” cell with the identifier vtkm::CELL_SHAPE_EMPTY and tag vtkm::CellShapeTagEmpty. This type of cell has no points, edges, or faces and can be thought of as a placeholder for a null or void cell.

struct CellShapeTagEmpty
enumerator CELL_SHAPE_EMPTY

Placeholder for empty or invalid cells.

There is also a special cell shape “tag” named vtkm::CellShapeTagGeneric that is used when the actual cell shape is not known at compile time. vtkm::CellShapeTagGeneric actually has a member variable named vtkm::CellShapeTagGeneric::Id that stores the identifier for the cell shape. There is no equivalent identifier for a generic cell; cell shape identifiers can be placed in a vtkm::IdComponent at runtime.

struct CellShapeTagGeneric

A special cell shape tag that holds a cell shape that is not known at compile time.

Unlike other cell set tags, the Id field is set at runtime so its value cannot be used in template parameters. You need to use vtkmGenericCellShapeMacro to specialize on the cell type.

Public Members

vtkm::UInt8 Id

An identifier that corresponds to one of the CELL_SHAPE_* identifiers.

This value is used to detect the proper shape at runtime.

When using cell shapes in templated classes and functions, you can use the VTKM_IS_CELL_SHAPE_TAG to ensure a type is a valid cell shape tag. This macro takes one argument and will produce a compile error if the argument is not a cell shape tag type.

VTKM_IS_CELL_SHAPE_TAG(tag)

Checks that the argument is a proper cell shape tag.

This is a handy concept check to make sure that a template argument is a proper cell shape tag.

4.7.1.1. Converting Between Tags and Identifiers

Every cell shape tag has a member variable named Id that contains the identifier for the cell shape. This provides a convenient mechanism for converting a cell shape tag to an identifier. Most cell shape tags have their Id member as a compile-time constant, but vtkm::CellShapeTagGeneric::Id is set at run time.

The vtkm/CellShape.h header also declares a templated class named vtkm::CellShapeIdToTag that converts a cell shape identifier to a cell shape tag. vtkm::CellShapeIdToTag has a single template argument that is the identifier. Inside the class is a type named vtkm::CellShapeIdToTag::Tag that is the type of the correct tag.

template<vtkm::IdComponent Id>
struct CellShapeIdToTag

A traits-like class to get an CellShapeId known at compile time to a tag.

Example 4.66 Using vtkm::CellShapeIdToTag.
 1void CellFunction(vtkm::CellShapeTagTriangle)
 2{
 3  std::cout << "In CellFunction for triangles." << std::endl;
 4}
 5
 6void DoSomethingWithACell()
 7{
 8  // Calls CellFunction overloaded with a vtkm::CellShapeTagTriangle.
 9  CellFunction(vtkm::CellShapeIdToTag<vtkm::CELL_SHAPE_TRIANGLE>::Tag());
10}

However, vtkm::CellShapeIdToTag is only viable if the identifier can be resolved at compile time. In the case where a cell identifier is stored in a variable or an array or the code is using a vtkm::CellShapeTagGeneric, the correct cell shape is not known until run time. In this case, the vtkmGenericCellShapeMacro macro can be used to check all possible conditions. This macro is embedded in a switch statement where the condition is the cell shape identifier.

vtkmGenericCellShapeMacro(call)

A macro used in a switch statement to determine cell shape.

The vtkmGenericCellShapeMacro is a series of case statements for all of the cell shapes supported by VTK-m. This macro is intended to be used inside of a switch statement on a cell type. For each cell shape condition, a CellShapeTag typedef is created and the given call is executed.

A typical use case of this class is to create the specialization of a function overloaded on a cell shape tag for the generic cell shape like as following.

template<typename WorkletType>
VTKM_EXEC
void MyCellOperation(vtkm::CellShapeTagGeneric cellShape,
                     const vtkm::exec::FunctorBase &worklet)
{
  switch(cellShape.CellShapeId)
  {
    vtkmGenericCellShapeMacro(
      MyCellOperation(CellShapeTag())
      );
    default: worklet.RaiseError("Encountered unknown cell shape."); break
  }
}

Note that vtkmGenericCellShapeMacro does not have a default case. You should consider adding one that gives a

Often this method is used to implement the condition for a vtkm::CellShapeTagGeneric in a function overloaded for cell types. A demonstration of vtkmGenericCellShapeMacro is given in Example 4.67.

4.7.1.2. Cell Traits

The vtkm/CellTraits.h header file contains a traits class named vtkm::CellTraits that provides information about a cell.

template<class CellTag>
struct CellTraits

Information about a cell based on its tag.

The templated CellTraits struct provides the basic high level information about cells (like the number of vertices in the cell or its dimensionality).

Public Types

using TopologicalDimensionsTag = vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS>

This tag is typedef’ed to vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS>.

This provides a convenient way to overload a function based on topological dimensions (which is usually more efficient than conditionals).

using IsSizeFixed = vtkm::CellTraitsTagSizeFixed

A tag specifying whether the number of points is fixed.

If set to vtkm::CellTraitsTagSizeFixed, then NUM_POINTS is set. If set to vtkm::CellTraitsTagSizeVariable, then the number of points is not known at compile time.

Public Static Attributes

static const vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = 3

This defines the topological dimensions of the cell type.

3 for polyhedra, 2 for polygons, 1 for lines, 0 for points.

static constexpr vtkm::IdComponent NUM_POINTS = 3

Number of points in the cell.

This is only defined for cell shapes of a fixed number of points (i.e., IsSizedFixed is set to vtkm::CellTraitsTagSizeFixed).

template<vtkm::IdComponent dimension>
struct CellTopologicalDimensionsTag

vtkm::CellTraits::TopologyDimensionType is typedef to this with the template parameter set to TOPOLOGICAL_DIMENSIONS.

See vtkm::CellTraits for more information.

struct CellTraitsTagSizeFixed

Tag for cell shapes with a fixed number of points.

struct CellTraitsTagSizeVariable

Tag for cell shapes that can have a variable number of points.

Example 4.67 Using vtkm::CellTraits to implement a polygon normal estimator.
 1namespace detail
 2{
 3
 4template<typename PointCoordinatesVector, typename WorkletType>
 5VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormalImpl(
 6  const PointCoordinatesVector& pointCoordinates,
 7  vtkm::CellTopologicalDimensionsTag<2>,
 8  const WorkletType& worklet)
 9{
10  if (pointCoordinates.GetNumberOfComponents() >= 3)
11  {
12    return vtkm::TriangleNormal(
13      pointCoordinates[0], pointCoordinates[1], pointCoordinates[2]);
14  }
15  else
16  {
17    worklet.RaiseError("Degenerate polygon.");
18    return typename PointCoordinatesVector::ComponentType();
19  }
20}
21
22template<typename PointCoordinatesVector,
23         vtkm::IdComponent Dimensions,
24         typename WorkletType>
25VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormalImpl(
26  const PointCoordinatesVector&,
27  vtkm::CellTopologicalDimensionsTag<Dimensions>,
28  const WorkletType& worklet)
29{
30  worklet.RaiseError("Only polygons supported for cell normals.");
31  return typename PointCoordinatesVector::ComponentType();
32}
33
34} // namespace detail
35
36template<typename CellShape, typename PointCoordinatesVector, typename WorkletType>
37VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormal(
38  CellShape,
39  const PointCoordinatesVector& pointCoordinates,
40  const WorkletType& worklet)
41{
42  return detail::CellNormalImpl(
43    pointCoordinates,
44    typename vtkm::CellTraits<CellShape>::TopologicalDimensionsTag(),
45    worklet);
46}
47
48template<typename PointCoordinatesVector, typename WorkletType>
49VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormal(
50  vtkm::CellShapeTagGeneric shape,
51  const PointCoordinatesVector& pointCoordinates,
52  const WorkletType& worklet)
53{
54  switch (shape.Id)
55  {
56    vtkmGenericCellShapeMacro(
57      return CellNormal(CellShapeTag(), pointCoordinates, worklet));
58    default:
59      worklet.RaiseError("Unknown cell type.");
60      return typename PointCoordinatesVector::ComponentType();
61  }
62}

4.7.2. Parametric and World Coordinates

Each cell type supports a one-to-one mapping between a set of parametric coordinates in the unit cube (or some subset of it) and the points in 3D space that are the locus contained in the cell. Parametric coordinates are useful because certain features of the cell, such as vertex location and center, are at a consistent location in parametric space irrespective of the location and distortion of the cell in world space. Also, many field operations are much easier with parametric coordinates.

The vtkm/exec/ParametricCoordinates.h header file contains the following functions for working with parametric coordinates. These functions contain several overloads for using different cell shape tags.

template<typename ParametricCoordType>
static inline vtkm::ErrorCode vtkm::exec::ParametricCoordinatesCenter(vtkm::IdComponent numPoints, vtkm::CellShapeTagGeneric shape, vtkm::Vec<ParametricCoordType, 3> &pcoords)

Returns the parametric center of the given cell shape with the given number of points.

Parameters:
  • numPoints[in] The number of points in the cell.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • pcoords[out] vtkm::Vec to store the parametric center.

template<typename ParametricCoordType>
static inline vtkm::ErrorCode vtkm::exec::ParametricCoordinatesPoint(vtkm::IdComponent numPoints, vtkm::IdComponent pointIndex, vtkm::CellShapeTagGeneric shape, vtkm::Vec<ParametricCoordType, 3> &pcoords)

Returns the parametric coordinate of a cell point of the given shape with the given number of points.

Parameters:
  • numPoints[in] The number of points in the cell.

  • pointIndex[in] The local index for the point to get the parametric coordinates of. This index is between 0 and n-1 where n is the number of points in the cell.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • pcoords[out] vtkm::Vec to store the parametric center.

template<typename WorldCoordVector, typename PCoordType>
static inline vtkm::ErrorCode vtkm::exec::ParametricCoordinatesToWorldCoordinates(const WorldCoordVector &pointWCoords, const vtkm::Vec<PCoordType, 3> &pcoords, vtkm::CellShapeTagGeneric shape, typename WorldCoordVector::ComponentType &result)

Converts parametric coordinates (coordinates relative to the cell) to world coordinates (coordinates in the global system).

Parameters:
  • pointWCoords[in] A list of world coordinates for each point in the cell. This usually comes from a FieldInPoint argument in a vtkm::worklet::WorkletVisitCellsWithPoints where the coordinate system is passed into that argument.

  • pcoords[in] The parametric coordinates where you want to get world coordinates for.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] vtkm::Vec to store the interpolated world coordinates.

template<typename WorldCoordVector>
static inline vtkm::ErrorCode vtkm::exec::WorldCoordinatesToParametricCoordinates(const WorldCoordVector &pointWCoords, const typename WorldCoordVector::ComponentType &wcoords, vtkm::CellShapeTagGeneric shape, typename WorldCoordVector::ComponentType &result)

Converts world coordinates (coordinates in the global system) to parametric coordinates (coordinates relative to the cell).

This function can be slow for cell types with nonlinear interpolation (which is anything that is not a simplex).

Parameters:
  • pointWCoords[in] A list of world coordinates for each point in the cell. This usually comes from a FieldInPoint argument in a vtkm::worklet::WorkletVisitCellsWithPoints where the coordinate system is passed into that argument.

  • wcoords[in] The world coordinates where you want to get parametric coordinates for.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] vtkm::Vec to store the associated parametric coordinates.

4.7.3. Interpolation

The shape of every cell is defined by the connections of some finite set of points. Field values defined on those points can be interpolated to any point within the cell to estimate a continuous field.

The vtkm/exec/CellInterpolate.h header contains the function vtkm::exec::CellInterpolate() to do this interpolation.

template<typename FieldVecType, typename ParametricCoordType>
vtkm::ErrorCode vtkm::exec::CellInterpolate(const FieldVecType &pointFieldValues, const vtkm::Vec<ParametricCoordType, 3> &parametricCoords, vtkm::CellShapeTagGeneric shape, typename FieldVecType::ComponentType &result)

Interpolate a point field in a cell.

Given the point field values for each node and the parametric coordinates of a point within the cell, interpolates the field to that point.

Parameters:
  • pointFieldValues[in] A list of field values for each point in the cell. This usually comes from a FieldInPoint argument in a vtkm::worklet::WorkletVisitCellsWithPoints.

  • parametricCoords[in] The parametric coordinates where you want to get the interpolated field value for.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] Value to store the interpolated field.

Example 4.68 Interpolating field values to a cell’s center.
 1struct CellCenters : vtkm::worklet::WorkletVisitCellsWithPoints
 2{
 3  using ControlSignature = void(CellSetIn,
 4                                FieldInPoint inputField,
 5                                FieldOutCell outputField);
 6  using ExecutionSignature = void(CellShape, PointCount, _2, _3);
 7  using InputDomain = _1;
 8
 9  template<typename CellShapeTag, typename FieldInVecType, typename FieldOutType>
10  VTKM_EXEC void operator()(CellShapeTag shape,
11                            vtkm::IdComponent pointCount,
12                            const FieldInVecType& inputField,
13                            FieldOutType& outputField) const
14  {
15    vtkm::Vec3f center;
16    vtkm::ErrorCode status =
17      vtkm::exec::ParametricCoordinatesCenter(pointCount, shape, center);
18    if (status != vtkm::ErrorCode::Success)
19    {
20      this->RaiseError(vtkm::ErrorString(status));
21      return;
22    }
23    vtkm::exec::CellInterpolate(inputField, center, shape, outputField);
24  }
25};

4.7.4. Derivatives

Since interpolations provide a continuous field function over a cell, it is reasonable to consider the derivative of this function. The vtkm/exec/CellDerivative.h header contains the function vtkm::exec::CellDerivative() to compute derivatives. The derivative is returned in a vtkm::Vec of size 3 corresponding to the partial derivatives in the \(x\), \(y\), and \(z\) directions. This derivative is equivalent to the gradient of the field.

Example 4.69 Computing the derivative of the field at cell centers.
 1struct CellDerivatives : vtkm::worklet::WorkletVisitCellsWithPoints
 2{
 3  using ControlSignature = void(CellSetIn,
 4                                FieldInPoint inputField,
 5                                FieldInPoint pointCoordinates,
 6                                FieldOutCell outputField);
 7  using ExecutionSignature = void(CellShape, PointCount, _2, _3, _4);
 8  using InputDomain = _1;
 9
10  template<typename CellShapeTag,
11           typename FieldInVecType,
12           typename PointCoordVecType,
13           typename FieldOutType>
14  VTKM_EXEC void operator()(CellShapeTag shape,
15                            vtkm::IdComponent pointCount,
16                            const FieldInVecType& inputField,
17                            const PointCoordVecType& pointCoordinates,
18                            FieldOutType& outputField) const
19  {
20    vtkm::Vec3f center;
21    vtkm::ErrorCode status =
22      vtkm::exec::ParametricCoordinatesCenter(pointCount, shape, center);
23    if (status != vtkm::ErrorCode::Success)
24    {
25      this->RaiseError(vtkm::ErrorString(status));
26      return;
27    }
28    vtkm::exec::CellDerivative(inputField, pointCoordinates, center, shape, outputField);
29  }
30};

4.7.5. Edges and Faces

As explained earlier in this chapter, a cell is defined by a collection of points and a shape identifier that describes how the points come together to form the structure of the cell. The cell shapes supported by VTK‑m are documented in Section 4.7.1 (Cell Shape Tags and Ids). It contains Figure 4.2, which shows how the points for each shape form the structure of the cell.

Most cell shapes can be broken into subelements. 2D and 3D cells have pairs of points that form edges at the boundaries of the cell. Likewise, 3D cells have loops of edges that form faces that encase the cell. Figure 4.3 demonstrates the relationship of these constituent elements for some example cell shapes.

_images/CellConstituents.png

Figure 4.3 The constituent elements (points, edges, and faces) of cells..

The header file vtkm/exec/CellEdge.h contains a collection of functions to help identify the edges of a cell.

static inline vtkm::ErrorCode vtkm::exec::CellEdgeNumberOfEdges(vtkm::IdComponent numPoints, vtkm::CellShapeTagGeneric shape, vtkm::IdComponent &numEdges)

Get the number of edges in a cell.

Parameters:
  • numPoints[in] The number of points in the cell.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • numEdges[out] A reference to return the number of edges.

static inline vtkm::ErrorCode vtkm::exec::CellEdgeLocalIndex(vtkm::IdComponent numPoints, vtkm::IdComponent pointIndex, vtkm::IdComponent edgeIndex, vtkm::CellShapeTagGeneric shape, vtkm::IdComponent &result)

Given the index for an edge of a cell and one of the points on that edge, this function returns the point index for the cell.

To get the point indices relative to the data set, the returned index should be used to reference a PointIndices list.

Parameters:
  • numPoints[in] The number of points in the cell.

  • pointIndex[in] The index of the edge within the cell.

  • edgeIndex[in] The index of the point on the edge (either 0 or 1).

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] Reference to put the index of the point relative to the cell (between 0 and the number of points in the cell).

template<typename CellShapeTag, typename GlobalPointIndicesVecType>
static inline vtkm::ErrorCode vtkm::exec::CellEdgeCanonicalId(vtkm::IdComponent numPoints, vtkm::IdComponent edgeIndex, CellShapeTag shape, const GlobalPointIndicesVecType &globalPointIndicesVec, vtkm::Id2 &result)

Returns a canonical identifier for a cell edge.

Given information about a cell edge and the global point indices for that cell, returns a vtkm::Id2 that contains values that are unique to that edge. The values for two edges will be the same if and only if the edges contain the same points.

The following example demonstrates a pair of worklets that use the cell edge functions. As is typical for operations of this nature, one worklet counts the number of edges in each cell and another uses this count to generate the data.

Did You Know?

Example 4.70 demonstrates one of many techniques for creating cell sets in a worklet. Chapter~ref{chap:GeneratingCellSets} describes this and many more such techniques.

Example 4.70 Using cell edge functions.
 1  struct EdgesCount : vtkm::worklet::WorkletVisitCellsWithPoints
 2  {
 3    using ControlSignature = void(CellSetIn, FieldOutCell numEdgesInCell);
 4    using ExecutionSignature = void(CellShape, PointCount, _2);
 5    using InputDomain = _1;
 6
 7    template<typename CellShapeTag>
 8    VTKM_EXEC void operator()(CellShapeTag cellShape,
 9                              vtkm::IdComponent numPointsInCell,
10                              vtkm::IdComponent& numEdges) const
11    {
12      vtkm::ErrorCode status =
13        vtkm::exec::CellEdgeNumberOfEdges(numPointsInCell, cellShape, numEdges);
14      if (status != vtkm::ErrorCode::Success)
15      {
16        this->RaiseError(vtkm::ErrorString(status));
17      }
18    }
19  };
20
21  struct EdgesExtract : vtkm::worklet::WorkletVisitCellsWithPoints
22  {
23    using ControlSignature = void(CellSetIn, FieldOutCell edgeIndices);
24    using ExecutionSignature = void(CellShape, PointIndices, VisitIndex, _2);
25    using InputDomain = _1;
26
27    using ScatterType = vtkm::worklet::ScatterCounting;
28
29    template<typename CellShapeTag,
30             typename PointIndexVecType,
31             typename EdgeIndexVecType>
32    VTKM_EXEC void operator()(CellShapeTag cellShape,
33                              const PointIndexVecType& globalPointIndicesForCell,
34                              vtkm::IdComponent edgeIndex,
35                              EdgeIndexVecType& edgeIndices) const
36    {
37      vtkm::IdComponent numPointsInCell =
38        globalPointIndicesForCell.GetNumberOfComponents();
39
40      vtkm::ErrorCode error;
41
42      vtkm::IdComponent pointInCellIndex0;
43      error = vtkm::exec::CellEdgeLocalIndex(
44        numPointsInCell, 0, edgeIndex, cellShape, pointInCellIndex0);
45      if (error != vtkm::ErrorCode::Success)
46      {
47        this->RaiseError(vtkm::ErrorString(error));
48        return;
49      }
50
51      vtkm::IdComponent pointInCellIndex1;
52      error = vtkm::exec::CellEdgeLocalIndex(
53        numPointsInCell, 1, edgeIndex, cellShape, pointInCellIndex1);
54      if (error != vtkm::ErrorCode::Success)
55      {
56        this->RaiseError(vtkm::ErrorString(error));
57        return;
58      }
59
60      edgeIndices[0] = globalPointIndicesForCell[pointInCellIndex0];
61      edgeIndices[1] = globalPointIndicesForCell[pointInCellIndex1];
62    }
63  };

The header file vtkm/exec/CellFace.h contains a collection of functions to help identify the faces of a cell.

template<typename CellShapeTag>
static inline vtkm::ErrorCode vtkm::exec::CellFaceNumberOfFaces(CellShapeTag shape, vtkm::IdComponent &result)

Get the number of faces in a cell.

Parameters:
  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] A reference to return the number of faces.

template<typename CellShapeTag>
static inline vtkm::ErrorCode vtkm::exec::CellFaceNumberOfPoints(vtkm::IdComponent faceIndex, CellShapeTag shape, vtkm::IdComponent &result)

Get the number of points in a face.

Given a local index to the face and a shape of the cell, this method returns the number of points in that particular face.

Parameters:
  • faceIndex[in] The index of the face within the cell.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] A reference to return the number of points in the selected face.

template<typename CellShapeTag>
static inline vtkm::ErrorCode vtkm::exec::CellFaceShape(vtkm::IdComponent faceIndex, CellShapeTag shape, vtkm::UInt8 &result)

Get the shape of a face.

Given a local index to the face and a shape of the cell, this method returns the identifier for the shape of that face. Faces are always polygons, so it is valid to just to treat the face as a CELL_SHAPE_POLYGON. However, the face will be checked to see if it can be further specialized to CELL_SHAPE_TRIANGLE or CELL_SHAPE_QUAD.

Parameters:
  • faceIndex[in] The index of the face within the cell.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] A reference to return the number of points in the selected face.

template<typename CellShapeTag>
static inline vtkm::ErrorCode vtkm::exec::CellFaceLocalIndex(vtkm::IdComponent pointIndex, vtkm::IdComponent faceIndex, CellShapeTag shape, vtkm::IdComponent &result)

Given the index for a face of a cell and one of the points on that face, this function returns the point index for the cell.

To get the point indices relative to the data set, the returned index should be used to reference a PointIndices list.

Parameters:
  • pointIndex[in] The index of the edge within the cell.

  • faceIndex[in] The index of the point on the face.

  • shape[in] A tag of type CellShapeTag* to identify the shape of the cell. This method is overloaded for different shape types.

  • result[out] Reference to put the index of the point relative to the cell (between 0 and the number of points in the cell).

template<typename CellShapeTag, typename GlobalPointIndicesVecType>
static inline vtkm::ErrorCode vtkm::exec::CellFaceCanonicalId(vtkm::IdComponent faceIndex, CellShapeTag shape, const GlobalPointIndicesVecType &globalPointIndicesVec, vtkm::Id3 &result)

Returns a canonical identifier for a cell face.

Given information about a cell face and the global point indices for that cell, returns a vtkm::Id3 that contains values that are unique to that face. The values for two faces will be the same if and only if the faces contain the same points.

Note that this property is only true if the mesh is conforming. That is, any two neighboring cells that share a face have the same points on that face. This preculdes 2 faces sharing more than a single point or single edge.

The following example demonstrates a triple of worklets that use the cell face functions. As is typical for operations of this nature, the worklets are used in steps to first count entities and then generate new entities. In this case, the first worklet counts the number of faces and the second worklet counts the points in each face. The third worklet generates cells for each face.

Example 4.71 Using cell face functions.
 1  struct FacesCount : vtkm::worklet::WorkletVisitCellsWithPoints
 2  {
 3    using ControlSignature = void(CellSetIn, FieldOutCell numFacesInCell);
 4    using ExecutionSignature = void(CellShape, _2);
 5    using InputDomain = _1;
 6
 7    template<typename CellShapeTag>
 8    VTKM_EXEC void operator()(CellShapeTag cellShape, vtkm::IdComponent& numFaces) const
 9    {
10      vtkm::ErrorCode status = vtkm::exec::CellFaceNumberOfFaces(cellShape, numFaces);
11      if (status != vtkm::ErrorCode::Success)
12      {
13        this->RaiseError(vtkm::ErrorString(status));
14      }
15    }
16  };
17
18  struct FacesCountPoints : vtkm::worklet::WorkletVisitCellsWithPoints
19  {
20    using ControlSignature = void(CellSetIn,
21                                  FieldOutCell numPointsInFace,
22                                  FieldOutCell faceShape);
23    using ExecutionSignature = void(CellShape, VisitIndex, _2, _3);
24    using InputDomain = _1;
25
26    using ScatterType = vtkm::worklet::ScatterCounting;
27
28    template<typename CellShapeTag>
29    VTKM_EXEC void operator()(CellShapeTag cellShape,
30                              vtkm::IdComponent faceIndex,
31                              vtkm::IdComponent& numPointsInFace,
32                              vtkm::UInt8& faceShape) const
33    {
34      vtkm::exec::CellFaceNumberOfPoints(faceIndex, cellShape, numPointsInFace);
35      switch (numPointsInFace)
36      {
37        case 3:
38          faceShape = vtkm::CELL_SHAPE_TRIANGLE;
39          break;
40        case 4:
41          faceShape = vtkm::CELL_SHAPE_QUAD;
42          break;
43        default:
44          faceShape = vtkm::CELL_SHAPE_POLYGON;
45          break;
46      }
47    }
48  };
49
50  struct FacesExtract : vtkm::worklet::WorkletVisitCellsWithPoints
51  {
52    using ControlSignature = void(CellSetIn, FieldOutCell faceIndices);
53    using ExecutionSignature = void(CellShape, PointIndices, VisitIndex, _2);
54    using InputDomain = _1;
55
56    using ScatterType = vtkm::worklet::ScatterCounting;
57
58    template<typename CellShapeTag,
59             typename PointIndexVecType,
60             typename FaceIndexVecType>
61    VTKM_EXEC void operator()(CellShapeTag cellShape,
62                              const PointIndexVecType& globalPointIndicesForCell,
63                              vtkm::IdComponent faceIndex,
64                              FaceIndexVecType& faceIndices) const
65    {
66      vtkm::IdComponent numPointsInFace = faceIndices.GetNumberOfComponents();
67      for (vtkm::IdComponent pointInFaceIndex = 0; pointInFaceIndex < numPointsInFace;
68           pointInFaceIndex++)
69      {
70        vtkm::IdComponent pointInCellIndex;
71        vtkm::ErrorCode error = vtkm::exec::CellFaceLocalIndex(
72          pointInFaceIndex, faceIndex, cellShape, pointInCellIndex);
73        if (error != vtkm::ErrorCode::Success)
74        {
75          this->RaiseError(vtkm::ErrorString(error));
76          return;
77        }
78        faceIndices[pointInFaceIndex] = globalPointIndicesForCell[pointInCellIndex];
79      }
80    }
81  };