Modify ImplicitFunctions to use Virtual Methods

This commit is contained in:
Sujin Philip 2017-03-29 12:11:09 -04:00
parent 968960c1a1
commit 82d02e46ef
25 changed files with 1282 additions and 732 deletions

@ -34,7 +34,6 @@ set(headers
Bounds.h
CellShape.h
CellTraits.h
ImplicitFunctions.h
ListTag.h
Math.h
Matrix.h

@ -1,450 +0,0 @@
//============================================================================
// 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 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_ImplicitFunctions_h
#define vtk_m_ImplicitFunctions_h
#include <vtkm/Types.h>
#include <vtkm/Math.h>
#include <vtkm/VectorAnalysis.h>
#include <iostream>
namespace vtkm {
/// \brief Implicit function for a plane
class Plane
{
public:
VTKM_CONT
Plane()
: Origin(FloatDefault(0)),
Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
{ }
VTKM_CONT
explicit Plane(const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(FloatDefault(0)),
Normal(normal)
{ }
VTKM_CONT
Plane(const vtkm::Vec<FloatDefault, 3> &origin,
const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(origin), Normal(normal)
{ }
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const
{
return this->Origin;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetNormal() const
{
return this->Normal;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Origin[0]) * this->Normal[0]) +
((y - this->Origin[1]) * this->Normal[1]) +
((z - this->Origin[2]) * this->Normal[2]);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const
{
return this->Normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const
{
return this->Normal;
}
private:
vtkm::Vec<FloatDefault, 3> Origin;
vtkm::Vec<FloatDefault, 3> Normal;
};
/// \brief Implicit function for a sphere
class Sphere
{
public:
VTKM_CONT
Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0))
{ }
VTKM_CONT
explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0))
{ }
VTKM_CONT
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
: Radius(radius), Center(center)
{ }
VTKM_EXEC_CONT
FloatDefault GetRadius() const
{
return this->Radius;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetCenter() const
{
return this->Center;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Center[0]) * (x - this->Center[0]) +
(y - this->Center[1]) * (y - this->Center[1]) +
(z - this->Center[2]) * (z - this->Center[2])) -
(this->Radius * this->Radius);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return FloatDefault(2) * (x - this->Center);
}
private:
FloatDefault Radius;
vtkm::Vec<FloatDefault, 3> Center;
};
/// \brief Implicit function for a box
class Box
{
public:
VTKM_CONT
Box() : MinPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(0), FloatDefault(0), FloatDefault(0))),
MaxPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(1), FloatDefault(1), FloatDefault(1)))
{ }
VTKM_CONT
Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint)
: MinPoint(minPoint), MaxPoint(maxPoint)
{ }
VTKM_CONT
Box(FloatDefault xmin, FloatDefault xmax,
FloatDefault ymin, FloatDefault ymax,
FloatDefault zmin, FloatDefault zmax)
{
MinPoint[0] = xmin; MaxPoint[0] = xmax;
MinPoint[1] = ymin; MaxPoint[1] = ymax;
MinPoint[2] = zmin; MaxPoint[2] = zmax;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetMinPoint() const
{
return this->MinPoint;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetMaxPoint() const
{
return this->MaxPoint;
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
FloatDefault minDistance = vtkm::NegativeInfinity32();
FloatDefault diff, t, dist;
FloatDefault distance = FloatDefault(0.0);
vtkm::IdComponent inside = 1;
for (vtkm::IdComponent d = 0; d < 3; d++)
{
diff = this->MaxPoint[d] - this->MinPoint[d];
if (diff != FloatDefault(0.0))
{
t = (x[d] - this->MinPoint[d]) / diff;
// Outside before the box
if (t < FloatDefault(0.0))
{
inside = 0;
dist = this->MinPoint[d] - x[d];
}
// Outside after the box
else if (t > FloatDefault(1.0))
{
inside = 0;
dist = x[d] - this->MaxPoint[d];
}
else
{
// Inside the box in lower half
if (t <= FloatDefault(0.5))
{
dist = MinPoint[d] - x[d];
}
// Inside the box in upper half
else
{
dist = x[d] - MaxPoint[d];
}
if (dist > minDistance)
{
minDistance = dist;
}
}
}
else
{
dist = vtkm::Abs(x[d] - MinPoint[d]);
if (dist > FloatDefault(0.0))
{
inside = 0;
}
}
if (dist > FloatDefault(0.0))
{
distance += dist*dist;
}
}
distance = vtkm::Sqrt(distance);
if (inside)
{
return minDistance;
}
else
{
return distance;
}
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Value(vtkm::Vec<vtkm::FloatDefault,3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
vtkm::IdComponent minAxis = 0;
FloatDefault dist = 0.0;
FloatDefault minDist = vtkm::Infinity32();
vtkm::Vec<vtkm::IdComponent,3> location;
vtkm::Vec<FloatDefault,3> normal;
vtkm::Vec<FloatDefault,3> inside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> outside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> center((this->MaxPoint[0] + this->MinPoint[0]) * FloatDefault(0.5),
(this->MaxPoint[1] + this->MinPoint[1]) * FloatDefault(0.5),
(this->MaxPoint[2] + this->MinPoint[2]) * FloatDefault(0.5));
// Compute the location of the point with respect to the box
// Point will lie in one of 27 separate regions around or within the box
// Gradient vector is computed differently in each of the regions.
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (x[d] < this->MinPoint[d])
{
// Outside the box low end
location[d] = 0;
outside[d] = -1.0;
}
else if (x[d] > this->MaxPoint[d])
{
// Outside the box high end
location[d] = 2;
outside[d] = 1.0;
}
else
{
location[d] = 1;
if (x[d] <= center[d])
{
// Inside the box low end
dist = x[d] - this->MinPoint[d];
inside[d] = -1.0;
}
else
{
// Inside the box high end
dist = this->MaxPoint[d] - x[d];
inside[d] = 1.0;
}
if (dist < minDist) // dist is negative
{
minDist = dist;
minAxis = d;
}
}
}
vtkm::Id indx = location[0] + 3*location[1] + 9*location[2];
switch (indx)
{
// verts - gradient points away from center point
case 0: case 2: case 6: case 8: case 18: case 20: case 24: case 26:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = x[d] - center[d];
}
vtkm::Normalize(normal);
break;
// edges - gradient points out from axis of cube
case 1: case 3: case 5: case 7:
case 9: case 11: case 15: case 17:
case 19: case 21: case 23: case 25:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (outside[d] != 0.0)
{
normal[d] = x[d] - center[d];
}
else
{
normal[d] = 0.0;
}
}
vtkm::Normalize(normal);
break;
// faces - gradient points perpendicular to face
case 4: case 10: case 12: case 14: case 16: case 22:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = outside[d];
}
break;
// interior - gradient is perpendicular to closest face
case 13:
normal[0] = normal[1] = normal[2] = 0.0;
normal[minAxis] = inside[minAxis];
break;
default:
VTKM_ASSERT(false);
break;
}
return normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
private:
vtkm::Vec<FloatDefault, 3> MinPoint;
vtkm::Vec<FloatDefault, 3> MaxPoint;
};
/// \brief A function object that evaluates the contained implicit function
template <typename ImplicitFunction>
class ImplicitFunctionValue
{
public:
VTKM_CONT
ImplicitFunctionValue()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionValue(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
template <typename ImplicitFunction>
class ImplicitFunctionGradient
{
public:
VTKM_CONT
ImplicitFunctionGradient()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionGradient(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
ImplicitFunction Function;
};
} // namespace vtkm
#endif // vtk_m_ImplicitFunctions_h

@ -25,6 +25,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/worklet/WorkletMapField.h>
@ -48,12 +49,14 @@ const static std::string DIVIDER(40, '-');
enum BenchmarkName {
BLACK_SCHOLES = 1,
MATH = 1 << 1,
FUSED_MATH = 1 << 3,
INTERPOLATE_FIELD = 1 << 4,
FUSED_MATH = 1 << 2,
INTERPOLATE_FIELD = 1 << 3,
IMPLICIT_FUNCTION = 1 << 4,
ALL = BLACK_SCHOLES |
MATH |
FUSED_MATH |
INTERPOLATE_FIELD
INTERPOLATE_FIELD |
IMPLICIT_FUNCTION
};
template<typename T>
@ -268,6 +271,51 @@ public:
}
};
template <typename ImplicitFunction>
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
ImplicitFunction Function;
};
template <typename T1, typename T2>
class Evaluate2ImplicitFunctions : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
Evaluate2ImplicitFunctions(const T1 &f1, const T2 &f2)
: Function1(f1), Function2(f2)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function1.Value(point) + this->Function2.Value(point);
}
private:
T1 Function1;
T2 Function2;
};
struct ValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>{};
struct InterpValueTypes : vtkm::ListTagBase<vtkm::Float32,
@ -657,6 +705,177 @@ private:
VTKM_MAKE_BENCHMARK(EdgeInterpDynamic, BenchEdgeInterpDynamic);
struct ImplicitFunctionBenchData
{
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> Points;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Result;
vtkm::cont::Sphere Sphere1, Sphere2;
};
static ImplicitFunctionBenchData MakeImplicitFunctionBenchData()
{
vtkm::Id count = ARRAY_SIZE;
vtkm::FloatDefault bounds[6] = { -2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f };
ImplicitFunctionBenchData data;
data.Points.Allocate(count);
data.Result.Allocate(count);
std::default_random_engine rangen;
std::uniform_real_distribution<vtkm::FloatDefault> distx(bounds[0], bounds[1]);
std::uniform_real_distribution<vtkm::FloatDefault> disty(bounds[2], bounds[3]);
std::uniform_real_distribution<vtkm::FloatDefault> distz(bounds[4], bounds[5]);
auto portal = data.Points.GetPortalControl();
for (vtkm::Id i = 0; i < count; ++i)
{
portal.Set(i, vtkm::make_Vec(distx(rangen), disty(rangen), distz(rangen)));
}
data.Sphere1 = vtkm::cont::Sphere({0.22f, 0.33f, 0.44f}, 0.55f);
data.Sphere2 = vtkm::cont::Sphere({0.22f, 0.33f, 0.11f}, 0.77f);
return data;
}
template<typename Value>
struct BenchImplicitFunction
{
BenchImplicitFunction()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = EvaluateImplicitFunction<vtkm::cont::Sphere>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1);
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function (vtkm::cont::Sphere) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct BenchDynamicImplicitFunction
{
BenchDynamicImplicitFunction()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = EvaluateImplicitFunction<vtkm::exec::ImplicitFunction>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()));
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function (DynamicImplicitFunction) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct Bench2ImplicitFunctions
{
Bench2ImplicitFunctions()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::cont::Sphere, vtkm::cont::Sphere>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1, Internal.Sphere2);
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function 2x(vtkm::cont::Sphere) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
template<typename Value>
struct Bench2DynamicImplicitFunctions
{
Bench2DynamicImplicitFunctions()
: Internal(MakeImplicitFunctionBenchData())
{ }
VTKM_CONT
vtkm::Float64 operator()()
{
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::exec::ImplicitFunction,
vtkm::exec::ImplicitFunction>;
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()),
Internal.Sphere2.PrepareForExecution(DeviceAdapterTag()));
vtkm::cont::Timer<DeviceAdapterTag> timer;
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const
{
std::stringstream description;
description << "Implicit Function 2x(DynamicImplicitFunction) on "
<< Internal.Points.GetNumberOfValues()
<< " points";
return description.str();
}
ImplicitFunctionBenchData Internal;
};
VTKM_MAKE_BENCHMARK(ImplicitFunction, BenchImplicitFunction);
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic, BenchDynamicImplicitFunction);
VTKM_MAKE_BENCHMARK(ImplicitFunction2, Bench2ImplicitFunctions);
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic2, Bench2DynamicImplicitFunctions);
public:
@ -687,6 +906,16 @@ public:
VTKM_RUN_BENCHMARK(EdgeInterpDynamic, InterpValueTypes());
}
if (benchmarks & IMPLICIT_FUNCTION) {
using FloatDefaultType = vtkm::ListTagBase<vtkm::FloatDefault>;
std::cout << "\nBenchmarking Implicit Function\n";
VTKM_RUN_BENCHMARK(ImplicitFunction, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunction2, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic2, FloatDefaultType());
}
return 0;
}
};
@ -723,6 +952,10 @@ int main(int argc, char *argv[])
{
benchmarks |= vtkm::benchmarking::INTERPOLATE_FIELD;
}
else if (arg == "implicit_function")
{
benchmarks |= vtkm::benchmarking::IMPLICIT_FUNCTION;
}
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;

