VTK-m uses static const/constexpr when supported ( so not on cuda 7.5 )

These changes now allow VTK-m to compile on CUDA 7.5 by using const arrays,
when compiling with CUDA 8+ support we upgrade to static const arrays, and
lastly when CUDA is disabled we fully elevate to static constexpr.
This commit is contained in:
Robert Maynard 2018-02-21 14:51:15 -05:00
parent 505e7aa1ec
commit 601a839d5d
17 changed files with 665 additions and 843 deletions

@ -25,6 +25,7 @@
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
#include <vtkm/internal/ExportMacros.h>
namespace vtkm
{
@ -56,6 +57,18 @@ struct VecAxisAlignedPointCoordinatesNumComponents<3>
static const vtkm::IdComponent NUM_COMPONENTS = 8;
};
struct VecAxisAlignedPointCoordinatesOffsetTable
{
VTKM_EXEC_CONT vtkm::FloatDefault Get(vtkm::Int32 i, vtkm::Int32 j) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::FloatDefault offsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
return offsetTable[i][j];
}
};
} // namespace detail
/// \brief An implicit vector for point coordinates in axis aligned cells. For
@ -104,15 +117,10 @@ public:
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
static const vtkm::FloatDefault VecAxisAlignedPointCoordinatesOffsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
const auto& offset = VecAxisAlignedPointCoordinatesOffsetTable[index];
return ComponentType(this->Origin[0] + offset[0] * this->Spacing[0],
this->Origin[1] + offset[1] * this->Spacing[1],
this->Origin[2] + offset[2] * this->Spacing[2]);
detail::VecAxisAlignedPointCoordinatesOffsetTable table;
return ComponentType(this->Origin[0] + table.Get(index, 0) * this->Spacing[0],
this->Origin[1] + table.Get(index, 1) * this->Spacing[1],
this->Origin[2] + table.Get(index, 2) * this->Spacing[2]);
}
VTKM_EXEC_CONT

@ -59,7 +59,7 @@ VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value
const vtkm::Vec<ValueType, N>& value1,
const vtkm::Vec<ValueType, N>& weight)
{
static const vtkm::Vec<ValueType, N> One(ValueType(1));
const vtkm::Vec<ValueType, N> One(ValueType(1));
return (One - weight) * value0 + weight * value1;
}

