vtk-m/vtkm/rendering/raytracing/MeshConnectivityStructures.h
Robert Maynard 601a839d5d 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.
2018-02-26 16:41:29 -05:00

773 lines
26 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_rendering_raytracing_MeshConnectivityStructures_h
#define vtk_m_rendering_raytracing_MeshConnectivityStructures_h
#include <sstream>
#include <vtkm/CellShape.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
#include <vtkm/rendering/raytracing/Logger.h>
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
#include <vtkm/rendering/raytracing/Ray.h>
#include <vtkm/rendering/raytracing/TriangleIntersector.h>
namespace vtkm
{
namespace rendering
{
namespace raytracing
{
// MeshConnectivityStrucutures:
// Policy classes for different types of meshes. Each implemented class
// Must implement GetConnetingCell( indexOfCurrentCell, face) that returns
// the index of the cell that connects to the "face" of the current cell.
// Each policy should have a copy constructor to facilitate clean passing
// to worklets (i.e., initialize execution portals if needed).
//
// Primary template for MeshConnExec Object
//
template <typename MeshType, typename Device>
class MeshConnExec
{
};
class UnstructuredMeshConn
{
public:
typedef vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
typedef vtkm::cont::ArrayHandle<vtkm::UInt8> UCharHandle;
// Control Environment Handles
// FaceConn
IdHandle FaceConnectivity;
IdHandle FaceOffsets;
//Cell Set
IdHandle CellConn;
IdHandle CellOffsets;
UCharHandle Shapes;
// Mesh Boundary
Id4Handle ExternalTriangles;
LinearBVH Bvh;
vtkm::Bounds CoordinateBounds;
vtkm::cont::CellSetExplicit<> Cellset;
vtkm::cont::CoordinateSystem Coords;
protected:
bool IsConstructed;
private:
VTKM_CONT
UnstructuredMeshConn(){};
public:
VTKM_CONT
UnstructuredMeshConn(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::cont::CoordinateSystem& coords)
: IsConstructed(false)
{
Coords = coords;
if (!cellset.IsSameType(vtkm::cont::CellSetExplicit<>()))
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Error: not an explicit cell set!");
}
Cellset = cellset.Cast<vtkm::cont::CellSetExplicit<>>();
//
// Grab the cell arrays
//
CellConn =
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
CellOffsets =
Cellset.GetIndexOffsetArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
Shapes =
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
}
//----------------------------------------------------------------------------
template <typename T>
VTKM_CONT UnstructuredMeshConn(const T& other)
: FaceConnectivity(other.FaceConnectivity)
, FaceOffsets(other.FaceOffsets)
, CellConn(other.CellConn)
, CellOffsets(other.CellOffsets)
, Shapes(other.Shapes)
, ExternalTriangles(other.ExternalTriangles)
, Bvh(other.Bvh)
, CoordinateBounds(other.CoordinateBounds)
, Cellset(other.Cellset)
, Coords(other.Coords)
, IsConstructed(other.IsConstructed)
{
}
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT void Construct(Device)
{
Logger* logger = Logger::GetInstance();
logger->OpenLogEntry("mesh_conn_construction");
vtkm::cont::Timer<Device> timer;
if (!IsConstructed)
{
CoordinateBounds = Coords.GetBounds();
MeshConnectivityBuilder<Device> connBuilder;
//
// Build the face-to-face connectivity
//
connBuilder.BuildConnectivity(Cellset, Coords.GetData(), CoordinateBounds);
//
// Initialize all of the array handles
//
FaceConnectivity = connBuilder.GetFaceConnectivity();
FaceOffsets = connBuilder.GetFaceOffsets();
ExternalTriangles = connBuilder.GetExternalTriangles();
//
// Build BVH on external triangles
//
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
Bvh.ConstructOnDevice(Device());
IsConstructed = true;
}
vtkm::Float64 time = timer.GetElapsedTime();
logger->CloseLogEntry(time);
}
//----------------------------------------------------------------------------
template <typename T, typename Device>
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
{
if (!IsConstructed)
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Error: FindEntry called before Construct");
}
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
bool getCellIndex = true;
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
}
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::Id GetNumberOfCells() { return this->Shapes.GetPortalConstControl().GetNumberOfValues(); }
//----------------------------------------------------------------------------
// Control Environment Methods
//----------------------------------------------------------------------------
VTKM_CONT
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
{
CoordinateBounds = Coords.GetBounds();
return CoordinateBounds;
}
//----------------------------------------------------------------------------
VTKM_CONT
bool GetIsConstructed() { return IsConstructed; }
}; //Unstructure mesh conn
template <typename Device>
class MeshConnExec<UnstructuredMeshConn, Device>
{
protected:
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
typedef typename vtkm::cont::ArrayHandle<vtkm::UInt8> UCharHandle;
typedef typename IdHandle::ExecutionTypes<Device>::PortalConst IdConstPortal;
typedef typename UCharHandle::ExecutionTypes<Device>::PortalConst UCharConstPortal;
// Constant Portals for the execution Environment
//FaceConn
IdConstPortal FaceConnPortal;
IdConstPortal FaceOffsetsPortal;
//Cell Set
IdConstPortal CellConnPortal;
IdConstPortal CellOffsetsPortal;
UCharConstPortal ShapesPortal;
private:
VTKM_CONT
MeshConnExec(){};
public:
VTKM_CONT
MeshConnExec(UnstructuredMeshConn& conn)
: FaceConnPortal(conn.FaceConnectivity.PrepareForInput(Device()))
, FaceOffsetsPortal(conn.FaceOffsets.PrepareForInput(Device()))
, CellConnPortal(conn.CellConn.PrepareForInput(Device()))
, CellOffsetsPortal(conn.CellOffsets.PrepareForInput(Device()))
, ShapesPortal(conn.Shapes.PrepareForInput(Device()))
{
if (!conn.GetIsConstructed())
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Error: GetExecObj called before Construct");
}
}
//----------------------------------------------------------------------------
template <typename T>
VTKM_CONT MeshConnExec(const T& other)
: FaceConnPortal(other.FaceConnPortal)
, FaceOffsetsPortal(other.FaceConnPortal)
, CellConnPortal(other.CellConnPortal)
, CellOffsetsPortal(other.CellOffsetsPortal)
, ShapesPortal(other.ShapesPortal)
{
}
//----------------------------------------------------------------------------
// Execution Environment Methods
//----------------------------------------------------------------------------
VTKM_EXEC
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
{
BOUNDS_CHECK(FaceOffsetsPortal, cellId);
vtkm::Id cellStartIndex = FaceOffsetsPortal.Get(cellId);
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
return FaceConnPortal.Get(cellStartIndex + face);
}
//----------------------------------------------------------------------------
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 = tables.FaceLookUp(tables.CellTypeLookUp(shapeId), 2);
BOUNDS_CHECK(CellOffsetsPortal, cellId);
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
for (vtkm::Int32 i = 0; i < numIndices; ++i)
{
BOUNDS_CHECK(CellConnPortal, cellOffset + i);
cellIndices[i] = CellConnPortal.Get(cellOffset + i);
}
return numIndices;
}
//----------------------------------------------------------------------------
VTKM_EXEC
inline vtkm::UInt8 GetCellShape(const vtkm::Id& cellId) const
{
BOUNDS_CHECK(ShapesPortal, cellId)
return ShapesPortal.Get(cellId);
}
}; //Unstructure mesh conn exec
// Specialized version for unstructured meshes consisting of
// a single type of cell.
class UnstructuredMeshConnSingleType
{
public:
typedef vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
typedef vtkm::cont::ArrayHandleCounting<vtkm::Id> CountingHandle;
typedef vtkm::cont::ArrayHandleConstant<vtkm::UInt8> ShapesHandle;
typedef vtkm::cont::ArrayHandleConstant<vtkm::IdComponent> NumIndicesHandle;
// Control Environment Handles
IdHandle FaceConnectivity;
CountingHandle CellOffsets;
IdHandle CellConnectivity;
// Mesh Boundary
LinearBVH Bvh;
Id4Handle ExternalTriangles;
vtkm::Bounds CoordinateBounds;
vtkm::cont::CoordinateSystem Coords;
vtkm::cont::CellSetSingleType<> Cellset;
vtkm::Int32 ShapeId;
vtkm::Int32 NumIndices;
vtkm::Int32 NumFaces;
protected:
bool IsConstructed;
private:
VTKM_CONT
UnstructuredMeshConnSingleType() {}
public:
VTKM_CONT
UnstructuredMeshConnSingleType(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::cont::CoordinateSystem& coords)
: IsConstructed(false)
{
Coords = coords;
if (!cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Single type Error: not an single type cell set!");
}
Cellset = cellset.Cast<vtkm::cont::CellSetSingleType<>>();
CellConnectivity =
Cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
Cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
CellTables tables;
ShapeId = shapes.GetPortalConstControl().Get(0);
NumIndices = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 2);
if (NumIndices == 0)
{
std::stringstream message;
message << "Unstructured Mesh Connecitity Single type Error: unsupported cell type: ";
message << ShapeId;
throw vtkm::cont::ErrorBadValue(message.str());
}
vtkm::Id start = 0;
NumFaces = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 1);
vtkm::Id numCells = CellConnectivity.GetPortalConstControl().GetNumberOfValues();
CellOffsets = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start, NumIndices, numCells);
//
// Initialize all of the array portals
//
}
template <typename T>
VTKM_CONT UnstructuredMeshConnSingleType(const T& other)
: FaceConnectivity(other.FaceConnectivity)
, CellOffsets(other.CellOffsets)
, CellConnectivity(other.CellConnectivity)
, Bvh(other.Bvh)
, ExternalTriangles(other.ExternalTriangles)
, CoordinateBounds(other.CoordinateBounds)
, Coords(other.coords)
, Cellset(other.Cellset)
, ShapeId(other.ShapeId)
, NumIndices(other.NumIndices)
, NumFaces(other.NumFaces)
, IsConstructed(other.IsConstructed)
{
}
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT void Construct(Device)
{
Logger* logger = Logger::GetInstance();
logger->OpenLogEntry("mesh_conn_construction");
vtkm::cont::Timer<Device> timer;
if (!IsConstructed)
{
CoordinateBounds = Coords.GetBounds();
MeshConnectivityBuilder<Device> connBuilder;
//
// Build the face-to-face connectivity
//
connBuilder.BuildConnectivity(Cellset, Coords.GetData(), CoordinateBounds);
//
// Initialize all of the array handles
//
FaceConnectivity = connBuilder.GetFaceConnectivity();
ExternalTriangles = connBuilder.GetExternalTriangles();
//
// Build BVH on external triangles
//
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
Bvh.ConstructOnDevice(Device());
IsConstructed = true;
}
vtkm::Float64 time = timer.GetElapsedTime();
logger->CloseLogEntry(time);
}
//----------------------------------------------------------------------------
template <typename T, typename Device>
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
{
if (!IsConstructed)
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Single Error: FindEntry called before Construct");
}
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
bool getCellIndex = true;
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
}
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::Id GetNumberOfCells() { return this->Cellset.GetNumberOfCells(); }
//----------------------------------------------------------------------------
VTKM_CONT
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
{
CoordinateBounds = Coords.GetBounds();
return CoordinateBounds;
}
//----------------------------------------------------------------------------
VTKM_CONT
bool GetIsConstructed() { return IsConstructed; }
}; //UnstructuredMeshConn Single Type
template <typename Device>
class MeshConnExec<UnstructuredMeshConnSingleType, Device>
{
protected:
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdHandle;
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
typedef typename vtkm::cont::ArrayHandleCounting<vtkm::Id> CountingHandle;
typedef typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8> ShapesHandle;
typedef typename IdHandle::ExecutionTypes<Device>::PortalConst IdConstPortal;
typedef typename CountingHandle::ExecutionTypes<Device>::PortalConst CountingPortal;
typedef typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent> NumIndicesHandle;
// Constant Portals for the execution Environment
IdConstPortal FaceConnPortal;
IdConstPortal CellConnectivityPortal;
CountingPortal CellOffsetsPortal;
vtkm::Int32 ShapeId;
vtkm::Int32 NumIndices;
vtkm::Int32 NumFaces;
private:
VTKM_CONT
MeshConnExec() {}
public:
VTKM_CONT
MeshConnExec(UnstructuredMeshConnSingleType& conn)
: FaceConnPortal(conn.FaceConnectivity.PrepareForInput(Device()))
, CellConnectivityPortal(conn.CellConnectivity.PrepareForInput(Device()))
, CellOffsetsPortal(conn.CellOffsets.PrepareForInput(Device()))
, ShapeId(conn.ShapeId)
, NumIndices(conn.NumIndices)
, NumFaces(conn.NumFaces)
{
if (!conn.GetIsConstructed())
{
throw vtkm::cont::ErrorBadValue(
"Unstructured Mesh Connecitity Single Error: GetExecObj called before Construct");
}
}
template <typename T>
VTKM_CONT MeshConnExec(const T& other)
: FaceConnPortal(other.FaceConnPortal)
, CellOffsetsPortal(other.CellOffsetsPortal)
, CellConnectivityPortal(other.CellConnectivityPortal)
, ShapeId(other.ShapeId)
, NumIndices(other.NumIndices)
, NumFaces(other.NumFaces)
{
}
//----------------------------------------------------------------------------
// Execution Environment Methods
//----------------------------------------------------------------------------
VTKM_EXEC
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
{
BOUNDS_CHECK(CellOffsetsPortal, cellId);
vtkm::Id cellStartIndex = cellId * NumFaces;
BOUNDS_CHECK(FaceConnPortal, cellStartIndex + face);
return FaceConnPortal.Get(cellStartIndex + face);
}
VTKM_EXEC
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellId) const
{
BOUNDS_CHECK(CellOffsetsPortal, cellId);
const vtkm::Id cellOffset = CellOffsetsPortal.Get(cellId);
for (vtkm::Int32 i = 0; i < NumIndices; ++i)
{
BOUNDS_CHECK(CellConnectivityPortal, cellOffset + i);
cellIndices[i] = CellConnectivityPortal.Get(cellOffset + i);
}
return NumIndices;
}
//----------------------------------------------------------------------------
VTKM_EXEC
inline vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const
{
return vtkm::UInt8(ShapeId);
}
}; //MeshConn Single type specialization
class StructuredMeshConn
{
public:
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
vtkm::Id3 CellDims;
vtkm::Id3 PointDims;
vtkm::Bounds CoordinateBounds;
vtkm::cont::CoordinateSystem Coords;
vtkm::cont::CellSetStructured<3> Cellset;
// Mesh Boundary
LinearBVH Bvh;
Id4Handle ExternalTriangles;
protected:
bool IsConstructed;
private:
VTKM_CONT
StructuredMeshConn() {}
public:
VTKM_CONT
StructuredMeshConn(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::cont::CoordinateSystem& coords)
: IsConstructed(false)
{
Coords = coords;
if (!cellset.IsSameType(vtkm::cont::CellSetStructured<3>()))
{
throw vtkm::cont::ErrorBadValue(
"Structured Mesh Connecitity Error: not a Structured<3> cell set!");
}
Cellset = cellset.Cast<vtkm::cont::CellSetStructured<3>>();
PointDims = Cellset.GetPointDimensions();
CellDims = Cellset.GetCellDimensions();
}
template <typename T>
VTKM_CONT StructuredMeshConn(const T& other)
: CellDims(other.CellDims)
, PointDims(other.PointDims)
, CoordinateBounds(other.CoordinateBounds)
, Coords(other.coords)
, Cellset(other.Cellset)
, Bvh(other.Bvh)
, ExternalTriangles(other.ExternalTriangles)
, IsConstructed(other.IsConstructed)
{
}
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT void Construct(Device)
{
Logger* logger = Logger::GetInstance();
logger->OpenLogEntry("mesh_conn_construction");
vtkm::cont::Timer<Device> timer;
if (!IsConstructed)
{
CoordinateBounds = Coords.GetBounds();
MeshConnectivityBuilder<Device> connBuilder;
ExternalTriangles = connBuilder.ExternalTrianglesStructured(Cellset);
//
// Build BVH on external triangles
//
Bvh.SetData(Coords.GetData(), ExternalTriangles, Coords.GetBounds());
Bvh.ConstructOnDevice(Device());
IsConstructed = true;
}
vtkm::Float64 time = timer.GetElapsedTime();
logger->CloseLogEntry(time);
}
//----------------------------------------------------------------------------
template <typename T, typename Device>
VTKM_CONT void FindEntry(Ray<T>& rays, Device)
{
if (!IsConstructed)
{
throw vtkm::cont::ErrorBadValue(
"Structured Mesh Connecitity Single Error: FindEntry called before Construct");
}
TriangleIntersector<Device, TriLeafIntersector<WaterTight<T>>> intersector;
bool getCellIndex = true;
intersector.runHitOnly(rays, Bvh, Coords.GetData(), getCellIndex);
}
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::Id GetNumberOfCells() { return this->CellDims[0] * this->CellDims[1] * this->CellDims[2]; }
//----------------------------------------------------------------------------
// Control Environment Methods
//----------------------------------------------------------------------------
VTKM_CONT
Id4Handle GetExternalTriangles() { return ExternalTriangles; }
//----------------------------------------------------------------------------
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates GetCoordinates() { return Coords.GetData(); }
//----------------------------------------------------------------------------
template <typename Device>
VTKM_CONT vtkm::Bounds GetCoordinateBounds(Device)
{
CoordinateBounds = Coords.GetBounds();
return CoordinateBounds;
}
//----------------------------------------------------------------------------
VTKM_CONT
bool GetIsConstructed() { return IsConstructed; }
}; //structure mesh conn
template <typename Device>
class MeshConnExec<StructuredMeshConn, Device>
{
protected:
typedef typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Id4Handle;
vtkm::Id3 CellDims;
vtkm::Id3 PointDims;
vtkm::Bounds CoordinateBounds;
private:
VTKM_CONT
MeshConnExec() {}
public:
VTKM_CONT
MeshConnExec(const StructuredMeshConn& other)
: CellDims(other.CellDims)
, PointDims(other.PointDims)
, CoordinateBounds(other.CoordinateBounds)
{
}
template <typename T>
VTKM_CONT MeshConnExec(const T& other)
: CellDims(other.CellDims)
, PointDims(other.PointDims)
, CoordinateBounds(other.CoordinateBounds)
{
}
//----------------------------------------------------------------------------
// Execution Environment Methods
//----------------------------------------------------------------------------
VTKM_EXEC_CONT
inline vtkm::Id GetConnectingCell(const vtkm::Id& cellId, const vtkm::Id& face) const
{
//TODO: there is probably a better way to do this.
vtkm::Id3 logicalCellId;
logicalCellId[0] = cellId % CellDims[0];
logicalCellId[1] = (cellId / CellDims[0]) % CellDims[1];
logicalCellId[2] = cellId / (CellDims[0] * CellDims[1]);
if (face == 0)
logicalCellId[1] -= 1;
if (face == 2)
logicalCellId[1] += 1;
if (face == 1)
logicalCellId[0] += 1;
if (face == 3)
logicalCellId[0] -= 1;
if (face == 4)
logicalCellId[2] -= 1;
if (face == 5)
logicalCellId[2] += 1;
vtkm::Id nextCell =
(logicalCellId[2] * CellDims[1] + logicalCellId[1]) * CellDims[0] + logicalCellId[0];
bool validCell = true;
if (logicalCellId[0] >= CellDims[0])
validCell = false;
if (logicalCellId[1] >= CellDims[1])
validCell = false;
if (logicalCellId[2] >= CellDims[2])
validCell = false;
vtkm::Id minId = vtkm::Min(logicalCellId[0], vtkm::Min(logicalCellId[1], logicalCellId[2]));
if (minId < 0)
validCell = false;
if (!validCell)
nextCell = -1;
return nextCell;
}
//----------------------------------------------------------------------------
VTKM_EXEC_CONT
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8], const vtkm::Id& cellIndex) const
{
vtkm::Id3 cellId;
cellId[0] = cellIndex % CellDims[0];
cellId[1] = (cellIndex / CellDims[0]) % CellDims[1];
cellId[2] = cellIndex / (CellDims[0] * CellDims[1]);
cellIndices[0] = (cellId[2] * PointDims[1] + cellId[1]) * PointDims[0] + cellId[0];
cellIndices[1] = cellIndices[0] + 1;
cellIndices[2] = cellIndices[1] + PointDims[0];
cellIndices[3] = cellIndices[2] - 1;
cellIndices[4] = cellIndices[0] + PointDims[0] * PointDims[1];
cellIndices[5] = cellIndices[4] + 1;
cellIndices[6] = cellIndices[5] + PointDims[0];
cellIndices[7] = cellIndices[6] - 1;
return 8;
}
//----------------------------------------------------------------------------
VTKM_EXEC_CONT
inline vtkm::Int32 GetCellIndices(vtkm::Id cellIndices[8],
const vtkm::Vec<vtkm::Id, 3>& cellId) const
{
cellIndices[0] = (cellId[2] * PointDims[1] + cellId[1]) * PointDims[0] + cellId[0];
cellIndices[1] = cellIndices[0] + 1;
cellIndices[2] = cellIndices[1] + PointDims[0];
cellIndices[3] = cellIndices[2] - 1;
cellIndices[4] = cellIndices[0] + PointDims[0] * PointDims[1];
cellIndices[5] = cellIndices[4] + 1;
cellIndices[6] = cellIndices[5] + PointDims[0];
cellIndices[7] = cellIndices[6] - 1;
return 8;
}
//----------------------------------------------------------------------------
VTKM_EXEC
inline vtkm::UInt8 GetCellShape(const vtkm::Id& vtkmNotUsed(cellId)) const
{
return vtkm::UInt8(CELL_SHAPE_HEXAHEDRON);
}
}; //Unstructure mesh conn
}
}
} //namespace vtkm::rendering::raytracing
#endif