@ -64,6 +64,7 @@ set(headers
ErrorExecution.h
ErrorInternal.h
Field.h
ImplicitFunction.h
RuntimeDeviceInformation.h
RuntimeDeviceTracker.h
Storage.h
@ -78,6 +79,7 @@ set(headers
set(header_impls
ArrayHandle.hxx
CellSetStructured.hxx
ImplicitFunction.hxx
StorageBasic.hxx
)
@ -88,6 +90,7 @@ set(sources
CoordinateSystem.cxx
DynamicArrayHandle.cxx
Field.cxx
ImplicitFunction.cxx
internal/SimplePolymorphicContainer.cxx
StorageBasic.cxx
)

@ -1,30 +1,28 @@
//=============================================================================
//
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
// Copyright 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//
//=============================================================================
//============================================================================
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/testing/TestingImplicitFunctions.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
namespace vtkm {
namespace cont {
ImplicitFunction::~ImplicitFunction() = default;
int UnitTestImplicitFunctions(int, char *[])
{
return vtkm::cont::testing::Testing::Run(
vtkm::testing::TestingImplicitFunctions<vtkm::cont::DeviceAdapterTagSerial>::Run);
}
} // vtkm::cont

@ -0,0 +1,341 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cont_ImplicitFunction_h
#define vtk_m_cont_ImplicitFunction_h
#include <vtkm/exec/ImplicitFunction.h>
#include <vtkm/cont/VirtualObjectCache.h>
#include <memory>
namespace vtkm {
namespace cont {
class VTKM_CONT_EXPORT ImplicitFunction
{
public:
virtual ~ImplicitFunction();
template<typename DeviceAdapter>
vtkm::exec::ImplicitFunction PrepareForExecution(DeviceAdapter device) const
{
if (!this->Cache->GetValid())
{
this->SetDefaultDevices();
}
return this->Cache->GetVirtualObject(device);
}
void Modified()
{
this->Cache->SetRefreshFlag(true);
}
protected:
using CacheType = vtkm::cont::VirtualObjectCache<vtkm::exec::ImplicitFunction>;
ImplicitFunction() : Cache(new CacheType)
{
}
ImplicitFunction(ImplicitFunction &&other)
: Cache(std::move(other.Cache))
{
}
ImplicitFunction& operator=(ImplicitFunction &&other)
{
if (this != &other)
{
this->Cache = std::move(other.Cache);
}
return *this;
}
virtual void SetDefaultDevices() const = 0;
std::unique_ptr<CacheType> Cache;
};
template<typename Derived>
class VTKM_ALWAYS_EXPORT ImplicitFunctionImpl : public ImplicitFunction
{
public:
template<typename DeviceAdapterList>
void ResetDevices(DeviceAdapterList devices)
{
this->Cache->Bind(static_cast<const Derived*>(this), devices);
}
protected:
ImplicitFunctionImpl() = default;
ImplicitFunctionImpl(const ImplicitFunctionImpl &) : ImplicitFunction()
{
}
// Cannot default due to a bug in VS2013
ImplicitFunctionImpl(ImplicitFunctionImpl &&other)
: ImplicitFunction(std::move(other))
{
}
ImplicitFunctionImpl& operator=(const ImplicitFunctionImpl &)
{
return *this;
}
// Cannot default due to a bug in VS2013
ImplicitFunctionImpl& operator=(ImplicitFunctionImpl &&other)
{
ImplicitFunction::operator=(std::move(other));
return *this;
}
void SetDefaultDevices() const override
{
this->Cache->Bind(static_cast<const Derived*>(this));
}
};
//============================================================================
// ImplicitFunctions:
//============================================================================
/// \brief Implicit function for a box
class VTKM_ALWAYS_EXPORT Box : public ImplicitFunctionImpl<Box>
{
public:
Box() : MinPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(0), FloatDefault(0), FloatDefault(0))),
MaxPoint(vtkm::Vec<FloatDefault,3>(FloatDefault(1), FloatDefault(1), FloatDefault(1)))
{ }
Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint)
: MinPoint(minPoint), MaxPoint(maxPoint)
{ }
Box(FloatDefault xmin, FloatDefault xmax,
FloatDefault ymin, FloatDefault ymax,
FloatDefault zmin, FloatDefault zmax)
{
MinPoint[0] = xmin; MaxPoint[0] = xmax;
MinPoint[1] = ymin; MaxPoint[1] = ymax;
MinPoint[2] = zmin; MaxPoint[2] = zmax;
}
void SetMinPoint(const vtkm::Vec<FloatDefault, 3> &point)
{
this->MinPoint = point;
this->Modified();
}
void SetMaxPoint(const vtkm::Vec<FloatDefault, 3> &point)
{
this->MaxPoint = point;
this->Modified();
}
const vtkm::Vec<FloatDefault, 3>& GetMinPoint() const
{
return this->MinPoint;
}
const vtkm::Vec<FloatDefault, 3>& GetMaxPoint() const
{
return this->MaxPoint;
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const;
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Value(vtkm::Vec<vtkm::FloatDefault,3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const;
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
private:
vtkm::Vec<FloatDefault, 3> MinPoint;
vtkm::Vec<FloatDefault, 3> MaxPoint;
};
//============================================================================
/// \brief Implicit function for a plane
class VTKM_ALWAYS_EXPORT Plane : public ImplicitFunctionImpl<Plane>
{
public:
Plane()
: Origin(FloatDefault(0)),
Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
{ }
explicit Plane(const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(FloatDefault(0)),
Normal(normal)
{ }
Plane(const vtkm::Vec<FloatDefault, 3> &origin,
const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(origin), Normal(normal)
{ }
void SetOrigin(const vtkm::Vec<FloatDefault, 3> &origin)
{
this->Origin = origin;
this->Modified();
}
void SetNormal(const vtkm::Vec<FloatDefault, 3> &normal)
{
this->Normal = normal;
this->Modified();
}
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const
{
return this->Origin;
}
const vtkm::Vec<FloatDefault, 3>& GetNormal() const
{
return this->Normal;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Origin[0]) * this->Normal[0]) +
((y - this->Origin[1]) * this->Normal[1]) +
((z - this->Origin[2]) * this->Normal[2]);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const
{
return this->Normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const
{
return this->Normal;
}
private:
vtkm::Vec<FloatDefault, 3> Origin;
vtkm::Vec<FloatDefault, 3> Normal;
};
//============================================================================
/// \brief Implicit function for a sphere
class VTKM_ALWAYS_EXPORT Sphere : public ImplicitFunctionImpl<Sphere>
{
public:
Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0))
{ }
explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0))
{ }
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
: Radius(radius), Center(center)
{ }
void SetRadius(FloatDefault radius)
{
this->Radius = radius;
this->Modified();
}
void GetCenter(const vtkm::Vec<FloatDefault, 3> &center)
{
this->Center = center;
this->Modified();
}
FloatDefault GetRadius() const
{
return this->Radius;
}
const vtkm::Vec<FloatDefault, 3>& GetCenter() const
{
return this->Center;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Center[0]) * (x - this->Center[0]) +
(y - this->Center[1]) * (y - this->Center[1]) +
(z - this->Center[2]) * (z - this->Center[2])) -
(this->Radius * this->Radius);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return FloatDefault(2) * (x - this->Center);
}
private:
FloatDefault Radius;
vtkm::Vec<FloatDefault, 3> Center;
};
}
} // vtkm::cont
#include <vtkm/cont/ImplicitFunction.hxx>
#endif // vtk_m_cont_ImplicitFunction_h

