VTK-m  2.2
CellFace.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_CellFace_h
11 #define vtk_m_exec_CellFace_h
12 
13 #include <vtkm/CellShape.h>
14 #include <vtkm/ErrorCode.h>
15 #include <vtkm/Types.h>
16 #include <vtkm/exec/FunctorBase.h>
17 
18 namespace vtkm
19 {
20 namespace exec
21 {
22 
23 namespace detail
24 {
25 
26 class CellFaceTables
27 {
28 public:
29  static constexpr vtkm::Int32 MAX_FACE_SIZE = 4;
30  static constexpr vtkm::Int32 MAX_NUM_FACES = 6;
31 
32  VTKM_EXEC vtkm::Int32 NumFaces(vtkm::Int32 cellShapeId) const
33  {
35  // NumFaces
36  0, // 0: CELL_SHAPE_EMPTY
37  0, // 1: CELL_SHAPE_VERTEX
38  0, // 2: Unused
39  0, // 3: CELL_SHAPE_LINE
40  0, // 4: CELL_SHAPE_POLY_LINE
41  0, // 5: CELL_SHAPE_TRIANGLE
42  0, // 6: Unused
43  0, // 7: CELL_SHAPE_POLYGON
44  0, // 8: Unused
45  0, // 9: CELL_SHAPE_QUAD
46  4, // 10: CELL_SHAPE_TETRA
47  0, // 11: Unused
48  6, // 12: CELL_SHAPE_HEXAHEDRON
49  5, // 13: CELL_SHAPE_WEDGE
50  5 // 14: CELL_SHAPE_PYRAMID
51  };
52  return numFaces[cellShapeId];
53  }
54 
55  VTKM_EXEC vtkm::Int32 NumPointsInFace(vtkm::Int32 cellShapeId, vtkm::Int32 faceIndex) const
56  {
58  numPointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES] = {
59  // NumPointsInFace
60  { -1, -1, -1, -1, -1, -1 }, // 0: CELL_SHAPE_EMPTY
61  { -1, -1, -1, -1, -1, -1 }, // 1: CELL_SHAPE_VERTEX
62  { -1, -1, -1, -1, -1, -1 }, // 2: Unused
63  { -1, -1, -1, -1, -1, -1 }, // 3: CELL_SHAPE_LINE
64  { -1, -1, -1, -1, -1, -1 }, // 4: CELL_SHAPE_POLY_LINE
65  { -1, -1, -1, -1, -1, -1 }, // 5: CELL_SHAPE_TRIANGLE
66  { -1, -1, -1, -1, -1, -1 }, // 6: Unused
67  { -1, -1, -1, -1, -1, -1 }, // 7: CELL_SHAPE_POLYGON
68  { -1, -1, -1, -1, -1, -1 }, // 8: Unused
69  { -1, -1, -1, -1, -1, -1 }, // 9: CELL_SHAPE_QUAD
70  { 3, 3, 3, 3, -1, -1 }, // 10: CELL_SHAPE_TETRA
71  { -1, -1, -1, -1, -1, -1 }, // 11: Unused
72  { 4, 4, 4, 4, 4, 4 }, // 12: CELL_SHAPE_HEXAHEDRON
73  { 3, 3, 4, 4, 4, -1 }, // 13: CELL_SHAPE_WEDGE
74  { 4, 3, 3, 3, 3, -1 } // 14: CELL_SHAPE_PYRAMID
75  };
76  return numPointsInFace[cellShapeId][faceIndex];
77  }
78 
79  VTKM_EXEC vtkm::Int32 PointsInFace(vtkm::Int32 cellShapeId,
80  vtkm::Int32 faceIndex,
81  vtkm::Int32 localPointIndex) const
82  {
83  // clang-format off
85  [MAX_FACE_SIZE] =
86  {
87  // PointsInFace
88  // 0: CELL_SHAPE_EMPTY
89  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
90  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
91  // 1: CELL_SHAPE_VERTEX
92  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
93  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
94  // 2: Unused
95  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
96  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
97  // 3: CELL_SHAPE_LINE
98  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
99  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
100  // 4: CELL_SHAPE_POLY_LINE
101  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
102  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
103  // 5: CELL_SHAPE_TRIANGLE
104  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
105  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
106  // 6: Unused
107  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
108  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
109  // 7: CELL_SHAPE_POLYGON
110  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
111  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
112  // 8: Unused
113  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
114  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
115  // 9: CELL_SHAPE_QUAD
116  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
117  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
118  // 10: CELL_SHAPE_TETRA
119  { { 0, 1, 3, -1 }, { 1, 2, 3, -1 }, { 2, 0, 3, -1 },
120  { 0, 2, 1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
121  // 11: Unused
122  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
123  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
124  // 12: CELL_SHAPE_HEXAHEDRON
125  { { 0, 4, 7, 3 }, { 1, 2, 6, 5 }, { 0, 1, 5, 4 },
126  { 3, 7, 6, 2 }, { 0, 3, 2, 1 }, { 4, 5, 6, 7 } },
127  // 13: CELL_SHAPE_WEDGE
128  { { 0, 1, 2, -1 }, { 3, 5, 4, -1 }, { 0, 3, 4, 1 },
129  { 1, 4, 5, 2 }, { 2, 5, 3, 0 }, { -1, -1, -1, -1 } },
130  // 14: CELL_SHAPE_PYRAMID
131  { { 0, 3, 2, 1 }, { 0, 1, 4, -1 }, { 1, 2, 4, -1 },
132  { 2, 3, 4, -1 }, { 3, 0, 4, -1 },{ -1, -1, -1, -1 } }
133  // clang-format on
134  };
135  return pointsInFace[cellShapeId][faceIndex][localPointIndex];
136  }
137 };
138 
139 } // namespace detail
140 
146 template <typename CellShapeTag>
147 static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfFaces(CellShapeTag shape,
148  vtkm::IdComponent& result)
149 {
150  (void)shape; //C4100 false positive workaround
151  detail::CellFaceTables table;
152  result = table.NumFaces(shape.Id);
154 }
155 
165 template <typename CellShapeTag>
166 static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfPoints(vtkm::IdComponent faceIndex,
167  CellShapeTag shape,
168  vtkm::IdComponent& result)
169 {
170  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
171  {
172  result = -1;
174  }
175 
176  vtkm::IdComponent numFaces;
177  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfFaces(shape, numFaces));
178  if (faceIndex >= numFaces)
179  {
180  result = -1;
182  }
183  detail::CellFaceTables table;
184  result = table.NumPointsInFace(shape.Id, faceIndex);
186 }
187 
200 template <typename CellShapeTag>
201 static inline VTKM_EXEC vtkm::ErrorCode CellFaceShape(vtkm::IdComponent faceIndex,
202  CellShapeTag shape,
203  vtkm::UInt8& result)
204 {
205 
206  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
207  {
208  result = vtkm::CELL_SHAPE_EMPTY;
210  }
211 
212  vtkm::IdComponent numFacePoints;
213  VTKM_RETURN_ON_ERROR(CellFaceNumberOfPoints(faceIndex, shape, numFacePoints));
214  switch (numFacePoints)
215  {
216  case 3:
217  result = vtkm::CELL_SHAPE_TRIANGLE;
218  break;
219  case 4:
220  result = vtkm::CELL_SHAPE_QUAD;
221  break;
222  default:
223  result = vtkm::CELL_SHAPE_POLYGON;
224  break;
225  }
227 }
228 
240 template <typename CellShapeTag>
241 static inline VTKM_EXEC vtkm::ErrorCode CellFaceLocalIndex(vtkm::IdComponent pointIndex,
242  vtkm::IdComponent faceIndex,
243  CellShapeTag shape,
244  vtkm::IdComponent& result)
245 {
246  vtkm::IdComponent numPointsInFace;
247  result = -1;
248  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
249  if (numPointsInFace < 1)
250  {
251  // An invalid face. We should already have gotten an error from
252  // CellFaceNumberOfPoints.
254  }
255 
256  detail::CellFaceTables table;
257  result = table.PointsInFace(shape.Id, faceIndex, pointIndex);
259 }
260 
271 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
272 static inline VTKM_EXEC vtkm::ErrorCode CellFaceCanonicalId(
273  vtkm::IdComponent faceIndex,
274  CellShapeTag shape,
275  const GlobalPointIndicesVecType& globalPointIndicesVec,
276  vtkm::Id3& result)
277 {
278  vtkm::IdComponent numPointsInFace;
279  result = { -1 };
280  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
281  if (numPointsInFace < 1)
282  {
283  // An invalid face. We should already have gotten an error from
284  // CellFaceNumberOfPoints.
286  }
287 
288  detail::CellFaceTables table;
289  //Sort the first 3 face points/nodes in ascending order
290  result = vtkm::Id3(globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)],
291  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)],
292  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)]);
293  vtkm::Id temp;
294  if (result[0] > result[2])
295  {
296  temp = result[0];
297  result[0] = result[2];
298  result[2] = temp;
299  }
300  if (result[0] > result[1])
301  {
302  temp = result[0];
303  result[0] = result[1];
304  result[1] = temp;
305  }
306  if (result[1] > result[2])
307  {
308  temp = result[1];
309  result[1] = result[2];
310  result[2] = temp;
311  }
312 
313  // Check the rest of the points to see if they are in the lowest 3
314  for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
315  {
316  vtkm::Id nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
317  if (nextPoint < result[2])
318  {
319  if (nextPoint < result[1])
320  {
321  result[2] = result[1];
322  if (nextPoint < result[0])
323  {
324  result[1] = result[0];
325  result[0] = nextPoint;
326  }
327  else // nextPoint > P0, nextPoint < P1
328  {
329  result[1] = nextPoint;
330  }
331  }
332  else // nextPoint > P1, nextPoint < P2
333  {
334  result[2] = nextPoint;
335  }
336  }
337  else // nextPoint > P2
338  {
339  // Do nothing. nextPoint not in top 3.
340  }
341  }
342 
344 }
345 
349 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
350 static inline VTKM_EXEC vtkm::ErrorCode CellFaceMinPointId(
351  vtkm::IdComponent faceIndex,
352  CellShapeTag shape,
353  const GlobalPointIndicesVecType& globalPointIndicesVec,
354  vtkm::Id& minFacePointId)
355 {
356  vtkm::IdComponent numPointsInFace;
357  minFacePointId = { -1 };
358  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
359  if (numPointsInFace < 1)
360  {
361  // An invalid face. We should already have gotten an error from
362  // CellFaceNumberOfPoints.
364  }
365 
366  detail::CellFaceTables table;
367  minFacePointId = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)];
368  vtkm::Id nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)];
369  if (nextPoint < minFacePointId)
370  {
371  minFacePointId = nextPoint;
372  }
373  nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)];
374  if (nextPoint < minFacePointId)
375  {
376  minFacePointId = nextPoint;
377  }
378 
379  // Check the rest of the points to see if they are in the lowest 3
380  for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
381  {
382  nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
383  if (nextPoint < minFacePointId)
384  {
385  minFacePointId = nextPoint;
386  }
387  }
388 
390 }
391 }
392 } // namespace vtkm::exec
393 
394 #endif //vtk_m_exec_CellFace_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::CELL_SHAPE_EMPTY
@ CELL_SHAPE_EMPTY
Placeholder for empty or invalid cells.
Definition: CellShape.h:37
CellShape.h
vtkm::ErrorCode::InvalidFaceId
@ InvalidFaceId
A bad face identifier was detected while operating on a cell.
ErrorCode.h
FunctorBase.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:169
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
A triangle.
Definition: CellShape.h:48
vtkm::Id3
vtkm::Vec< vtkm::Id, 3 > Id3
Id3 corresponds to a 3-dimensional index for 3d arrays.
Definition: Types.h:1044
vtkm::Vec< vtkm::Id, 3 >
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
vtkm::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
A general polygon shape.
Definition: CellShape.h:53
vtkm::CELL_SHAPE_QUAD
@ CELL_SHAPE_QUAD
A four-sided polygon.
Definition: CellShape.h:56