@ -38,237 +38,86 @@ namespace detail
class CellEdgeTables
{
public:
static const vtkm::IdComponent MAX_NUM_EDGES = 12;
private:
struct Tables
{
vtkm::IdComponent NumEdges[vtkm::NUMBER_OF_CELL_SHAPES];
vtkm::IdComponent PointsInEdge[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2];
};
static constexpr vtkm::Int32 MAX_NUM_EDGES = 12;
public:
VTKM_EXEC_CONT static const Tables& Get()
VTKM_EXEC vtkm::Int32 NumEdges(vtkm::Int32 i) const
{
static const Tables table = { {
// NumEdges
0, // 0: CELL_SHAPE_EMPTY
0, // 1: CELL_SHAPE_VERTEX
0, // 2: Unused
0, // 3: CELL_SHAPE_LINE
0, // 4: Unused
3, // 5: CELL_SHAPE_TRIANGLE
0, // 6: Unused
-1, // 7: CELL_SHAPE_POLYGON ---special case---
0, // 8: Unused
4, // 9: CELL_SHAPE_QUAD
6, // 10: CELL_SHAPE_TETRA
0, // 11: Unused
12, // 12: CELL_SHAPE_HEXAHEDRON
9, // 13: CELL_SHAPE_WEDGE
8 // 14: CELL_SHAPE_PYRAMID
},
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 numEdges[vtkm::NUMBER_OF_CELL_SHAPES] = {
// NumEdges
0, // 0: CELL_SHAPE_EMPTY
0, // 1: CELL_SHAPE_VERTEX
0, // 2: Unused
0, // 3: CELL_SHAPE_LINE
0, // 4: Unused
3, // 5: CELL_SHAPE_TRIANGLE
0, // 6: Unused
-1, // 7: CELL_SHAPE_POLYGON ---special case---
0, // 8: Unused
4, // 9: CELL_SHAPE_QUAD
6, // 10: CELL_SHAPE_TETRA
0, // 11: Unused
12, // 12: CELL_SHAPE_HEXAHEDRON
9, // 13: CELL_SHAPE_WEDGE
8 // 14: CELL_SHAPE_PYRAMID
};
return numEdges[i];
}
{
// PointsInEdge
// 0: CELL_SHAPE_EMPTY
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 1: CELL_SHAPE_VERTEX
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 2: Unused
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 3: CELL_SHAPE_LINE
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 4: Unused
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 5: CELL_SHAPE_TRIANGLE
{ { 0, 1 },
{ 1, 2 },
{ 2, 0 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 6: Unused
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 7: CELL_SHAPE_POLYGON --- special case ---
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 8: Unused
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 9: CELL_SHAPE_QUAD
{ { 0, 1 },
{ 1, 2 },
{ 2, 3 },
{ 3, 0 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 10: CELL_SHAPE_TETRA
{ { 0, 1 },
{ 1, 2 },
{ 2, 0 },
{ 0, 3 },
{ 1, 3 },
{ 2, 3 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 11: Unused
{ { -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 12: CELL_SHAPE_HEXAHEDRON
{ { 0, 1 },
{ 1, 2 },
{ 3, 2 },
{ 0, 3 },
{ 4, 5 },
{ 5, 6 },
{ 7, 6 },
{ 4, 7 },
{ 0, 4 },
{ 1, 5 },
{ 3, 7 },
{ 2, 6 } },
// 13: CELL_SHAPE_WEDGE
{ { 0, 1 },
{ 1, 2 },
{ 2, 0 },
{ 3, 4 },
{ 4, 5 },
{ 5, 3 },
{ 0, 3 },
{ 1, 4 },
{ 2, 5 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
// 14: CELL_SHAPE_PYRAMID
{ { 0, 1 },
{ 1, 2 },
{ 2, 3 },
{ 3, 0 },
{ 0, 4 },
{ 1, 4 },
{ 2, 4 },
{ 3, 4 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 },
{ -1, -1 } },
} };
VTKM_EXEC vtkm::Int32 PointsInEdge(vtkm::Int32 i, vtkm::Int32 j, vtkm::Int32 k) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32
pointsInEdge[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_EDGES][2] = {
// clang-format off
// 0: CELL_SHAPE_EMPTY
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 1: CELL_SHAPE_VERTEX
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 2: Unused
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 3: CELL_SHAPE_LINE
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 4: Unused
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 5: CELL_SHAPE_TRIANGLE
{ { 0, 1 }, { 1, 2 }, { 2, 0 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 6: Unused
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 7: CELL_SHAPE_POLYGON --- special case ---
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 8: Unused
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 9: CELL_SHAPE_QUAD
{ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 10: CELL_SHAPE_TETRA
{ { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 11: Unused
{ { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 },
{ -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 12: CELL_SHAPE_HEXAHEDRON
{ { 0, 1 }, { 1, 2 }, { 3, 2 }, { 0, 3 }, { 4, 5 }, { 5, 6 },
{ 7, 6 }, { 4, 7 }, { 0, 4 }, { 1, 5 }, { 3, 7 }, { 2, 6 } },
// 13: CELL_SHAPE_WEDGE
{ { 0, 1 }, { 1, 2 }, { 2, 0 }, { 3, 4 }, { 4, 5 }, { 5, 3 },
{ 0, 3 }, { 1, 4 }, { 2, 5 }, { -1, -1 }, { -1, -1 }, { -1, -1 } },
// 14: CELL_SHAPE_PYRAMID
{ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 },
{ 2, 4 }, { 3, 4 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 } }
// clang-format on
};
return table;
return pointsInEdge[i][j][k];
}
};
@ -281,7 +130,7 @@ static inline VTKM_EXEC vtkm::IdComponent CellEdgeNumberOfEdges(vtkm::IdComponen
{
(void)numPoints; // Silence compiler warnings.
VTKM_ASSERT(numPoints == vtkm::CellTraits<CellShapeTag>::NUM_POINTS);
return detail::CellEdgeTables::Get().NumEdges[CellShapeTag::Id];
return detail::CellEdgeTables{}.NumEdges(CellShapeTag::Id);
}
static inline VTKM_EXEC vtkm::IdComponent CellEdgeNumberOfEdges(vtkm::IdComponent numPoints,
@ -303,7 +152,7 @@ static inline VTKM_EXEC vtkm::IdComponent CellEdgeNumberOfEdges(
}
else
{
return detail::CellEdgeTables::Get().NumEdges[shape.Id];
return detail::CellEdgeTables{}.NumEdges(shape.Id);
}
}
@ -322,8 +171,9 @@ static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
return vtkm::Vec<vtkm::IdComponent, 2>(0);
}
return vtkm::make_Vec(detail::CellEdgeTables::Get().PointsInEdge[CellShapeTag::Id][edgeIndex][0],
detail::CellEdgeTables::Get().PointsInEdge[CellShapeTag::Id][edgeIndex][1]);
detail::CellEdgeTables table;
return vtkm::make_Vec(table.PointsInEdge(CellShapeTag::Id, edgeIndex, 0),
table.PointsInEdge(CellShapeTag::Id, edgeIndex, 1));
}
static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
@ -361,14 +211,15 @@ static inline VTKM_EXEC vtkm::Vec<vtkm::IdComponent, 2> CellEdgeLocalIndices(
}
else
{
if (edgeIndex >= detail::CellEdgeTables::Get().NumEdges[shape.Id])
detail::CellEdgeTables table;
if (edgeIndex >= table.NumEdges(shape.Id))
{
worklet.RaiseError("Invalid edge number.");
return vtkm::Vec<vtkm::IdComponent, 2>(0);
}
return vtkm::make_Vec(detail::CellEdgeTables::Get().PointsInEdge[shape.Id][edgeIndex][0],
detail::CellEdgeTables::Get().PointsInEdge[shape.Id][edgeIndex][1]);
return vtkm::make_Vec(table.PointsInEdge(shape.Id, edgeIndex, 0),
table.PointsInEdge(shape.Id, edgeIndex, 1));
}
}

@ -37,168 +37,111 @@ namespace detail
class CellFaceTables
{
public:
static const vtkm::IdComponent MAX_FACE_SIZE = 4;
static const vtkm::IdComponent MAX_NUM_FACES = 6;
static constexpr vtkm::Int32 MAX_FACE_SIZE = 4;
static constexpr vtkm::Int32 MAX_NUM_FACES = 6;
private:
struct Tables
VTKM_EXEC vtkm::Int32 NumFaces(vtkm::Int32 i) const
{
vtkm::IdComponent NumFaces[vtkm::NUMBER_OF_CELL_SHAPES];
vtkm::IdComponent NumPointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES];
vtkm::IdComponent PointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES][MAX_FACE_SIZE];
};
public:
VTKM_EXEC_CONT
static const Tables& Get()
{
static const Tables table = { // NumFaces
{
0, // 0: CELL_SHAPE_EMPTY
0, // 1: CELL_SHAPE_VERTEX
0, // 2: Unused
0, // 3: CELL_SHAPE_LINE
0, // 4: Unused
0, // 5: CELL_SHAPE_TRIANGLE
0, // 6: Unused
0, // 7: CELL_SHAPE_POLYGON
0, // 8: Unused
0, // 9: CELL_SHAPE_QUAD
4, // 10: CELL_SHAPE_TETRA
0, // 11: Unused
6, // 12: CELL_SHAPE_HEXAHEDRON
5, // 13: CELL_SHAPE_WEDGE
5 // 14: CELL_SHAPE_PYRAMID
},
// NumPointsInFace
{
{ -1, -1, -1, -1, -1, -1 }, // 0: CELL_SHAPE_EMPTY
{ -1, -1, -1, -1, -1, -1 }, // 1: CELL_SHAPE_VERTEX
{ -1, -1, -1, -1, -1, -1 }, // 2: Unused
{ -1, -1, -1, -1, -1, -1 }, // 3: CELL_SHAPE_LINE
{ -1, -1, -1, -1, -1, -1 }, // 4: Unused
{ -1, -1, -1, -1, -1, -1 }, // 5: CELL_SHAPE_TRIANGLE
{ -1, -1, -1, -1, -1, -1 }, // 6: Unused
{ -1, -1, -1, -1, -1, -1 }, // 7: CELL_SHAPE_POLYGON
{ -1, -1, -1, -1, -1, -1 }, // 8: Unused
{ -1, -1, -1, -1, -1, -1 }, // 9: CELL_SHAPE_QUAD
{ 3, 3, 3, 3, -1, -1 }, // 10: CELL_SHAPE_TETRA
{ -1, -1, -1, -1, -1, -1 }, // 11: Unused
{ 4, 4, 4, 4, 4, 4 }, // 12: CELL_SHAPE_HEXAHEDRON
{ 3, 3, 4, 4, 4, -1 }, // 13: CELL_SHAPE_WEDGE
{ 4, 3, 3, 3, 3, -1 } // 14: CELL_SHAPE_PYRAMID
},
// PointsInFace
{ // 0: CELL_SHAPE_EMPTY
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 1: CELL_SHAPE_VERTEX
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 2: Unused
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 3: CELL_SHAPE_LINE
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 4: Unused
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 5: CELL_SHAPE_TRIANGLE
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 6: Unused
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 7: CELL_SHAPE_POLYGON
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 8: Unused
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 9: CELL_SHAPE_QUAD
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 10: CELL_SHAPE_TETRA
{ { 0, 1, 3, -1 },
{ 1, 2, 3, -1 },
{ 2, 0, 3, -1 },
{ 0, 2, 1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 11: Unused
{ { -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 },
{ -1, -1, -1, -1 } },
// 12: CELL_SHAPE_HEXAHEDRON
{ { 0, 4, 7, 3 },
{ 1, 2, 6, 5 },
{ 0, 1, 5, 4 },
{ 3, 7, 6, 2 },
{ 0, 3, 2, 1 },
{ 4, 5, 6, 7 } },
// 13: CELL_SHAPE_WEDGE
{ { 0, 1, 2, -1 },
{ 3, 5, 4, -1 },
{ 0, 3, 4, 1 },
{ 1, 4, 5, 2 },
{ 2, 5, 3, 0 },
{ -1, -1, -1, -1 } },
// 14: CELL_SHAPE_PYRAMID
{ { 0, 3, 2, 1 },
{ 0, 1, 4, -1 },
{ 1, 2, 4, -1 },
{ 2, 3, 4, -1 },
{ 3, 0, 4, -1 },
{ -1, -1, -1, -1 } } }
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 numFaces[vtkm::NUMBER_OF_CELL_SHAPES] = {
// NumFaces
0, // 0: CELL_SHAPE_EMPTY
0, // 1: CELL_SHAPE_VERTEX
0, // 2: Unused
0, // 3: CELL_SHAPE_LINE
0, // 4: Unused
0, // 5: CELL_SHAPE_TRIANGLE
0, // 6: Unused
0, // 7: CELL_SHAPE_POLYGON
0, // 8: Unused
0, // 9: CELL_SHAPE_QUAD
4, // 10: CELL_SHAPE_TETRA
0, // 11: Unused
6, // 12: CELL_SHAPE_HEXAHEDRON
5, // 13: CELL_SHAPE_WEDGE
5 // 14: CELL_SHAPE_PYRAMID
};
return numFaces[i];
}
return table;
VTKM_EXEC vtkm::Int32 NumPointsInFace(vtkm::Int32 i, vtkm::Int32 j) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32
numPointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES] = {
// NumPointsInFace
{ -1, -1, -1, -1, -1, -1 }, // 0: CELL_SHAPE_EMPTY
{ -1, -1, -1, -1, -1, -1 }, // 1: CELL_SHAPE_VERTEX
{ -1, -1, -1, -1, -1, -1 }, // 2: Unused
{ -1, -1, -1, -1, -1, -1 }, // 3: CELL_SHAPE_LINE
{ -1, -1, -1, -1, -1, -1 }, // 4: Unused
{ -1, -1, -1, -1, -1, -1 }, // 5: CELL_SHAPE_TRIANGLE
{ -1, -1, -1, -1, -1, -1 }, // 6: Unused
{ -1, -1, -1, -1, -1, -1 }, // 7: CELL_SHAPE_POLYGON
{ -1, -1, -1, -1, -1, -1 }, // 8: Unused
{ -1, -1, -1, -1, -1, -1 }, // 9: CELL_SHAPE_QUAD
{ 3, 3, 3, 3, -1, -1 }, // 10: CELL_SHAPE_TETRA
{ -1, -1, -1, -1, -1, -1 }, // 11: Unused
{ 4, 4, 4, 4, 4, 4 }, // 12: CELL_SHAPE_HEXAHEDRON
{ 3, 3, 4, 4, 4, -1 }, // 13: CELL_SHAPE_WEDGE
{ 4, 3, 3, 3, 3, -1 } // 14: CELL_SHAPE_PYRAMID
};
return numPointsInFace[i][j];
}
VTKM_EXEC vtkm::Int32 PointsInFace(vtkm::Int32 i, vtkm::Int32 j, vtkm::Int32 k) const
{
// clang-format off
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 pointsInFace[vtkm::NUMBER_OF_CELL_SHAPES][MAX_NUM_FACES]
[MAX_FACE_SIZE] =
{
// PointsInFace
// 0: CELL_SHAPE_EMPTY
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 1: CELL_SHAPE_VERTEX
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 2: Unused
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 3: CELL_SHAPE_LINE
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 4: Unused
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 5: CELL_SHAPE_TRIANGLE
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 6: Unused
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 7: CELL_SHAPE_POLYGON
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 8: Unused
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 9: CELL_SHAPE_QUAD
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 10: CELL_SHAPE_TETRA
{ { 0, 1, 3, -1 }, { 1, 2, 3, -1 }, { 2, 0, 3, -1 },
{ 0, 2, 1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 11: Unused
{ { -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 },
{ -1, -1, -1, -1 }, { -1, -1, -1, -1 }, { -1, -1, -1, -1 } },
// 12: CELL_SHAPE_HEXAHEDRON
{ { 0, 4, 7, 3 }, { 1, 2, 6, 5 }, { 0, 1, 5, 4 },
{ 3, 7, 6, 2 }, { 0, 3, 2, 1 }, { 4, 5, 6, 7 } },
// 13: CELL_SHAPE_WEDGE
{ { 0, 1, 2, -1 }, { 3, 5, 4, -1 }, { 0, 3, 4, 1 },
{ 1, 4, 5, 2 }, { 2, 5, 3, 0 }, { -1, -1, -1, -1 } },
// 14: CELL_SHAPE_PYRAMID
{ { 0, 3, 2, 1 }, { 0, 1, 4, -1 }, { 1, 2, 4, -1 },
{ 2, 3, 4, -1 }, { 3, 0, 4, -1 },{ -1, -1, -1, -1 } }
// clang-format on
};
return pointsInFace[i][j][k];
}
};
@ -209,7 +152,8 @@ static inline VTKM_EXEC vtkm::IdComponent CellFaceNumberOfFaces(CellShapeTag sha
const vtkm::exec::FunctorBase&)
{
(void)shape; //C4100 false positive workaround
return detail::CellFaceTables::Get().NumFaces[shape.Id];
detail::CellFaceTables table;
return table.NumFaces(shape.Id);
}
template <typename CellShapeTag>
@ -225,8 +169,8 @@ static inline VTKM_EXEC vtkm::IdComponent CellFaceNumberOfPoints(
worklet.RaiseError("Invalid face number.");
return 0;
}
return detail::CellFaceTables::Get().NumPointsInFace[shape.Id][faceIndex];
detail::CellFaceTables table;
return table.NumPointsInFace(shape.Id, faceIndex);
}
template <typename CellShapeTag>
@ -247,24 +191,6 @@ static inline VTKM_EXEC vtkm::UInt8 CellFaceShape(vtkm::IdComponent faceIndex,
}
}
template <typename CellShapeTag>
static inline VTKM_EXEC vtkm::VecCConst<vtkm::IdComponent> CellFaceLocalIndices(
vtkm::IdComponent faceIndex,
CellShapeTag shape,
const vtkm::exec::FunctorBase& worklet)
{
vtkm::IdComponent numPointsInFace = vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, worklet);
if (numPointsInFace < 1)
{
// An invalid face. We should already have gotten an error from
// CellFaceNumberOfPoints.
return vtkm::VecCConst<vtkm::IdComponent>();
}
return vtkm::make_VecC(detail::CellFaceTables::Get().PointsInFace[shape.Id][faceIndex],
numPointsInFace);
}
/// \brief Returns a canonical identifier for a cell face
///
/// Given information about a cell face and the global point indices for that cell, returns a
@ -282,15 +208,20 @@ static inline VTKM_EXEC vtkm::Id3 CellFaceCanonicalId(
const GlobalPointIndicesVecType& globalPointIndicesVec,
const vtkm::exec::FunctorBase& worklet)
{
vtkm::VecCConst<vtkm::IdComponent> localPointIndices =
vtkm::exec::CellFaceLocalIndices(faceIndex, shape, worklet);
VTKM_ASSERT(localPointIndices.GetNumberOfComponents() >= 3);
const vtkm::IdComponent numPointsInFace =
vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, worklet);
if (numPointsInFace == 0)
{
// An invalid face. We should already have gotten an error from
// CellFaceNumberOfPoints.
return vtkm::Id3(0);
}
detail::CellFaceTables table;
//Sort the first 3 face points/nodes in ascending order
vtkm::Id3 sorted(globalPointIndicesVec[localPointIndices[0]],
globalPointIndicesVec[localPointIndices[1]],
globalPointIndicesVec[localPointIndices[2]]);
vtkm::Id3 sorted(globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 0)],
globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 1)],
globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, 2)]);
vtkm::Id temp;
if (sorted[0] > sorted[2])
{
@ -312,10 +243,9 @@ static inline VTKM_EXEC vtkm::Id3 CellFaceCanonicalId(
}
// Check the rest of the points to see if they are in the lowest 3
vtkm::IdComponent numPointsInFace = localPointIndices.GetNumberOfComponents();
for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
{
vtkm::Id nextPoint = globalPointIndicesVec[localPointIndices[pointIndex]];
vtkm::Id nextPoint = globalPointIndicesVec[table.PointsInFace(shape.Id, faceIndex, pointIndex)];
if (nextPoint < sorted[2])
{
if (nextPoint < sorted[1])

@ -94,23 +94,28 @@ struct TestCellFacesFunctor
std::set<EdgeType> edgesFoundInFaces;
for (vtkm::IdComponent faceIndex = 0; faceIndex < numFaces; faceIndex++)
{
vtkm::VecCConst<vtkm::IdComponent> facePoints =
vtkm::exec::CellFaceLocalIndices(faceIndex, shape, workletProxy);
vtkm::IdComponent numPointsInFace = facePoints.GetNumberOfComponents();
vtkm::exec::detail::CellFaceTables table;
const vtkm::IdComponent numPointsInFace =
vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, workletProxy);
VTKM_TEST_ASSERT(numPointsInFace >= 3, "Face has fewer points than a triangle.");
for (vtkm::IdComponent pointIndex = 0; pointIndex < numPointsInFace; pointIndex++)
{
VTKM_TEST_ASSERT(facePoints[pointIndex] >= 0, "Invalid point index for face.");
VTKM_TEST_ASSERT(facePoints[pointIndex] <= numPoints, "Invalid point index for face.");
VTKM_TEST_ASSERT(table.PointsInFace(shape.Id, faceIndex, pointIndex) >= 0,
"Invalid point index for face.");
VTKM_TEST_ASSERT(table.PointsInFace(shape.Id, faceIndex, pointIndex) <= numPoints,
"Invalid point index for face.");
EdgeType edge;
if (pointIndex < numPointsInFace - 1)
{
edge = EdgeType(facePoints[pointIndex], facePoints[pointIndex + 1]);
edge = EdgeType(table.PointsInFace(shape.Id, faceIndex, pointIndex),
table.PointsInFace(shape.Id, faceIndex, pointIndex + 1));
}
else
{
edge = EdgeType(facePoints[0], facePoints[pointIndex]);
edge = EdgeType(table.PointsInFace(shape.Id, faceIndex, 0),
table.PointsInFace(shape.Id, faceIndex, pointIndex));
}
MakeEdgeCanonical(edge);
VTKM_TEST_ASSERT(edgeSet.find(edge) != edgeSet.end(), "Edge in face not in cell's edges");

@ -78,12 +78,17 @@
#endif
// cuda 7.5 doesn't support static const or static constexpr variables
// that exist inside methods or classes, so in those cases we gracefully
// fall back to using just constexpr
// that exist inside methods or classes, so in those cases we have to use
// just constexpr
#if defined(VTKM_CUDA_VERSION_MAJOR) && (VTKM_CUDA_VERSION_MAJOR < 8)
#define VTKM_STATIC_CONSTEXPR constexpr
#define VTKM_STATIC_CONSTEXPR_ARRAY constexpr
// cuda 8+ doesn't support static constexpr pointers/fixed size arrays
// that exist inside methods or classes, so in those cases we gracefully
// fall back to static const
#elif defined(VTKM_CUDA_VERSION_MAJOR) && (VTKM_CUDA_VERSION_MAJOR >= 8)
#define VTKM_STATIC_CONSTEXPR_ARRAY static const
#else
#define VTKM_STATIC_CONSTEXPR static constexpr
#define VTKM_STATIC_CONSTEXPR_ARRAY static constexpr
#endif
// Clang will warn about weak vtables (-Wweak-vtables) on exception classes,

@ -47,10 +47,10 @@ VTKM_EXEC_CONT inline void IntersectZoo(T xpoints[8],
vtkm::Int32 kx, ky, kz;
WaterTight<T> intersector;
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
const vtkm::Int32 tableOffset =
CellTables::Get().ZooLookUp[CellTables::Get().CellTypeLookUp[shapeType]][0];
const vtkm::Int32 numTriangles =
CellTables::Get().ZooLookUp[CellTables::Get().CellTypeLookUp[shapeType]][1];
CellTables tables;
const vtkm::Int32 tableOffset = tables.ZooLookUp(tables.CellTypeLookUp(shapeType), 0);
const vtkm::Int32 numTriangles = tables.ZooLookUp(tables.CellTypeLookUp(shapeType), 1);
// Decompose each face into two triangles
for (int i = 0; i < 6; ++i)
distances[i] = -1.;
@ -58,16 +58,16 @@ VTKM_EXEC_CONT inline void IntersectZoo(T xpoints[8],
{
const vtkm::Int32 offset = tableOffset + i;
vtkm::Vec<T, 3> a, c, b;
a[0] = xpoints[CellTables::Get().ZooTable[offset][1]];
a[1] = ypoints[CellTables::Get().ZooTable[offset][1]];
a[2] = zpoints[CellTables::Get().ZooTable[offset][1]];
b[0] = xpoints[CellTables::Get().ZooTable[offset][2]];
b[1] = ypoints[CellTables::Get().ZooTable[offset][2]];
b[2] = zpoints[CellTables::Get().ZooTable[offset][2]];
c[0] = xpoints[CellTables::Get().ZooTable[offset][3]];
c[1] = ypoints[CellTables::Get().ZooTable[offset][3]];
c[2] = zpoints[CellTables::Get().ZooTable[offset][3]];
const vtkm::Int32 faceId = CellTables::Get().ZooTable[offset][0];
a[0] = xpoints[tables.ZooTable(offset, 1)];
a[1] = ypoints[tables.ZooTable(offset, 1)];
a[2] = zpoints[tables.ZooTable(offset, 1)];
b[0] = xpoints[tables.ZooTable(offset, 2)];
b[1] = ypoints[tables.ZooTable(offset, 2)];
b[2] = zpoints[tables.ZooTable(offset, 2)];
c[0] = xpoints[tables.ZooTable(offset, 3)];
c[1] = ypoints[tables.ZooTable(offset, 3)];
c[2] = zpoints[tables.ZooTable(offset, 3)];
const vtkm::Int32 faceId = tables.ZooTable(offset, 0);
T distance = -1.f;
T uNotUsed, vNotUsed;
@ -109,22 +109,24 @@ VTKM_EXEC_CONT inline void IntersectHex(T xpoints[8],
vtkm::Int32 kx, ky, kz;
WaterTight<T> intersector;
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
CellTables tables;
// Decompose each face into two triangles
for (int i = 0; i < 6; ++i)
{
vtkm::Vec<T, 3> a, c, b, d;
a[0] = xpoints[CellTables::Get().ShapesFaceList[i][1]];
a[1] = ypoints[CellTables::Get().ShapesFaceList[i][1]];
a[2] = zpoints[CellTables::Get().ShapesFaceList[i][1]];
b[0] = xpoints[CellTables::Get().ShapesFaceList[i][2]];
b[1] = ypoints[CellTables::Get().ShapesFaceList[i][2]];
b[2] = zpoints[CellTables::Get().ShapesFaceList[i][2]];
c[0] = xpoints[CellTables::Get().ShapesFaceList[i][3]];
c[1] = ypoints[CellTables::Get().ShapesFaceList[i][3]];
c[2] = zpoints[CellTables::Get().ShapesFaceList[i][3]];
d[0] = xpoints[CellTables::Get().ShapesFaceList[i][4]];
d[1] = ypoints[CellTables::Get().ShapesFaceList[i][4]];
d[2] = zpoints[CellTables::Get().ShapesFaceList[i][4]];
a[0] = xpoints[tables.ShapesFaceList(i, 1)];
a[1] = ypoints[tables.ShapesFaceList(i, 1)];
a[2] = zpoints[tables.ShapesFaceList(i, 1)];
b[0] = xpoints[tables.ShapesFaceList(i, 2)];
b[1] = ypoints[tables.ShapesFaceList(i, 2)];
b[2] = zpoints[tables.ShapesFaceList(i, 2)];
c[0] = xpoints[tables.ShapesFaceList(i, 3)];
c[1] = ypoints[tables.ShapesFaceList(i, 3)];
c[2] = zpoints[tables.ShapesFaceList(i, 3)];
d[0] = xpoints[tables.ShapesFaceList(i, 4)];
d[1] = ypoints[tables.ShapesFaceList(i, 4)];
d[2] = zpoints[tables.ShapesFaceList(i, 4)];
T distance = -1.f;
distances[i] = distance; //init to -1
@ -191,20 +193,20 @@ VTKM_EXEC_CONT inline void IntersectTet(T xpoints[8],
WaterTight<T> intersector;
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
const vtkm::Int32 tableOffset =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[CELL_SHAPE_TETRA]][0];
CellTables tables;
const vtkm::Int32 tableOffset = tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_TETRA), 0);
for (vtkm::Int32 i = 0; i < 4; ++i)
{
vtkm::Vec<T, 3> a, c, b;
a[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
a[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
a[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
b[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
b[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
b[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
c[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
c[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
c[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
a[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 1)];
a[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 1)];
a[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 1)];
b[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 2)];
b[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 2)];
b[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 2)];
c[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 3)];
c[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 3)];
c[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 3)];
T distance = -1.f;
distances[i] = distance; //init to -1
@ -248,24 +250,24 @@ VTKM_EXEC_CONT inline void IntersectWedge(T xpoints[8],
WaterTight<T> intersector;
intersector.FindDir(dir, sx, sy, sz, kx, ky, kz);
// TODO: try two sepate loops to see performance impact
const vtkm::Int32 tableOffset =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[CELL_SHAPE_WEDGE]][0];
CellTables tables;
const vtkm::Int32 tableOffset = tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_WEDGE), 0);
// Decompose each face into two triangles
for (int i = 0; i < 5; ++i)
{
vtkm::Vec<T, 3> a, c, b, d;
a[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
a[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
a[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][1]];
b[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
b[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
b[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][2]];
c[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
c[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
c[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][3]];
d[0] = xpoints[CellTables::Get().ShapesFaceList[i + tableOffset][4]];
d[1] = ypoints[CellTables::Get().ShapesFaceList[i + tableOffset][4]];
d[2] = zpoints[CellTables::Get().ShapesFaceList[i + tableOffset][4]];
a[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 1)];
a[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 1)];
a[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 1)];
b[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 2)];
b[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 2)];
b[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 2)];
c[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 3)];
c[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 3)];
c[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 3)];
d[0] = xpoints[tables.ShapesFaceList(i + tableOffset, 4)];
d[1] = ypoints[tables.ShapesFaceList(i + tableOffset, 4)];
d[2] = zpoints[tables.ShapesFaceList(i + tableOffset, 4)];
T distance = -1.f;
distances[i] = distance; //init to -1

@ -29,114 +29,117 @@ namespace rendering
{
namespace raytracing
{
class CellTables
struct CellTables
{
private:
struct Tables
// CellTypeLookUp: LookUp of Shapes to FaceLookUp
VTKM_EXEC vtkm::Int32 CellTypeLookUp(vtkm::Int32 x) const
{
vtkm::Int32 CellTypeLookUp[15];
vtkm::Int32 FaceLookUp[5][3];
vtkm::Int32 ShapesFaceList[20][5];
vtkm::Int32 ZooTable[30][4];
vtkm::Int32 ZooLookUp[5][2];
};
public:
VTKM_EXEC_CONT static const Tables& Get()
{
static const Tables tables = {
// CellTypeLookUp: LookUp of Shapes to FaceLookUp
{
4, // 0 Nothing
4, // 1 Vertex
4, // 2 (Not Used) Poly Vertex
4, // 3 Line
4, // 4 (Not Used) Poly Line
4, // 5 Triangle
4, // 6 (not used) triangle strip
4, // 7 Polygon
4, // 8 (Not used)Pixel
4, // 9 Quad
1, // 10 Tetra
4, // 11 (Not used) Voxel
0, // 12 Hex
2, // 13 Wedge
3 // 14 Pyramid
},
// FaceLookUp
{
{ 0, 6, 8 }, //hex offset into shapes face list, num faces and number of Indices
{ 6, 4, 4 }, //tet
{ 10, 5, 6 }, //wedge
{ 15, 5, 5 }, //pyramid
{ -1, 0, 0 } //unsupported shape
},
// ShapesFaceList:
// The convention for the faces is that looking from the outside of
// the shape at a face, triangles should wind CCW.
// Quads are broken up by {4=quad,a,b,c,d}:
// t1 = abc and t2 = acd. Indices of the face are ordered CW, and the mapping
// of t1 and t2 become CCW.
// Since we know the triangle winding, we could tell
// if we hit an inside face or outside face.
{ //hex
{ 4, 0, 1, 5, 4 }, //face 0
{ 4, 1, 2, 6, 5 },
{ 4, 3, 7, 6, 2 },
{ 4, 0, 4, 7, 3 },
{ 4, 0, 3, 2, 1 },
{ 4, 4, 5, 6, 7 }, //face 5
//tet
{ 3, 0, 3, 1, -1 },
{ 3, 1, 2, 3, -1 },
{ 3, 0, 2, 3, -1 },
{ 3, 0, 2, 1, -1 },
//wedge
{ 3, 0, 1, 2, -1 },
{ 3, 3, 5, 4, -1 },
{ 4, 3, 0, 2, 5 },
{ 4, 1, 4, 5, 2 },
{ 4, 0, 3, 4, 1 },
//pyramid
{ 3, 0, 4, 1, -1 },
{ 3, 1, 2, 4, -1 },
{ 3, 2, 3, 4, -1 },
{ 3, 0, 4, 3, -1 },
{ 4, 3, 2, 1, 0 } },
// ZooTable:
// Test of zoo table.
// Format (faceNumber, triangle)
//
{ { 0, 0, 1, 5 }, // hex
{ 0, 0, 5, 4 }, { 1, 1, 2, 6 }, { 1, 1, 6, 5 }, { 2, 3, 7, 6 }, { 2, 3, 6, 2 },
{ 3, 0, 4, 7 }, { 3, 0, 7, 3 }, { 4, 0, 3, 2 }, { 4, 0, 2, 1 }, { 5, 4, 5, 6 },
{ 5, 4, 6, 7 }, { 0, 0, 3, 1 }, // Tet
{ 1, 1, 2, 3 }, { 2, 0, 2, 3 }, { 3, 0, 2, 1 }, { 0, 0, 1, 2 }, // Wedge
{ 1, 3, 5, 4 }, { 2, 3, 0, 2 }, { 2, 3, 2, 5 }, { 3, 1, 4, 5 }, { 3, 1, 5, 2 },
{ 4, 0, 3, 4 }, { 4, 0, 4, 1 }, { 0, 0, 4, 1 }, // Pyramid
{ 1, 1, 2, 4 }, { 2, 2, 3, 4 }, { 3, 0, 4, 3 }, { 4, 3, 2, 1 }, { 4, 3, 1, 0 } },
// ZooLookUp:
// Offset into zoo table and the
// number of triangles for the shape
//
{
{ 0, 12 }, //hex offset into shapes face list, num faces and number of Indices
{ 12, 4 }, //tet
{ 16, 8 }, //wedge
{ 24, 6 }, //pyramid
{ -1, 0 } //unsupported shape
}
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 lookup[15] = {
4, // 0 Nothing
4, // 1 Vertex
4, // 2 (Not Used) Poly Vertex
4, // 3 Line
4, // 4 (Not Used) Poly Line
4, // 5 Triangle
4, // 6 (not used) triangle strip
4, // 7 Polygon
4, // 8 (Not used)Pixel
4, // 9 Quad
1, // 10 Tetra
4, // 11 (Not used) Voxel
0, // 12 Hex
2, // 13 Wedge
3 // 14 Pyramid
};
return lookup[x];
}
return tables;
// FaceLookUp
VTKM_EXEC vtkm::Int32 FaceLookUp(vtkm::Int32 x, vtkm::Int32 y) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 faces[5][3] = {
{ 0, 6, 8 }, //hex offset into shapes face list, num faces and number of Indices
{ 6, 4, 4 }, //tet
{ 10, 5, 6 }, //wedge
{ 15, 5, 5 }, //pyramid
{ -1, 0, 0 } //unsupported shape
};
return faces[x][y];
}
// ShapesFaceList:
// The convention for the faces is that looking from the outside of
// the shape at a face, triangles should wind CCW.
// Quads are broken up by {4=quad,a,b,c,d}:
// t1 = abc and t2 = acd. Indices of the face are ordered CW, and the mapping
// of t1 and t2 become CCW.
// Since we know the triangle winding, we could tell
// if we hit an inside face or outside face.
VTKM_EXEC vtkm::Int32 ShapesFaceList(vtkm::Int32 x, vtkm::Int32 y) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 shapes[20][5] = { //hex
{ 4, 0, 1, 5, 4 }, //face 0
{ 4, 1, 2, 6, 5 },
{ 4, 3, 7, 6, 2 },
{ 4, 0, 4, 7, 3 },
{ 4, 0, 3, 2, 1 },
{ 4, 4, 5, 6, 7 }, //face 5
//tet
{ 3, 0, 3, 1, -1 },
{ 3, 1, 2, 3, -1 },
{ 3, 0, 2, 3, -1 },
{ 3, 0, 2, 1, -1 },
//wedge
{ 3, 0, 1, 2, -1 },
{ 3, 3, 5, 4, -1 },
{ 4, 3, 0, 2, 5 },
{ 4, 1, 4, 5, 2 },
{ 4, 0, 3, 4, 1 },
//pyramid
{ 3, 0, 4, 1, -1 },
{ 3, 1, 2, 4, -1 },
{ 3, 2, 3, 4, -1 },
{ 3, 0, 4, 3, -1 },
{ 4, 3, 2, 1, 0 }
};
return shapes[x][y];
}
// ZooTable:
// Test of zoo table.
// Format (faceNumber, triangle)
VTKM_EXEC vtkm::Int32 ZooTable(vtkm::Int32 x, vtkm::Int32 y) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 zoo[30][4] = {
{ 0, 0, 1, 5 }, // hex
{ 0, 0, 5, 4 }, { 1, 1, 2, 6 }, { 1, 1, 6, 5 }, { 2, 3, 7, 6 }, { 2, 3, 6, 2 },
{ 3, 0, 4, 7 }, { 3, 0, 7, 3 }, { 4, 0, 3, 2 }, { 4, 0, 2, 1 }, { 5, 4, 5, 6 },
{ 5, 4, 6, 7 }, { 0, 0, 3, 1 }, // Tet
{ 1, 1, 2, 3 }, { 2, 0, 2, 3 }, { 3, 0, 2, 1 }, { 0, 0, 1, 2 }, // Wedge
{ 1, 3, 5, 4 }, { 2, 3, 0, 2 }, { 2, 3, 2, 5 }, { 3, 1, 4, 5 }, { 3, 1, 5, 2 },
{ 4, 0, 3, 4 }, { 4, 0, 4, 1 }, { 0, 0, 4, 1 }, // Pyramid
{ 1, 1, 2, 4 }, { 2, 2, 3, 4 }, { 3, 0, 4, 3 }, { 4, 3, 2, 1 }, { 4, 3, 1, 0 }
};
return zoo[x][y];
}
// ZooLookUp:
// Offset into zoo table and the
// number of triangles for the shape
//
VTKM_EXEC vtkm::Int32 ZooLookUp(vtkm::Int32 x, vtkm::Int32 y) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 zoo[5][2] = {
{ 0, 12 }, //hex offset into shapes face list, num faces and number of Indices
{ 12, 4 }, //tet
{ 16, 8 }, //wedge
{ 24, 6 }, //pyramid
{ -1, 0 } //unsupported shape
};
return zoo[x][y];
}
};

@ -219,8 +219,9 @@ public:
}
const vtkm::UInt8 cellShape = MeshConn.GetCellShape(currentCell);
Intersector.IntersectCell(xpoints, ypoints, zpoints, dir, origin, distances, cellShape);
const vtkm::Int32 numFaces =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[cellShape]][1];
CellTables tables;
const vtkm::Int32 numFaces = tables.FaceLookUp(tables.CellTypeLookUp(cellShape), 1);
//vtkm::Int32 minFace = 6;
vtkm::Int32 maxFace = -1;
@ -354,8 +355,9 @@ public:
const vtkm::UInt8 cellShape = MeshConn.GetCellShape(currentCell);
Intersector.IntersectCell(xpoints, ypoints, zpoints, dir, origin, distances, cellShape);
const vtkm::Int32 numFaces =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[cellShape]][1];
CellTables tables;
const vtkm::Int32 numFaces = tables.FaceLookUp(tables.CellTypeLookUp(cellShape), 1);
//vtkm::Int32 minFace = 6;
vtkm::Int32 maxFace = -1;

@ -106,23 +106,24 @@ public:
inline vtkm::Int32 GetShapeOffset(const vtkm::UInt8& shapeType) const
{
CellTables tables;
//TODO: This might be better as if if if
vtkm::Int32 tableOffset = 0;
if (shapeType == vtkm::CELL_SHAPE_TETRA)
{
tableOffset = CellTables::Get().FaceLookUp[1][0];
tableOffset = tables.FaceLookUp(1, 0);
}
else if (shapeType == vtkm::CELL_SHAPE_HEXAHEDRON)
{
tableOffset = CellTables::Get().FaceLookUp[0][0];
tableOffset = tables.FaceLookUp(0, 0);
}
else if (shapeType == vtkm::CELL_SHAPE_WEDGE)
{
tableOffset = CellTables::Get().FaceLookUp[2][0];
tableOffset = tables.FaceLookUp(2, 0);
}
else if (shapeType == vtkm::CELL_SHAPE_PYRAMID)
{
tableOffset = CellTables::Get().FaceLookUp[3][0];
tableOffset = tables.FaceLookUp(3, 0);
}
else
printf("Error shape not recognized %d\n", (int)shapeType);
@ -172,6 +173,7 @@ public:
bool isInternal = false;
vtkm::Id connectedCell = -1;
CellTables tables;
while (currentIndex > -1 && myCode == myNeighbor)
{
myNeighbor = mortonCodes.Get(currentIndex);
@ -186,12 +188,13 @@ public:
vtkm::Id cellId2 = faceIdPairs.Get(currentIndex)[0];
BOUNDS_CHECK(shapes, cellId1);
BOUNDS_CHECK(shapes, cellId2);
vtkm::Id shape1Offset = GetShapeOffset(shapes.Get(cellId1)) + faceIdPairs.Get(index)[1];
vtkm::Id shape2Offset =
GetShapeOffset(shapes.Get(cellId2)) + faceIdPairs.Get(currentIndex)[1];
vtkm::Int32 shape1Offset =
GetShapeOffset(shapes.Get(cellId1)) + static_cast<vtkm::Int32>(faceIdPairs.Get(index)[1]);
vtkm::Int32 shape2Offset = GetShapeOffset(shapes.Get(cellId2)) +
static_cast<vtkm::Int32>(faceIdPairs.Get(currentIndex)[1]);
vtkm::Int32 icount1 = CellTables::Get().ShapesFaceList[shape1Offset][0];
vtkm::Int32 icount2 = CellTables::Get().ShapesFaceList[shape2Offset][0];
const vtkm::Int32 icount1 = tables.ShapesFaceList(shape1Offset, 0);
const vtkm::Int32 icount2 = tables.ShapesFaceList(shape2Offset, 0);
//Check to see if we have the same number of idices
if (icount1 != icount2)
continue;
@ -201,24 +204,25 @@ public:
vtkm::Vec<vtkm::Id, 4> indices1;
vtkm::Vec<vtkm::Id, 4> indices2;
for (vtkm::Int32 i = 1; i <= CellTables::Get().ShapesFaceList[shape1Offset][0]; ++i)
const auto faceLength = tables.ShapesFaceList(shape1Offset, 0);
for (vtkm::Int32 i = 1; i <= faceLength; ++i)
{
BOUNDS_CHECK(offsets, cellId1);
BOUNDS_CHECK(offsets, cellId2);
BOUNDS_CHECK(connectivity,
(offsets.Get(cellId1) + CellTables::Get().ShapesFaceList[shape1Offset][i]));
(offsets.Get(cellId1) + tables.ShapesFaceList(shape1Offset, i)));
BOUNDS_CHECK(connectivity,
(offsets.Get(cellId2) + CellTables::Get().ShapesFaceList[shape2Offset][i]));
indices1[i - 1] = connectivity.Get(offsets.Get(cellId1) +
CellTables::Get().ShapesFaceList[shape1Offset][i]);
indices2[i - 1] = connectivity.Get(offsets.Get(cellId2) +
CellTables::Get().ShapesFaceList[shape2Offset][i]);
(offsets.Get(cellId2) + tables.ShapesFaceList(shape2Offset, i)));
indices1[i - 1] =
connectivity.Get(offsets.Get(cellId1) + tables.ShapesFaceList(shape1Offset, i));
indices2[i - 1] =
connectivity.Get(offsets.Get(cellId2) + tables.ShapesFaceList(shape2Offset, i));
}
bool isEqual = true;
for (vtkm::Int32 i = 0; i < CellTables::Get().ShapesFaceList[shape1Offset][0]; ++i)
for (vtkm::Int32 i = 0; i < faceLength; ++i)
{
if (!IsIn(indices1[i], indices2, CellTables::Get().ShapesFaceList[shape1Offset][0]))
if (!IsIn(indices1[i], indices2, faceLength))
isEqual = false;
}
@ -281,14 +285,14 @@ public:
const OutIndicesPortalType& outputIndices,
const vtkm::Id& outputOffset) const
{
CellTables tables;
vtkm::Id cellId = faceIdPair[0];
BOUNDS_CHECK(shapeOffsets, cellId);
vtkm::Id offset = shapeOffsets.Get(cellId);
BOUNDS_CHECK(shapes, cellId);
vtkm::Int32 shapeId = static_cast<vtkm::Int32>(shapes.Get(cellId));
vtkm::Int32 shapesFaceOffset =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[shapeId]][0];
vtkm::Int32 shapesFaceOffset = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 0);
if (shapesFaceOffset == -1)
{
printf("Unsupported Shape Type %d\n", shapeId);
@ -297,12 +301,12 @@ public:
vtkm::Vec<vtkm::Id, 4> faceIndices(-1, -1, -1, -1);
vtkm::Int32 tableIndex = static_cast<vtkm::Int32>(shapesFaceOffset + faceIdPair[1]);
const vtkm::Int32 numIndices = CellTables::Get().ShapesFaceList[tableIndex][0];
const vtkm::Int32 numIndices = tables.ShapesFaceList(tableIndex, 0);
for (vtkm::Int32 i = 1; i <= numIndices; ++i)
{
BOUNDS_CHECK(indices, offset + CellTables::Get().ShapesFaceList[tableIndex][i]);
faceIndices[i - 1] = indices.Get(offset + CellTables::Get().ShapesFaceList[tableIndex][i]);
BOUNDS_CHECK(indices, offset + tables.ShapesFaceList(tableIndex, i));
faceIndices[i - 1] = indices.Get(offset + tables.ShapesFaceList(tableIndex, i));
}
vtkm::Vec<vtkm::Id, 4> triangle;
triangle[0] = cellId;
@ -390,10 +394,10 @@ public:
{
// Each one of size segments will process
// one face of the hex and domain
static const vtkm::Int32 SegmentToFace[6] = { 0, 2, 1, 3, 4, 5 };
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 SegmentToFace[6] = { 0, 2, 1, 3, 4, 5 };
// Each face/segment has 2 varying dimensions
static const vtkm::Int32 SegmentDirections[6][2] = {
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 SegmentDirections[6][2] = {
{ 0, 2 }, //face 0 and 2 have the same directions
{ 0, 2 }, { 1, 2 }, //1 and 3
{ 1, 2 }, { 0, 1 }, // 4 and 5
@ -454,8 +458,9 @@ public:
// Look up the offset into the face list for each cell type
// This should always be zero, but in case this table changes I don't
// want to break anything.
CellTables tables;
vtkm::Int32 shapesFaceOffset =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[CELL_SHAPE_HEXAHEDRON]][0];
tables.FaceLookUp(tables.CellTypeLookUp(CELL_SHAPE_HEXAHEDRON), 0);
vtkm::Vec<vtkm::Id, 4> faceIndices;
vtkm::Int32 tableIndex = shapesFaceOffset + cellFace;
@ -463,7 +468,7 @@ public:
// Load the face
for (vtkm::Int32 i = 1; i <= 4; ++i)
{
faceIndices[i - 1] = cellIndices[CellTables::Get().ShapesFaceList[tableIndex][i]];
faceIndices[i - 1] = cellIndices[tables.ShapesFaceList(tableIndex, i)];
}
const vtkm::Id outputOffset = index * 2;
vtkm::Vec<vtkm::Id, 4> triangle;
@ -495,18 +500,19 @@ public:
const ShapePortalType& shapes,
vtkm::Id& triangleCount) const
{
CellTables tables;
vtkm::Id cellId = faceIdPair[0];
vtkm::Id cellFace = faceIdPair[1];
vtkm::Int32 shapeType = static_cast<vtkm::Int32>(shapes.Get(cellId));
vtkm::Int32 faceStartIndex =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[shapeType]][0];
vtkm::Int32 faceStartIndex = tables.FaceLookUp(tables.CellTypeLookUp(shapeType), 0);
if (faceStartIndex == -1)
{
//Unsupported Shape Type this should never happen
triangleCount = 0;
return;
}
vtkm::Int32 faceType = CellTables::Get().ShapesFaceList[faceStartIndex + cellFace][0];
vtkm::Int32 faceType =
tables.ShapesFaceList(faceStartIndex + static_cast<vtkm::Int32>(cellFace), 0);
// The face will either have 4 or 3 indices, so quad or tri
triangleCount = (faceType == 4) ? 2 : 1;

@ -265,9 +265,9 @@ public:
VTKM_EXEC
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const
{
CellTables tables;
const vtkm::Int32 shapeId = static_cast<vtkm::Int32>(ShapesPortal.Get(cellId));
const vtkm::Int32 numIndices =
CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[shapeId]][2];
const vtkm::Int32 numIndices = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 2);
BOUNDS_CHECK(CellOffsetsPortal, cellId);
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
@ -345,8 +345,9 @@ public:
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
CellTables tables;
ShapeId = shapes.GetPortalConstControl().Get(0);
NumIndices = CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[ShapeId]][2];
NumIndices = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 2);
if (NumIndices == 0)
{
@ -356,7 +357,7 @@ public:
throw vtkm::cont::ErrorBadValue(message.str());
}
vtkm::Id start = 0;
NumFaces = CellTables::Get().FaceLookUp[CellTables::Get().CellTypeLookUp[ShapeId]][1];
NumFaces = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 1);
vtkm::Id numCells = CellConnectivity.GetPortalConstControl().GetNumberOfValues();
CellOffsets = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start, NumIndices, numCells);