@ -0,0 +1,204 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/VectorAnalysis.h>
namespace vtkm {
namespace cont {
//============================================================================
VTKM_EXEC_CONT
inline FloatDefault
Box::Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
FloatDefault minDistance = vtkm::NegativeInfinity32();
FloatDefault diff, t, dist;
FloatDefault distance = FloatDefault(0.0);
vtkm::IdComponent inside = 1;
for (vtkm::IdComponent d = 0; d < 3; d++)
{
diff = this->MaxPoint[d] - this->MinPoint[d];
if (diff != FloatDefault(0.0))
{
t = (x[d] - this->MinPoint[d]) / diff;
// Outside before the box
if (t < FloatDefault(0.0))
{
inside = 0;
dist = this->MinPoint[d] - x[d];
}
// Outside after the box
else if (t > FloatDefault(1.0))
{
inside = 0;
dist = x[d] - this->MaxPoint[d];
}
else
{
// Inside the box in lower half
if (t <= FloatDefault(0.5))
{
dist = MinPoint[d] - x[d];
}
// Inside the box in upper half
else
{
dist = x[d] - MaxPoint[d];
}
if (dist > minDistance)
{
minDistance = dist;
}
}
}
else
{
dist = vtkm::Abs(x[d] - MinPoint[d]);
if (dist > FloatDefault(0.0))
{
inside = 0;
}
}
if (dist > FloatDefault(0.0))
{
distance += dist*dist;
}
}
distance = vtkm::Sqrt(distance);
if (inside)
{
return minDistance;
}
else
{
return distance;
}
}
//============================================================================
VTKM_EXEC_CONT
inline vtkm::Vec<FloatDefault, 3>
Box::Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
vtkm::IdComponent minAxis = 0;
FloatDefault dist = 0.0;
FloatDefault minDist = vtkm::Infinity32();
vtkm::Vec<vtkm::IdComponent,3> location;
vtkm::Vec<FloatDefault,3> normal;
vtkm::Vec<FloatDefault,3> inside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> outside(FloatDefault(0), FloatDefault(0), FloatDefault(0));
vtkm::Vec<FloatDefault,3> center((this->MaxPoint[0] + this->MinPoint[0]) * FloatDefault(0.5),
(this->MaxPoint[1] + this->MinPoint[1]) * FloatDefault(0.5),
(this->MaxPoint[2] + this->MinPoint[2]) * FloatDefault(0.5));
// Compute the location of the point with respect to the box
// Point will lie in one of 27 separate regions around or within the box
// Gradient vector is computed differently in each of the regions.
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (x[d] < this->MinPoint[d])
{
// Outside the box low end
location[d] = 0;
outside[d] = -1.0;
}
else if (x[d] > this->MaxPoint[d])
{
// Outside the box high end
location[d] = 2;
outside[d] = 1.0;
}
else
{
location[d] = 1;
if (x[d] <= center[d])
{
// Inside the box low end
dist = x[d] - this->MinPoint[d];
inside[d] = -1.0;
}
else
{
// Inside the box high end
dist = this->MaxPoint[d] - x[d];
inside[d] = 1.0;
}
if (dist < minDist) // dist is negative
{
minDist = dist;
minAxis = d;
}
}
}
vtkm::Id indx = location[0] + 3*location[1] + 9*location[2];
switch (indx)
{
// verts - gradient points away from center point
case 0: case 2: case 6: case 8: case 18: case 20: case 24: case 26:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = x[d] - center[d];
}
vtkm::Normalize(normal);
break;
// edges - gradient points out from axis of cube
case 1: case 3: case 5: case 7:
case 9: case 11: case 15: case 17:
case 19: case 21: case 23: case 25:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
if (outside[d] != 0.0)
{
normal[d] = x[d] - center[d];
}
else
{
normal[d] = 0.0;
}
}
vtkm::Normalize(normal);
break;
// faces - gradient points perpendicular to face
case 4: case 10: case 12: case 14: case 16: case 22:
for (vtkm::IdComponent d = 0; d < 3; d++)
{
normal[d] = outside[d];
}
break;
// interior - gradient is perpendicular to closest face
case 13:
normal[0] = normal[1] = normal[2] = 0.0;
normal[minAxis] = inside[minAxis];
break;
default:
VTKM_ASSERT(false);
break;
}
return normal;
}
}
} // vtkm::cont

