VTK-m  2.0
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 
141 template <typename CellShapeTag>
142 static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfFaces(CellShapeTag shape,
143  vtkm::IdComponent& result)
144 {
145  (void)shape; //C4100 false positive workaround
146  detail::CellFaceTables table;
147  result = table.NumFaces(shape.Id);
149 }
150 
151 template <typename CellShapeTag>
152 static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfPoints(vtkm::IdComponent faceIndex,
153  CellShapeTag shape,
154  vtkm::IdComponent& result)
155 {
156  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
157  {
158  result = -1;
160  }
161 
162  vtkm::IdComponent numFaces;
163  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfFaces(shape, numFaces));
164  if (faceIndex >= numFaces)
165  {
166  result = -1;
168  }
169  detail::CellFaceTables table;
170  result = table.NumPointsInFace(shape.Id, faceIndex);
172 }
173 
174 template <typename CellShapeTag>
175 static inline VTKM_EXEC vtkm::ErrorCode CellFaceShape(vtkm::IdComponent faceIndex,
176  CellShapeTag shape,
177  vtkm::UInt8& result)
178 {
179 
180  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
181  {
182  result = vtkm::CELL_SHAPE_EMPTY;
184  }
185 
186  vtkm::IdComponent numFacePoints;
187  VTKM_RETURN_ON_ERROR(CellFaceNumberOfPoints(faceIndex, shape, numFacePoints));
188  switch (numFacePoints)
189  {
190  case 3:
191  result = vtkm::CELL_SHAPE_TRIANGLE;
192  break;
193  case 4:
194  result = vtkm::CELL_SHAPE_QUAD;
195  break;
196  default:
197  result = vtkm::CELL_SHAPE_POLYGON;
198  break;
199  }
201 }
202 
203 template <typename CellShapeTag>
204 static inline VTKM_EXEC vtkm::ErrorCode CellFaceLocalIndex(vtkm::IdComponent pointIndex,
205  vtkm::IdComponent faceIndex,
206  CellShapeTag shape,
207  vtkm::IdComponent& result)
208 {
209  vtkm::IdComponent numPointsInFace;
210  result = -1;
211  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
212  if (numPointsInFace < 1)
213  {
214  // An invalid face. We should already have gotten an error from
215  // CellFaceNumberOfPoints.
217  }
218 
219  detail::CellFaceTables table;
220  result = table.PointsInFace(shape.Id, faceIndex, pointIndex);
222 }
223 
234 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
235 static inline VTKM_EXEC vtkm::ErrorCode CellFaceCanonicalId(
236  vtkm::IdComponent faceIndex,
237  CellShapeTag shape,
238  const GlobalPointIndicesVecType& globalPointIndicesVec,
239  vtkm::Id3& result)
240 {
241  vtkm::IdComponent numPointsInFace;
242  result = { -1 };
243  VTKM_RETURN_ON_ERROR(vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
244  if (numPointsInFace == 0)
245  {
246  // An invalid face. We should already have gotten an error from
247  // CellFaceNumberOfPoints.
249  }
250 
251  detail::CellFaceTables table;
252  //Sort the first 3 face points/nodes in ascending order
253  result = vtkm::Id3(globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)],
254  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)],
255  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)]);
256  vtkm::Id temp;
257  if (result[0] > result[2])
258  {
259  temp = result[0];
260  result[0] = result[2];
261  result[2] = temp;
262  }
263  if (result[0] > result[1])
264  {
265  temp = result[0];
266  result[0] = result[1];
267  result[1] = temp;
268  }
269  if (result[1] > result[2])
270  {
271  temp = result[1];
272  result[1] = result[2];
273  result[2] = temp;
274  }
275 
276  // Check the rest of the points to see if they are in the lowest 3
277  for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
278  {
279  vtkm::Id nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
280  if (nextPoint < result[2])
281  {
282  if (nextPoint < result[1])
283  {
284  result[2] = result[1];
285  if (nextPoint < result[0])
286  {
287  result[1] = result[0];
288  result[0] = nextPoint;
289  }
290  else // nextPoint > P0, nextPoint < P1
291  {
292  result[1] = nextPoint;
293  }
294  }
295  else // nextPoint > P1, nextPoint < P2
296  {
297  result[2] = nextPoint;
298  }
299  }
300  else // nextPoint > P2
301  {
302  // Do nothing. nextPoint not in top 3.
303  }
304  }
305 
307 }
308 
309 }
310 } // namespace vtkm::exec
311 
312 #endif //vtk_m_exec_CellFace_h
vtkm::ErrorCode
ErrorCode
Definition: ErrorCode.h:19
vtkm::NUMBER_OF_CELL_SHAPES
@ NUMBER_OF_CELL_SHAPES
Definition: CellShape.h:52
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
Represents a component ID (index of component in a vector).
Definition: Types.h:168
VTKM_STATIC_CONSTEXPR_ARRAY
#define VTKM_STATIC_CONSTEXPR_ARRAY
Definition: ExportMacros.h:107
vtkm::ErrorCode::Success
@ Success
vtkm::CELL_SHAPE_EMPTY
@ CELL_SHAPE_EMPTY
Definition: CellShape.h:36
CellShape.h
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::ErrorCode::InvalidFaceId
@ InvalidFaceId
ErrorCode.h
FunctorBase.h
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
Definition: CellShape.h:41
vtkm::Id3
vtkm::Vec< vtkm::Id, 3 > Id3
Id3 corresponds to a 3-dimensional index for 3d arrays.
Definition: Types.h:1003
vtkm::Vec< vtkm::Id, 3 >
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:111
vtkm::Int32
int32_t Int32
Definition: Types.h:160
vtkm::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
Definition: CellShape.h:43
vtkm::CELL_SHAPE_QUAD
@ CELL_SHAPE_QUAD
Definition: CellShape.h:45