@ -170,28 +170,29 @@ public:
MortonPortalType& mortonCodes,
CellFaceIdsPortalType& cellFaceIds) const
{
CellTables tables;
vtkm::Int32 faceCount;
vtkm::Int32 tableOffset;
if (cellShape.Id == vtkm::CELL_SHAPE_TETRA)
{
faceCount = CellTables::Get().FaceLookUp[1][1];
tableOffset = CellTables::Get().FaceLookUp[1][0];
faceCount = tables.FaceLookUp(1, 1);
tableOffset = tables.FaceLookUp(1, 0);
}
else if (cellShape.Id == vtkm::CELL_SHAPE_HEXAHEDRON)
{
faceCount = CellTables::Get().FaceLookUp[0][1];
tableOffset = CellTables::Get().FaceLookUp[0][0];
faceCount = tables.FaceLookUp(0, 1);
tableOffset = tables.FaceLookUp(0, 0);
}
else if (cellShape.Id == vtkm::CELL_SHAPE_WEDGE)
{
faceCount = CellTables::Get().FaceLookUp[2][1];
tableOffset = CellTables::Get().FaceLookUp[2][0];
faceCount = tables.FaceLookUp(2, 1);
tableOffset = tables.FaceLookUp(2, 0);
}
else if (cellShape.Id == vtkm::CELL_SHAPE_PYRAMID)
{
faceCount = CellTables::Get().FaceLookUp[3][1];
tableOffset = CellTables::Get().FaceLookUp[3][0];
faceCount = tables.FaceLookUp(3, 1);
tableOffset = tables.FaceLookUp(3, 0);
}
else
{
@ -215,10 +216,10 @@ public:
vtkm::Vec<vtkm::Id, 4> faceIndices;
faceIndices[3] = -1;
//Number of indices this face has
const vtkm::Id indiceCount = CellTables::Get().ShapesFaceList[tableOffset + i][0];
const vtkm::Int32 indiceCount = tables.ShapesFaceList(tableOffset + i, 0);
for (vtkm::Int32 j = 1; j <= indiceCount; j++)
{
faceIndices[j - 1] = cellIndices[CellTables::Get().ShapesFaceList[tableOffset + i][j]];
faceIndices[j - 1] = cellIndices[tables.ShapesFaceList(tableOffset + i, j)];
}
//sort the indices in descending order
Sort4(faceIndices);

@ -46,83 +46,89 @@ namespace UnitTestMathNamespace
class Lists
{
public:
static const vtkm::IdComponent NUM_NUMBERS = 5;
static constexpr vtkm::IdComponent NUM_NUMBERS = 5;
private:
struct Data
VTKM_EXEC_CONT vtkm::Float64 NumberList(vtkm::Int32 i) const
{
vtkm::Float64 NumberList[NUM_NUMBERS];
vtkm::Float64 AngleList[NUM_NUMBERS];
vtkm::Float64 OppositeList[NUM_NUMBERS];
vtkm::Float64 AdjacentList[NUM_NUMBERS];
vtkm::Float64 HypotenuseList[NUM_NUMBERS];
vtkm::Float64 NumeratorList[NUM_NUMBERS];
vtkm::Float64 DenominatorList[NUM_NUMBERS];
vtkm::Float64 FModRemainderList[NUM_NUMBERS];
vtkm::Float64 RemainderList[NUM_NUMBERS];
vtkm::Int64 QuotientList[NUM_NUMBERS];
vtkm::Float64 XList[NUM_NUMBERS];
vtkm::Float64 FractionalList[NUM_NUMBERS];
vtkm::Float64 FloorList[NUM_NUMBERS];
vtkm::Float64 CeilList[NUM_NUMBERS];
vtkm::Float64 RoundList[NUM_NUMBERS];
};
public:
VTKM_EXEC_CONT static const Data& Get()
vtkm::Float64 numberList[NUM_NUMBERS] = { 0.25, 0.5, 1.0, 2.0, 3.75 };
return numberList[i];
}
VTKM_EXEC_CONT vtkm::Float64 AngleList(vtkm::Int32 i) const
{
static const Data data = {
// NumberList
{ 0.25, 0.5, 1.0, 2.0, 3.75 },
// AngleList
{ 0.643501108793284, // angle for 3, 4, 5 triangle.
0.78539816339745, // pi/4
0.5235987755983, // pi/6
1.0471975511966, // pi/3
0.0 },
// OppositeList
{ 3.0, 1.0, 1.0, 1.732050807568877 /*sqrt(3)*/, 0.0 },
// AdjacentList
{ 4.0, 1.0, 1.732050807568877 /*sqrt(3)*/, 1.0, 1.0 },
// HypotenuseList
{ 5.0, 1.414213562373095 /*sqrt(2)*/, 2.0, 2.0, 1.0 },
// NumeratorList
{ 6.5, 5.8, 9.3, 77.0, 0.1 },
// DenominatorList
{ 2.3, 1.6, 3.1, 19.0, 0.4 },
// FModRemainderList
{ 1.9, 1.0, 0.0, 1.0, 0.1 },
// RemainderList
{ -0.4, -0.6, 0.0, 1.0, 0.1 },
// QuotientList
{ 3, 4, 3, 4, 0 },
// XList
{ 4.6, 0.1, 73.4, 55.0, 3.75 },
// FractionalList
{ 0.6, 0.1, 0.4, 0.0, 0.75 },
// FloorList
{ 4.0, 0.0, 73.0, 55.0, 3.0 },
// CeilList
{ 5.0, 1.0, 74.0, 55.0, 4.0 },
// RoundList
{ 5.0, 0.0, 73.0, 55.0, 4.0 },
vtkm::Float64 angleList[NUM_NUMBERS] = { 0.643501108793284, // angle for 3, 4, 5 triangle.
0.78539816339745, // pi/4
0.5235987755983, // pi/6
1.0471975511966, // pi/3
0.0 };
return angleList[i];
}
VTKM_EXEC_CONT vtkm::Float64 OppositeList(vtkm::Int32 i) const
{
vtkm::Float64 oppositeList[NUM_NUMBERS] = { 3.0, 1.0, 1.0, 1.732050807568877 /*sqrt(3)*/, 0.0 };
return oppositeList[i];
}
VTKM_EXEC_CONT vtkm::Float64 AdjacentList(vtkm::Int32 i) const
{
vtkm::Float64 adjacentList[NUM_NUMBERS] = { 4.0, 1.0, 1.732050807568877 /*sqrt(3)*/, 1.0, 1.0 };
return adjacentList[i];
}
VTKM_EXEC_CONT vtkm::Float64 HypotenuseList(vtkm::Int32 i) const
{
vtkm::Float64 hypotenuseList[NUM_NUMBERS] = {
5.0, 1.414213562373095 /*sqrt(2)*/, 2.0, 2.0, 1.0
};
return data;
return hypotenuseList[i];
}
VTKM_EXEC_CONT vtkm::Float64 NumeratorList(vtkm::Int32 i) const
{
vtkm::Float64 numeratorList[NUM_NUMBERS] = { 6.5, 5.8, 9.3, 77.0, 0.1 };
return numeratorList[i];
}
VTKM_EXEC_CONT vtkm::Float64 DenominatorList(vtkm::Int32 i) const
{
vtkm::Float64 denominatorList[NUM_NUMBERS] = { 2.3, 1.6, 3.1, 19.0, 0.4 };
return denominatorList[i];
}
VTKM_EXEC_CONT vtkm::Float64 FModRemainderList(vtkm::Int32 i) const
{
vtkm::Float64 fModRemainderList[NUM_NUMBERS] = { 1.9, 1.0, 0.0, 1.0, 0.1 };
return fModRemainderList[i];
}
VTKM_EXEC_CONT vtkm::Float64 RemainderList(vtkm::Int32 i) const
{
vtkm::Float64 remainderList[NUM_NUMBERS] = { -0.4, -0.6, 0.0, 1.0, 0.1 };
return remainderList[i];
}
VTKM_EXEC_CONT vtkm::Int64 QuotientList(vtkm::Int32 i) const
{
vtkm::Int64 quotientList[NUM_NUMBERS] = { 3, 4, 3, 4, 0 };
return quotientList[i];
}
VTKM_EXEC_CONT vtkm::Float64 XList(vtkm::Int32 i) const
{
vtkm::Float64 xList[NUM_NUMBERS] = { 4.6, 0.1, 73.4, 55.0, 3.75 };
return xList[i];
}
VTKM_EXEC_CONT vtkm::Float64 FractionalList(vtkm::Int32 i) const
{
vtkm::Float64 fractionalList[NUM_NUMBERS] = { 0.6, 0.1, 0.4, 0.0, 0.75 };
return fractionalList[i];
}
VTKM_EXEC_CONT vtkm::Float64 FloorList(vtkm::Int32 i) const
{
vtkm::Float64 floorList[NUM_NUMBERS] = { 4.0, 0.0, 73.0, 55.0, 3.0 };
return floorList[i];
}
VTKM_EXEC_CONT vtkm::Float64 CeilList(vtkm::Int32 i) const
{
vtkm::Float64 ceilList[NUM_NUMBERS] = { 5.0, 1.0, 74.0, 55.0, 4.0 };
return ceilList[i];
}
VTKM_EXEC_CONT vtkm::Float64 RoundList(vtkm::Int32 i) const
{
vtkm::Float64 roundList[NUM_NUMBERS] = { 5.0, 0.0, 73.0, 55.0, 4.0 };
return roundList[i];
}
};
@ -164,7 +170,7 @@ struct ScalarFieldTests : public vtkm::exec::FunctorBase
// std::cout << "Running power tests." << std::endl;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS; index++)
{
T x = static_cast<T>(Lists::Get().NumberList[index]);
T x = static_cast<T>(Lists{}.NumberList(index));
T powx = vtkm::Pow(x, static_cast<T>(2.0));
T sqrx = x * x;
VTKM_MATH_ASSERT(test_equal(powx, sqrx), "Power gave wrong result.");
@ -238,13 +244,14 @@ struct ScalarFieldTests : public vtkm::exec::FunctorBase
void TestRemainders() const
{
// std::cout << "Testing remainders." << std::endl;
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS; index++)
{
T numerator = static_cast<T>(Lists::Get().NumeratorList[index]);
T denominator = static_cast<T>(Lists::Get().DenominatorList[index]);
T fmodremainder = static_cast<T>(Lists::Get().FModRemainderList[index]);
T remainder = static_cast<T>(Lists::Get().RemainderList[index]);
vtkm::Int64 quotient = Lists::Get().QuotientList[index];
T numerator = static_cast<T>(table.NumeratorList(index));
T denominator = static_cast<T>(table.DenominatorList(index));
T fmodremainder = static_cast<T>(table.FModRemainderList(index));
T remainder = static_cast<T>(table.RemainderList(index));
vtkm::Int64 quotient = table.QuotientList(index);
VTKM_MATH_ASSERT(test_equal(vtkm::FMod(numerator, denominator), fmodremainder),
"Bad FMod remainder.");
@ -261,13 +268,14 @@ struct ScalarFieldTests : public vtkm::exec::FunctorBase
void TestRound() const
{
// std::cout << "Testing round." << std::endl;
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS; index++)
{
T x = static_cast<T>(Lists::Get().XList[index]);
T fractional = static_cast<T>(Lists::Get().FractionalList[index]);
T floor = static_cast<T>(Lists::Get().FloorList[index]);
T ceil = static_cast<T>(Lists::Get().CeilList[index]);
T round = static_cast<T>(Lists::Get().RoundList[index]);
T x = static_cast<T>(table.XList(index));
T fractional = static_cast<T>(table.FractionalList(index));
T floor = static_cast<T>(table.FloorList(index));
T ceil = static_cast<T>(table.CeilList(index));
T round = static_cast<T>(table.RoundList(index));
T intPart;
VTKM_MATH_ASSERT(test_equal(vtkm::ModF(x, intPart), fractional),
@ -343,7 +351,7 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
void TestTriangleTrig() const
{
// std::cout << "Testing normal trig functions." << std::endl;
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS - NUM_COMPONENTS + 1; index++)
{
VectorType angle;
@ -352,22 +360,21 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
VectorType hypotenuse;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
Traits::SetComponent(
angle,
componentIndex,
static_cast<ComponentType>(Lists::Get().AngleList[componentIndex + index]));
Traits::SetComponent(angle,
componentIndex,
static_cast<ComponentType>(table.AngleList(componentIndex + index)));
Traits::SetComponent(
opposite,
componentIndex,
static_cast<ComponentType>(Lists::Get().OppositeList[componentIndex + index]));
static_cast<ComponentType>(table.OppositeList(componentIndex + index)));
Traits::SetComponent(
adjacent,
componentIndex,
static_cast<ComponentType>(Lists::Get().AdjacentList[componentIndex + index]));
static_cast<ComponentType>(table.AdjacentList(componentIndex + index)));
Traits::SetComponent(
hypotenuse,
componentIndex,
static_cast<ComponentType>(Lists::Get().HypotenuseList[componentIndex + index]));
static_cast<ComponentType>(table.HypotenuseList(componentIndex + index)));
}
VTKM_MATH_ASSERT(test_equal(vtkm::Sin(angle), opposite / hypotenuse), "Sin failed test.");
@ -400,16 +407,14 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
const VectorType zero(0);
const VectorType half(0.5);
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS - NUM_COMPONENTS + 1; index++)
{
VectorType x;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
Traits::SetComponent(
x,
componentIndex,
static_cast<ComponentType>(Lists::Get().AngleList[componentIndex + index]));
x, componentIndex, static_cast<ComponentType>(table.AngleList(componentIndex + index)));
}
const VectorType minusX = zero - x;
@ -430,14 +435,14 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
template <typename FunctionType>
VTKM_EXEC void RaiseToTest(FunctionType function, ComponentType exponent) const
{
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS - NUM_COMPONENTS + 1; index++)
{
VectorType original;
VectorType raiseresult;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
ComponentType x =
static_cast<ComponentType>(Lists::Get().NumberList[componentIndex + index]);
ComponentType x = static_cast<ComponentType>(table.NumberList(componentIndex + index));
Traits::SetComponent(original, componentIndex, x);
Traits::SetComponent(raiseresult, componentIndex, vtkm::Pow(x, exponent));
}
@ -502,14 +507,14 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
ComponentType exponentbias = 0.0,
ComponentType resultbias = 0.0) const
{
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS - NUM_COMPONENTS + 1; index++)
{
VectorType original;
VectorType raiseresult;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
ComponentType x =
static_cast<ComponentType>(Lists::Get().NumberList[componentIndex + index]);
ComponentType x = static_cast<ComponentType>(table.NumberList(componentIndex + index));
Traits::SetComponent(original, componentIndex, x);
Traits::SetComponent(
raiseresult, componentIndex, vtkm::Pow(base, x + exponentbias) + resultbias);
@ -574,6 +579,7 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
ComponentType base,
ComponentType bias = 0.0) const
{
Lists table;
for (vtkm::IdComponent index = 0; index < Lists::NUM_NUMBERS - NUM_COMPONENTS + 1; index++)
{
VectorType basevector(base);
@ -581,8 +587,7 @@ struct ScalarVectorFieldTests : public vtkm::exec::FunctorBase
VectorType biased;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
ComponentType x =
static_cast<ComponentType>(Lists::Get().NumberList[componentIndex + index]);
ComponentType x = static_cast<ComponentType>(table.NumberList(componentIndex + index));
Traits::SetComponent(original, componentIndex, x);
Traits::SetComponent(biased, componentIndex, x + bias);
}

@ -306,9 +306,8 @@ struct ExternalFaces
vtkm::IdComponent faceIndex = FindFaceIndexForVisit(visitIndex, pointCoordinates);
vtkm::VecCConst<vtkm::IdComponent> localFaceIndices =
vtkm::exec::CellFaceLocalIndices(faceIndex, shape, *this);
vtkm::IdComponent numFacePoints = localFaceIndices.GetNumberOfComponents();
const vtkm::IdComponent numFacePoints =
vtkm::exec::CellFaceNumberOfPoints(faceIndex, shape, *this);
VTKM_ASSERT(numFacePoints == faceConnectivity.GetNumberOfComponents());
typename CellSetType::IndicesType inCellIndices = cellSet.GetIndices(inputIndex);
@ -316,9 +315,11 @@ struct ExternalFaces
shapeOut = vtkm::CELL_SHAPE_QUAD;
numFacePointsOut = 4;
vtkm::exec::detail::CellFaceTables table;
for (vtkm::IdComponent facePointIndex = 0; facePointIndex < numFacePoints; facePointIndex++)
{
faceConnectivity[facePointIndex] = inCellIndices[localFaceIndices[facePointIndex]];
faceConnectivity[facePointIndex] =
inCellIndices[table.PointsInFace(shape.Id, faceIndex, facePointIndex)];
}
}
@ -602,23 +603,27 @@ public:
ConnectivityType& connectivityOut,
vtkm::Id& cellIdMapOut) const
{
vtkm::IdComponent myIndex =
const vtkm::IdComponent myIndex =
ExternalFaces::FindUniqueFace(cellSet, originCells, originFaces, visitIndex, this);
const vtkm::IdComponent myFace = originFaces[myIndex];
typename CellSetType::CellShapeTag shapeIn = cellSet.GetCellShape(originCells[myIndex]);
shapeOut = vtkm::exec::CellFaceShape(originFaces[myIndex], shapeIn, *this);
shapeOut = vtkm::exec::CellFaceShape(myFace, shapeIn, *this);
cellIdMapOut = originCells[myIndex];
vtkm::VecCConst<vtkm::IdComponent> localFaceIndices =
vtkm::exec::CellFaceLocalIndices(originFaces[myIndex], shapeIn, *this);
vtkm::IdComponent numFacePoints = localFaceIndices.GetNumberOfComponents();
const vtkm::IdComponent numFacePoints =
vtkm::exec::CellFaceNumberOfPoints(myFace, shapeIn, *this);
VTKM_ASSERT(numFacePoints == connectivityOut.GetNumberOfComponents());
typename CellSetType::IndicesType inCellIndices = cellSet.GetIndices(originCells[myIndex]);
vtkm::exec::detail::CellFaceTables table;
for (vtkm::IdComponent facePointIndex = 0; facePointIndex < numFacePoints; facePointIndex++)
{
connectivityOut[facePointIndex] = inCellIndices[localFaceIndices[facePointIndex]];
connectivityOut[facePointIndex] =
inCellIndices[table.PointsInFace(shapeIn.Id, myFace, facePointIndex)];
}
}