@ -25,6 +25,7 @@ set(unit_tests
UnitTestCudaDataSetExplicit.cu
UnitTestCudaDataSetSingleType.cu
UnitTestCudaDeviceAdapter.cu
UnitTestCudaImplicitFunction.cu
UnitTestCudaMath.cu
UnitTestCudaVirtualObjectCache.cu
)

@ -0,0 +1,37 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagCuda());
}
} // anonymous namespace
int UnitTestCudaImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -25,6 +25,7 @@ set(unit_tests
UnitTestSerialDataSetExplicit.cxx
UnitTestSerialDataSetSingleType.cxx
UnitTestSerialDeviceAdapter.cxx
UnitTestSerialImplicitFunction.cxx
UnitTestSerialVirtualObjectCache.cxx
)
vtkm_unit_tests(TBB SOURCES ${unit_tests})

@ -0,0 +1,38 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagSerial());
}
} // anonymous namespace
int UnitTestSerialImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -25,6 +25,7 @@ set(unit_tests
UnitTestTBBDataSetExplicit.cxx
UnitTestTBBDataSetSingleType.cxx
UnitTestTBBDeviceAdapter.cxx
UnitTestTBBImplicitFunction.cxx
UnitTestTBBVirtualObjectCache.cxx
)
vtkm_unit_tests(TBB SOURCES ${unit_tests})

