vtk-m/vtkm/rendering/raytracing/CellSampler.h
Kenneth Moreland 51e817adc1 Introduce vtkm::ErrorCode
This is a flag that functions in the execution environment can return to
report on the status of the operation. This way they can report an error
without forcing the entire invocation to shut down.
2020-03-13 18:58:33 -06:00

285 lines
8.4 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.
//============================================================================
#ifndef vtk_m_rendering_raytracing_CellSampler_h
#define vtk_m_rendering_raytracing_CellSampler_h
#include <vtkm/VecVariable.h>
#include <vtkm/exec/CellInterpolate.h>
#include <vtkm/exec/ParametricCoordinates.h>
#ifndef CELL_SHAPE_ZOO
#define CELL_SHAPE_ZOO 255
#endif
#ifndef CELL_SHAPE_STRUCTURED
#define CELL_SHAPE_STRUCTURED 254
#endif
namespace vtkm
{
namespace rendering
{
namespace raytracing
{
namespace detail
{
template <typename CellTag>
VTKM_EXEC_CONT inline vtkm::Int32 GetNumberOfPoints(CellTag tag);
template <>
VTKM_EXEC_CONT inline vtkm::Int32 GetNumberOfPoints<vtkm::CellShapeTagHexahedron>(
vtkm::CellShapeTagHexahedron vtkmNotUsed(tag))
{
return 8;
}
template <>
VTKM_EXEC_CONT inline vtkm::Int32 GetNumberOfPoints<vtkm::CellShapeTagTetra>(
vtkm::CellShapeTagTetra vtkmNotUsed(tag))
{
return 4;
}
template <>
VTKM_EXEC_CONT inline vtkm::Int32 GetNumberOfPoints<vtkm::CellShapeTagWedge>(
vtkm::CellShapeTagWedge vtkmNotUsed(tag))
{
return 6;
}
template <>
VTKM_EXEC_CONT inline vtkm::Int32 GetNumberOfPoints<vtkm::CellShapeTagPyramid>(
vtkm::CellShapeTagPyramid vtkmNotUsed(tag))
{
return 5;
}
template <typename P, typename S, typename CellShapeTagType>
VTKM_EXEC_CONT inline bool Sample(const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const CellShapeTagType& shapeTag)
{
bool validSample = true;
vtkm::VecVariable<vtkm::Vec<P, 3>, 8> pointsVec;
vtkm::VecVariable<S, 8> scalarVec;
for (vtkm::Int32 i = 0; i < GetNumberOfPoints(shapeTag); ++i)
{
pointsVec.Append(points[i]);
scalarVec.Append(scalars[i]);
}
vtkm::Vec<P, 3> pcoords;
vtkm::exec::WorldCoordinatesToParametricCoordinates(pointsVec, sampleLocation, shapeTag, pcoords);
P pmin, pmax;
pmin = vtkm::Min(vtkm::Min(pcoords[0], pcoords[1]), pcoords[2]);
pmax = vtkm::Max(vtkm::Max(pcoords[0], pcoords[1]), pcoords[2]);
if (pmin < 0.f || pmax > 1.f)
{
validSample = false;
}
vtkm::exec::CellInterpolate(scalarVec, pcoords, shapeTag, lerpedScalar);
return validSample;
}
template <typename S, typename P, typename CellShapeTagType>
VTKM_EXEC_CONT inline bool Sample(const vtkm::VecAxisAlignedPointCoordinates<3>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const CellShapeTagType& vtkmNotUsed(shapeTag))
{
bool validSample = true;
vtkm::Vec<P, 3> pcoords;
vtkm::exec::WorldCoordinatesToParametricCoordinates(
points, sampleLocation, vtkm::CellShapeTagHexahedron(), pcoords);
P pmin, pmax;
pmin = vtkm::Min(vtkm::Min(pcoords[0], pcoords[1]), pcoords[2]);
pmax = vtkm::Max(vtkm::Max(pcoords[0], pcoords[1]), pcoords[2]);
if (pmin < 0.f || pmax > 1.f)
{
validSample = false;
}
vtkm::exec::CellInterpolate(scalars, pcoords, vtkm::CellShapeTagHexahedron(), lerpedScalar);
return validSample;
}
} // namespace detail
//
// General Template: returns false if sample location is outside the cell
//
template <int CellType>
class CellSampler
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(const vtkm::Vec<vtkm::Vec<P, 3>, 8>& vtkmNotUsed(points),
const vtkm::Vec<S, 8>& vtkmNotUsed(scalars),
const vtkm::Vec<P, 3>& vtkmNotUsed(sampleLocation),
S& vtkmNotUsed(lerpedScalar),
const vtkm::Int32& vtkmNotUsed(cellShape = CellType)) const
{
static_assert(CellType != CELL_SHAPE_ZOO && CellType != CELL_SHAPE_STRUCTURED &&
CellType != CELL_SHAPE_HEXAHEDRON && CellType != CELL_SHAPE_TETRA &&
CellType != CELL_SHAPE_WEDGE && CellType != CELL_SHAPE_PYRAMID,
"Cell Sampler: Default template. This should not happen.\n");
return false;
}
};
//
// Zoo Sampler
//
template <>
class CellSampler<255>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& cellShape) const
{
bool valid = false;
if (cellShape == CELL_SHAPE_HEXAHEDRON)
{
valid = detail::Sample(
points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagHexahedron());
}
if (cellShape == CELL_SHAPE_TETRA)
{
valid =
detail::Sample(points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagTetra());
}
if (cellShape == CELL_SHAPE_WEDGE)
{
valid =
detail::Sample(points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagWedge());
}
if (cellShape == CELL_SHAPE_PYRAMID)
{
valid =
detail::Sample(points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagPyramid());
}
return valid;
}
};
//
// Single type hex
//
template <>
class CellSampler<CELL_SHAPE_HEXAHEDRON>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(
const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& vtkmNotUsed(cellShape = CELL_SHAPE_HEXAHEDRON)) const
{
return detail::Sample(
points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagHexahedron());
}
};
//
// Single type hex uniform and rectilinear
// calls fast path for sampling
//
template <>
class CellSampler<CELL_SHAPE_STRUCTURED>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(
const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& vtkmNotUsed(cellShape = CELL_SHAPE_HEXAHEDRON)) const
{
vtkm::VecAxisAlignedPointCoordinates<3> rPoints(points[0], points[6] - points[0]);
return detail::Sample(
rPoints, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagHexahedron());
}
};
//
// Single type pyramid
//
template <>
class CellSampler<CELL_SHAPE_PYRAMID>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(
const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& vtkmNotUsed(cellShape = CELL_SHAPE_PYRAMID)) const
{
return detail::Sample(
points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagPyramid());
}
};
//
// Single type Tet
//
template <>
class CellSampler<CELL_SHAPE_TETRA>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(
const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& vtkmNotUsed(cellShape = CELL_SHAPE_TETRA)) const
{
return detail::Sample(points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagTetra());
}
};
//
// Single type Wedge
//
template <>
class CellSampler<CELL_SHAPE_WEDGE>
{
public:
template <typename P, typename S>
VTKM_EXEC_CONT inline bool SampleCell(
const vtkm::Vec<vtkm::Vec<P, 3>, 8>& points,
const vtkm::Vec<S, 8>& scalars,
const vtkm::Vec<P, 3>& sampleLocation,
S& lerpedScalar,
const vtkm::Int32& vtkmNotUsed(cellShape = CELL_SHAPE_WEDGE)) const
{
return detail::Sample(points, scalars, sampleLocation, lerpedScalar, vtkm::CellShapeTagWedge());
}
};
}
}
} // namespace vtkm::rendering::raytracing
#endif