@ -31,12 +31,12 @@ namespace worklet
{
namespace internal
{
// clang-format off
// table format:
// ncells, {{celltype, nverts, {edge/verts(>=100), ...}}, ...}, \n
// values < 100 represent edges where the corresponding vertex lies
// values >= 100 reresent existing vertices of the input cell (vertex = value - 100)
static const vtkm::UInt8 ClipTablesData[] = {
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::UInt8 ClipTablesData[] = {
// vtkm::CELL_SHAPE_VERTEX
0, // 0
1,
@ -19004,7 +19004,7 @@ static const vtkm::UInt8 ClipTablesData[] = {
};
// Index into ClipTablesData for each shape and configuration
static vtkm::UInt16 ClipTablesIndices[] = {
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::UInt16 ClipTablesIndices[] = {
// vtkm::CELL_SHAPE_VERTEX
0,
1,
@ -19422,7 +19422,7 @@ enum
};
#define X 255
static vtkm::UInt8 CellEdges[CELL_EDGES_SIZE] = {
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::UInt8 CellEdges[CELL_EDGES_SIZE] = {
X, X, X, X, X, X, X, X, X, X, X, X,
X, X, X, X, X, X, X, X, X, X, X, X, // vtkm::CELL_SHAPE_EMPTY_CELL
X, X, X, X, X, X, X, X, X, X, X, X,
@ -19455,6 +19455,7 @@ static vtkm::UInt8 CellEdges[CELL_EDGES_SIZE] = {
2, 4, 3, 4, X, X, X, X, X, X, X, X // vtkm::CELL_SHAPE_PYRAMID
};
#undef X
// clang-format on
class ClipTables
{
@ -19469,7 +19470,7 @@ public:
vtkm::Id GetCaseIndex(vtkm::Id shape, vtkm::Id caseId) const
{
// index into ClipTablesIndices for each shape
static vtkm::Int16 CellIndexLookup[vtkm::NUMBER_OF_CELL_SHAPES] = {
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::Int32 CellIndexLookup[vtkm::NUMBER_OF_CELL_SHAPES] = {
-1, // 0 = vtkm::CELL_SHAPE_EMPTY_CELL
0, // 1 = vtkm::CELL_SHAPE_VERTEX
-1, // 2 = vtkm::CELL_SHAPE_POLY_VERTEX

@ -40,56 +40,55 @@ namespace vtkm
namespace worklet
{
namespace tetrahedralize
{
//
// Worklet to turn hexahedra into tetrahedra
// Vertices remain the same and each cell is processed with needing topology
//
class TetrahedralizeCell : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(CellSetIn cellset, FieldOutCell<> connectivityOut);
typedef void ExecutionSignature(PointIndices, _2, ThreadIndices);
using InputDomain = _1;
using ScatterType = vtkm::worklet::ScatterUniform;
VTKM_CONT
ScatterType GetScatter() const { return ScatterType(5); }
// Each hexahedron cell produces five tetrahedron cells
template <typename ConnectivityInVec, typename ConnectivityOutVec, typename ThreadIndicesType>
VTKM_EXEC void operator()(const ConnectivityInVec& connectivityIn,
ConnectivityOutVec& connectivityOut,
const ThreadIndicesType threadIndices) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::IdComponent StructuredTetrahedronIndices[2][5][4] = {
{ { 0, 1, 3, 4 }, { 1, 4, 5, 6 }, { 1, 4, 6, 3 }, { 1, 3, 6, 2 }, { 3, 6, 7, 4 } },
{ { 2, 1, 5, 0 }, { 0, 2, 3, 7 }, { 2, 5, 6, 7 }, { 0, 7, 4, 5 }, { 0, 2, 7, 5 } }
};
vtkm::Id3 inputIndex = threadIndices.GetInputIndex3D();
// Calculate the type of tetrahedron generated because it alternates
vtkm::Id indexType = (inputIndex[0] + inputIndex[1] + inputIndex[2]) % 2;
vtkm::IdComponent visitIndex = threadIndices.GetVisitIndex();
connectivityOut[0] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][0]];
connectivityOut[1] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][1]];
connectivityOut[2] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][2]];
connectivityOut[3] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][3]];
}
};
}
/// \brief Compute the tetrahedralize cells for a uniform grid data set
template <typename DeviceAdapter>
class TetrahedralizeStructured
{
public:
TetrahedralizeStructured() {}
//
// Worklet to turn hexahedra into tetrahedra
// Vertices remain the same and each cell is processed with needing topology
//
class TetrahedralizeCell : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(CellSetIn cellset, FieldOutCell<> connectivityOut);
typedef void ExecutionSignature(PointIndices, _2, ThreadIndices);
using InputDomain = _1;
using ScatterType = vtkm::worklet::ScatterUniform;
VTKM_CONT
ScatterType GetScatter() const { return ScatterType(5); }
VTKM_CONT
TetrahedralizeCell() {}
// Each hexahedron cell produces five tetrahedron cells
template <typename ConnectivityInVec, typename ConnectivityOutVec, typename ThreadIndicesType>
VTKM_EXEC void operator()(const ConnectivityInVec& connectivityIn,
ConnectivityOutVec& connectivityOut,
const ThreadIndicesType threadIndices) const
{
const static vtkm::IdComponent StructuredTetrahedronIndices[2][5][4] = {
{ { 0, 1, 3, 4 }, { 1, 4, 5, 6 }, { 1, 4, 6, 3 }, { 1, 3, 6, 2 }, { 3, 6, 7, 4 } },
{ { 2, 1, 5, 0 }, { 0, 2, 3, 7 }, { 2, 5, 6, 7 }, { 0, 7, 4, 5 }, { 0, 2, 7, 5 } }
};
vtkm::Id3 inputIndex = threadIndices.GetInputIndex3D();
// Calculate the type of tetrahedron generated because it alternates
vtkm::Id indexType = (inputIndex[0] + inputIndex[1] + inputIndex[2]) % 2;
vtkm::IdComponent visitIndex = threadIndices.GetVisitIndex();
connectivityOut[0] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][0]];
connectivityOut[1] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][1]];
connectivityOut[2] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][2]];
connectivityOut[3] = connectivityIn[StructuredTetrahedronIndices[indexType][visitIndex][3]];
}
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
@ -99,7 +98,8 @@ public:
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::worklet::DispatcherMapTopology<TetrahedralizeCell, DeviceAdapter> dispatcher;
vtkm::worklet::DispatcherMapTopology<tetrahedralize::TetrahedralizeCell, DeviceAdapter>
dispatcher;
dispatcher.Invoke(cellSet, vtkm::cont::make_ArrayHandleGroupVec<4>(connectivity));
// Fill in array of output cells per input cell