@ -0,0 +1,37 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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.
//============================================================================
#include <vtkm/cont/testing/TestingImplicitFunction.h>
namespace {
void TestImplicitFunctions()
{
vtkm::cont::testing::TestingImplicitFunction testing;
testing.Run(vtkm::cont::DeviceAdapterTagTBB());
}
} // anonymous namespace
int UnitTestTBBImplicitFunction(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestImplicitFunctions);
}

@ -28,6 +28,7 @@ set(headers
TestingDataSetExplicit.h
TestingDataSetSingleType.h
TestingFancyArrayHandles.h
TestingImplicitFunction.h
TestingVirtualObjectCache.h
)

@ -0,0 +1,187 @@
//============================================================================
// 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 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cont_testing_TestingImplicitFunction_h
#define vtk_m_cont_testing_TestingImplicitFunction_h
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/internal/Configure.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <array>
namespace vtkm {
namespace cont {
namespace testing {
namespace implicit_function_detail {
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const vtkm::exec::ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
vtkm::exec::ImplicitFunction Function;
};
template <typename DeviceAdapter>
void EvaluateOnCoordinates(vtkm::cont::CoordinateSystem points,
const vtkm::cont::ImplicitFunction &function,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> &values,
DeviceAdapter device)
{
typedef vtkm::worklet::DispatcherMapField<EvaluateImplicitFunction, DeviceAdapter>
EvalDispatcher;
EvaluateImplicitFunction eval(function.PrepareForExecution(device));
EvalDispatcher(eval).Invoke(points, values);
}
template <std::size_t N>
bool TestArrayEqual(const vtkm::cont::ArrayHandle<vtkm::FloatDefault> &result,
const std::array<vtkm::FloatDefault, N> &expected)
{
if (result.GetNumberOfValues() != N)
{
return false;
}
vtkm::cont::ArrayHandle<vtkm::FloatDefault>::PortalConstControl portal =
result.GetPortalConstControl();
for (std::size_t i = 0; i < N; ++i)
{
if (!test_equal(portal.Get(static_cast<vtkm::Id>(i)), expected[i]))
{
return false;
}
}
return true;
}
} // anonymous namespace
class TestingImplicitFunction
{
public:
TestingImplicitFunction()
: Input(vtkm::cont::testing::MakeTestDataSet().Make3DExplicitDataSet2())
{
}
template<typename DeviceAdapter>
void Run(DeviceAdapter device)
{
this->TestSphere(device);
this->TestPlane(device);
this->TestBox(device);
}
private:
template <typename DeviceAdapter>
void TestSphere(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Sphere on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Sphere sphere({0.0f, 0.0f, 0.0f}, 1.0f);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), sphere, values, device);
std::array<vtkm::FloatDefault, 8> expected =
{ {-1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 1.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected),
"Result does not match expected values");
}
template <typename DeviceAdapter>
void TestPlane(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Plane on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Plane plane({0.5f, 0.5f, 0.5f}, {1.0f, 0.0f, 1.0f});
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), plane, values, device);
std::array<vtkm::FloatDefault, 8> expected1 =
{ {-1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected1),
"Result does not match expected values");
plane.SetNormal({-1.0f, 0.0f, -1.0f});
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), plane, values, device);
std::array<vtkm::FloatDefault, 8> expected2 =
{ {1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected2),
"Result does not match expected values");
}
template <typename DeviceAdapter>
void TestBox(DeviceAdapter device)
{
std::cout << "Testing vtkm::cont::Box on "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< "\n";
vtkm::cont::Box box({0.0f, -0.5f, -0.5f}, {1.5f, 1.5f, 0.5f});
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
implicit_function_detail::EvaluateOnCoordinates(
this->Input.GetCoordinateSystem(0), box, values, device);
std::array<vtkm::FloatDefault, 8> expected =
{ {0.0f, -0.5f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.5f} };
VTKM_TEST_ASSERT(implicit_function_detail::TestArrayEqual(values, expected),
"Result does not match expected values");
}
vtkm::cont::DataSet Input;
};
}
}
} // vtmk::cont::testing
#endif //vtk_m_cont_testing_TestingImplicitFunction_h

