VTK-m  2.2
CellEdge.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_exec_CellEdge_h
11 #define vtk_m_exec_CellEdge_h
12 
13 #include <vtkm/CellShape.h>
14 #include <vtkm/CellTraits.h>
15 #include <vtkm/ErrorCode.h>
16 #include <vtkm/Types.h>
17 #include <vtkm/exec/FunctorBase.h>
18 
19 namespace vtkm
20 {
21 namespace exec
22 {
23 
24 namespace detail
25 {
26 
27 class CellEdgeTables
28 {
29 public:
30  static constexpr vtkm::Int32 MAX_NUM_EDGES = 12;
31 
32 public:
33  VTKM_EXEC vtkm::Int32 NumEdges(vtkm::Int32 cellShapeId) const
34  {
36  // NumEdges
37  0, // 0: CELL_SHAPE_EMPTY
38  0, // 1: CELL_SHAPE_VERTEX
39  0, // 2: Unused
40  0, // 3: CELL_SHAPE_LINE
41  0, // 4: CELL_SHAPE_POLY_LINE
42  3, // 5: CELL_SHAPE_TRIANGLE
43  0, // 6: Unused
44  -1, // 7: CELL_SHAPE_POLYGON ---special case---
45  0, // 8: Unused
46  4, // 9: CELL_SHAPE_QUAD
47  6, // 10: CELL_SHAPE_TETRA
48  0, // 11: Unused
49  12, // 12: CELL_SHAPE_HEXAHEDRON
50  9, // 13: CELL_SHAPE_WEDGE
51  8 // 14: CELL_SHAPE_PYRAMID
52  };
53  return numEdges[cellShapeId];
54  }
55 
56  VTKM_EXEC vtkm::Int32 PointsInEdge(vtkm::Int32 cellShapeId,
57  vtkm::Int32 edgeIndex,
58  vtkm::Int32 localPointIndex) const
59  {
61  pointsInEdge[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2] = {
62  // clang-format off
63  // 0: CELL_SHAPE_EMPTY
64  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
65  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
66  // 1: CELL_SHAPE_VERTEX
67  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
68  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
69  // 2: Unused
70  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
71  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
72  // 3: CELL_SHAPE_LINE
73  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
74  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
75  // 4: CELL_SHAPE_POLY_LINE
76  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
77  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
78  // 5: CELL_SHAPE_TRIANGLE
79  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
80  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
81  // 6: Unused
82  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
83  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
84  // 7: CELL_SHAPE_POLYGON --- special case ---
85  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
86  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
87  // 8: Unused
88  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
89  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
90  // 9: CELL_SHAPE_QUAD
91  { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { -1, -1 }, { -1, -1 },
92  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
93  // 10: CELL_SHAPE_TETRA
94  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 },
95  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
96  // 11: Unused
97  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
98  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
99  // 12: CELL_SHAPE_HEXAHEDRON
100  { { 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 },
101  { 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 3, 7 }, { 2, 6 } },
102  // 13: CELL_SHAPE_WEDGE
103  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 3, 4 }, { 4, 5 }, { 5, 3 },
104  { 0, 3 }, { 1, 4 }, { 2, 5 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
105  // 14: CELL_SHAPE_PYRAMID
106  { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 },
107  { 2, 4 }, { 3, 4 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } }
108  // clang-format on
109  };
110 
111  return pointsInEdge[cellShapeId][edgeIndex][localPointIndex];
112  }
113 };
114 
115 } // namespace detail
116 
117 template <typename CellShapeTag>
118 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent numPoints,
119  CellShapeTag,
120  vtkm::IdComponent& numEdges)
121 {
123  {
124  numEdges = -1;
126  }
127  numEdges = detail::CellEdgeTables{}.NumEdges(CellShapeTag::Id);
129 }
130 
131 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent numPoints,
133  vtkm::IdComponent& numEdges)
134 {
135  if (numPoints <= 0)
136  {
137  numEdges = -1;
139  }
140  numEdges = numPoints;
142 }
143 
144 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent numPoints,
146  vtkm::IdComponent& numEdges)
147 {
148  if (numPoints <= 0)
149  {
150  numEdges = -1;
152  }
153  numEdges = detail::CellEdgeTables{}.NumEdges(vtkm::CELL_SHAPE_POLY_LINE);
155 }
156 
163 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent numPoints,
165  vtkm::IdComponent& numEdges)
166 {
167  if (shape.Id == vtkm::CELL_SHAPE_POLYGON)
168  {
169  return CellEdgeNumberOfEdges(numPoints, vtkm::CellShapeTagPolygon(), numEdges);
170  }
171  else if (shape.Id == vtkm::CELL_SHAPE_POLY_LINE)
172  {
173  return CellEdgeNumberOfEdges(numPoints, vtkm::CellShapeTagPolyLine(), numEdges);
174  }
175  else
176  {
177  numEdges = detail::CellEdgeTables{}.NumEdges(shape.Id);
179  }
180 }
181 
182 template <typename CellShapeTag>
183 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent numPoints,
184  vtkm::IdComponent pointIndex,
185  vtkm::IdComponent edgeIndex,
186  CellShapeTag shape,
187  vtkm::IdComponent& result)
188 {
189  if ((pointIndex < 0) || (pointIndex > 1))
190  {
191  result = -1;
193  }
194  if ((edgeIndex < 0) || (edgeIndex >= detail::CellEdgeTables::MAX_NUM_EDGES))
195  {
196  result = -1;
198  }
199 
200  vtkm::IdComponent numEdges;
201  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, numEdges));
202  if (edgeIndex >= numEdges)
203  {
204  result = -1;
206  }
207 
208  detail::CellEdgeTables table;
209  result = table.PointsInEdge(CellShapeTag::Id, edgeIndex, pointIndex);
211 }
212 
213 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent numPoints,
214  vtkm::IdComponent pointIndex,
215  vtkm::IdComponent edgeIndex,
217  vtkm::IdComponent& result)
218 {
219  if (numPoints < 3)
220  {
221  result = -1;
223  }
224  if ((pointIndex < 0) || (pointIndex > 1))
225  {
226  result = -1;
228  }
229  if ((edgeIndex < 0) || (edgeIndex >= numPoints))
230  {
231  result = -1;
233  }
234 
235  if (edgeIndex + pointIndex < numPoints)
236  {
237  result = edgeIndex + pointIndex;
238  }
239  else
240  {
241  result = 0;
242  }
244 }
245 
258 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent numPoints,
259  vtkm::IdComponent pointIndex,
260  vtkm::IdComponent edgeIndex,
262  vtkm::IdComponent& result)
263 {
264  if ((pointIndex < 0) || (pointIndex > 1))
265  {
266  result = -1;
268  }
269  if ((edgeIndex < 0) || (edgeIndex >= detail::CellEdgeTables::MAX_NUM_EDGES))
270  {
271  result = -1;
273  }
274 
275  if (shape.Id == vtkm::CELL_SHAPE_POLYGON)
276  {
277  return CellEdgeLocalIndex(
278  numPoints, pointIndex, edgeIndex, vtkm::CellShapeTagPolygon(), result);
279  }
280  else
281  {
282  detail::CellEdgeTables table;
283  if (edgeIndex >= table.NumEdges(shape.Id))
284  {
285  result = -1;
287  }
288 
289  result = table.PointsInEdge(shape.Id, edgeIndex, pointIndex);
291  }
292 }
293 
300 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
301 static inline VTKM_EXEC vtkm::ErrorCode CellEdgeCanonicalId(
302  vtkm::IdComponent numPoints,
303  vtkm::IdComponent edgeIndex,
304  CellShapeTag shape,
305  const GlobalPointIndicesVecType& globalPointIndicesVec,
306  vtkm::Id2& result)
307 {
308  result = { -1, -1 };
309 
310  vtkm::IdComponent localIndex0;
311  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeLocalIndex(numPoints, 0, edgeIndex, shape, localIndex0));
312  vtkm::Id pointIndex0 = globalPointIndicesVec[localIndex0];
313 
314  vtkm::IdComponent localIndex1;
315  VTKM_RETURN_ON_ERROR(vtkm::exec::CellEdgeLocalIndex(numPoints, 1, edgeIndex, shape, localIndex1));
316  vtkm::Id pointIndex1 = globalPointIndicesVec[localIndex1];
317 
318  if (pointIndex0 < pointIndex1)
319  {
320  result = vtkm::Id2(pointIndex0, pointIndex1);
321  }
322  else
323  {
324  result = vtkm::Id2(pointIndex1, pointIndex0);
325  }
326 
328 }
329 
330 }
331 } // namespace vtkm::exec
332 
333 #endif //vtk_m_exec_CellFaces_h
vtkm::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:28
vtkm::NUMBER_OF_CELL_SHAPES
@ NUMBER_OF_CELL_SHAPES
Definition: CellShape.h:70
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
Types.h
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
VTKM_STATIC_CONSTEXPR_ARRAY
#define VTKM_STATIC_CONSTEXPR_ARRAY
Definition: ExportMacros.h:107
vtkm::ErrorCode::Success
@ Success
A successful operation.
vtkm::ErrorCode::InvalidEdgeId
@ InvalidEdgeId
A bad edge identifier was detected while operating on a cell.
CellShape.h
vtkm::CellShapeTagPolygon
Definition: CellShape.h:154
ErrorCode.h
vtkm::CellShapeTagPolyLine
Definition: CellShape.h:151
vtkm::CELL_SHAPE_POLY_LINE
@ CELL_SHAPE_POLY_LINE
A sequence of line segments.
Definition: CellShape.h:46
FunctorBase.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::ErrorCode::InvalidPointId
@ InvalidPointId
A bad point identifier was detected while operating on a cell.
vtkm::Vec< vtkm::Id, 2 >
vtkm::CellShapeTagGeneric::Id
vtkm::UInt8 Id
An identifier that corresponds to one of the CELL_SHAPE_* identifiers.
Definition: CellShape.h:180
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:202
vtkm::Int32
int32_t Int32
Base type to use for 32-bit signed integer numbers.
Definition: Types.h:181
CellTraits.h
vtkm::CellShapeTagGeneric
A special cell shape tag that holds a cell shape that is not known at compile time.
Definition: CellShape.h:170
vtkm::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
A general polygon shape.
Definition: CellShape.h:53
vtkm::CellTraits
Information about a cell based on its tag.
Definition: CellTraits.h:46
vtkm::ErrorCode::InvalidNumberOfPoints
@ InvalidNumberOfPoints
The wrong number of points was provided for a given cell type.
vtkm::Id2
vtkm::Vec< vtkm::Id, 2 > Id2
Id2 corresponds to a 2-dimensional index.
Definition: Types.h:923