@ -39,46 +39,43 @@ namespace vtkm
{
namespace worklet
{
namespace triangulate
{
//
// Worklet to turn quads into triangles
// Vertices remain the same and each cell is processed with needing topology
//
class TriangulateCell : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(CellSetIn cellset, FieldOutCell<> connectivityOut);
typedef void ExecutionSignature(PointIndices, _2, VisitIndex);
using InputDomain = _1;
using ScatterType = vtkm::worklet::ScatterUniform;
VTKM_CONT
ScatterType GetScatter() const { return ScatterType(2); }
// Each quad cell produces 2 triangle cells
template <typename ConnectivityInVec, typename ConnectivityOutVec>
VTKM_EXEC void operator()(const ConnectivityInVec& connectivityIn,
ConnectivityOutVec& connectivityOut,
vtkm::IdComponent visitIndex) const
{
VTKM_STATIC_CONSTEXPR_ARRAY vtkm::IdComponent StructuredTriangleIndices[2][3] = { { 0, 1, 2 },
{ 0, 2, 3 } };
connectivityOut[0] = connectivityIn[StructuredTriangleIndices[visitIndex][0]];
connectivityOut[1] = connectivityIn[StructuredTriangleIndices[visitIndex][1]];
connectivityOut[2] = connectivityIn[StructuredTriangleIndices[visitIndex][2]];
}
};
}
/// \brief Compute the triangulate cells for a uniform grid data set
template <typename DeviceAdapter>
class TriangulateStructured
{
public:
TriangulateStructured() {}
//
// Worklet to turn quads into triangles
// Vertices remain the same and each cell is processed with needing topology
//
class TriangulateCell : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(CellSetIn cellset, FieldOutCell<> connectivityOut);
typedef void ExecutionSignature(PointIndices, _2, VisitIndex);
using InputDomain = _1;
using ScatterType = vtkm::worklet::ScatterUniform;
VTKM_CONT
ScatterType GetScatter() const { return ScatterType(2); }
VTKM_CONT
TriangulateCell() {}
// Each quad cell produces 2 triangle cells
template <typename ConnectivityInVec, typename ConnectivityOutVec>
VTKM_EXEC void operator()(const ConnectivityInVec& connectivityIn,
ConnectivityOutVec& connectivityOut,
vtkm::IdComponent visitIndex) const
{
const static vtkm::IdComponent StructuredTriangleIndices[2][3] = { { 0, 1, 2 }, { 0, 2, 3 } };
connectivityOut[0] = connectivityIn[StructuredTriangleIndices[visitIndex][0]];
connectivityOut[1] = connectivityIn[StructuredTriangleIndices[visitIndex][1]];
connectivityOut[2] = connectivityIn[StructuredTriangleIndices[visitIndex][2]];
}
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
@ -89,7 +86,7 @@ public:
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::worklet::DispatcherMapTopology<TriangulateCell, DeviceAdapter> dispatcher;
vtkm::worklet::DispatcherMapTopology<triangulate::TriangulateCell, DeviceAdapter> dispatcher;
dispatcher.Invoke(cellSet, vtkm::cont::make_ArrayHandleGroupVec<3>(connectivity));
// Fill in array of output cells per input cell