@ -30,6 +30,7 @@ set(headers
ExecutionObjectBase.h
ExecutionWholeArray.h
FunctorBase.h
ImplicitFunction.h
Jacobian.h
ParametricCoordinates.h
)

@ -0,0 +1,143 @@
//============================================================================
// 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 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_exec_ImplicitFunction_h
#define vtk_m_exec_ImplicitFunction_h
#include <vtkm/Types.h>
namespace vtkm {
namespace exec {
class VTKM_ALWAYS_EXPORT ImplicitFunction
{
public:
ImplicitFunction()
: Function(nullptr), ValueCaller(nullptr), GradientCaller(nullptr)
{ }
VTKM_EXEC
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->ValueCaller(this->Function, x, y, z);
}
VTKM_EXEC
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->ValueCaller(this->Function, x[0], x[1], x[2]);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y,
FloatDefault z) const
{
return this->GradientCaller(this->Function, x, y, z);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->GradientCaller(this->Function, x[0], x[1], x[2]);
}
template<typename T>
VTKM_EXEC
void Bind(const T *function)
{
this->Function = function;
this->ValueCaller =
[](const void *t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Value(x, y, z);
};
this->GradientCaller =
[](const void *t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Gradient(x, y, z);
};
}
private:
using ValueCallerSig =
FloatDefault(const void*, FloatDefault, FloatDefault, FloatDefault);
using GradientCallerSig =
vtkm::Vec<FloatDefault, 3>(const void*, FloatDefault, FloatDefault, FloatDefault);
const void *Function;
ValueCallerSig *ValueCaller;
GradientCallerSig *GradientCaller;
};
/// \brief A function object that evaluates the contained implicit function
class VTKM_ALWAYS_EXPORT ImplicitFunctionValue
{
public:
ImplicitFunctionValue() = default;
explicit ImplicitFunctionValue(const vtkm::exec::ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
class VTKM_ALWAYS_EXPORT ImplicitFunctionGradient
{
public:
ImplicitFunctionGradient() = default;
explicit ImplicitFunctionGradient(const vtkm::exec::ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
}
} // vtkm::exec
#endif // vtk_m_exec_ImplicitFunction_h

@ -20,7 +20,6 @@
set(headers
Testing.h
TestingImplicitFunctions.h
TestingMath.h
OptionParser.h
VecTraitsTests.h
@ -34,7 +33,6 @@ set(unit_tests
UnitTestBounds.cxx
UnitTestCellShape.cxx
UnitTestExceptions.cxx
UnitTestImplicitFunctions.cxx
UnitTestListTag.cxx
UnitTestMath.cxx
UnitTestMatrix.cxx

@ -1,213 +0,0 @@
//============================================================================
// 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 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_testing_TestingImplicitFunctions_h
#define vtk_m_testing_TestingImplicitFunctions_h
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <random>
namespace vtkm {
namespace testing {
namespace {
inline vtkm::FloatDefault GetRandomValue()
{
static std::mt19937 gen;
std::uniform_real_distribution<vtkm::FloatDefault> dist(-7.0, 7.0);
return dist(gen);
}
}
template<typename DeviceAdapter>
struct TestingImplicitFunctions
{
typedef vtkm::Vec<vtkm::FloatDefault, 3> FVec3;
template<typename ImplicitFunction>
class EvaluateImplicitFunction : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef void ExecutionSignature(_1, _2);
EvaluateImplicitFunction(const ImplicitFunction &function)
: Function(function)
{ }
template<typename VecType, typename ScalarType>
VTKM_EXEC
void operator()(const VecType &point, ScalarType &val) const
{
val = this->Function.Value(point);
}
private:
ImplicitFunction Function;
};
static void TestBoxValue()
{
typedef EvaluateImplicitFunction<vtkm::Box> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 half(vtkm::Abs(GetRandomValue()), vtkm::Abs(GetRandomValue()), vtkm::Abs(GetRandomValue()));
FVec3 minPoint(GetRandomValue(), GetRandomValue(), GetRandomValue());
FVec3 maxPoint(minPoint[0] + 2.f * half[0], minPoint[1] + 2.f * half[1], minPoint[2] + 2.f * half[2]);
vtkm::Box box(minPoint, maxPoint);
FVec3 data[8] = { minPoint,
maxPoint,
minPoint + FVec3(FloatDefault(0), half[1], half[2]),
minPoint + FVec3(half[0], FloatDefault(0), half[2]),
minPoint + FVec3(half[0], half[1], FloatDefault(0)),
minPoint + half,
minPoint - half,
maxPoint + half
};
vtkm::cont::ArrayHandle<FVec3> points = vtkm::cont::make_ArrayHandle(data, 8);
EvalWorklet eval(box);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = test_equal(portal.Get(0), FloatDefault(0.0) ) &&
test_equal(portal.Get(1), FloatDefault(0.0) ) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
test_equal(portal.Get(3), FloatDefault(0.0) ) &&
test_equal(portal.Get(4), FloatDefault(0.0) ) &&
(portal.Get(5) < 0.0) &&
(portal.Get(6) > 0.0) &&
(portal.Get(7) > 0.0);
VTKM_TEST_ASSERT(success, "Box: did not get expected results.");
}
static void TestSphereValue()
{
typedef EvaluateImplicitFunction<vtkm::Sphere> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 center(GetRandomValue(), GetRandomValue(), GetRandomValue());
FloatDefault radius = vtkm::Abs(GetRandomValue());
vtkm::Sphere sphere(center, radius);
FloatDefault r = radius;
FVec3 cube[8] = { center + FVec3(0, 0, 0),
center + FVec3(r, 0, 0),
center + FVec3(0, r, 0),
center + FVec3(r, r, 0),
center + FVec3(0, 0, r),
center + FVec3(r, 0, r),
center + FVec3(0, r, r),
center + FVec3(r, r, r)
};
vtkm::cont::ArrayHandle<FVec3> points = vtkm::cont::make_ArrayHandle(cube, 8);
EvalWorklet eval(sphere);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = (portal.Get(0) == -(r*r)) &&
test_equal(portal.Get(1), FloatDefault(0.0) ) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
test_equal(portal.Get(4), FloatDefault(0.0) ) &&
(portal.Get(3) > 0.0) &&
(portal.Get(5) > 0.0) &&
(portal.Get(6) > 0.0) &&
(portal.Get(7) > 0.0);
VTKM_TEST_ASSERT(success, "Sphere: did not get expected results.");
}
static void TestPlaneValue()
{
typedef EvaluateImplicitFunction<vtkm::Plane> EvalWorklet;
typedef vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapter>
EvalDispatcher;
FVec3 origin(GetRandomValue(), GetRandomValue(), GetRandomValue());
FVec3 normal(GetRandomValue(), GetRandomValue(), GetRandomValue());
vtkm::Plane plane(origin, normal);
FloatDefault t[] = { -2.0, -1.0, 0.0, 1.0, 2.0 };
vtkm::cont::ArrayHandle<FVec3> points;
points.Allocate(5);
for (int i = 0; i < 5; ++i)
{
points.GetPortalControl().Set(i, origin + (t[i] * normal));
}
EvalWorklet eval(plane);
vtkm::cont::ArrayHandle<FloatDefault> values;
EvalDispatcher(eval).Invoke(points, values);
vtkm::cont::ArrayHandle<FloatDefault>::PortalConstControl portal =
values.GetPortalConstControl();
bool success = (portal.Get(0) < 0.0) &&
(portal.Get(1) < 0.0) &&
test_equal(portal.Get(2), FloatDefault(0.0) ) &&
(portal.Get(3) > 0.0) &&
(portal.Get(4) > 0.0);
VTKM_TEST_ASSERT(success, "Plane: did not get expected results.");
}
static void Run()
{
for (int i = 0; i < 50; ++i)
{
TestSphereValue();
}
for (int i = 0; i < 50; ++i)
{
TestPlaneValue();
}
for (int i = 0; i < 50; ++i)
{
TestBoxValue();
}
}
};
}
} // namespace vtkm::testing
#endif // vtk_m_testing_TestingImplicitFunctions_h

@ -29,8 +29,8 @@
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/exec/FunctorBase.h>
@ -529,13 +529,13 @@ public:
return output;
}
template<typename ImplicitFunction, typename DeviceAdapter>
template<typename DeviceAdapter>
class ClipWithImplicitFunction
{
public:
VTKM_CONT
ClipWithImplicitFunction(Clip *clipper, const vtkm::cont::DynamicCellSet &cellSet,
ImplicitFunction function, vtkm::cont::CellSetExplicit<> *result)
const vtkm::exec::ImplicitFunction &function, vtkm::cont::CellSetExplicit<> *result)
: Clipper(clipper), CellSet(&cellSet), Function(function), Result(result)
{ }
@ -546,40 +546,37 @@ public:
vtkm::cont::ArrayHandleTransform<
vtkm::FloatDefault,
ArrayHandleType,
vtkm::ImplicitFunctionValue<ImplicitFunction> > clipScalars(handle,
this->Function);
vtkm::exec::ImplicitFunctionValue> clipScalars(handle, this->Function);
*this->Result = this->Clipper->Run(*this->CellSet,
clipScalars,
0.0,
DeviceAdapter());
// Clip at locations where the implicit function evaluates to 0
*this->Result = this->Clipper->Run(*this->CellSet,
clipScalars,
0.0,
DeviceAdapter());
}
private:
Clip *Clipper;
const vtkm::cont::DynamicCellSet *CellSet;
const vtkm::ImplicitFunctionValue<ImplicitFunction> Function;
const vtkm::exec::ImplicitFunctionValue Function;
vtkm::cont::CellSetExplicit<> *Result;
};
template <typename CellSetList,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetExplicit<>
Run(const vtkm::cont::DynamicCellSetBase<CellSetList> &cellSet,
const ImplicitFunction &clipFunction,
const vtkm::cont::ImplicitFunction &clipFunction,
const vtkm::cont::CoordinateSystem &coords,
DeviceAdapter device)
{
(void) device;
vtkm::cont::CellSetExplicit<> output;
ClipWithImplicitFunction<ImplicitFunction,
DeviceAdapter> clip(this,
cellSet,
clipFunction,
&output);
CastAndCall(coords, clip);
ClipWithImplicitFunction<DeviceAdapter> clip(this,
cellSet,
clipFunction.PrepareForExecution(device),
&output);
CastAndCall(coords, clip);
return output;
}

