Add ImplicitFunctionGeneral

This commit is contained in:
Kenneth Moreland 2021-02-18 16:40:56 -07:00
parent 5ab9ddb637
commit 180d11e7f2
2 changed files with 108 additions and 3 deletions

@ -14,11 +14,16 @@
#include <vtkm/Deprecated.h>
#include <vtkm/Math.h>
#include <vtkm/VectorAnalysis.h>
#include <vtkm/VirtualObjectBase.h>
#include <vtkm/exec/internal/Variant.h>
// For interface class only.
#include <vtkm/cont/ExecutionAndControlObjectBase.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/VirtualObjectBase.h>
#endif // VTKM_NO_DEPRECATED_VIRTUAL
namespace vtkm
{
@ -778,6 +783,84 @@ private:
Vector Center;
};
namespace detail
{
struct ImplicitFunctionValueFunctor
{
template <typename ImplicitFunctionType>
VTKM_EXEC_CONT typename ImplicitFunctionType::Scalar operator()(
const ImplicitFunctionType& function,
const typename ImplicitFunctionType::Vector& point) const
{
return function.Value(point);
}
};
struct ImplicitFunctionGradientFunctor
{
template <typename ImplicitFunctionType>
VTKM_EXEC_CONT typename ImplicitFunctionType::Vector operator()(
const ImplicitFunctionType& function,
const typename ImplicitFunctionType::Vector& point) const
{
return function.Gradient(point);
}
};
} // namespace detail
template <typename... ImplicitFunctionTypes>
class ImplicitFunctionMultiplexer
: public vtkm::internal::ImplicitFunctionBase<
ImplicitFunctionMultiplexer<ImplicitFunctionTypes...>>
{
vtkm::exec::internal::Variant<ImplicitFunctionTypes...> Variant;
using Superclass =
vtkm::internal::ImplicitFunctionBase<ImplicitFunctionMultiplexer<ImplicitFunctionTypes...>>;
public:
using Scalar = typename Superclass::Scalar;
using Vector = typename Superclass::Vector;
VTKM_EXEC_CONT ImplicitFunctionMultiplexer() = default;
template <typename FunctionType>
VTKM_EXEC_CONT ImplicitFunctionMultiplexer(
const vtkm::internal::ImplicitFunctionBase<FunctionType>& function)
: Variant(reinterpret_cast<const FunctionType&>(function))
{
}
VTKM_EXEC_CONT Scalar Value(const Vector& point) const
{
return this->Variant.CastAndCall(detail::ImplicitFunctionValueFunctor{}, point);
}
VTKM_EXEC_CONT Vector Gradient(const Vector& point) const
{
return this->Variant.CastAndCall(detail::ImplicitFunctionGradientFunctor{}, point);
}
};
class ImplicitFunctionGeneral
: public vtkm::ImplicitFunctionMultiplexer<vtkm::Box,
vtkm::Cylinder,
vtkm::Frustum,
vtkm::Plane,
vtkm::Sphere>
{
using Superclass = vtkm::ImplicitFunctionMultiplexer<vtkm::Box,
vtkm::Cylinder,
vtkm::Frustum,
vtkm::Plane,
vtkm::Sphere>;
public:
using Superclass::Superclass;
};
} // namespace vtkm
#endif //vtk_m_ImplicitFunction_h

@ -131,10 +131,32 @@ private:
VTKM_TEST_ASSERT(test_equal_ArrayHandles(values, expectedValuesArray));
VTKM_TEST_ASSERT(test_equal_ArrayHandles(gradients, expectedGradientsArray));
}
}
VTKM_DEPRECATED_SUPPRESS_END
VTKM_DEPRECATED_SUPPRESS_END
#endif //!VTKM_NO_DEPRECATED_VIRTUAL
{
vtkm::ImplicitFunctionMultiplexer<ImplicitFunctorType> functionChoose(function);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> gradients;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), functionChoose, values, gradients, device);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(values, expectedValuesArray));
VTKM_TEST_ASSERT(test_equal_ArrayHandles(gradients, expectedGradientsArray));
}
{
vtkm::ImplicitFunctionGeneral functionChoose(function);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> gradients;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), functionChoose, values, gradients, device);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(values, expectedValuesArray));
VTKM_TEST_ASSERT(test_equal_ArrayHandles(gradients, expectedGradientsArray));
}
}
template <typename DeviceAdapter>
void TestBox(DeviceAdapter device)
{