Viskores  1.0
CellFace.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_exec_CellFace_h
19 #define viskores_exec_CellFace_h
20 
21 #include <viskores/CellShape.h>
22 #include <viskores/ErrorCode.h>
23 #include <viskores/Types.h>
25 
26 namespace viskores
27 {
28 namespace exec
29 {
30 
31 namespace detail
32 {
33 
34 class CellFaceTables
35 {
36 public:
37  static constexpr viskores::Int32 MAX_FACE_SIZE = 4;
38  static constexpr viskores::Int32 MAX_NUM_FACES = 6;
39 
40  VISKORES_EXEC viskores::Int32 NumFaces(viskores::Int32 cellShapeId) const
41  {
43  // NumFaces
44  0, // 0: CELL_SHAPE_EMPTY
45  0, // 1: CELL_SHAPE_VERTEX
46  0, // 2: Unused
47  0, // 3: CELL_SHAPE_LINE
48  0, // 4: CELL_SHAPE_POLY_LINE
49  0, // 5: CELL_SHAPE_TRIANGLE
50  0, // 6: Unused
51  0, // 7: CELL_SHAPE_POLYGON
52  0, // 8: Unused
53  0, // 9: CELL_SHAPE_QUAD
54  4, // 10: CELL_SHAPE_TETRA
55  0, // 11: Unused
56  6, // 12: CELL_SHAPE_HEXAHEDRON
57  5, // 13: CELL_SHAPE_WEDGE
58  5 // 14: CELL_SHAPE_PYRAMID
59  };
60  return numFaces[cellShapeId];
61  }
62 
63  VISKORES_EXEC viskores::Int32 NumPointsInFace(viskores::Int32 cellShapeId,
64  viskores::Int32 faceIndex) const
65  {
67  numPointsInFace[viskores::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES] = {
68  // NumPointsInFace
69  { -1, -1, -1, -1, -1, -1 }, // 0: CELL_SHAPE_EMPTY
70  { -1, -1, -1, -1, -1, -1 }, // 1: CELL_SHAPE_VERTEX
71  { -1, -1, -1, -1, -1, -1 }, // 2: Unused
72  { -1, -1, -1, -1, -1, -1 }, // 3: CELL_SHAPE_LINE
73  { -1, -1, -1, -1, -1, -1 }, // 4: CELL_SHAPE_POLY_LINE
74  { -1, -1, -1, -1, -1, -1 }, // 5: CELL_SHAPE_TRIANGLE
75  { -1, -1, -1, -1, -1, -1 }, // 6: Unused
76  { -1, -1, -1, -1, -1, -1 }, // 7: CELL_SHAPE_POLYGON
77  { -1, -1, -1, -1, -1, -1 }, // 8: Unused
78  { -1, -1, -1, -1, -1, -1 }, // 9: CELL_SHAPE_QUAD
79  { 3, 3, 3, 3, -1, -1 }, // 10: CELL_SHAPE_TETRA
80  { -1, -1, -1, -1, -1, -1 }, // 11: Unused
81  { 4, 4, 4, 4, 4, 4 }, // 12: CELL_SHAPE_HEXAHEDRON
82  { 3, 3, 4, 4, 4, -1 }, // 13: CELL_SHAPE_WEDGE
83  { 4, 3, 3, 3, 3, -1 } // 14: CELL_SHAPE_PYRAMID
84  };
85  return numPointsInFace[cellShapeId][faceIndex];
86  }
87 
88  VISKORES_EXEC viskores::Int32 PointsInFace(viskores::Int32 cellShapeId,
89  viskores::Int32 faceIndex,
90  viskores::Int32 localPointIndex) const
91  {
92  // clang-format off
94  [MAX_FACE_SIZE] =
95  {
96  // PointsInFace
97  // 0: CELL_SHAPE_EMPTY
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  // 1: CELL_SHAPE_VERTEX
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  // 2: Unused
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  // 3: CELL_SHAPE_LINE
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  // 4: CELL_SHAPE_POLY_LINE
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  // 5: CELL_SHAPE_TRIANGLE
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  // 6: Unused
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  // 7: CELL_SHAPE_POLYGON
119  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
120  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
121  // 8: 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  // 9: CELL_SHAPE_QUAD
125  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
126  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
127  // 10: CELL_SHAPE_TETRA
128  { { 0, 1, 3, -1 }, { 1, 2, 3, -1 }, { 2, 0, 3, -1 },
129  { 0, 2, 1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
130  // 11: Unused
131  { { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
132  { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
133  // 12: CELL_SHAPE_HEXAHEDRON
134  { { 0, 4, 7, 3 }, { 1, 2, 6, 5 }, { 0, 1, 5, 4 },
135  { 3, 7, 6, 2 }, { 0, 3, 2, 1 }, { 4, 5, 6, 7 } },
136  // 13: CELL_SHAPE_WEDGE
137  { { 0, 1, 2, -1 }, { 3, 5, 4, -1 }, { 0, 3, 4, 1 },
138  { 1, 4, 5, 2 }, { 2, 5, 3, 0 }, { -1, -1, -1, -1 } },
139  // 14: CELL_SHAPE_PYRAMID
140  { { 0, 3, 2, 1 }, { 0, 1, 4, -1 }, { 1, 2, 4, -1 },
141  { 2, 3, 4, -1 }, { 3, 0, 4, -1 },{ -1, -1, -1, -1 } }
142  // clang-format on
143  };
144  return pointsInFace[cellShapeId][faceIndex][localPointIndex];
145  }
146 };
147 
148 } // namespace detail
149 
155 template <typename CellShapeTag>
156 static inline VISKORES_EXEC viskores::ErrorCode CellFaceNumberOfFaces(CellShapeTag shape,
157  viskores::IdComponent& result)
158 {
159  (void)shape; //C4100 false positive workaround
160  detail::CellFaceTables table;
161  result = table.NumFaces(shape.Id);
163 }
164 
174 template <typename CellShapeTag>
175 static inline VISKORES_EXEC viskores::ErrorCode CellFaceNumberOfPoints(
176  viskores::IdComponent faceIndex,
177  CellShapeTag shape,
178  viskores::IdComponent& result)
179 {
180  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
181  {
182  result = -1;
184  }
185 
186  viskores::IdComponent numFaces;
187  VISKORES_RETURN_ON_ERROR(viskores::exec::CellFaceNumberOfFaces(shape, numFaces));
188  if (faceIndex >= numFaces)
189  {
190  result = -1;
192  }
193  detail::CellFaceTables table;
194  result = table.NumPointsInFace(shape.Id, faceIndex);
196 }
197 
210 template <typename CellShapeTag>
211 static inline VISKORES_EXEC viskores::ErrorCode CellFaceShape(viskores::IdComponent faceIndex,
212  CellShapeTag shape,
213  viskores::UInt8& result)
214 {
215 
216  if ((faceIndex < 0) || (faceIndex >= detail::CellFaceTables::MAX_NUM_FACES))
217  {
220  }
221 
222  viskores::IdComponent numFacePoints;
223  VISKORES_RETURN_ON_ERROR(CellFaceNumberOfPoints(faceIndex, shape, numFacePoints));
224  switch (numFacePoints)
225  {
226  case 3:
228  break;
229  case 4:
230  result = viskores::CELL_SHAPE_QUAD;
231  break;
232  default:
234  break;
235  }
237 }
238 
250 template <typename CellShapeTag>
251 static inline VISKORES_EXEC viskores::ErrorCode CellFaceLocalIndex(viskores::IdComponent pointIndex,
252  viskores::IdComponent faceIndex,
253  CellShapeTag shape,
254  viskores::IdComponent& result)
255 {
256  viskores::IdComponent numPointsInFace;
257  result = -1;
259  viskores::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
260  if (numPointsInFace < 1)
261  {
262  // An invalid face. We should already have gotten an error from
263  // CellFaceNumberOfPoints.
265  }
266 
267  detail::CellFaceTables table;
268  result = table.PointsInFace(shape.Id, faceIndex, pointIndex);
270 }
271 
282 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
283 static inline VISKORES_EXEC viskores::ErrorCode CellFaceCanonicalId(
284  viskores::IdComponent faceIndex,
285  CellShapeTag shape,
286  const GlobalPointIndicesVecType& globalPointIndicesVec,
287  viskores::Id3& result)
288 {
289  viskores::IdComponent numPointsInFace;
290  result = { -1 };
292  viskores::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
293  if (numPointsInFace < 1)
294  {
295  // An invalid face. We should already have gotten an error from
296  // CellFaceNumberOfPoints.
298  }
299 
300  detail::CellFaceTables table;
301  //Sort the first 3 face points/nodes in ascending order
302  result = viskores::Id3(globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)],
303  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)],
304  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)]);
305  viskores::Id temp;
306  if (result[0] > result[2])
307  {
308  temp = result[0];
309  result[0] = result[2];
310  result[2] = temp;
311  }
312  if (result[0] > result[1])
313  {
314  temp = result[0];
315  result[0] = result[1];
316  result[1] = temp;
317  }
318  if (result[1] > result[2])
319  {
320  temp = result[1];
321  result[1] = result[2];
322  result[2] = temp;
323  }
324 
325  // Check the rest of the points to see if they are in the lowest 3
326  for (viskores::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
327  {
328  viskores::Id nextPoint =
329  globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
330  if (nextPoint < result[2])
331  {
332  if (nextPoint < result[1])
333  {
334  result[2] = result[1];
335  if (nextPoint < result[0])
336  {
337  result[1] = result[0];
338  result[0] = nextPoint;
339  }
340  else // nextPoint > P0, nextPoint < P1
341  {
342  result[1] = nextPoint;
343  }
344  }
345  else // nextPoint > P1, nextPoint < P2
346  {
347  result[2] = nextPoint;
348  }
349  }
350  else // nextPoint > P2
351  {
352  // Do nothing. nextPoint not in top 3.
353  }
354  }
355 
357 }
358 
362 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
363 static inline VISKORES_EXEC viskores::ErrorCode CellFaceMinPointId(
364  viskores::IdComponent faceIndex,
365  CellShapeTag shape,
366  const GlobalPointIndicesVecType& globalPointIndicesVec,
367  viskores::Id& minFacePointId)
368 {
369  viskores::IdComponent numPointsInFace;
370  minFacePointId = { -1 };
372  viskores::exec::CellFaceNumberOfPoints(faceIndex, shape, numPointsInFace));
373  if (numPointsInFace < 1)
374  {
375  // An invalid face. We should already have gotten an error from
376  // CellFaceNumberOfPoints.
378  }
379 
380  detail::CellFaceTables table;
381  minFacePointId = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)];
382  viskores::Id nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)];
383  if (nextPoint < minFacePointId)
384  {
385  minFacePointId = nextPoint;
386  }
387  nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)];
388  if (nextPoint < minFacePointId)
389  {
390  minFacePointId = nextPoint;
391  }
392 
393  // Check the rest of the points to see if they are in the lowest 3
394  for (viskores::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
395  {
396  nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
397  if (nextPoint < minFacePointId)
398  {
399  minFacePointId = nextPoint;
400  }
401  }
402 
404 }
405 }
406 } // namespace viskores::exec
407 
408 #endif //viskores_exec_CellFace_h
viskores::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
A general polygon shape.
Definition: CellShape.h:61
viskores::ErrorCode::InvalidFaceId
@ InvalidFaceId
A bad face identifier was detected while operating on a cell.
Types.h
viskores::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:36
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
CellShape.h
ErrorCode.h
VISKORES_RETURN_ON_ERROR
#define VISKORES_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:210
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
A triangle.
Definition: CellShape.h:56
FunctorBase.h
VISKORES_STATIC_CONSTEXPR_ARRAY
#define VISKORES_STATIC_CONSTEXPR_ARRAY
Definition: ExportMacros.h:115
viskores::CELL_SHAPE_EMPTY
@ CELL_SHAPE_EMPTY
Placeholder for empty or invalid cells.
Definition: CellShape.h:45
viskores::Id3
viskores::Vec< viskores::Id, 3 > Id3
Id3 corresponds to a 3-dimensional index for 3d arrays.
Definition: Types.h:1053
viskores::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:177
viskores::Int32
int32_t Int32
Base type to use for 32-bit signed integer numbers.
Definition: Types.h:189
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::CELL_SHAPE_QUAD
@ CELL_SHAPE_QUAD
A four-sided polygon.
Definition: CellShape.h:64
viskores::NUMBER_OF_CELL_SHAPES
@ NUMBER_OF_CELL_SHAPES
Definition: CellShape.h:78
viskores::Vec< viskores::Id, 3 >
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59