@ -28,7 +28,7 @@
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/cont/ImplicitFunction.h>
namespace vtkm {
namespace worklet {
@ -40,7 +40,6 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Worklet to identify cells within volume of interest
template <typename ImplicitFunction>
class ExtractCellsByVOI : public vtkm::worklet::WorkletMapPointToCell
{
public:
@ -53,7 +52,7 @@ public:
ExtractCellsByVOI() : Function() {}
VTKM_CONT
explicit ExtractCellsByVOI(const ImplicitFunction &function)
explicit ExtractCellsByVOI(const vtkm::exec::ImplicitFunction &function)
: Function(function) {}
template <typename ConnectivityInVec, typename InVecFieldPortalType>
@ -76,7 +75,7 @@ public:
}
private:
ImplicitFunction Function;
vtkm::exec::ImplicitFunction Function;
};
////////////////////////////////////////////////////////////////////////////////////
@ -99,22 +98,20 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Extract cells by implicit function permutes input data
template <typename CellSetType,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetPermutation<CellSetType> Run(
const CellSetType &cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
const ImplicitFunction &implicitFunction,
DeviceAdapter)
const vtkm::cont::ImplicitFunction &implicitFunction,
DeviceAdapter device)
{
typedef vtkm::cont::CellSetPermutation<CellSetType> OutputType;
// Worklet output will be a boolean passFlag array
typedef ExtractCellsByVOI<ImplicitFunction> ExtractCellsWorklet;
vtkm::cont::ArrayHandle<bool> passFlags;
ExtractCellsWorklet worklet(implicitFunction);
DispatcherMapTopology<ExtractCellsWorklet, DeviceAdapter> dispatcher(worklet);
ExtractCellsByVOI worklet(implicitFunction.PrepareForExecution(device));
DispatcherMapTopology<ExtractCellsByVOI, DeviceAdapter> dispatcher(worklet);
dispatcher.Invoke(cellSet,
coordinates,
passFlags);

@ -26,7 +26,7 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/ImplicitFunctions.h>
#include <vtkm/cont/ImplicitFunction.h>
namespace vtkm {
namespace worklet {
@ -38,7 +38,6 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Worklet to identify points within volume of interest
template<typename ImplicitFunction>
class ExtractPointsByVOI : public vtkm::worklet::WorkletMapCellToPoint
{
public:
@ -48,7 +47,7 @@ public:
typedef _3 ExecutionSignature(_2);
VTKM_CONT
ExtractPointsByVOI(const ImplicitFunction &function) :
ExtractPointsByVOI(const vtkm::exec::ImplicitFunction &function) :
Function(function) {}
VTKM_EXEC
@ -62,7 +61,7 @@ public:
}
private:
ImplicitFunction Function;
vtkm::exec::ImplicitFunction Function;
};
////////////////////////////////////////////////////////////////////////////////////
@ -90,23 +89,20 @@ public:
////////////////////////////////////////////////////////////////////////////////////
// Extract points by implicit function
template <typename CellSetType,
typename ImplicitFunction,
typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(
const CellSetType &cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
const ImplicitFunction &implicitFunction,
DeviceAdapter)
const vtkm::cont::ImplicitFunction &implicitFunction,
DeviceAdapter device)
{
typedef typename vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
// Worklet output will be a boolean passFlag array
vtkm::cont::ArrayHandle<bool> passFlags;
// Worklet output will be a boolean passFlag array
typedef ExtractPointsByVOI<ImplicitFunction> ExtractPointsWorklet;
ExtractPointsWorklet worklet(implicitFunction);
DispatcherMapTopology<ExtractPointsWorklet, DeviceAdapter> dispatcher(worklet);
ExtractPointsByVOI worklet(implicitFunction.PrepareForExecution(device));
DispatcherMapTopology<ExtractPointsByVOI, DeviceAdapter> dispatcher(worklet);
dispatcher.Invoke(cellSet, coordinates, passFlags);
vtkm::cont::ArrayHandleCounting<vtkm::Id> indices =

@ -30,8 +30,8 @@
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/ImplicitFunction.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/ImplicitFunctions.h>
#include <vector>
@ -230,7 +230,7 @@ void TestClippingWithImplicitFunction()
{
vtkm::Vec<vtkm::FloatDefault, 3> center(1, 1, 0);
vtkm::FloatDefault radius(0.5);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
vtkm::cont::DataSet ds = MakeTestDatasetStructured();

@ -95,7 +95,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.5f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(2.0f, 2.0f, 2.0f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output data set with cell set containing extracted cells and all points
vtkm::worklet::ExtractGeometry extractGeometry;
@ -215,7 +215,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(1.0f, 1.0f, 1.0f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.0f, 3.0f, 3.0f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractGeometry extractGeometry;
@ -255,7 +255,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
vtkm::FloatDefault radius(1.8f);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
// Output data set with cell set containing extracted cells
vtkm::worklet::ExtractGeometry extractGeometry;

@ -78,7 +78,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(1.f, 1.f, 1.f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.f, 3.f, 3.f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
@ -108,7 +108,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
vtkm::FloatDefault radius(1.8f);
vtkm::Sphere sphere(center, radius);
vtkm::cont::Sphere sphere(center, radius);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
@ -138,7 +138,7 @@ public:
// Implicit function
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.f, 0.f, 0.f);
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(1.f, 1.f, 1.f);
vtkm::Box box(minPoint, maxPoint);
vtkm::cont::Box box(minPoint, maxPoint);
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;