Viskores  1.0
CellEdge.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_CellEdge_h
19 #define viskores_exec_CellEdge_h
20 
21 #include <viskores/CellShape.h>
22 #include <viskores/CellTraits.h>
23 #include <viskores/ErrorCode.h>
24 #include <viskores/Types.h>
26 
27 namespace viskores
28 {
29 namespace exec
30 {
31 
32 namespace detail
33 {
34 
35 class CellEdgeTables
36 {
37 public:
38  static constexpr viskores::Int32 MAX_NUM_EDGES = 12;
39 
40 public:
41  VISKORES_EXEC viskores::Int32 NumEdges(viskores::Int32 cellShapeId) const
42  {
44  // NumEdges
45  0, // 0: CELL_SHAPE_EMPTY
46  0, // 1: CELL_SHAPE_VERTEX
47  0, // 2: Unused
48  0, // 3: CELL_SHAPE_LINE
49  0, // 4: CELL_SHAPE_POLY_LINE
50  3, // 5: CELL_SHAPE_TRIANGLE
51  0, // 6: Unused
52  -1, // 7: CELL_SHAPE_POLYGON ---special case---
53  0, // 8: Unused
54  4, // 9: CELL_SHAPE_QUAD
55  6, // 10: CELL_SHAPE_TETRA
56  0, // 11: Unused
57  12, // 12: CELL_SHAPE_HEXAHEDRON
58  9, // 13: CELL_SHAPE_WEDGE
59  8 // 14: CELL_SHAPE_PYRAMID
60  };
61  return numEdges[cellShapeId];
62  }
63 
64  VISKORES_EXEC viskores::Int32 PointsInEdge(viskores::Int32 cellShapeId,
65  viskores::Int32 edgeIndex,
66  viskores::Int32 localPointIndex) const
67  {
69  pointsInEdge[viskores::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2] = {
70  // clang-format off
71  // 0: CELL_SHAPE_EMPTY
72  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
73  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
74  // 1: CELL_SHAPE_VERTEX
75  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
76  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
77  // 2: Unused
78  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
79  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
80  // 3: CELL_SHAPE_LINE
81  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
82  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
83  // 4: CELL_SHAPE_POLY_LINE
84  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
85  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
86  // 5: CELL_SHAPE_TRIANGLE
87  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
88  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
89  // 6: Unused
90  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
91  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
92  // 7: CELL_SHAPE_POLYGON --- special case ---
93  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
94  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
95  // 8: Unused
96  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
97  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
98  // 9: CELL_SHAPE_QUAD
99  { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { -1, -1 }, { -1, -1 },
100  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
101  // 10: CELL_SHAPE_TETRA
102  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 },
103  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
104  // 11: Unused
105  { { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
106  { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
107  // 12: CELL_SHAPE_HEXAHEDRON
108  { { 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 },
109  { 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 3, 7 }, { 2, 6 } },
110  // 13: CELL_SHAPE_WEDGE
111  { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 3, 4 }, { 4, 5 }, { 5, 3 },
112  { 0, 3 }, { 1, 4 }, { 2, 5 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
113  // 14: CELL_SHAPE_PYRAMID
114  { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 },
115  { 2, 4 }, { 3, 4 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } }
116  // clang-format on
117  };
118 
119  return pointsInEdge[cellShapeId][edgeIndex][localPointIndex];
120  }
121 };
122 
123 } // namespace detail
124 
125 template <typename CellShapeTag>
126 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeNumberOfEdges(
127  viskores::IdComponent numPoints,
128  CellShapeTag,
129  viskores::IdComponent& numEdges)
130 {
132  {
133  numEdges = -1;
135  }
136  numEdges = detail::CellEdgeTables{}.NumEdges(CellShapeTag::Id);
138 }
139 
140 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeNumberOfEdges(
141  viskores::IdComponent numPoints,
143  viskores::IdComponent& numEdges)
144 {
145  if (numPoints <= 0)
146  {
147  numEdges = -1;
149  }
150  numEdges = numPoints;
152 }
153 
154 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeNumberOfEdges(
155  viskores::IdComponent numPoints,
157  viskores::IdComponent& numEdges)
158 {
159  if (numPoints <= 0)
160  {
161  numEdges = -1;
163  }
164  numEdges = detail::CellEdgeTables{}.NumEdges(viskores::CELL_SHAPE_POLY_LINE);
166 }
167 
174 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeNumberOfEdges(
175  viskores::IdComponent numPoints,
177  viskores::IdComponent& numEdges)
178 {
179  if (shape.Id == viskores::CELL_SHAPE_POLYGON)
180  {
181  return CellEdgeNumberOfEdges(numPoints, viskores::CellShapeTagPolygon(), numEdges);
182  }
183  else if (shape.Id == viskores::CELL_SHAPE_POLY_LINE)
184  {
185  return CellEdgeNumberOfEdges(numPoints, viskores::CellShapeTagPolyLine(), numEdges);
186  }
187  else
188  {
189  numEdges = detail::CellEdgeTables{}.NumEdges(shape.Id);
191  }
192 }
193 
194 template <typename CellShapeTag>
195 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeLocalIndex(viskores::IdComponent numPoints,
196  viskores::IdComponent pointIndex,
197  viskores::IdComponent edgeIndex,
198  CellShapeTag shape,
199  viskores::IdComponent& result)
200 {
201  if ((pointIndex < 0) || (pointIndex > 1))
202  {
203  result = -1;
205  }
206  if ((edgeIndex < 0) || (edgeIndex >= detail::CellEdgeTables::MAX_NUM_EDGES))
207  {
208  result = -1;
210  }
211 
212  viskores::IdComponent numEdges;
213  VISKORES_RETURN_ON_ERROR(viskores::exec::CellEdgeNumberOfEdges(numPoints, shape, numEdges));
214  if (edgeIndex >= numEdges)
215  {
216  result = -1;
218  }
219 
220  detail::CellEdgeTables table;
221  result = table.PointsInEdge(CellShapeTag::Id, edgeIndex, pointIndex);
223 }
224 
225 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeLocalIndex(viskores::IdComponent numPoints,
226  viskores::IdComponent pointIndex,
227  viskores::IdComponent edgeIndex,
229  viskores::IdComponent& result)
230 {
231  if (numPoints < 3)
232  {
233  result = -1;
235  }
236  if ((pointIndex < 0) || (pointIndex > 1))
237  {
238  result = -1;
240  }
241  if ((edgeIndex < 0) || (edgeIndex >= numPoints))
242  {
243  result = -1;
245  }
246 
247  if (edgeIndex + pointIndex < numPoints)
248  {
249  result = edgeIndex + pointIndex;
250  }
251  else
252  {
253  result = 0;
254  }
256 }
257 
270 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeLocalIndex(
271  viskores::IdComponent numPoints,
272  viskores::IdComponent pointIndex,
273  viskores::IdComponent edgeIndex,
275  viskores::IdComponent& result)
276 {
277  if ((pointIndex < 0) || (pointIndex > 1))
278  {
279  result = -1;
281  }
282  if ((edgeIndex < 0) || (edgeIndex >= detail::CellEdgeTables::MAX_NUM_EDGES))
283  {
284  result = -1;
286  }
287 
288  if (shape.Id == viskores::CELL_SHAPE_POLYGON)
289  {
290  return CellEdgeLocalIndex(
291  numPoints, pointIndex, edgeIndex, viskores::CellShapeTagPolygon(), result);
292  }
293  else
294  {
295  detail::CellEdgeTables table;
296  if (edgeIndex >= table.NumEdges(shape.Id))
297  {
298  result = -1;
300  }
301 
302  result = table.PointsInEdge(shape.Id, edgeIndex, pointIndex);
304  }
305 }
306 
313 template <typename CellShapeTag, typename GlobalPointIndicesVecType>
314 static inline VISKORES_EXEC viskores::ErrorCode CellEdgeCanonicalId(
315  viskores::IdComponent numPoints,
316  viskores::IdComponent edgeIndex,
317  CellShapeTag shape,
318  const GlobalPointIndicesVecType& globalPointIndicesVec,
319  viskores::Id2& result)
320 {
321  result = { -1, -1 };
322 
323  viskores::IdComponent localIndex0;
325  viskores::exec::CellEdgeLocalIndex(numPoints, 0, edgeIndex, shape, localIndex0));
326  viskores::Id pointIndex0 = globalPointIndicesVec[localIndex0];
327 
328  viskores::IdComponent localIndex1;
330  viskores::exec::CellEdgeLocalIndex(numPoints, 1, edgeIndex, shape, localIndex1));
331  viskores::Id pointIndex1 = globalPointIndicesVec[localIndex1];
332 
333  if (pointIndex0 < pointIndex1)
334  {
335  result = viskores::Id2(pointIndex0, pointIndex1);
336  }
337  else
338  {
339  result = viskores::Id2(pointIndex1, pointIndex0);
340  }
341 
343 }
344 
345 }
346 } // namespace viskores::exec
347 
348 #endif //viskores_exec_CellFaces_h
viskores::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
A general polygon shape.
Definition: CellShape.h:61
viskores::Id2
viskores::Vec< viskores::Id, 2 > Id2
Id2 corresponds to a 2-dimensional index.
Definition: Types.h:935
viskores::CellShapeTagGeneric::Id
viskores::UInt8 Id
An identifier that corresponds to one of the CELL_SHAPE_* identifiers.
Definition: CellShape.h:188
Types.h
viskores::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:36
viskores::ErrorCode::InvalidEdgeId
@ InvalidEdgeId
A bad edge identifier was detected while operating on a cell.
viskores::ErrorCode::InvalidNumberOfPoints
@ InvalidNumberOfPoints
The wrong number of points was provided for a given cell type.
viskores::ErrorCode::InvalidPointId
@ InvalidPointId
A bad point identifier was detected while operating on a cell.
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
CellShape.h
viskores::CellShapeTagGeneric
A special cell shape tag that holds a cell shape that is not known at compile time.
Definition: CellShape.h:178
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
FunctorBase.h
VISKORES_STATIC_CONSTEXPR_ARRAY
#define VISKORES_STATIC_CONSTEXPR_ARRAY
Definition: ExportMacros.h:115
viskores::CellTraits
Information about a cell based on its tag.
Definition: CellTraits.h:54
viskores::Int32
int32_t Int32
Base type to use for 32-bit signed integer numbers.
Definition: Types.h:189
viskores::CellShapeTagPolygon
Definition: CellShape.h:162
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::CellShapeTagPolyLine
Definition: CellShape.h:159
viskores::NUMBER_OF_CELL_SHAPES
@ NUMBER_OF_CELL_SHAPES
Definition: CellShape.h:78
CellTraits.h
viskores::Vec< viskores::Id, 2 >
viskores::CELL_SHAPE_POLY_LINE
@ CELL_SHAPE_POLY_LINE
A sequence of line segments.
Definition: CellShape.h:54
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59