mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 02:25:42 +00:00
Switch from faux to true virtuals
This commit is contained in:
parent
280ea84990
commit
8c242cef91
@ -35,6 +35,7 @@ set(headers
|
||||
CellShape.h
|
||||
CellTraits.h
|
||||
Hash.h
|
||||
ImplicitFunction.h
|
||||
ListTag.h
|
||||
Math.h
|
||||
Matrix.h
|
||||
@ -55,6 +56,7 @@ set(headers
|
||||
VectorAnalysis.h
|
||||
VecTraits.h
|
||||
VecVariable.h
|
||||
VirtualObjectBase.h
|
||||
UnaryPredicates.h
|
||||
)
|
||||
|
||||
|
643
vtkm/ImplicitFunction.h
Normal file
643
vtkm/ImplicitFunction.h
Normal file
@ -0,0 +1,643 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_ImplicitFunction_h
|
||||
#define vtk_m_ImplicitFunction_h
|
||||
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/VirtualObjectBase.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
//============================================================================
|
||||
class VTKM_ALWAYS_EXPORT ImplicitFunction : public vtkm::VirtualObjectBase
|
||||
{
|
||||
public:
|
||||
using Scalar = vtkm::FloatDefault;
|
||||
using Vector = vtkm::Vec<Scalar, 3>;
|
||||
|
||||
VTKM_EXEC_CONT virtual Scalar Value(const Vector& point) const = 0;
|
||||
VTKM_EXEC_CONT virtual Vector Gradient(const Vector& point) const = 0;
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(Scalar x, Scalar y, Scalar z) const
|
||||
{
|
||||
return this->Value(Vector(x, y, z));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(Scalar x, Scalar y, Scalar z) const
|
||||
{
|
||||
return this->Gradient(Vector(x, y, z));
|
||||
}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// A helpful functor that calls the (virtual) value method of a given ImplicitFunction. Can be
|
||||
/// passed to things that expect a functor instead of an ImplictFunction class (like an array
|
||||
/// transform).
|
||||
///
|
||||
class VTKM_ALWAYS_EXPORT ImplicitFunctionValue
|
||||
{
|
||||
public:
|
||||
using Scalar = vtkm::ImplicitFunction::Scalar;
|
||||
using Vector = vtkm::ImplicitFunction::Vector;
|
||||
|
||||
VTKM_EXEC_CONT ImplicitFunctionValue()
|
||||
: Function(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT ImplicitFunctionValue(const ImplicitFunction* function)
|
||||
: Function(function)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Scalar operator()(const Vector& point) const
|
||||
{
|
||||
return this->Function->Value(point);
|
||||
}
|
||||
|
||||
private:
|
||||
const vtkm::ImplicitFunction* Function;
|
||||
};
|
||||
|
||||
/// A helpful functor that calls the (virtual) gradient method of a given ImplicitFunction. Can be
|
||||
/// passed to things that expect a functor instead of an ImplictFunction class (like an array
|
||||
/// transform).
|
||||
///
|
||||
class VTKM_ALWAYS_EXPORT ImplicitFunctionGradient
|
||||
{
|
||||
public:
|
||||
using Scalar = vtkm::ImplicitFunction::Scalar;
|
||||
using Vector = vtkm::ImplicitFunction::Vector;
|
||||
|
||||
VTKM_EXEC_CONT ImplicitFunctionGradient()
|
||||
: Function(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT ImplicitFunctionGradient(const ImplicitFunction* function)
|
||||
: Function(function)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector operator()(const Vector& point) const
|
||||
{
|
||||
return this->Function->Gradient(point);
|
||||
}
|
||||
|
||||
private:
|
||||
const vtkm::ImplicitFunction* Function;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a box
|
||||
class VTKM_ALWAYS_EXPORT Box : public ImplicitFunction
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT Box()
|
||||
: MinPoint(Vector(Scalar(0)))
|
||||
, MaxPoint(Vector(Scalar(0)))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Box(const Vector& minPoint, const Vector& maxPoint)
|
||||
: MinPoint(minPoint)
|
||||
, MaxPoint(maxPoint)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Box(Scalar xmin, Scalar xmax, Scalar ymin, Scalar ymax, Scalar zmin, Scalar zmax)
|
||||
: MinPoint(xmin, ymin, zmin)
|
||||
, MaxPoint(xmax, ymax, zmax)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT void SetMinPoint(const Vector& point)
|
||||
{
|
||||
this->MinPoint = point;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT void SetMaxPoint(const Vector& point)
|
||||
{
|
||||
this->MaxPoint = point;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT const Vector& GetMinPoint() const { return this->MinPoint; }
|
||||
|
||||
VTKM_EXEC_CONT const Vector& GetMaxPoint() const { return this->MaxPoint; }
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(const Vector& point) const override
|
||||
{
|
||||
Scalar minDistance = vtkm::NegativeInfinity32();
|
||||
Scalar diff, t, dist;
|
||||
Scalar distance = Scalar(0.0);
|
||||
vtkm::IdComponent inside = 1;
|
||||
|
||||
for (vtkm::IdComponent d = 0; d < 3; d++)
|
||||
{
|
||||
diff = this->MaxPoint[d] - this->MinPoint[d];
|
||||
if (diff != Scalar(0.0))
|
||||
{
|
||||
t = (point[d] - this->MinPoint[d]) / diff;
|
||||
// Outside before the box
|
||||
if (t < Scalar(0.0))
|
||||
{
|
||||
inside = 0;
|
||||
dist = this->MinPoint[d] - point[d];
|
||||
}
|
||||
// Outside after the box
|
||||
else if (t > Scalar(1.0))
|
||||
{
|
||||
inside = 0;
|
||||
dist = point[d] - this->MaxPoint[d];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Inside the box in lower half
|
||||
if (t <= Scalar(0.5))
|
||||
{
|
||||
dist = MinPoint[d] - point[d];
|
||||
}
|
||||
// Inside the box in upper half
|
||||
else
|
||||
{
|
||||
dist = point[d] - MaxPoint[d];
|
||||
}
|
||||
if (dist > minDistance)
|
||||
{
|
||||
minDistance = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = vtkm::Abs(point[d] - MinPoint[d]);
|
||||
if (dist > Scalar(0.0))
|
||||
{
|
||||
inside = 0;
|
||||
}
|
||||
}
|
||||
if (dist > Scalar(0.0))
|
||||
{
|
||||
distance += dist * dist;
|
||||
}
|
||||
}
|
||||
|
||||
distance = vtkm::Sqrt(distance);
|
||||
if (inside)
|
||||
{
|
||||
return minDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return distance;
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(const Vector& point) const override
|
||||
{
|
||||
vtkm::IdComponent minAxis = 0;
|
||||
Scalar dist = 0.0;
|
||||
Scalar minDist = vtkm::Infinity32();
|
||||
vtkm::Vec<vtkm::IdComponent, 3> location;
|
||||
Vector normal(Scalar(0));
|
||||
Vector inside(Scalar(0));
|
||||
Vector outside(Scalar(0));
|
||||
Vector center((this->MaxPoint + this->MinPoint) * Scalar(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 (point[d] < this->MinPoint[d])
|
||||
{
|
||||
// Outside the box low end
|
||||
location[d] = 0;
|
||||
outside[d] = -1.0;
|
||||
}
|
||||
else if (point[d] > this->MaxPoint[d])
|
||||
{
|
||||
// Outside the box high end
|
||||
location[d] = 2;
|
||||
outside[d] = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
location[d] = 1;
|
||||
if (point[d] <= center[d])
|
||||
{
|
||||
// Inside the box low end
|
||||
dist = point[d] - this->MinPoint[d];
|
||||
inside[d] = -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Inside the box high end
|
||||
dist = this->MaxPoint[d] - point[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] = point[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] = point[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;
|
||||
}
|
||||
|
||||
private:
|
||||
Vector MinPoint;
|
||||
Vector MaxPoint;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a cylinder
|
||||
class VTKM_ALWAYS_EXPORT Cylinder : public vtkm::ImplicitFunction
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT Cylinder()
|
||||
: Center(Scalar(0))
|
||||
, Axis(Scalar(1), Scalar(0), Scalar(0))
|
||||
, Radius(Scalar(0.2))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Cylinder(const Vector& axis, Scalar radius)
|
||||
: Center(Scalar(0))
|
||||
, Axis(axis)
|
||||
, Radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Cylinder(const Vector& center, const Vector& axis, Scalar radius)
|
||||
: Center(center)
|
||||
, Axis(axis)
|
||||
, Radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT void SetCenter(const Vector& center)
|
||||
{
|
||||
this->Center = center;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT void SetAxis(const Vector& axis)
|
||||
{
|
||||
this->Axis = axis;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT void SetRadius(Scalar radius)
|
||||
{
|
||||
this->Radius = radius;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(const Vector& point) const override
|
||||
{
|
||||
Vector x2c = point - this->Center;
|
||||
FloatDefault proj = vtkm::dot(this->Axis, x2c);
|
||||
return vtkm::dot(x2c, x2c) - (proj * proj) - (this->Radius * this->Radius);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(const Vector& point) const override
|
||||
{
|
||||
Vector x2c = point - this->Center;
|
||||
FloatDefault t = this->Axis[0] * x2c[0] + this->Axis[1] * x2c[1] + this->Axis[2] * x2c[2];
|
||||
vtkm::Vec<FloatDefault, 3> closestPoint = this->Center + (this->Axis * t);
|
||||
return (point - closestPoint) * FloatDefault(2);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Vector Center;
|
||||
Vector Axis;
|
||||
Scalar Radius;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a frustum
|
||||
class VTKM_ALWAYS_EXPORT Frustum : public vtkm::ImplicitFunction
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT Frustum() = default;
|
||||
|
||||
VTKM_EXEC_CONT Frustum(const Vector points[6], const Vector normals[6])
|
||||
{
|
||||
this->SetPlanes(points, normals);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT explicit Frustum(const Vector points[8]) { this->CreateFromPoints(points); }
|
||||
|
||||
VTKM_EXEC void SetPlanes(const Vector points[6], const Vector normals[6])
|
||||
{
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
this->Points[index] = points[index];
|
||||
}
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
this->Normals[index] = normals[index];
|
||||
}
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC void SetPlane(int idx, const Vector& point, const Vector& normal)
|
||||
{
|
||||
VTKM_ASSERT((idx >= 0) && (idx < 6));
|
||||
this->Points[idx] = point;
|
||||
this->Normals[idx] = normal;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT void GetPlanes(Vector points[6], Vector normals[6]) const
|
||||
{
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
points[index] = this->Points[index];
|
||||
}
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
normals[index] = this->Normals[index];
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT const Vector* GetPoints() const { return this->Points; }
|
||||
|
||||
VTKM_EXEC_CONT const Vector* GetNormals() const { return this->Normals; }
|
||||
|
||||
// The points should be specified in the order of hex-cell vertices
|
||||
VTKM_EXEC_CONT void CreateFromPoints(const Vector points[8])
|
||||
{
|
||||
// XXX(clang-format-3.9): 3.8 is silly. 3.9 makes it look like this.
|
||||
// clang-format off
|
||||
int planes[6][3] = {
|
||||
{ 3, 2, 0 }, { 4, 5, 7 }, { 0, 1, 4 }, { 1, 2, 5 }, { 2, 3, 6 }, { 3, 0, 7 }
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
const Vector& v0 = points[planes[i][0]];
|
||||
const Vector& v1 = points[planes[i][1]];
|
||||
const Vector& v2 = points[planes[i][2]];
|
||||
|
||||
this->Points[i] = v0;
|
||||
this->Normals[i] = vtkm::Normal(vtkm::Cross(v2 - v0, v1 - v0));
|
||||
}
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(const Vector& point) const override
|
||||
{
|
||||
Scalar maxVal = vtkm::NegativeInfinity<Scalar>();
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
const Vector& p = this->Points[index];
|
||||
const Vector& n = this->Normals[index];
|
||||
const Scalar val = vtkm::dot(point - p, n);
|
||||
maxVal = vtkm::Max(maxVal, val);
|
||||
}
|
||||
return maxVal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(const Vector& point) const override
|
||||
{
|
||||
Scalar maxVal = vtkm::NegativeInfinity<Scalar>();
|
||||
vtkm::Id maxValIdx = 0;
|
||||
for (vtkm::Id index : { 0, 1, 2, 3, 4, 5 })
|
||||
{
|
||||
const Vector& p = this->Points[index];
|
||||
const Vector& n = this->Normals[index];
|
||||
Scalar val = vtkm::dot(point - p, n);
|
||||
if (val > maxVal)
|
||||
{
|
||||
maxVal = val;
|
||||
maxValIdx = index;
|
||||
}
|
||||
}
|
||||
return this->Normals[maxValIdx];
|
||||
}
|
||||
|
||||
private:
|
||||
Vector Points[6];
|
||||
Vector Normals[6];
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a plane
|
||||
class VTKM_ALWAYS_EXPORT Plane : public vtkm::ImplicitFunction
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT Plane()
|
||||
: Origin(Scalar(0))
|
||||
, Normal(Scalar(0), Scalar(0), Scalar(1))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT explicit Plane(const Vector& normal)
|
||||
: Origin(Scalar(0))
|
||||
, Normal(normal)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Plane(const Vector& origin, const Vector& normal)
|
||||
: Origin(origin)
|
||||
, Normal(normal)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT void SetOrigin(const Vector& origin)
|
||||
{
|
||||
this->Origin = origin;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT void SetNormal(const Vector& normal)
|
||||
{
|
||||
this->Normal = normal;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT const Vector& GetOrigin() const { return this->Origin; }
|
||||
VTKM_EXEC_CONT const Vector& GetNormal() const { return this->Normal; }
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(const Vector& point) const override
|
||||
{
|
||||
return vtkm::dot(point - this->Origin, this->Normal);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(const Vector&) const override { return this->Normal; }
|
||||
|
||||
private:
|
||||
Vector Origin;
|
||||
Vector Normal;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a sphere
|
||||
class VTKM_ALWAYS_EXPORT Sphere : public vtkm::ImplicitFunction
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT Sphere()
|
||||
: Radius(Scalar(0.2))
|
||||
, Center(Scalar(0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT explicit Sphere(Scalar radius)
|
||||
: Radius(radius)
|
||||
, Center(Scalar(0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Sphere(Vector center, Scalar radius)
|
||||
: Radius(radius)
|
||||
, Center(center)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT void SetRadius(Scalar radius)
|
||||
{
|
||||
this->Radius = radius;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT void SetCenter(const Vector& center)
|
||||
{
|
||||
this->Center = center;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Scalar GetRadius() const { return this->Radius; }
|
||||
|
||||
VTKM_EXEC_CONT const Vector& GetCenter() const { return this->Center; }
|
||||
|
||||
VTKM_EXEC_CONT Scalar Value(const Vector& point) const override
|
||||
{
|
||||
return vtkm::MagnitudeSquared(point - this->Center) - (this->Radius * this->Radius);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT Vector Gradient(const Vector& point) const override
|
||||
{
|
||||
return Scalar(2) * (point - this->Center);
|
||||
}
|
||||
|
||||
private:
|
||||
Scalar Radius;
|
||||
Vector Center;
|
||||
};
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#ifdef VTKM_CUDA
|
||||
|
||||
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
|
||||
// to be instantiated in a consitent order among all the translation units of an
|
||||
// executable. Failing to do so results in random crashes and incorrect results.
|
||||
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
|
||||
// all the implicit functions here.
|
||||
|
||||
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
|
||||
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::Box);
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::Cylinder);
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::Frustum);
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::Plane);
|
||||
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::Sphere);
|
||||
|
||||
#endif
|
||||
|
||||
#endif //vtk_m_ImplicitFunction_h
|
82
vtkm/VirtualObjectBase.h
Normal file
82
vtkm/VirtualObjectBase.h
Normal file
@ -0,0 +1,82 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_VirtualObjectBase_h
|
||||
#define vtk_m_VirtualObjectBase_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
/// \brief Base class for virtual objects that work in the execution environment
|
||||
///
|
||||
/// Any class built in VTK-m that has virtual methods and is intended to work in both the control
|
||||
/// and execution environment should inherit from \c VirtualObjectBase. Hierarchies under \c
|
||||
/// VirtualObjectBase can be used in conjunction with \c VirtualObjectHandle to transfer from the
|
||||
/// control environment (where they are set up) to the execution environment (where they are used).
|
||||
///
|
||||
/// In addition to inheriting from \c VirtualObjectBase, virtual objects have to satisfy 2 other
|
||||
/// conditions to work correctly. First, they have to be a plain old data type that can be copied
|
||||
/// with \c memcpy (with the exception of the virtual table, which \c VirtualObjectHandle will take
|
||||
/// care of). Second, if the object changes its state in the control environment, it should call
|
||||
/// \c Modified on itself so the \c VirtualObjectHandle will know it update the object in the
|
||||
/// execution environment.
|
||||
///
|
||||
class VTKM_ALWAYS_EXPORT VirtualObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT virtual ~VirtualObjectBase() = default;
|
||||
|
||||
VTKM_EXEC_CONT void Modified() { this->ModifiedCount++; }
|
||||
|
||||
VTKM_EXEC_CONT vtkm::Id GetModifiedCount() const { return this->ModifiedCount; }
|
||||
|
||||
protected:
|
||||
VTKM_EXEC_CONT VirtualObjectBase()
|
||||
: ModifiedCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT VirtualObjectBase(const VirtualObjectBase&) = default;
|
||||
|
||||
VTKM_EXEC_CONT VirtualObjectBase(VirtualObjectBase&& other)
|
||||
: ModifiedCount(other.ModifiedCount)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT VirtualObjectBase& operator=(const VirtualObjectBase&)
|
||||
{
|
||||
this->Modified();
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT VirtualObjectBase& operator=(VirtualObjectBase&&)
|
||||
{
|
||||
this->Modified();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id ModifiedCount;
|
||||
};
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#endif //vtk_m_VirtualObjectBase_h
|
@ -24,7 +24,7 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
@ -264,7 +264,7 @@ public:
|
||||
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
|
||||
EvaluateImplicitFunction(const ImplicitFunction& function)
|
||||
EvaluateImplicitFunction(const ImplicitFunction* function)
|
||||
: Function(function)
|
||||
{
|
||||
}
|
||||
@ -272,11 +272,11 @@ public:
|
||||
template <typename VecType, typename ScalarType>
|
||||
VTKM_EXEC void operator()(const VecType& point, ScalarType& val) const
|
||||
{
|
||||
val = this->Function.Value(point);
|
||||
val = this->Function->Value(point);
|
||||
}
|
||||
|
||||
private:
|
||||
ImplicitFunction Function;
|
||||
const ImplicitFunction* Function;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
@ -286,7 +286,7 @@ public:
|
||||
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
|
||||
Evaluate2ImplicitFunctions(const T1& f1, const T2& f2)
|
||||
Evaluate2ImplicitFunctions(const T1* f1, const T2* f2)
|
||||
: Function1(f1)
|
||||
, Function2(f2)
|
||||
{
|
||||
@ -295,12 +295,12 @@ public:
|
||||
template <typename VecType, typename ScalarType>
|
||||
VTKM_EXEC void operator()(const VecType& point, ScalarType& val) const
|
||||
{
|
||||
val = this->Function1.Value(point) + this->Function2.Value(point);
|
||||
val = this->Function1->Value(point) + this->Function2->Value(point);
|
||||
}
|
||||
|
||||
private:
|
||||
T1 Function1;
|
||||
T2 Function2;
|
||||
const T1* Function1;
|
||||
const T2* Function2;
|
||||
};
|
||||
|
||||
struct ValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>
|
||||
@ -680,7 +680,7 @@ private:
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> Points;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Result;
|
||||
vtkm::cont::Sphere Sphere1, Sphere2;
|
||||
vtkm::Sphere Sphere1, Sphere2;
|
||||
};
|
||||
|
||||
static ImplicitFunctionBenchData MakeImplicitFunctionBenchData()
|
||||
@ -703,8 +703,8 @@ private:
|
||||
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);
|
||||
data.Sphere1 = vtkm::Sphere({ 0.22f, 0.33f, 0.44f }, 0.55f);
|
||||
data.Sphere2 = vtkm::Sphere({ 0.22f, 0.33f, 0.11f }, 0.77f);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -720,10 +720,13 @@ private:
|
||||
VTKM_CONT
|
||||
vtkm::Float64 operator()()
|
||||
{
|
||||
using EvalWorklet = EvaluateImplicitFunction<vtkm::cont::Sphere>;
|
||||
using EvalWorklet = EvaluateImplicitFunction<vtkm::Sphere>;
|
||||
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
|
||||
|
||||
EvalWorklet eval(Internal.Sphere1);
|
||||
auto handle = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
|
||||
auto function =
|
||||
static_cast<const vtkm::Sphere*>(handle.PrepareForExecution(DeviceAdapterTag()));
|
||||
EvalWorklet eval(function);
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapterTag> timer;
|
||||
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
|
||||
@ -734,8 +737,8 @@ private:
|
||||
std::string Description() const
|
||||
{
|
||||
std::stringstream description;
|
||||
description << "Implicit Function (vtkm::cont::Sphere) on "
|
||||
<< Internal.Points.GetNumberOfValues() << " points";
|
||||
description << "Implicit Function (vtkm::Sphere) on " << Internal.Points.GetNumberOfValues()
|
||||
<< " points";
|
||||
return description.str();
|
||||
}
|
||||
|
||||
@ -743,9 +746,9 @@ private:
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
struct BenchDynamicImplicitFunction
|
||||
struct BenchVirtualImplicitFunction
|
||||
{
|
||||
BenchDynamicImplicitFunction()
|
||||
BenchVirtualImplicitFunction()
|
||||
: Internal(MakeImplicitFunctionBenchData())
|
||||
{
|
||||
}
|
||||
@ -753,10 +756,11 @@ private:
|
||||
VTKM_CONT
|
||||
vtkm::Float64 operator()()
|
||||
{
|
||||
using EvalWorklet = EvaluateImplicitFunction<vtkm::exec::ImplicitFunction>;
|
||||
using EvalWorklet = EvaluateImplicitFunction<vtkm::ImplicitFunction>;
|
||||
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
|
||||
|
||||
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()));
|
||||
auto sphere = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
|
||||
EvalWorklet eval(sphere.PrepareForExecution(DeviceAdapterTag()));
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapterTag> timer;
|
||||
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
|
||||
@ -767,7 +771,7 @@ private:
|
||||
std::string Description() const
|
||||
{
|
||||
std::stringstream description;
|
||||
description << "Implicit Function (DynamicImplicitFunction) on "
|
||||
description << "Implicit Function (VirtualImplicitFunction) on "
|
||||
<< Internal.Points.GetNumberOfValues() << " points";
|
||||
return description.str();
|
||||
}
|
||||
@ -786,10 +790,14 @@ private:
|
||||
VTKM_CONT
|
||||
vtkm::Float64 operator()()
|
||||
{
|
||||
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::cont::Sphere, vtkm::cont::Sphere>;
|
||||
using EvalWorklet = Evaluate2ImplicitFunctions<vtkm::Sphere, vtkm::Sphere>;
|
||||
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
|
||||
|
||||
EvalWorklet eval(Internal.Sphere1, Internal.Sphere2);
|
||||
auto h1 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
|
||||
auto h2 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere2);
|
||||
auto f1 = static_cast<const vtkm::Sphere*>(h1.PrepareForExecution(DeviceAdapterTag()));
|
||||
auto f2 = static_cast<const vtkm::Sphere*>(h2.PrepareForExecution(DeviceAdapterTag()));
|
||||
EvalWorklet eval(f1, f2);
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapterTag> timer;
|
||||
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
|
||||
@ -800,8 +808,8 @@ private:
|
||||
std::string Description() const
|
||||
{
|
||||
std::stringstream description;
|
||||
description << "Implicit Function 2x(vtkm::cont::Sphere) on "
|
||||
<< Internal.Points.GetNumberOfValues() << " points";
|
||||
description << "Implicit Function 2x(vtkm::Sphere) on " << Internal.Points.GetNumberOfValues()
|
||||
<< " points";
|
||||
return description.str();
|
||||
}
|
||||
|
||||
@ -809,9 +817,9 @@ private:
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
struct Bench2DynamicImplicitFunctions
|
||||
struct Bench2VirtualImplicitFunctions
|
||||
{
|
||||
Bench2DynamicImplicitFunctions()
|
||||
Bench2VirtualImplicitFunctions()
|
||||
: Internal(MakeImplicitFunctionBenchData())
|
||||
{
|
||||
}
|
||||
@ -820,11 +828,13 @@ private:
|
||||
vtkm::Float64 operator()()
|
||||
{
|
||||
using EvalWorklet =
|
||||
Evaluate2ImplicitFunctions<vtkm::exec::ImplicitFunction, vtkm::exec::ImplicitFunction>;
|
||||
Evaluate2ImplicitFunctions<vtkm::ImplicitFunction, vtkm::ImplicitFunction>;
|
||||
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet, DeviceAdapterTag>;
|
||||
|
||||
EvalWorklet eval(Internal.Sphere1.PrepareForExecution(DeviceAdapterTag()),
|
||||
Internal.Sphere2.PrepareForExecution(DeviceAdapterTag()));
|
||||
auto s1 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
|
||||
auto s2 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere2);
|
||||
EvalWorklet eval(s1.PrepareForExecution(DeviceAdapterTag()),
|
||||
s2.PrepareForExecution(DeviceAdapterTag()));
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapterTag> timer;
|
||||
EvalDispatcher(eval).Invoke(this->Internal.Points, this->Internal.Result);
|
||||
@ -835,7 +845,7 @@ private:
|
||||
std::string Description() const
|
||||
{
|
||||
std::stringstream description;
|
||||
description << "Implicit Function 2x(DynamicImplicitFunction) on "
|
||||
description << "Implicit Function 2x(VirtualImplicitFunction) on "
|
||||
<< Internal.Points.GetNumberOfValues() << " points";
|
||||
return description.str();
|
||||
}
|
||||
@ -844,9 +854,9 @@ private:
|
||||
};
|
||||
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunction, BenchImplicitFunction);
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic, BenchDynamicImplicitFunction);
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunctionVirtual, BenchVirtualImplicitFunction);
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunction2, Bench2ImplicitFunctions);
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunctionDynamic2, Bench2DynamicImplicitFunctions);
|
||||
VTKM_MAKE_BENCHMARK(ImplicitFunctionVirtual2, Bench2VirtualImplicitFunctions);
|
||||
|
||||
public:
|
||||
static VTKM_CONT int Run(int benchmarks)
|
||||
@ -887,9 +897,9 @@ public:
|
||||
|
||||
std::cout << "\nBenchmarking Implicit Function\n";
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunction, FloatDefaultType());
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic, FloatDefaultType());
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual, FloatDefaultType());
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunction2, FloatDefaultType());
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunctionDynamic2, FloatDefaultType());
|
||||
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual2, FloatDefaultType());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -69,7 +69,7 @@ set(headers
|
||||
ErrorExecution.h
|
||||
ErrorInternal.h
|
||||
Field.h
|
||||
ImplicitFunction.h
|
||||
ImplicitFunctionHandle.h
|
||||
MultiBlock.h
|
||||
PointLocatorUniformGrid.h
|
||||
RuntimeDeviceInformation.h
|
||||
@ -80,14 +80,13 @@ set(headers
|
||||
StorageListTag.h
|
||||
Timer.h
|
||||
TryExecute.h
|
||||
VirtualObjectCache.h
|
||||
VirtualObjectHandle.h
|
||||
)
|
||||
|
||||
set(header_impls
|
||||
ArrayHandle.hxx
|
||||
CellSetExplicit.hxx
|
||||
CellSetStructured.hxx
|
||||
ImplicitFunction.hxx
|
||||
StorageBasic.hxx
|
||||
)
|
||||
|
||||
@ -99,7 +98,6 @@ set(sources
|
||||
CoordinateSystem.cxx
|
||||
DynamicArrayHandle.cxx
|
||||
Field.cxx
|
||||
ImplicitFunction.cxx
|
||||
internal/SimplePolymorphicContainer.cxx
|
||||
MultiBlock.cxx
|
||||
internal/ArrayManagerExecutionShareWithControl.cxx
|
||||
|
@ -40,6 +40,47 @@ struct DeviceAdapterListTagCommon : vtkm::ListTagBase<vtkm::cont::DeviceAdapterT
|
||||
vtkm::cont::DeviceAdapterTagSerial>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename FunctorType>
|
||||
class ExecuteIfValidDeviceTag
|
||||
{
|
||||
private:
|
||||
template <typename DeviceAdapter>
|
||||
using EnableIfValid = std::enable_if<vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
using EnableIfInvalid = std::enable_if<!vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
|
||||
|
||||
public:
|
||||
explicit ExecuteIfValidDeviceTag(const FunctorType& functor)
|
||||
: Functor(functor)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
typename EnableIfValid<DeviceAdapter>::type operator()(DeviceAdapter) const
|
||||
{
|
||||
this->Functor(DeviceAdapter());
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
typename EnableIfInvalid<DeviceAdapter>::type operator()(DeviceAdapter) const
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
FunctorType Functor;
|
||||
};
|
||||
} // detail
|
||||
|
||||
template <typename DeviceList, typename Functor>
|
||||
VTKM_CONT void ForEachValidDevice(DeviceList devices, const Functor& functor)
|
||||
{
|
||||
vtkm::ListForEach(detail::ExecuteIfValidDeviceTag<Functor>(functor), devices);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -1,29 +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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
ImplicitFunction::~ImplicitFunction() = default;
|
||||
}
|
||||
} // vtkm::cont
|
@ -1,286 +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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_cont_ImplicitFunction_h
|
||||
#define vtk_m_cont_ImplicitFunction_h
|
||||
|
||||
#include <vtkm/internal/Configure.h>
|
||||
|
||||
#include <vtkm/cont/VirtualObjectCache.h>
|
||||
#include <vtkm/exec/ImplicitFunction.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();
|
||||
Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint);
|
||||
Box(FloatDefault xmin,
|
||||
FloatDefault xmax,
|
||||
FloatDefault ymin,
|
||||
FloatDefault ymax,
|
||||
FloatDefault zmin,
|
||||
FloatDefault zmax);
|
||||
|
||||
void SetMinPoint(const vtkm::Vec<FloatDefault, 3>& point);
|
||||
void SetMaxPoint(const vtkm::Vec<FloatDefault, 3>& point);
|
||||
|
||||
const vtkm::Vec<FloatDefault, 3>& GetMinPoint() const;
|
||||
const vtkm::Vec<FloatDefault, 3>& GetMaxPoint() const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
vtkm::Vec<FloatDefault, 3> MinPoint;
|
||||
vtkm::Vec<FloatDefault, 3> MaxPoint;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a cylinder
|
||||
class VTKM_ALWAYS_EXPORT Cylinder : public ImplicitFunctionImpl<Cylinder>
|
||||
{
|
||||
public:
|
||||
Cylinder();
|
||||
Cylinder(const vtkm::Vec<FloatDefault, 3>& axis, FloatDefault radius);
|
||||
Cylinder(const vtkm::Vec<FloatDefault, 3>& center,
|
||||
const vtkm::Vec<FloatDefault, 3>& axis,
|
||||
FloatDefault radius);
|
||||
|
||||
void SetCenter(const vtkm::Vec<FloatDefault, 3>& center);
|
||||
void SetAxis(const vtkm::Vec<FloatDefault, 3>& axis);
|
||||
void SetRadius(FloatDefault radius);
|
||||
|
||||
const vtkm::Vec<FloatDefault, 3>& GetCenter() const;
|
||||
const vtkm::Vec<FloatDefault, 3>& GetAxis() const;
|
||||
FloatDefault GetRadius() const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
vtkm::Vec<FloatDefault, 3> Center;
|
||||
vtkm::Vec<FloatDefault, 3> Axis;
|
||||
FloatDefault Radius;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a frustum
|
||||
class VTKM_ALWAYS_EXPORT Frustum : public ImplicitFunctionImpl<Frustum>
|
||||
{
|
||||
public:
|
||||
Frustum();
|
||||
Frustum(const vtkm::Vec<FloatDefault, 3> points[6], const vtkm::Vec<FloatDefault, 3> normals[6]);
|
||||
explicit Frustum(const vtkm::Vec<FloatDefault, 3> points[8]);
|
||||
|
||||
void SetPlanes(const vtkm::Vec<FloatDefault, 3> points[6],
|
||||
const vtkm::Vec<FloatDefault, 3> normals[6]);
|
||||
void SetPlane(int idx, vtkm::Vec<FloatDefault, 3>& point, vtkm::Vec<FloatDefault, 3>& normal);
|
||||
|
||||
void GetPlanes(vtkm::Vec<FloatDefault, 3> points[6], vtkm::Vec<FloatDefault, 3> normals[6]) const;
|
||||
const vtkm::Vec<FloatDefault, 3>* GetPoints() const;
|
||||
const vtkm::Vec<FloatDefault, 3>* GetNormals() const;
|
||||
|
||||
// The points should be specified in the order of hex-cell vertices
|
||||
void CreateFromPoints(const vtkm::Vec<FloatDefault, 3> points[8]);
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const;
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const;
|
||||
|
||||
private:
|
||||
vtkm::Vec<FloatDefault, 3> Points[6];
|
||||
vtkm::Vec<FloatDefault, 3> Normals[6];
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
/// \brief Implicit function for a plane
|
||||
class VTKM_ALWAYS_EXPORT Plane : public ImplicitFunctionImpl<Plane>
|
||||
{
|
||||
public:
|
||||
Plane();
|
||||
explicit Plane(const vtkm::Vec<FloatDefault, 3>& normal);
|
||||
Plane(const vtkm::Vec<FloatDefault, 3>& origin, const vtkm::Vec<FloatDefault, 3>& normal);
|
||||
|
||||
void SetOrigin(const vtkm::Vec<FloatDefault, 3>& origin);
|
||||
void SetNormal(const vtkm::Vec<FloatDefault, 3>& normal);
|
||||
|
||||
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const;
|
||||
const vtkm::Vec<FloatDefault, 3>& GetNormal() const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const;
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const;
|
||||
|
||||
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();
|
||||
explicit Sphere(FloatDefault radius);
|
||||
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius);
|
||||
|
||||
void SetRadius(FloatDefault radius);
|
||||
void SetCenter(const vtkm::Vec<FloatDefault, 3>& center);
|
||||
|
||||
FloatDefault GetRadius() const;
|
||||
const vtkm::Vec<FloatDefault, 3>& GetCenter() const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
VTKM_EXEC_CONT
|
||||
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z) const;
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>& x) const;
|
||||
|
||||
private:
|
||||
FloatDefault Radius;
|
||||
vtkm::Vec<FloatDefault, 3> Center;
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
#include <vtkm/cont/ImplicitFunction.hxx>
|
||||
|
||||
#endif // vtk_m_cont_ImplicitFunction_h
|
@ -1,640 +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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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.
|
||||
//============================================================================
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
//============================================================================
|
||||
inline Box::Box()
|
||||
: MinPoint(vtkm::Vec<FloatDefault, 3>(FloatDefault(0)))
|
||||
, MaxPoint(vtkm::Vec<FloatDefault, 3>(FloatDefault(1)))
|
||||
{
|
||||
}
|
||||
|
||||
inline Box::Box(vtkm::Vec<FloatDefault, 3> minPoint, vtkm::Vec<FloatDefault, 3> maxPoint)
|
||||
: MinPoint(minPoint)
|
||||
, MaxPoint(maxPoint)
|
||||
{
|
||||
}
|
||||
|
||||
inline Box::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;
|
||||
}
|
||||
|
||||
inline void Box::SetMinPoint(const vtkm::Vec<FloatDefault, 3>& point)
|
||||
{
|
||||
this->MinPoint = point;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Box::SetMaxPoint(const vtkm::Vec<FloatDefault, 3>& point)
|
||||
{
|
||||
this->MaxPoint = point;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Box::GetMinPoint() const
|
||||
{
|
||||
return this->MinPoint;
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Box::GetMaxPoint() const
|
||||
{
|
||||
return this->MaxPoint;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Box::Value(FloatDefault x, FloatDefault y, FloatDefault z) const
|
||||
{
|
||||
return this->Value(vtkm::Vec<vtkm::FloatDefault, 3>(x, y, z));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Box::Gradient(FloatDefault x,
|
||||
FloatDefault y,
|
||||
FloatDefault z) const
|
||||
{
|
||||
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
|
||||
}
|
||||
|
||||
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(FloatDefault(0));
|
||||
vtkm::Vec<FloatDefault, 3> inside(FloatDefault(0));
|
||||
vtkm::Vec<FloatDefault, 3> outside(FloatDefault(0));
|
||||
vtkm::Vec<FloatDefault, 3> center((this->MaxPoint + this->MinPoint) * 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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
inline Cylinder::Cylinder()
|
||||
: Center(FloatDefault(0))
|
||||
, Axis(vtkm::make_Vec(FloatDefault(1), FloatDefault(0), FloatDefault(0)))
|
||||
, Radius(FloatDefault(0.2))
|
||||
{
|
||||
}
|
||||
|
||||
inline Cylinder::Cylinder(const vtkm::Vec<FloatDefault, 3>& axis, FloatDefault radius)
|
||||
: Center(FloatDefault(0))
|
||||
, Axis(vtkm::Normal(axis))
|
||||
, Radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
inline Cylinder::Cylinder(const vtkm::Vec<FloatDefault, 3>& center,
|
||||
const vtkm::Vec<FloatDefault, 3>& axis,
|
||||
FloatDefault radius)
|
||||
: Center(center)
|
||||
, Axis(vtkm::Normal(axis))
|
||||
, Radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
inline void Cylinder::SetCenter(const vtkm::Vec<FloatDefault, 3>& center)
|
||||
{
|
||||
this->Center = center;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Cylinder::SetAxis(const vtkm::Vec<FloatDefault, 3>& axis)
|
||||
{
|
||||
this->Axis = vtkm::Normal(axis);
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Cylinder::SetRadius(FloatDefault radius)
|
||||
{
|
||||
this->Radius = radius;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Cylinder::GetCenter() const
|
||||
{
|
||||
return this->Center;
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Cylinder::GetAxis() const
|
||||
{
|
||||
return this->Axis;
|
||||
}
|
||||
|
||||
inline FloatDefault Cylinder::GetRadius() const
|
||||
{
|
||||
return this->Radius;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Cylinder::Value(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
vtkm::Vec<FloatDefault, 3> x2c = x - this->Center;
|
||||
FloatDefault proj = vtkm::dot(this->Axis, x2c);
|
||||
return vtkm::dot(x2c, x2c) - (proj * proj) - (this->Radius * this->Radius);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Cylinder::Value(FloatDefault x, FloatDefault y, FloatDefault z) const
|
||||
{
|
||||
return this->Value(vtkm::Vec<vtkm::FloatDefault, 3>(x, y, z));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Cylinder::Gradient(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
vtkm::Vec<FloatDefault, 3> x2c = x - this->Center;
|
||||
FloatDefault t = this->Axis[0] * x2c[0] + this->Axis[1] * x2c[1] + this->Axis[2] * x2c[2];
|
||||
vtkm::Vec<FloatDefault, 3> closestPoint = this->Center + (this->Axis * t);
|
||||
return (x - closestPoint) * FloatDefault(2);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Cylinder::Gradient(FloatDefault x,
|
||||
FloatDefault y,
|
||||
FloatDefault z) const
|
||||
{
|
||||
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
inline Frustum::Frustum()
|
||||
{
|
||||
std::fill(this->Points, this->Points + 6, vtkm::Vec<FloatDefault, 3>{});
|
||||
std::fill(this->Normals, this->Normals + 6, vtkm::Vec<FloatDefault, 3>{});
|
||||
}
|
||||
|
||||
inline Frustum::Frustum(const vtkm::Vec<FloatDefault, 3> points[6],
|
||||
const vtkm::Vec<FloatDefault, 3> normals[6])
|
||||
{
|
||||
std::copy(points, points + 6, this->Points);
|
||||
std::copy(normals, normals + 6, this->Normals);
|
||||
}
|
||||
|
||||
inline Frustum::Frustum(const vtkm::Vec<FloatDefault, 3> points[8])
|
||||
{
|
||||
this->CreateFromPoints(points);
|
||||
}
|
||||
|
||||
inline void Frustum::SetPlanes(const vtkm::Vec<FloatDefault, 3> points[6],
|
||||
const vtkm::Vec<FloatDefault, 3> normals[6])
|
||||
{
|
||||
std::copy(points, points + 6, this->Points);
|
||||
std::copy(normals, normals + 6, this->Normals);
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Frustum::GetPlanes(vtkm::Vec<FloatDefault, 3> points[6],
|
||||
vtkm::Vec<FloatDefault, 3> normals[6]) const
|
||||
{
|
||||
std::copy(this->Points, this->Points + 6, points);
|
||||
std::copy(this->Normals, this->Normals + 6, normals);
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>* Frustum::GetPoints() const
|
||||
{
|
||||
return this->Points;
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>* Frustum::GetNormals() const
|
||||
{
|
||||
return this->Normals;
|
||||
}
|
||||
|
||||
inline void Frustum::SetPlane(int idx,
|
||||
vtkm::Vec<FloatDefault, 3>& point,
|
||||
vtkm::Vec<FloatDefault, 3>& normal)
|
||||
{
|
||||
if (idx < 0 || idx >= 6)
|
||||
{
|
||||
std::string msg = "Plane idx ";
|
||||
msg += std::to_string(idx) + " is out of range [0, 5]";
|
||||
throw vtkm::cont::ErrorBadValue(msg);
|
||||
}
|
||||
|
||||
this->Points[idx] = point;
|
||||
this->Normals[idx] = normal;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Frustum::CreateFromPoints(const vtkm::Vec<FloatDefault, 3> points[8])
|
||||
{
|
||||
// XXX(clang-format-3.9): 3.8 is silly. 3.9 makes it look like this.
|
||||
// clang-format off
|
||||
int planes[6][3] = {
|
||||
{ 3, 2, 0 }, { 4, 5, 7 }, { 0, 1, 4 }, { 1, 2, 5 }, { 2, 3, 6 }, { 3, 0, 7 }
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
auto& v0 = points[planes[i][0]];
|
||||
auto& v1 = points[planes[i][1]];
|
||||
auto& v2 = points[planes[i][2]];
|
||||
|
||||
this->Points[i] = v0;
|
||||
this->Normals[i] = vtkm::Normal(vtkm::Cross(v2 - v0, v1 - v0));
|
||||
this->Modified();
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Frustum::Value(FloatDefault x, FloatDefault y, FloatDefault z) const
|
||||
{
|
||||
FloatDefault maxVal = -std::numeric_limits<FloatDefault>::max();
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
auto& p = this->Points[i];
|
||||
auto& n = this->Normals[i];
|
||||
FloatDefault val = ((x - p[0]) * n[0]) + ((y - p[1]) * n[1]) + ((z - p[2]) * n[2]);
|
||||
maxVal = vtkm::Max(maxVal, val);
|
||||
}
|
||||
return maxVal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Frustum::Value(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
return this->Value(x[0], x[1], x[2]);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Frustum::Gradient(FloatDefault x,
|
||||
FloatDefault y,
|
||||
FloatDefault z) const
|
||||
{
|
||||
FloatDefault maxVal = -std::numeric_limits<FloatDefault>::max();
|
||||
int maxValIdx = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
auto& p = this->Points[i];
|
||||
auto& n = this->Normals[i];
|
||||
FloatDefault val = ((x - p[0]) * n[0]) + ((y - p[1]) * n[1]) + ((z - p[2]) * n[2]);
|
||||
if (val > maxVal)
|
||||
{
|
||||
maxVal = val;
|
||||
maxValIdx = i;
|
||||
}
|
||||
}
|
||||
return this->Normals[maxValIdx];
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Frustum::Gradient(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
return this->Gradient(x[0], x[1], x[2]);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
inline Plane::Plane()
|
||||
: Origin(FloatDefault(0))
|
||||
, Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
|
||||
{
|
||||
}
|
||||
|
||||
inline Plane::Plane(const vtkm::Vec<FloatDefault, 3>& normal)
|
||||
: Origin(FloatDefault(0))
|
||||
, Normal(normal)
|
||||
{
|
||||
}
|
||||
|
||||
inline Plane::Plane(const vtkm::Vec<FloatDefault, 3>& origin,
|
||||
const vtkm::Vec<FloatDefault, 3>& normal)
|
||||
: Origin(origin)
|
||||
, Normal(normal)
|
||||
{
|
||||
}
|
||||
|
||||
inline void Plane::SetOrigin(const vtkm::Vec<FloatDefault, 3>& origin)
|
||||
{
|
||||
this->Origin = origin;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Plane::SetNormal(const vtkm::Vec<FloatDefault, 3>& normal)
|
||||
{
|
||||
this->Normal = normal;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Plane::GetOrigin() const
|
||||
{
|
||||
return this->Origin;
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Plane::GetNormal() const
|
||||
{
|
||||
return this->Normal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Plane::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
|
||||
inline FloatDefault Plane::Value(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
return this->Value(x[0], x[1], x[2]);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Plane::Gradient(FloatDefault, FloatDefault, FloatDefault) const
|
||||
{
|
||||
return this->Normal;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Plane::Gradient(const vtkm::Vec<FloatDefault, 3>&) const
|
||||
{
|
||||
return this->Normal;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
inline Sphere::Sphere()
|
||||
: Radius(FloatDefault(0.2))
|
||||
, Center(FloatDefault(0))
|
||||
{
|
||||
}
|
||||
|
||||
inline Sphere::Sphere(FloatDefault radius)
|
||||
: Radius(radius)
|
||||
, Center(FloatDefault(0))
|
||||
{
|
||||
}
|
||||
|
||||
inline Sphere::Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
|
||||
: Radius(radius)
|
||||
, Center(center)
|
||||
{
|
||||
}
|
||||
|
||||
inline void Sphere::SetRadius(FloatDefault radius)
|
||||
{
|
||||
this->Radius = radius;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline void Sphere::SetCenter(const vtkm::Vec<FloatDefault, 3>& center)
|
||||
{
|
||||
this->Center = center;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
inline FloatDefault Sphere::GetRadius() const
|
||||
{
|
||||
return this->Radius;
|
||||
}
|
||||
|
||||
inline const vtkm::Vec<FloatDefault, 3>& Sphere::GetCenter() const
|
||||
{
|
||||
return this->Center;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline FloatDefault Sphere::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
|
||||
inline FloatDefault Sphere::Value(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
return this->Value(x[0], x[1], x[2]);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Sphere::Gradient(FloatDefault x,
|
||||
FloatDefault y,
|
||||
FloatDefault z) const
|
||||
{
|
||||
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline vtkm::Vec<FloatDefault, 3> Sphere::Gradient(const vtkm::Vec<FloatDefault, 3>& x) const
|
||||
{
|
||||
return FloatDefault(2) * (x - this->Center);
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
78
vtkm/cont/ImplicitFunctionHandle.h
Normal file
78
vtkm/cont/ImplicitFunctionHandle.h
Normal file
@ -0,0 +1,78 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_cont_ImplicitFunctionHandle_h
|
||||
#define vtk_m_cont_ImplicitFunctionHandle_h
|
||||
|
||||
#include <vtkm/ImplicitFunction.h>
|
||||
#include <vtkm/cont/VirtualObjectHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
class VTKM_ALWAYS_EXPORT ImplicitFunctionHandle
|
||||
: public vtkm::cont::VirtualObjectHandle<vtkm::ImplicitFunction>
|
||||
{
|
||||
private:
|
||||
using Superclass = vtkm::cont::VirtualObjectHandle<vtkm::ImplicitFunction>;
|
||||
|
||||
public:
|
||||
ImplicitFunctionHandle() = default;
|
||||
|
||||
template <typename ImplicitFunctionType,
|
||||
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
explicit ImplicitFunctionHandle(ImplicitFunctionType* function,
|
||||
bool acquireOwnership = true,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
: Superclass(function, acquireOwnership, devices)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ImplicitFunctionType,
|
||||
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
VTKM_CONT ImplicitFunctionHandle
|
||||
make_ImplicitFunctionHandle(ImplicitFunctionType&& func,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
{
|
||||
using IFType = typename std::remove_reference<ImplicitFunctionType>::type;
|
||||
return ImplicitFunctionHandle(
|
||||
new IFType(std::forward<ImplicitFunctionType>(func)), true, devices);
|
||||
}
|
||||
|
||||
template <typename ImplicitFunctionType, typename... Args>
|
||||
VTKM_CONT ImplicitFunctionHandle make_ImplicitFunctionHandle(Args&&... args)
|
||||
{
|
||||
return ImplicitFunctionHandle(new ImplicitFunctionType(std::forward<Args>(args)...),
|
||||
true,
|
||||
VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG());
|
||||
}
|
||||
|
||||
template <typename ImplicitFunctionType, typename DeviceAdapterList, typename... Args>
|
||||
VTKM_CONT ImplicitFunctionHandle make_ImplicitFunctionHandle(Args&&... args)
|
||||
{
|
||||
return ImplicitFunctionHandle(
|
||||
new ImplicitFunctionType(std::forward<Args>(args)...), true, DeviceAdapterList());
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
#endif // vtk_m_cont_ImplicitFunctionHandle_h
|
@ -1,310 +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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_cont_VirtualObjectCache_h
|
||||
#define vtk_m_cont_VirtualObjectCache_h
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
||||
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
#define VTKM_MAX_DEVICE_ADAPTER_ID 8
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
/// \brief Implements VTK-m's execution side <em> Virtual Methods </em>
|
||||
/// functionality.
|
||||
///
|
||||
/// The template parameter \c VirtualObject is the class that acts as the
|
||||
/// interface. Following is a method for implementing such classes:
|
||||
/// 1. Create a <tt>const void*</tt> member variable that will hold a
|
||||
/// reference to the target class.
|
||||
/// 2. For each virtual-like method:
|
||||
/// a. Create a typedef for a function with the same signature,
|
||||
/// except for an extra <tt>const void*</tt> argument.
|
||||
/// b. Create a function pointer member variable with the type of the
|
||||
/// associated typedef from 2a.
|
||||
/// c. Create an implementation of the method, that calls the associated
|
||||
/// function pointer with the void pointer to the target class as one of
|
||||
/// the arguments.
|
||||
/// 3. Create the following template function:
|
||||
/// \code{.cpp}
|
||||
/// template<typename TargetClass>
|
||||
/// VTKM_EXEC void Bind(const TargetClass *deviceTarget);
|
||||
/// \endcode
|
||||
/// This function should set the void pointer from 1 to \c deviceTarget,
|
||||
/// and assign the function pointers from 2b to functions that cast their
|
||||
/// first argument to <tt>const TargetClass*</tt> and call the corresponding
|
||||
/// member function on it.
|
||||
///
|
||||
/// Both \c VirtualObject and target class objects should be bitwise copyable.
|
||||
///
|
||||
/// \sa vtkm::exec::ImplicitFunction, vtkm::cont::ImplicitFunction
|
||||
///
|
||||
template <typename VirtualObject>
|
||||
class VirtualObjectCache
|
||||
{
|
||||
public:
|
||||
VirtualObjectCache()
|
||||
: Target(nullptr)
|
||||
, CurrentDevice(VTKM_DEVICE_ADAPTER_UNDEFINED)
|
||||
, DeviceState(nullptr)
|
||||
, RefreshFlag(false)
|
||||
{
|
||||
}
|
||||
|
||||
~VirtualObjectCache() { this->Reset(); }
|
||||
|
||||
VirtualObjectCache(const VirtualObjectCache& other)
|
||||
: Target(other.Target)
|
||||
, Transfers(other.Transfers)
|
||||
, CurrentDevice(VTKM_DEVICE_ADAPTER_UNDEFINED)
|
||||
, DeviceState(nullptr)
|
||||
, RefreshFlag(false)
|
||||
{
|
||||
}
|
||||
|
||||
VirtualObjectCache& operator=(const VirtualObjectCache& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->Target = other.Target;
|
||||
this->Transfers = other.Transfers;
|
||||
this->CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
|
||||
this->DeviceState = nullptr;
|
||||
this->RefreshFlag = false;
|
||||
this->Object = VirtualObject();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VirtualObjectCache(VirtualObjectCache&& other)
|
||||
: Target(other.Target)
|
||||
, Transfers(other.Transfers)
|
||||
, CurrentDevice(other.CurrentDevice)
|
||||
, DeviceState(other.DeviceState)
|
||||
, RefreshFlag(other.RefreshFlag)
|
||||
, Object(other.Object)
|
||||
{
|
||||
other.CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
|
||||
other.DeviceState = nullptr;
|
||||
}
|
||||
|
||||
VirtualObjectCache& operator=(VirtualObjectCache&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->Target = other.Target;
|
||||
this->Transfers = std::move(other.Transfers);
|
||||
this->CurrentDevice = other.CurrentDevice;
|
||||
this->DeviceState = other.DeviceState;
|
||||
this->RefreshFlag = other.RefreshFlag;
|
||||
this->Object = std::move(other.Object);
|
||||
|
||||
other.CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
|
||||
other.DeviceState = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Reset to the default constructed state
|
||||
void Reset()
|
||||
{
|
||||
this->ReleaseResources();
|
||||
|
||||
this->Target = nullptr;
|
||||
this->Transfers.fill(TransferInterface());
|
||||
}
|
||||
|
||||
void ReleaseResources()
|
||||
{
|
||||
if (this->CurrentDevice > 0)
|
||||
{
|
||||
this->GetCurrentTransfer().Cleanup(this->DeviceState);
|
||||
this->CurrentDevice = VTKM_DEVICE_ADAPTER_UNDEFINED;
|
||||
this->DeviceState = nullptr;
|
||||
this->RefreshFlag = false;
|
||||
this->Object = VirtualObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// Get if in a valid state (a target is bound)
|
||||
bool GetValid() const { return this->Target != nullptr; }
|
||||
|
||||
// Set/Get if the cached virtual object should be refreshed to the current
|
||||
// state of the target
|
||||
void SetRefreshFlag(bool value) { this->RefreshFlag = value; }
|
||||
bool GetRefreshFlag() const { return this->RefreshFlag; }
|
||||
|
||||
/// Bind to \c target. The lifetime of target is expected to be managed
|
||||
/// externally, and should be valid for as long as it is bound.
|
||||
/// Also accepts a list-tag of device adapters where the virtual
|
||||
/// object may be used (default = \c VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG).
|
||||
///
|
||||
template <typename TargetClass, typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
void Bind(const TargetClass* target, DeviceAdapterList devices = DeviceAdapterList())
|
||||
{
|
||||
this->Reset();
|
||||
|
||||
this->Target = target;
|
||||
vtkm::ListForEach(CreateTransferInterface<TargetClass>(this->Transfers.data()), devices);
|
||||
}
|
||||
|
||||
/// Get a \c VirtualObject for \c DeviceAdapter.
|
||||
/// VirtualObjectCache and VirtualObject are analogous to ArrayHandle and Portal
|
||||
/// The returned VirtualObject will be invalidated if:
|
||||
/// 1. A new VirtualObject is requested for a different DeviceAdapter
|
||||
/// 2. VirtualObjectCache is destroyed
|
||||
/// 3. Reset or ReleaseResources is called
|
||||
///
|
||||
template <typename DeviceAdapter>
|
||||
VirtualObject GetVirtualObject(DeviceAdapter)
|
||||
{
|
||||
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
|
||||
|
||||
if (!this->GetValid())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("No target object bound");
|
||||
}
|
||||
|
||||
vtkm::cont::DeviceAdapterId deviceId = DeviceInfo::GetId();
|
||||
if (deviceId < 0 || deviceId >= VTKM_MAX_DEVICE_ADAPTER_ID)
|
||||
{
|
||||
std::string msg = "Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
|
||||
std::to_string(deviceId) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
|
||||
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
|
||||
if (this->CurrentDevice != deviceId)
|
||||
{
|
||||
this->ReleaseResources();
|
||||
|
||||
std::size_t idx = static_cast<std::size_t>(deviceId);
|
||||
TransferInterface& transfer = this->Transfers[idx];
|
||||
if (!TransferInterfaceValid(transfer))
|
||||
{
|
||||
std::string msg = DeviceInfo::GetName() + " was not in the list specified in Bind";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
this->CurrentDevice = deviceId;
|
||||
this->DeviceState = transfer.Create(this->Object, this->Target);
|
||||
}
|
||||
else if (this->RefreshFlag)
|
||||
{
|
||||
this->GetCurrentTransfer().Update(this->DeviceState, this->Target);
|
||||
}
|
||||
|
||||
this->RefreshFlag = false;
|
||||
return this->Object;
|
||||
}
|
||||
|
||||
private:
|
||||
struct TransferInterface
|
||||
{
|
||||
using CreateSig = void*(VirtualObject&, const void*);
|
||||
using UpdateSig = void(void*, const void*);
|
||||
using CleanupSig = void(void*);
|
||||
|
||||
CreateSig* Create = nullptr;
|
||||
UpdateSig* Update = nullptr;
|
||||
CleanupSig* Cleanup = nullptr;
|
||||
};
|
||||
|
||||
static bool TransferInterfaceValid(const TransferInterface& t) { return t.Create != nullptr; }
|
||||
|
||||
TransferInterface& GetCurrentTransfer()
|
||||
{
|
||||
return this->Transfers[static_cast<std::size_t>(this->CurrentDevice)];
|
||||
}
|
||||
|
||||
template <typename TargetClass>
|
||||
class CreateTransferInterface
|
||||
{
|
||||
private:
|
||||
template <typename DeviceAdapter>
|
||||
using EnableIfValid = std::enable_if<vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
using EnableIfInvalid = std::enable_if<!vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
|
||||
|
||||
public:
|
||||
CreateTransferInterface(TransferInterface* transfers)
|
||||
: Transfers(transfers)
|
||||
{
|
||||
}
|
||||
|
||||
// Use SFINAE to create entries for valid device adapters only
|
||||
template <typename DeviceAdapter>
|
||||
typename EnableIfValid<DeviceAdapter>::type operator()(DeviceAdapter) const
|
||||
{
|
||||
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
|
||||
|
||||
if (DeviceInfo::GetId() >= 0 && DeviceInfo::GetId() < VTKM_MAX_DEVICE_ADAPTER_ID)
|
||||
{
|
||||
using TransferImpl =
|
||||
internal::VirtualObjectTransfer<VirtualObject, TargetClass, DeviceAdapter>;
|
||||
|
||||
std::size_t id = static_cast<std::size_t>(DeviceInfo::GetId());
|
||||
TransferInterface& transfer = this->Transfers[id];
|
||||
|
||||
transfer.Create = &TransferImpl::Create;
|
||||
transfer.Update = &TransferImpl::Update;
|
||||
transfer.Cleanup = &TransferImpl::Cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = "Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
|
||||
std::to_string(DeviceInfo::GetId()) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
|
||||
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
typename EnableIfInvalid<DeviceAdapter>::type operator()(DeviceAdapter) const
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
TransferInterface* Transfers;
|
||||
};
|
||||
|
||||
const void* Target;
|
||||
std::array<TransferInterface, VTKM_MAX_DEVICE_ADAPTER_ID> Transfers;
|
||||
|
||||
vtkm::cont::DeviceAdapterId CurrentDevice;
|
||||
void* DeviceState;
|
||||
bool RefreshFlag;
|
||||
VirtualObject Object;
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
#undef VTKM_MAX_DEVICE_ADAPTER_ID
|
||||
|
||||
#endif // vtk_m_cont_VirtualObjectCache_h
|
277
vtkm/cont/VirtualObjectHandle.h
Normal file
277
vtkm/cont/VirtualObjectHandle.h
Normal file
@ -0,0 +1,277 @@
|
||||
//============================================================================
|
||||
// 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 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2017 UT-Battelle, LLC.
|
||||
// Copyright 2017 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_cont_VirtualObjectHandle_h
|
||||
#define vtk_m_cont_VirtualObjectHandle_h
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
||||
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
#define VTKM_MAX_DEVICE_ADAPTER_ID 8
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
/// \brief Implements VTK-m's execution side <em> Virtual Methods </em> functionality.
|
||||
///
|
||||
/// The template parameter \c VirtualBaseType is the base class that acts as the
|
||||
/// interface. This base clase must inherit from \c vtkm::VirtualObjectBase. See the
|
||||
/// documentation of that class to see the other requirements.
|
||||
///
|
||||
/// A derived object can be bound to the handle either during construction or using the \c Reset
|
||||
/// function on previously constructed handles. These function accept a control side pointer to
|
||||
/// the derived class object, a boolean flag stating if the handle should acquire ownership of
|
||||
/// the object (i.e. manage the lifetime), and a type-list of device adapter tags where the object
|
||||
/// is expected to be used.
|
||||
///
|
||||
/// To get an execution side pointer call the \c PrepareForExecution function. The device adapter
|
||||
/// passed to this function should be one of the device in the list passed during the set up of
|
||||
/// the handle.
|
||||
///
|
||||
///
|
||||
/// \sa vtkm::VirtualObjectBase
|
||||
///
|
||||
template <typename VirtualBaseType>
|
||||
class VTKM_ALWAYS_EXPORT VirtualObjectHandle
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_base_of<vtkm::VirtualObjectBase, VirtualBaseType>::value),
|
||||
"All virtual objects must be subclass of vtkm::VirtualObjectBase.");
|
||||
|
||||
public:
|
||||
VTKM_CONT VirtualObjectHandle()
|
||||
: Internals(new InternalStruct)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename VirtualDerivedType,
|
||||
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
VTKM_CONT explicit VirtualObjectHandle(VirtualDerivedType* derived,
|
||||
bool acquireOwnership = true,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
: Internals(new InternalStruct)
|
||||
{
|
||||
this->Reset(derived, acquireOwnership, devices);
|
||||
}
|
||||
|
||||
/// Get if in a valid state (a target is bound)
|
||||
VTKM_CONT bool GetValid() const { return this->Internals->VirtualObject != nullptr; }
|
||||
|
||||
/// Get if this handle owns the control side target object
|
||||
VTKM_CONT bool OwnsObject() const { return this->Internals->Owner; }
|
||||
|
||||
/// Get the control side pointer to the virtual object
|
||||
VTKM_CONT VirtualBaseType* Get() const { return this->Internals->VirtualObject; }
|
||||
|
||||
/// Reset the underlying derived type object
|
||||
template <typename VirtualDerivedType,
|
||||
typename DeviceAdapterList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
||||
VTKM_CONT void Reset(VirtualDerivedType* derived,
|
||||
bool acquireOwnership = true,
|
||||
DeviceAdapterList devices = DeviceAdapterList())
|
||||
{
|
||||
this->Reset();
|
||||
if (derived)
|
||||
{
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_base_of<VirtualBaseType, VirtualDerivedType>::value),
|
||||
"Tried to bind a type that is not a subclass of the base class.");
|
||||
|
||||
this->Internals->VirtualObject = derived;
|
||||
this->Internals->Owner = acquireOwnership;
|
||||
vtkm::cont::ForEachValidDevice(
|
||||
devices,
|
||||
CreateTransferInterface<VirtualDerivedType>(this->Internals->Transfers.data(), derived));
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() { this->Internals->Reset(); }
|
||||
|
||||
/// Release all the execution side resources
|
||||
VTKM_CONT void ReleaseExecutionResources() { this->Internals->ReleaseExecutionResources(); }
|
||||
|
||||
/// Get a valid \c VirtualBaseType* with the current control side state for \c DeviceAdapter.
|
||||
/// VirtualObjectHandle and the returned pointer are analogous to ArrayHandle and Portal
|
||||
/// The returned pointer will be invalidated if:
|
||||
/// 1. A new pointer is requested for a different DeviceAdapter
|
||||
/// 2. VirtualObjectHandle is destroyed
|
||||
/// 3. Reset or ReleaseResources is called
|
||||
///
|
||||
template <typename DeviceAdapter>
|
||||
VTKM_CONT const VirtualBaseType* PrepareForExecution(DeviceAdapter) const
|
||||
{
|
||||
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
|
||||
|
||||
if (!this->GetValid())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("No target object bound");
|
||||
}
|
||||
|
||||
vtkm::cont::DeviceAdapterId deviceId = DeviceInfo::GetId();
|
||||
if (deviceId < 0 || deviceId >= VTKM_MAX_DEVICE_ADAPTER_ID)
|
||||
{
|
||||
std::string msg = "Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
|
||||
std::to_string(deviceId) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
|
||||
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
|
||||
if (!this->Internals->Current || this->Internals->Current->GetDeviceId() != deviceId)
|
||||
{
|
||||
if (!this->Internals->Transfers[static_cast<std::size_t>(deviceId)])
|
||||
{
|
||||
std::string msg = DeviceInfo::GetName() + " was not in the list specified in Bind";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
|
||||
if (this->Internals->Current)
|
||||
{
|
||||
this->Internals->Current->ReleaseResources();
|
||||
}
|
||||
this->Internals->Current =
|
||||
this->Internals->Transfers[static_cast<std::size_t>(deviceId)].get();
|
||||
}
|
||||
|
||||
return this->Internals->Current->PrepareForExecution();
|
||||
}
|
||||
|
||||
private:
|
||||
class TransferInterface
|
||||
{
|
||||
public:
|
||||
VTKM_CONT virtual ~TransferInterface() = default;
|
||||
|
||||
VTKM_CONT virtual vtkm::cont::DeviceAdapterId GetDeviceId() const = 0;
|
||||
VTKM_CONT virtual const VirtualBaseType* PrepareForExecution() = 0;
|
||||
VTKM_CONT virtual void ReleaseResources() = 0;
|
||||
};
|
||||
|
||||
template <typename VirtualDerivedType, typename DeviceAdapter>
|
||||
class TransferInterfaceImpl : public TransferInterface
|
||||
{
|
||||
public:
|
||||
VTKM_CONT TransferInterfaceImpl(const VirtualDerivedType* virtualObject)
|
||||
: LastModifiedCount(-1)
|
||||
, VirtualObject(virtualObject)
|
||||
, Transfer(virtualObject)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT vtkm::cont::DeviceAdapterId GetDeviceId() const override
|
||||
{
|
||||
return vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId();
|
||||
}
|
||||
|
||||
VTKM_CONT const VirtualBaseType* PrepareForExecution() override
|
||||
{
|
||||
vtkm::Id modifiedCount = this->VirtualObject->GetModifiedCount();
|
||||
bool updateData = (this->LastModifiedCount != modifiedCount);
|
||||
const VirtualBaseType* executionObject = this->Transfer.PrepareForExecution(updateData);
|
||||
this->LastModifiedCount = modifiedCount;
|
||||
return executionObject;
|
||||
}
|
||||
|
||||
VTKM_CONT void ReleaseResources() override { this->Transfer.ReleaseResources(); }
|
||||
|
||||
private:
|
||||
vtkm::Id LastModifiedCount;
|
||||
const VirtualDerivedType* VirtualObject;
|
||||
vtkm::cont::internal::VirtualObjectTransfer<VirtualDerivedType, DeviceAdapter> Transfer;
|
||||
};
|
||||
|
||||
template <typename VirtualDerivedType>
|
||||
class CreateTransferInterface
|
||||
{
|
||||
public:
|
||||
CreateTransferInterface(std::unique_ptr<TransferInterface>* transfers,
|
||||
const VirtualDerivedType* virtualObject)
|
||||
: Transfers(transfers)
|
||||
, VirtualObject(virtualObject)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
void operator()(DeviceAdapter) const
|
||||
{
|
||||
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
|
||||
|
||||
if (DeviceInfo::GetId() < 0 || DeviceInfo::GetId() >= VTKM_MAX_DEVICE_ADAPTER_ID)
|
||||
{
|
||||
std::string msg = "Device '" + DeviceInfo::GetName() + "' has invalid ID of " +
|
||||
std::to_string(DeviceInfo::GetId()) + "(VTKM_MAX_DEVICE_ADAPTER_ID = " +
|
||||
std::to_string(VTKM_MAX_DEVICE_ADAPTER_ID) + ")";
|
||||
throw vtkm::cont::ErrorBadType(msg);
|
||||
}
|
||||
using TransferImpl = TransferInterfaceImpl<VirtualDerivedType, DeviceAdapter>;
|
||||
this->Transfers[DeviceInfo::GetId()].reset(new TransferImpl(this->VirtualObject));
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<TransferInterface>* Transfers;
|
||||
const VirtualDerivedType* VirtualObject;
|
||||
};
|
||||
|
||||
struct InternalStruct
|
||||
{
|
||||
VirtualBaseType* VirtualObject = nullptr;
|
||||
bool Owner = false;
|
||||
std::array<std::unique_ptr<TransferInterface>, VTKM_MAX_DEVICE_ADAPTER_ID> Transfers;
|
||||
TransferInterface* Current = nullptr;
|
||||
|
||||
VTKM_CONT void ReleaseExecutionResources()
|
||||
{
|
||||
if (this->Current)
|
||||
{
|
||||
this->Current->ReleaseResources();
|
||||
this->Current = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void Reset()
|
||||
{
|
||||
this->ReleaseExecutionResources();
|
||||
for (auto& transfer : this->Transfers)
|
||||
{
|
||||
transfer.reset(nullptr);
|
||||
}
|
||||
if (this->Owner)
|
||||
{
|
||||
delete this->VirtualObject;
|
||||
}
|
||||
this->VirtualObject = nullptr;
|
||||
this->Owner = false;
|
||||
}
|
||||
|
||||
VTKM_CONT ~InternalStruct() { this->Reset(); }
|
||||
};
|
||||
|
||||
std::shared_ptr<InternalStruct> Internals;
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
#undef VTKM_MAX_DEVICE_ADAPTER_ID
|
||||
|
||||
#endif // vtk_m_cont_VirtualObjectHandle_h
|
@ -20,6 +20,7 @@
|
||||
#ifndef vtk_m_cont_cuda_internal_VirtualObjectTransferCuda_h
|
||||
#define vtk_m_cont_cuda_internal_VirtualObjectTransferCuda_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/cuda/ErrorCuda.h>
|
||||
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
||||
@ -34,45 +35,108 @@ namespace internal
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
__global__ void CreateKernel(VirtualObject* object, const TargetClass* target)
|
||||
template <typename VirtualDerivedType>
|
||||
__global__ void ConstructVirtualObjectKernel(VirtualDerivedType* deviceObject,
|
||||
const VirtualDerivedType* targetObject)
|
||||
{
|
||||
object->Bind(target);
|
||||
// Use the "placement new" syntax to construct an object in pre-allocated memory
|
||||
new (deviceObject) VirtualDerivedType(*targetObject);
|
||||
}
|
||||
|
||||
template <typename VirtualDerivedType>
|
||||
__global__ void UpdateVirtualObjectKernel(VirtualDerivedType* deviceObject,
|
||||
const VirtualDerivedType* targetObject)
|
||||
{
|
||||
*deviceObject = *targetObject;
|
||||
}
|
||||
|
||||
template <typename VirtualDerivedType>
|
||||
__global__ void DeleteVirtualObjectKernel(VirtualDerivedType* deviceObject)
|
||||
{
|
||||
deviceObject->~VirtualDerivedType();
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
struct VirtualObjectTransfer<VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagCuda>
|
||||
template <typename VirtualDerivedType>
|
||||
struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagCuda>
|
||||
{
|
||||
static void* Create(VirtualObject& object, const void* target)
|
||||
VTKM_CONT VirtualObjectTransfer(const VirtualDerivedType* virtualObject)
|
||||
: ControlObject(virtualObject)
|
||||
, ExecutionObject(nullptr)
|
||||
{
|
||||
TargetClass* cutarget;
|
||||
VTKM_CUDA_CALL(cudaMalloc(&cutarget, sizeof(TargetClass)));
|
||||
VTKM_CUDA_CALL(cudaMemcpyAsync(
|
||||
cutarget, target, sizeof(TargetClass), cudaMemcpyHostToDevice, cudaStreamPerThread));
|
||||
|
||||
VirtualObject* cuobject;
|
||||
VTKM_CUDA_CALL(cudaMalloc(&cuobject, sizeof(VirtualObject)));
|
||||
detail::CreateKernel<<<1, 1, 0, cudaStreamPerThread>>>(cuobject, cutarget);
|
||||
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
|
||||
VTKM_CUDA_CALL(cudaMemcpyAsync(
|
||||
&object, cuobject, sizeof(VirtualObject), cudaMemcpyDeviceToHost, cudaStreamPerThread));
|
||||
VTKM_CUDA_CALL(cudaFree(cuobject));
|
||||
|
||||
return cutarget;
|
||||
}
|
||||
|
||||
static void Update(void* deviceState, const void* target)
|
||||
VTKM_CONT ~VirtualObjectTransfer() { this->ReleaseResources(); }
|
||||
|
||||
VirtualObjectTransfer(const VirtualObjectTransfer&) = delete;
|
||||
void operator=(const VirtualObjectTransfer&) = delete;
|
||||
|
||||
VTKM_CONT const VirtualDerivedType* PrepareForExecution(bool updateData)
|
||||
{
|
||||
VTKM_CUDA_CALL(cudaMemcpyAsync(
|
||||
deviceState, target, sizeof(TargetClass), cudaMemcpyHostToDevice, cudaStreamPerThread));
|
||||
if (this->ExecutionObject == nullptr)
|
||||
{
|
||||
// deviceTarget will hold a byte copy of the host object on the device. The virtual table
|
||||
// will be wrong.
|
||||
VirtualDerivedType* deviceTarget;
|
||||
VTKM_CUDA_CALL(cudaMalloc(&deviceTarget, sizeof(VirtualDerivedType)));
|
||||
VTKM_CUDA_CALL(cudaMemcpy(
|
||||
deviceTarget, this->ControlObject, sizeof(VirtualDerivedType), cudaMemcpyHostToDevice));
|
||||
|
||||
// Allocate memory for the object that will eventually be a correct copy on the device.
|
||||
VTKM_CUDA_CALL(cudaMalloc(&this->ExecutionObject, sizeof(VirtualDerivedType)));
|
||||
|
||||
// Initialize the device object
|
||||
detail::ConstructVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject, deviceTarget);
|
||||
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
|
||||
|
||||
// Clean up intermediate copy
|
||||
VTKM_CUDA_CALL(cudaFree(deviceTarget));
|
||||
}
|
||||
else if (updateData)
|
||||
{
|
||||
// deviceTarget will hold a byte copy of the host object on the device. The virtual table
|
||||
// will be wrong.
|
||||
VirtualDerivedType* deviceTarget;
|
||||
VTKM_CUDA_CALL(cudaMalloc(&deviceTarget, sizeof(VirtualDerivedType)));
|
||||
VTKM_CUDA_CALL(cudaMemcpy(
|
||||
deviceTarget, this->ControlObject, sizeof(VirtualDerivedType), cudaMemcpyHostToDevice));
|
||||
|
||||
// Initialize the device object
|
||||
detail::UpdateVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject, deviceTarget);
|
||||
VTKM_CUDA_CHECK_ASYNCHRONOUS_ERROR();
|
||||
|
||||
// Clean up intermediate copy
|
||||
VTKM_CUDA_CALL(cudaFree(deviceTarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do. The device object is already up to date.
|
||||
}
|
||||
|
||||
return this->ExecutionObject;
|
||||
}
|
||||
|
||||
static void Cleanup(void* deviceState) { VTKM_CUDA_CALL(cudaFree(deviceState)); }
|
||||
VTKM_CONT void ReleaseResources()
|
||||
{
|
||||
if (this->ExecutionObject != nullptr)
|
||||
{
|
||||
detail::DeleteVirtualObjectKernel<<<1, 1>>>(this->ExecutionObject);
|
||||
VTKM_CUDA_CALL(cudaFree(this->ExecutionObject));
|
||||
this->ExecutionObject = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const VirtualDerivedType* ControlObject;
|
||||
VirtualDerivedType* ExecutionObject;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // vtkm::cont::internal
|
||||
|
||||
#define VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(DerivedType) \
|
||||
template class vtkm::cont::internal::VirtualObjectTransfer<DerivedType, \
|
||||
vtkm::cont::DeviceAdapterTagCuda>
|
||||
|
||||
#endif // vtk_m_cont_cuda_internal_VirtualObjectTransferCuda_h
|
||||
|
@ -29,6 +29,6 @@ set(unit_tests
|
||||
UnitTestCudaMath.cu
|
||||
UnitTestCudaShareUserProvidedManagedMemory.cu
|
||||
UnitTestCudaPointLocatorUniformGrid.cxx
|
||||
UnitTestCudaVirtualObjectCache.cu
|
||||
UnitTestCudaVirtualObjectHandle.cu
|
||||
)
|
||||
vtkm_unit_tests(CUDA SOURCES ${unit_tests})
|
||||
|
@ -17,22 +17,22 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectHandle.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void TestVirtualObjectCache()
|
||||
void TestVirtualObjectHandle()
|
||||
{
|
||||
using DeviceAdapterList =
|
||||
vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial, vtkm::cont::DeviceAdapterTagCuda>;
|
||||
|
||||
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
|
||||
vtkm::cont::testing::TestingVirtualObjectHandle<DeviceAdapterList>::Run();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestCudaVirtualObjectCache(int, char* [])
|
||||
int UnitTestCudaVirtualObjectHandle(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectHandle);
|
||||
}
|
@ -20,6 +20,8 @@
|
||||
#ifndef vtk_m_cont_internal_VirtualObjectTransfer_h
|
||||
#define vtk_m_cont_internal_VirtualObjectTransfer_h
|
||||
|
||||
#include <vtkm/VirtualObjectBase.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -27,23 +29,31 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename VirtualObject, typename TargetClass, typename DeviceAdapter>
|
||||
template <typename VirtualDerivedType, typename DeviceAdapter>
|
||||
struct VirtualObjectTransfer
|
||||
#ifdef VTKM_DOXYGEN_ONLY
|
||||
{
|
||||
/// Takes a void* to host copy of the target object, transfers it to the
|
||||
/// device, binds it to the VirtualObject, and returns a void* to an internal
|
||||
/// state structure.
|
||||
/// A VirtualObjectTransfer is constructed with a pointer to the derived type that (eventually)
|
||||
/// gets transferred to the execution environment of the given DeviceAdapter.
|
||||
///
|
||||
static void* Create(VirtualObject& object, const void* hostTarget);
|
||||
VTKM_CONT VirtualObjectTransfer(const VirtualDerivedType* virtualObject);
|
||||
|
||||
/// Performs cleanup of the device state used to track the VirtualObject on
|
||||
/// the device.
|
||||
/// \brief Transfers the virtual object to the execution environment.
|
||||
///
|
||||
static void Cleanup(void* deviceState);
|
||||
/// This method transfers the virtual object to the execution environment and returns a pointer
|
||||
/// to the object that can be used in the execution environment (but not necessarily the control
|
||||
/// environment). If the \c updateData flag is true, then the data is always copied to the
|
||||
/// execution environment (such as if the data were updated since the last call to \c
|
||||
/// PrepareForExecution). If the \c updateData flag is false and the object was already
|
||||
/// transferred previously, the previously created object is returned.
|
||||
///
|
||||
VTKM_CONT const VirtualDerivedType* PrepareForExecution(bool updateData);
|
||||
|
||||
/// Update the device state with the state of target
|
||||
static void Update(void* deviceState, const void* target);
|
||||
/// \brief Frees up any resources in the execution environment.
|
||||
///
|
||||
/// Any previously returned virtual object from \c PrepareForExecution becomes invalid.
|
||||
///
|
||||
VTKM_CONT void ReleaseResources();
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
@ -20,6 +20,11 @@
|
||||
#ifndef vtk_m_cont_internal_VirtualObjectTransferShareWithControl_h
|
||||
#define vtk_m_cont_internal_VirtualObjectTransferShareWithControl_h
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/VirtualObjectBase.h>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -27,19 +32,23 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
template <typename VirtualDerivedType>
|
||||
struct VirtualObjectTransferShareWithControl
|
||||
{
|
||||
static void* Create(VirtualObject& object, const void* target)
|
||||
VTKM_CONT VirtualObjectTransferShareWithControl(const VirtualDerivedType* virtualObject)
|
||||
: VirtualObject(virtualObject)
|
||||
{
|
||||
static int dummyState = 0;
|
||||
object.Bind(static_cast<const TargetClass*>(target));
|
||||
return &dummyState;
|
||||
}
|
||||
|
||||
static void Update(void*, const void*) {}
|
||||
VTKM_CONT const VirtualDerivedType* PrepareForExecution(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return this->VirtualObject;
|
||||
}
|
||||
|
||||
static void Cleanup(void*) {}
|
||||
VTKM_CONT void ReleaseResources() {}
|
||||
|
||||
private:
|
||||
const VirtualDerivedType* VirtualObject;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,14 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
struct VirtualObjectTransfer<VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagSerial>
|
||||
: public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
|
||||
template <typename VirtualDerivedType>
|
||||
struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagSerial>
|
||||
: VirtualObjectTransferShareWithControl<VirtualDerivedType>
|
||||
{
|
||||
VTKM_CONT VirtualObjectTransfer(const VirtualDerivedType* virtualObject)
|
||||
: VirtualObjectTransferShareWithControl<VirtualDerivedType>(virtualObject)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ set(unit_tests
|
||||
UnitTestSerialDeviceAdapter.cxx
|
||||
UnitTestSerialImplicitFunction.cxx
|
||||
UnitTestSerialPointLocatorUniformGrid.cxx
|
||||
UnitTestSerialVirtualObjectCache.cxx
|
||||
UnitTestSerialVirtualObjectHandle.cxx
|
||||
)
|
||||
vtkm_unit_tests(TBB SOURCES ${unit_tests})
|
||||
|
@ -17,21 +17,21 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectHandle.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void TestVirtualObjectCache()
|
||||
void TestVirtualObjectHandle()
|
||||
{
|
||||
using DeviceAdapterList = vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial>;
|
||||
|
||||
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
|
||||
vtkm::cont::testing::TestingVirtualObjectHandle<DeviceAdapterList>::Run();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestSerialVirtualObjectCache(int, char* [])
|
||||
int UnitTestSerialVirtualObjectHandle(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectHandle);
|
||||
}
|
@ -31,10 +31,14 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
struct VirtualObjectTransfer<VirtualObject, TargetClass, vtkm::cont::DeviceAdapterTagTBB>
|
||||
: public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
|
||||
template <typename VirtualDerivedType>
|
||||
struct VirtualObjectTransfer<VirtualDerivedType, vtkm::cont::DeviceAdapterTagTBB>
|
||||
: VirtualObjectTransferShareWithControl<VirtualDerivedType>
|
||||
{
|
||||
VTKM_CONT VirtualObjectTransfer(const VirtualDerivedType* virtualObject)
|
||||
: VirtualObjectTransferShareWithControl<VirtualDerivedType>(virtualObject)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ set(unit_tests
|
||||
UnitTestTBBDeviceAdapter.cxx
|
||||
UnitTestTBBImplicitFunction.cxx
|
||||
UnitTestTBBPointLocatorUniformGrid.cxx
|
||||
UnitTestTBBVirtualObjectCache.cxx
|
||||
UnitTestTBBVirtualObjectHandle.cxx
|
||||
)
|
||||
vtkm_unit_tests(TBB SOURCES ${unit_tests})
|
||||
|
@ -17,22 +17,22 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectCache.h>
|
||||
#include <vtkm/cont/testing/TestingVirtualObjectHandle.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void TestVirtualObjectCache()
|
||||
void TestVirtualObjectHandle()
|
||||
{
|
||||
using DeviceAdapterList =
|
||||
vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagSerial, vtkm::cont::DeviceAdapterTagTBB>;
|
||||
|
||||
vtkm::cont::testing::TestingVirtualObjectCache<DeviceAdapterList>::Run();
|
||||
vtkm::cont::testing::TestingVirtualObjectHandle<DeviceAdapterList>::Run();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestTBBVirtualObjectCache(int, char* [])
|
||||
int UnitTestTBBVirtualObjectHandle(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectCache);
|
||||
return vtkm::cont::testing::Testing::Run(TestVirtualObjectHandle);
|
||||
}
|
@ -31,7 +31,7 @@ set(headers
|
||||
TestingFancyArrayHandles.h
|
||||
TestingImplicitFunction.h
|
||||
TestingPointLocatorUniformGrid.h
|
||||
TestingVirtualObjectCache.h
|
||||
TestingVirtualObjectHandle.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
@ -316,44 +316,31 @@ public:
|
||||
class VirtualObjectTransferKernel
|
||||
{
|
||||
public:
|
||||
struct Interface
|
||||
struct Interface : public vtkm::VirtualObjectBase
|
||||
{
|
||||
using FooSig = vtkm::Id(const void*);
|
||||
|
||||
template <typename T>
|
||||
VTKM_EXEC void Bind(const T* target)
|
||||
{
|
||||
this->Target = target;
|
||||
this->FooPtr = [](const void* t) { return static_cast<const T*>(t)->Foo(); };
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::Id Foo() const { return this->FooPtr(this->Target); }
|
||||
|
||||
const void* Target;
|
||||
FooSig* FooPtr;
|
||||
VTKM_EXEC virtual vtkm::Id Foo() const = 0;
|
||||
};
|
||||
|
||||
struct Concrete
|
||||
struct Concrete : public Interface
|
||||
{
|
||||
vtkm::Id Foo() const { return this->Value; }
|
||||
VTKM_EXEC vtkm::Id Foo() const override { return this->Value; }
|
||||
|
||||
vtkm::Id Value = 0;
|
||||
};
|
||||
|
||||
VirtualObjectTransferKernel(const Interface& vo, IdArrayHandle& result)
|
||||
VirtualObjectTransferKernel(const Interface* vo, IdArrayHandle& result)
|
||||
: Virtual(vo)
|
||||
, Result(result.PrepareForInPlace(DeviceAdapterTag()))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id) const { this->Result.Set(0, this->Virtual.Foo()); }
|
||||
void operator()(vtkm::Id) const { this->Result.Set(0, this->Virtual->Foo()); }
|
||||
|
||||
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
||||
|
||||
private:
|
||||
Interface Virtual;
|
||||
const Interface* Virtual;
|
||||
IdPortalType Result;
|
||||
};
|
||||
|
||||
@ -512,10 +499,9 @@ private:
|
||||
VTKM_CONT
|
||||
static void TestVirtualObjectTransfer()
|
||||
{
|
||||
using VirtualObject = typename VirtualObjectTransferKernel::Interface;
|
||||
using BaseType = typename VirtualObjectTransferKernel::Interface;
|
||||
using TargetType = typename VirtualObjectTransferKernel::Concrete;
|
||||
using Transfer =
|
||||
vtkm::cont::internal::VirtualObjectTransfer<VirtualObject, TargetType, DeviceAdapterTag>;
|
||||
using Transfer = vtkm::cont::internal::VirtualObjectTransfer<TargetType, DeviceAdapterTag>;
|
||||
|
||||
IdArrayHandle result;
|
||||
result.Allocate(1);
|
||||
@ -524,21 +510,21 @@ private:
|
||||
TargetType target;
|
||||
target.Value = 5;
|
||||
|
||||
VirtualObject vo;
|
||||
void* state = Transfer::Create(vo, &target);
|
||||
Transfer transfer(&target);
|
||||
const BaseType* base = transfer.PrepareForExecution(false);
|
||||
|
||||
std::cout << "-------------------------------------------" << std::endl;
|
||||
std::cout << "Testing VirtualObjectTransfer" << std::endl;
|
||||
|
||||
Algorithm::Schedule(VirtualObjectTransferKernel(vo, result), 1);
|
||||
Algorithm::Schedule(VirtualObjectTransferKernel(base, result), 1);
|
||||
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(0) == 5, "Did not get expected result");
|
||||
|
||||
target.Value = 10;
|
||||
Transfer::Update(state, &target);
|
||||
Algorithm::Schedule(VirtualObjectTransferKernel(vo, result), 1);
|
||||
base = transfer.PrepareForExecution(true);
|
||||
Algorithm::Schedule(VirtualObjectTransferKernel(base, result), 1);
|
||||
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(0) == 10, "Did not get expected result");
|
||||
|
||||
Transfer::Cleanup(state);
|
||||
transfer.ReleaseResources();
|
||||
}
|
||||
|
||||
static VTKM_CONT void TestAlgorithmSchedule()
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DeviceAdapterListTag.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
@ -50,7 +50,7 @@ public:
|
||||
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
|
||||
EvaluateImplicitFunction(const vtkm::exec::ImplicitFunction& function)
|
||||
EvaluateImplicitFunction(const vtkm::ImplicitFunction* function)
|
||||
: Function(function)
|
||||
{
|
||||
}
|
||||
@ -58,16 +58,16 @@ public:
|
||||
template <typename VecType, typename ScalarType>
|
||||
VTKM_EXEC void operator()(const VecType& point, ScalarType& val) const
|
||||
{
|
||||
val = this->Function.Value(point);
|
||||
val = this->Function->Value(point);
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::exec::ImplicitFunction Function;
|
||||
const vtkm::ImplicitFunction* Function;
|
||||
};
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
void EvaluateOnCoordinates(vtkm::cont::CoordinateSystem points,
|
||||
const vtkm::cont::ImplicitFunction& function,
|
||||
const vtkm::cont::ImplicitFunctionHandle& function,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>& values,
|
||||
DeviceAdapter device)
|
||||
{
|
||||
@ -141,13 +141,16 @@ private:
|
||||
template <typename DeviceAdapter>
|
||||
void TestBox(DeviceAdapter device)
|
||||
{
|
||||
std::cout << "Testing vtkm::cont::Box on "
|
||||
std::cout << "Testing vtkm::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);
|
||||
this->Input.GetCoordinateSystem(0),
|
||||
vtkm::cont::make_ImplicitFunctionHandle(
|
||||
vtkm::Box({ 0.0f, -0.5f, -0.5f }, { 1.5f, 1.5f, 0.5f })),
|
||||
values,
|
||||
device);
|
||||
|
||||
std::array<vtkm::FloatDefault, 8> expected = {
|
||||
{ 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.5f }
|
||||
@ -159,17 +162,20 @@ private:
|
||||
template <typename DeviceAdapter>
|
||||
void TestCylinder(DeviceAdapter device)
|
||||
{
|
||||
std::cout << "Testing vtkm::cont::Cylinder on "
|
||||
std::cout << "Testing vtkm::Cylinder on "
|
||||
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName() << "\n";
|
||||
|
||||
vtkm::cont::Cylinder cylinder;
|
||||
vtkm::Cylinder cylinder;
|
||||
cylinder.SetCenter({ 0.0f, 0.0f, 1.0f });
|
||||
cylinder.SetAxis({ 0.0f, 1.0f, 0.0f });
|
||||
cylinder.SetRadius(1.0f);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
|
||||
implicit_function_detail::EvaluateOnCoordinates(
|
||||
this->Input.GetCoordinateSystem(0), cylinder, values, device);
|
||||
this->Input.GetCoordinateSystem(0),
|
||||
vtkm::cont::ImplicitFunctionHandle(&cylinder, false),
|
||||
values,
|
||||
device);
|
||||
|
||||
std::array<vtkm::FloatDefault, 8> expected = {
|
||||
{ 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f }
|
||||
@ -181,7 +187,7 @@ private:
|
||||
template <typename DeviceAdapter>
|
||||
void TestFrustum(DeviceAdapter device)
|
||||
{
|
||||
std::cout << "Testing vtkm::cont::Frustum on "
|
||||
std::cout << "Testing vtkm::Frustum on "
|
||||
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName() << "\n";
|
||||
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> points[8] = {
|
||||
@ -194,12 +200,15 @@ private:
|
||||
{ 1.5f, 1.5f, 1.5f }, // 6
|
||||
{ 0.5f, 1.5f, 1.5f } // 7
|
||||
};
|
||||
vtkm::cont::Frustum frustum;
|
||||
vtkm::Frustum frustum;
|
||||
frustum.CreateFromPoints(points);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
|
||||
implicit_function_detail::EvaluateOnCoordinates(
|
||||
this->Input.GetCoordinateSystem(0), frustum, values, device);
|
||||
this->Input.GetCoordinateSystem(0),
|
||||
vtkm::cont::make_ImplicitFunctionHandle(frustum),
|
||||
values,
|
||||
device);
|
||||
|
||||
std::array<vtkm::FloatDefault, 8> expected = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.316228f, 0.316228f, -0.316228f, 0.316228f }
|
||||
@ -211,23 +220,25 @@ private:
|
||||
template <typename DeviceAdapter>
|
||||
void TestPlane(DeviceAdapter device)
|
||||
{
|
||||
std::cout << "Testing vtkm::cont::Plane on "
|
||||
std::cout << "Testing vtkm::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;
|
||||
auto planeHandle = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Plane>(
|
||||
vtkm::make_Vec(0.5f, 0.5f, 0.5f), vtkm::make_Vec(1.0f, 0.0f, 1.0f));
|
||||
auto plane = static_cast<vtkm::Plane*>(planeHandle.Get());
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> values;
|
||||
implicit_function_detail::EvaluateOnCoordinates(
|
||||
this->Input.GetCoordinateSystem(0), plane, values, device);
|
||||
this->Input.GetCoordinateSystem(0), planeHandle, 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 });
|
||||
plane->SetNormal({ -1.0f, 0.0f, -1.0f });
|
||||
implicit_function_detail::EvaluateOnCoordinates(
|
||||
this->Input.GetCoordinateSystem(0), plane, values, device);
|
||||
this->Input.GetCoordinateSystem(0), planeHandle, values, device);
|
||||
std::array<vtkm::FloatDefault, 8> expected2 = {
|
||||
{ 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f }
|
||||
};
|
||||
@ -238,13 +249,15 @@ private:
|
||||
template <typename DeviceAdapter>
|
||||
void TestSphere(DeviceAdapter device)
|
||||
{
|
||||
std::cout << "Testing vtkm::cont::Sphere on "
|
||||
std::cout << "Testing vtkm::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);
|
||||
this->Input.GetCoordinateSystem(0),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Sphere>(vtkm::make_Vec(0.0f, 0.0f, 0.0f), 1.0f),
|
||||
values,
|
||||
device);
|
||||
|
||||
std::array<vtkm::FloatDefault, 8> expected = {
|
||||
{ -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 1.0f }
|
||||
|
@ -17,14 +17,14 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_testing_TestingVirtualObjectCache_h
|
||||
#define vtk_m_cont_testing_TestingVirtualObjectCache_h
|
||||
#ifndef vtk_m_cont_testing_TestingVirtualObjectHandle_h
|
||||
#define vtk_m_cont_testing_TestingVirtualObjectHandle_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/VirtualObjectCache.h>
|
||||
#include <vtkm/cont/VirtualObjectHandle.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
#define ARRAY_LEN 8
|
||||
@ -39,62 +39,76 @@ namespace testing
|
||||
namespace virtual_object_detail
|
||||
{
|
||||
|
||||
class Transformer
|
||||
class Transformer : public vtkm::VirtualObjectBase
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
VTKM_EXEC void Bind(const T* target)
|
||||
VTKM_EXEC
|
||||
virtual vtkm::FloatDefault Eval(vtkm::FloatDefault val) const = 0;
|
||||
};
|
||||
|
||||
class Square : public Transformer
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC
|
||||
vtkm::FloatDefault Eval(vtkm::FloatDefault val) const override { return val * val; }
|
||||
};
|
||||
|
||||
class Multiply : public Transformer
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
void SetMultiplicand(vtkm::FloatDefault val)
|
||||
{
|
||||
this->Concrete = target;
|
||||
this->Caller = [](const void* concrete, vtkm::FloatDefault val) {
|
||||
return static_cast<const T*>(concrete)->operator()(val);
|
||||
};
|
||||
this->Multiplicand = val;
|
||||
this->Modified();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::FloatDefault GetMultiplicand() const { return this->Multiplicand; }
|
||||
|
||||
VTKM_EXEC
|
||||
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const
|
||||
vtkm::FloatDefault Eval(vtkm::FloatDefault val) const override
|
||||
{
|
||||
return this->Caller(this->Concrete, val);
|
||||
return val * this->Multiplicand;
|
||||
}
|
||||
|
||||
private:
|
||||
using Signature = vtkm::FloatDefault(const void*, vtkm::FloatDefault);
|
||||
|
||||
const void* Concrete;
|
||||
Signature* Caller;
|
||||
vtkm::FloatDefault Multiplicand = 0.0f;
|
||||
};
|
||||
|
||||
struct Square
|
||||
class TransformerFunctor
|
||||
{
|
||||
VTKM_EXEC
|
||||
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const { return val * val; }
|
||||
};
|
||||
public:
|
||||
TransformerFunctor() = default;
|
||||
explicit TransformerFunctor(const Transformer* impl)
|
||||
: Impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
struct Multiply
|
||||
{
|
||||
VTKM_EXEC
|
||||
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const { return val * this->Multiplicand; }
|
||||
vtkm::FloatDefault operator()(vtkm::FloatDefault val) const { return this->Impl->Eval(val); }
|
||||
|
||||
vtkm::FloatDefault Multiplicand;
|
||||
private:
|
||||
const Transformer* Impl;
|
||||
};
|
||||
|
||||
} // virtual_object_detail
|
||||
|
||||
template <typename DeviceAdapterList>
|
||||
class TestingVirtualObjectCache
|
||||
class TestingVirtualObjectHandle
|
||||
{
|
||||
private:
|
||||
using FloatArrayHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
|
||||
using ArrayTransform =
|
||||
vtkm::cont::ArrayHandleTransform<FloatArrayHandle, virtual_object_detail::Transformer>;
|
||||
using TransformerCache = vtkm::cont::VirtualObjectCache<virtual_object_detail::Transformer>;
|
||||
vtkm::cont::ArrayHandleTransform<FloatArrayHandle, virtual_object_detail::TransformerFunctor>;
|
||||
using TransformerHandle = vtkm::cont::VirtualObjectHandle<virtual_object_detail::Transformer>;
|
||||
|
||||
class TestStage1
|
||||
{
|
||||
public:
|
||||
TestStage1(const FloatArrayHandle& input, TransformerCache& manager)
|
||||
TestStage1(const FloatArrayHandle& input, TransformerHandle& handle)
|
||||
: Input(&input)
|
||||
, Manager(&manager)
|
||||
, Handle(&handle)
|
||||
{
|
||||
}
|
||||
|
||||
@ -107,7 +121,9 @@ private:
|
||||
|
||||
for (int n = 0; n < 2; ++n)
|
||||
{
|
||||
ArrayTransform transformed(*this->Input, this->Manager->GetVirtualObject(device));
|
||||
virtual_object_detail::TransformerFunctor tfnctr(this->Handle->PrepareForExecution(device));
|
||||
ArrayTransform transformed(*this->Input, tfnctr);
|
||||
|
||||
FloatArrayHandle output;
|
||||
Algorithm::Copy(transformed, output);
|
||||
auto portal = output.GetPortalConstControl();
|
||||
@ -120,14 +136,14 @@ private:
|
||||
if (n == 0)
|
||||
{
|
||||
std::cout << "\tReleaseResources and test again..." << std::endl;
|
||||
this->Manager->ReleaseResources();
|
||||
this->Handle->ReleaseExecutionResources();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const FloatArrayHandle* Input;
|
||||
TransformerCache* Manager;
|
||||
TransformerHandle* Handle;
|
||||
};
|
||||
|
||||
class TestStage2
|
||||
@ -135,10 +151,10 @@ private:
|
||||
public:
|
||||
TestStage2(const FloatArrayHandle& input,
|
||||
virtual_object_detail::Multiply& mul,
|
||||
TransformerCache& manager)
|
||||
TransformerHandle& handle)
|
||||
: Input(&input)
|
||||
, Mul(&mul)
|
||||
, Manager(&manager)
|
||||
, Handle(&handle)
|
||||
{
|
||||
}
|
||||
|
||||
@ -149,17 +165,18 @@ private:
|
||||
std::cout << "\tDeviceAdapter: " << vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
|
||||
<< std::endl;
|
||||
|
||||
this->Mul->Multiplicand = 2;
|
||||
this->Manager->SetRefreshFlag(true);
|
||||
this->Mul->SetMultiplicand(2);
|
||||
for (int n = 0; n < 2; ++n)
|
||||
{
|
||||
ArrayTransform transformed(*this->Input, this->Manager->GetVirtualObject(device));
|
||||
virtual_object_detail::TransformerFunctor tfnctr(this->Handle->PrepareForExecution(device));
|
||||
ArrayTransform transformed(*this->Input, tfnctr);
|
||||
|
||||
FloatArrayHandle output;
|
||||
Algorithm::Copy(transformed, output);
|
||||
auto portal = output.GetPortalConstControl();
|
||||
for (vtkm::Id i = 0; i < ARRAY_LEN; ++i)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(i) == FloatDefault(i) * this->Mul->Multiplicand,
|
||||
VTKM_TEST_ASSERT(portal.Get(i) == FloatDefault(i) * this->Mul->GetMultiplicand(),
|
||||
"\tIncorrect result");
|
||||
}
|
||||
std::cout << "\tSuccess." << std::endl;
|
||||
@ -167,8 +184,7 @@ private:
|
||||
if (n == 0)
|
||||
{
|
||||
std::cout << "\tUpdate and test again..." << std::endl;
|
||||
this->Mul->Multiplicand = 3;
|
||||
this->Manager->SetRefreshFlag(true);
|
||||
this->Mul->SetMultiplicand(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,7 +192,7 @@ private:
|
||||
private:
|
||||
const FloatArrayHandle* Input;
|
||||
virtual_object_detail::Multiply* Mul;
|
||||
TransformerCache* Manager;
|
||||
TransformerHandle* Handle;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -190,20 +206,20 @@ public:
|
||||
portal.Set(i, vtkm::FloatDefault(i));
|
||||
}
|
||||
|
||||
TransformerCache manager;
|
||||
TransformerHandle handle;
|
||||
|
||||
std::cout << "Testing with concrete type 1 (Square)..." << std::endl;
|
||||
virtual_object_detail::Square sqr;
|
||||
manager.Bind(&sqr, DeviceAdapterList());
|
||||
vtkm::ListForEach(TestStage1(input, manager), DeviceAdapterList());
|
||||
handle.Reset(&sqr, false, DeviceAdapterList());
|
||||
vtkm::ListForEach(TestStage1(input, handle), DeviceAdapterList());
|
||||
|
||||
std::cout << "Reset..." << std::endl;
|
||||
manager.Reset();
|
||||
handle.Reset();
|
||||
|
||||
std::cout << "Testing with concrete type 2 (Multiply)..." << std::endl;
|
||||
virtual_object_detail::Multiply mul;
|
||||
manager.Bind(&mul, DeviceAdapterList());
|
||||
vtkm::ListForEach(TestStage2(input, mul, manager), DeviceAdapterList());
|
||||
handle.Reset(&mul, false, DeviceAdapterList());
|
||||
vtkm::ListForEach(TestStage2(input, mul, handle), DeviceAdapterList());
|
||||
}
|
||||
};
|
||||
}
|
@ -90,12 +90,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename VirtualObject, typename TargetClass>
|
||||
struct VirtualObjectTransfer<VirtualObject,
|
||||
TargetClass,
|
||||
vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>
|
||||
: public VirtualObjectTransferShareWithControl<VirtualObject, TargetClass>
|
||||
template <typename TargetClass>
|
||||
struct VirtualObjectTransfer<TargetClass, vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>
|
||||
: public VirtualObjectTransferShareWithControl<TargetClass>
|
||||
{
|
||||
VirtualObjectTransfer(const TargetClass* target)
|
||||
: VirtualObjectTransferShareWithControl<TargetClass>(target)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -21,12 +21,10 @@
|
||||
#ifndef vtk_m_filter_ClipWithImplicitFunction_h
|
||||
#define vtk_m_filter_ClipWithImplicitFunction_h
|
||||
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/filter/FilterDataSet.h>
|
||||
#include <vtkm/worklet/Clip.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
@ -34,26 +32,18 @@ namespace filter
|
||||
|
||||
/// \brief Clip a dataset using an implicit function
|
||||
///
|
||||
/// Clip a dataset using a given implicit function value, such as vtkm::cont::Sphere
|
||||
/// or vtkm::cont::Frustum.
|
||||
/// Clip a dataset using a given implicit function value, such as vtkm::Sphere
|
||||
/// or vtkm::Frustum.
|
||||
/// The resulting geometry will not be water tight.
|
||||
class ClipWithImplicitFunction : public vtkm::filter::FilterDataSet<ClipWithImplicitFunction>
|
||||
{
|
||||
public:
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
template <typename ImplicitFunctionType>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func)
|
||||
void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func)
|
||||
{
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> GetImplicitFunction() const
|
||||
{
|
||||
return this->Function;
|
||||
}
|
||||
const vtkm::cont::ImplicitFunctionHandle& GetImplicitFunction() const { return this->Function; }
|
||||
|
||||
template <typename DerivedPolicy, typename DeviceAdapter>
|
||||
vtkm::filter::Result DoExecute(const vtkm::cont::DataSet& input,
|
||||
@ -70,7 +60,7 @@ public:
|
||||
const DeviceAdapter& tag);
|
||||
|
||||
private:
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> Function;
|
||||
vtkm::cont::ImplicitFunctionHandle Function;
|
||||
vtkm::worklet::Clip Worklet;
|
||||
};
|
||||
}
|
||||
|
@ -53,16 +53,6 @@ struct PointMapHelper
|
||||
|
||||
} // end namespace clipwithimplicitfunction
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
inline void ClipWithImplicitFunction::SetImplicitFunction(
|
||||
const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
func->ResetDevices(DerivedPolicy::DeviceAdapterList);
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy, typename DeviceAdapter>
|
||||
inline vtkm::filter::Result ClipWithImplicitFunction::DoExecute(
|
||||
@ -79,7 +69,7 @@ inline vtkm::filter::Result ClipWithImplicitFunction::DoExecute(
|
||||
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
|
||||
|
||||
vtkm::cont::CellSetExplicit<> outputCellSet = this->Worklet.Run(
|
||||
vtkm::filter::ApplyPolicy(cells, policy), *this->Function, inputCoords, device);
|
||||
vtkm::filter::ApplyPolicy(cells, policy), this->Function, inputCoords, device);
|
||||
|
||||
// compute output coordinates
|
||||
vtkm::cont::DynamicArrayHandle outputCoordsArray;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef vtk_m_filter_ExtractGeometry_h
|
||||
#define vtk_m_filter_ExtractGeometry_h
|
||||
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/filter/FilterDataSet.h>
|
||||
#include <vtkm/worklet/ExtractGeometry.h>
|
||||
|
||||
@ -52,20 +52,12 @@ public:
|
||||
ExtractGeometry();
|
||||
|
||||
// Set the volume of interest to extract
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
template <typename ImplicitFunctionType>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func)
|
||||
void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func)
|
||||
{
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> GetImplicitFunction() const
|
||||
{
|
||||
return this->Function;
|
||||
}
|
||||
const vtkm::cont::ImplicitFunctionHandle& GetImplicitFunction() const { return this->Function; }
|
||||
|
||||
VTKM_CONT
|
||||
bool GetExtractInside() { return this->ExtractInside; }
|
||||
@ -111,7 +103,7 @@ private:
|
||||
bool ExtractInside;
|
||||
bool ExtractBoundaryCells;
|
||||
bool ExtractOnlyBoundaryCells;
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> Function;
|
||||
vtkm::cont::ImplicitFunctionHandle Function;
|
||||
vtkm::worklet::ExtractGeometry Worklet;
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ struct CallWorker
|
||||
vtkm::cont::DynamicCellSet& Output;
|
||||
vtkm::worklet::ExtractGeometry& Worklet;
|
||||
const vtkm::cont::CoordinateSystem& Coords;
|
||||
const vtkm::cont::ImplicitFunction& Function;
|
||||
const vtkm::cont::ImplicitFunctionHandle& Function;
|
||||
bool ExtractInside;
|
||||
bool ExtractBoundaryCells;
|
||||
bool ExtractOnlyBoundaryCells;
|
||||
@ -42,7 +42,7 @@ struct CallWorker
|
||||
CallWorker(vtkm::cont::DynamicCellSet& output,
|
||||
vtkm::worklet::ExtractGeometry& worklet,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
const vtkm::cont::ImplicitFunction& function,
|
||||
const vtkm::cont::ImplicitFunctionHandle& function,
|
||||
bool extractInside,
|
||||
bool extractBoundaryCells,
|
||||
bool extractOnlyBoundaryCells)
|
||||
@ -76,15 +76,6 @@ namespace vtkm
|
||||
namespace filter
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
inline void ExtractGeometry::SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
func->ResetDevices(DerivedPolicy::DeviceAdapterList);
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline VTKM_CONT ExtractGeometry::ExtractGeometry()
|
||||
: vtkm::filter::FilterDataSet<ExtractGeometry>()
|
||||
@ -110,7 +101,7 @@ inline VTKM_CONT vtkm::filter::Result ExtractGeometry::DoExecute(
|
||||
CallWorker<DeviceAdapter> worker(outCells,
|
||||
this->Worklet,
|
||||
coords,
|
||||
*this->Function,
|
||||
this->Function,
|
||||
this->ExtractInside,
|
||||
this->ExtractBoundaryCells,
|
||||
this->ExtractOnlyBoundaryCells);
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef vtk_m_filter_ExtractPoints_h
|
||||
#define vtk_m_filter_ExtractPoints_h
|
||||
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/filter/CleanGrid.h>
|
||||
#include <vtkm/filter/FilterDataSet.h>
|
||||
#include <vtkm/worklet/ExtractPoints.h>
|
||||
@ -53,21 +53,12 @@ public:
|
||||
void SetCompactPoints(bool value) { this->CompactPoints = value; }
|
||||
|
||||
/// Set the volume of interest to extract
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
/// Set the volume of interest to extract
|
||||
template <typename ImplicitFunctionType>
|
||||
void SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func)
|
||||
void SetImplicitFunction(const vtkm::cont::ImplicitFunctionHandle& func)
|
||||
{
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> GetImplicitFunction() const
|
||||
{
|
||||
return this->Function;
|
||||
}
|
||||
const vtkm::cont::ImplicitFunctionHandle& GetImplicitFunction() const { return this->Function; }
|
||||
|
||||
VTKM_CONT
|
||||
bool GetExtractInside() { return this->ExtractInside; }
|
||||
@ -93,7 +84,7 @@ public:
|
||||
|
||||
private:
|
||||
bool ExtractInside;
|
||||
std::shared_ptr<vtkm::cont::ImplicitFunction> Function;
|
||||
vtkm::cont::ImplicitFunctionHandle Function;
|
||||
|
||||
bool CompactPoints;
|
||||
vtkm::filter::CleanGrid Compactor;
|
||||
|
@ -44,15 +44,6 @@ namespace vtkm
|
||||
namespace filter
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename ImplicitFunctionType, typename DerivedPolicy>
|
||||
inline void ExtractPoints::SetImplicitFunction(const std::shared_ptr<ImplicitFunctionType>& func,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
func->ResetDevices(DerivedPolicy::DeviceAdapterList);
|
||||
this->Function = func;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline VTKM_CONT ExtractPoints::ExtractPoints()
|
||||
: vtkm::filter::FilterDataSet<ExtractPoints>()
|
||||
@ -79,7 +70,7 @@ inline vtkm::filter::Result ExtractPoints::DoExecute(
|
||||
|
||||
outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy),
|
||||
vtkm::filter::ApplyPolicy(coords, policy),
|
||||
*this->Function,
|
||||
this->Function,
|
||||
this->ExtractInside,
|
||||
device);
|
||||
|
||||
|
@ -60,11 +60,10 @@ void TestClipStructured()
|
||||
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> center(1, 1, 0);
|
||||
vtkm::FloatDefault radius(0.5);
|
||||
auto sphere = std::make_shared<vtkm::cont::Sphere>(center, radius);
|
||||
|
||||
vtkm::filter::Result result;
|
||||
vtkm::filter::ClipWithImplicitFunction clip;
|
||||
clip.SetImplicitFunction(sphere);
|
||||
clip.SetImplicitFunction(vtkm::cont::make_ImplicitFunctionHandle(vtkm::Sphere(center, radius)));
|
||||
|
||||
result = clip.Execute(ds);
|
||||
clip.MapFieldOntoOutput(result, ds.GetField("scalars"));
|
||||
|
@ -40,7 +40,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractGeometry extractGeometry;
|
||||
@ -76,7 +76,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractGeometry extractGeometry;
|
||||
@ -112,7 +112,7 @@ public:
|
||||
// Implicit function
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.5f, 0.5f, 0.5f);
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.5f, 3.5f, 3.5f);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractGeometry extractGeometry;
|
||||
@ -147,7 +147,7 @@ public:
|
||||
// Implicit function
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> minPoint(0.5f, 0.5f, 0.5f);
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> maxPoint(3.5f, 3.5f, 3.5f);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractGeometry extractGeometry;
|
||||
|
@ -40,7 +40,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractPoints extractPoints;
|
||||
@ -82,7 +82,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractPoints extractPoints;
|
||||
@ -125,7 +125,7 @@ public:
|
||||
// Implicit function
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
|
||||
vtkm::FloatDefault radius(1.8f);
|
||||
auto sphere = std::make_shared<vtkm::cont::Sphere>(center, radius);
|
||||
auto sphere = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Sphere>(center, radius);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractPoints extractPoints;
|
||||
@ -154,7 +154,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractPoints extractPoints;
|
||||
@ -183,7 +183,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);
|
||||
auto box = std::make_shared<vtkm::cont::Box>(minPoint, maxPoint);
|
||||
auto box = vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint);
|
||||
|
||||
// Setup and run filter to extract by volume of interest
|
||||
vtkm::filter::ExtractPoints extractPoints;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/exec/ExecutionWholeArray.h>
|
||||
@ -522,7 +522,7 @@ public:
|
||||
VTKM_CONT
|
||||
ClipWithImplicitFunction(Clip* clipper,
|
||||
const DynamicCellSet& cellSet,
|
||||
const vtkm::exec::ImplicitFunction& function,
|
||||
const vtkm::ImplicitFunction* function,
|
||||
vtkm::cont::CellSetExplicit<>* result)
|
||||
: Clipper(clipper)
|
||||
, CellSet(&cellSet)
|
||||
@ -536,8 +536,8 @@ public:
|
||||
{
|
||||
// Evaluate the implicit function on the input coordinates using
|
||||
// ArrayHandleTransform
|
||||
vtkm::cont::ArrayHandleTransform<ArrayHandleType, vtkm::exec::ImplicitFunctionValue>
|
||||
clipScalars(handle, this->Function);
|
||||
vtkm::cont::ArrayHandleTransform<ArrayHandleType, vtkm::ImplicitFunctionValue> clipScalars(
|
||||
handle, this->Function);
|
||||
|
||||
// Clip at locations where the implicit function evaluates to 0
|
||||
*this->Result = this->Clipper->Run(*this->CellSet, clipScalars, 0.0, DeviceAdapter());
|
||||
@ -546,13 +546,13 @@ public:
|
||||
private:
|
||||
Clip* Clipper;
|
||||
const DynamicCellSet* CellSet;
|
||||
const vtkm::exec::ImplicitFunctionValue Function;
|
||||
vtkm::ImplicitFunctionValue Function;
|
||||
vtkm::cont::CellSetExplicit<>* Result;
|
||||
};
|
||||
|
||||
template <typename CellSetList, typename DeviceAdapter>
|
||||
vtkm::cont::CellSetExplicit<> Run(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
|
||||
const vtkm::cont::ImplicitFunction& clipFunction,
|
||||
const vtkm::cont::ImplicitFunctionHandle& clipFunction,
|
||||
const vtkm::cont::CoordinateSystem& coords,
|
||||
DeviceAdapter device)
|
||||
{
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <vtkm/cont/CellSetPermutation.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -58,7 +58,7 @@ public:
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
ExtractCellsByVOI(const vtkm::exec::ImplicitFunction& function,
|
||||
ExtractCellsByVOI(const vtkm::ImplicitFunction* function,
|
||||
bool extractInside,
|
||||
bool extractBoundaryCells,
|
||||
bool extractOnlyBoundaryCells)
|
||||
@ -77,11 +77,12 @@ public:
|
||||
// Count points inside/outside volume of interest
|
||||
vtkm::IdComponent inCnt = 0;
|
||||
vtkm::IdComponent outCnt = 0;
|
||||
for (vtkm::IdComponent indx = 0; indx < numIndices; indx++)
|
||||
vtkm::Id indx;
|
||||
for (indx = 0; indx < numIndices; indx++)
|
||||
{
|
||||
vtkm::Id ptId = connectivityIn[indx];
|
||||
vtkm::Id ptId = connectivityIn[static_cast<vtkm::IdComponent>(indx)];
|
||||
vtkm::Vec<FloatDefault, 3> coordinate = coordinates.Get(ptId);
|
||||
vtkm::FloatDefault value = this->Function.Value(coordinate);
|
||||
vtkm::FloatDefault value = this->Function->Value(coordinate);
|
||||
if (value <= 0)
|
||||
inCnt++;
|
||||
if (value >= 0)
|
||||
@ -106,7 +107,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::exec::ImplicitFunction Function;
|
||||
const vtkm::ImplicitFunction* Function;
|
||||
bool ExtractInside;
|
||||
bool ExtractBoundaryCells;
|
||||
bool ExtractOnlyBoundaryCells;
|
||||
@ -155,7 +156,7 @@ public:
|
||||
vtkm::cont::CellSetPermutation<CellSetType> Run(
|
||||
const CellSetType& cellSet,
|
||||
const vtkm::cont::CoordinateSystem& coordinates,
|
||||
const vtkm::cont::ImplicitFunction& implicitFunction,
|
||||
const vtkm::cont::ImplicitFunctionHandle& implicitFunction,
|
||||
bool extractInside,
|
||||
bool extractBoundaryCells,
|
||||
bool extractOnlyBoundaryCells,
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -51,7 +51,7 @@ public:
|
||||
typedef _3 ExecutionSignature(_2);
|
||||
|
||||
VTKM_CONT
|
||||
ExtractPointsByVOI(const vtkm::exec::ImplicitFunction& function, bool extractInside)
|
||||
ExtractPointsByVOI(const vtkm::ImplicitFunction* function, bool extractInside)
|
||||
: Function(function)
|
||||
, passValue(extractInside)
|
||||
, failValue(!extractInside)
|
||||
@ -62,14 +62,14 @@ public:
|
||||
bool operator()(const vtkm::Vec<vtkm::Float64, 3>& coordinate) const
|
||||
{
|
||||
bool pass = passValue;
|
||||
vtkm::Float64 value = this->Function.Value(coordinate);
|
||||
vtkm::Float64 value = this->Function->Value(coordinate);
|
||||
if (value > 0)
|
||||
pass = failValue;
|
||||
return pass;
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::exec::ImplicitFunction Function;
|
||||
const vtkm::ImplicitFunction* Function;
|
||||
bool passValue;
|
||||
bool failValue;
|
||||
};
|
||||
@ -97,7 +97,7 @@ public:
|
||||
template <typename CellSetType, typename CoordinateType, typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
|
||||
const CoordinateType& coordinates,
|
||||
const vtkm::cont::ImplicitFunction& implicitFunction,
|
||||
const vtkm::cont::ImplicitFunctionHandle& implicitFunction,
|
||||
bool extractInside,
|
||||
DeviceAdapter device)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <vtkm/cont/DataSetFieldAdd.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/ImplicitFunction.h>
|
||||
#include <vtkm/cont/ImplicitFunctionHandle.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
#include <vector>
|
||||
@ -243,13 +243,15 @@ void TestClippingWithImplicitFunction()
|
||||
{
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> center(1, 1, 0);
|
||||
vtkm::FloatDefault radius(0.5);
|
||||
vtkm::cont::Sphere sphere(center, radius);
|
||||
|
||||
vtkm::cont::DataSet ds = MakeTestDatasetStructured();
|
||||
|
||||
vtkm::worklet::Clip clip;
|
||||
vtkm::cont::CellSetExplicit<> outputCellSet =
|
||||
clip.Run(ds.GetCellSet(0), sphere, ds.GetCoordinateSystem("coords"), DeviceAdapter());
|
||||
clip.Run(ds.GetCellSet(0),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Sphere>(center, radius),
|
||||
ds.GetCoordinateSystem("coords"),
|
||||
DeviceAdapter());
|
||||
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates coordsIn;
|
||||
ds.GetCoordinateSystem("coords").GetData().CopyTo(coordsIn);
|
||||
|
@ -77,7 +77,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
|
||||
bool extractInside = true;
|
||||
bool extractBoundaryCells = false;
|
||||
@ -88,7 +87,7 @@ public:
|
||||
vtkm::cont::DynamicCellSet outCellSet =
|
||||
extractGeometry.Run(cellSet,
|
||||
dataset.GetCoordinateSystem("coordinates"),
|
||||
box,
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
extractBoundaryCells,
|
||||
extractOnlyBoundaryCells,
|
||||
@ -187,7 +186,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
|
||||
bool extractInside = true;
|
||||
bool extractBoundaryCells = false;
|
||||
@ -198,7 +196,7 @@ public:
|
||||
vtkm::cont::DynamicCellSet outCellSet =
|
||||
extractGeometry.Run(cellSet,
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
box,
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
extractBoundaryCells,
|
||||
extractOnlyBoundaryCells,
|
||||
@ -229,7 +227,6 @@ public:
|
||||
// Implicit function
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
|
||||
vtkm::FloatDefault radius(1.8f);
|
||||
vtkm::cont::Sphere sphere(center, radius);
|
||||
|
||||
bool extractInside = true;
|
||||
bool extractBoundaryCells = false;
|
||||
@ -240,7 +237,7 @@ public:
|
||||
vtkm::cont::DynamicCellSet outCellSet =
|
||||
extractGeometry.Run(cellSet,
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
sphere,
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Sphere>(center, radius),
|
||||
extractInside,
|
||||
extractBoundaryCells,
|
||||
extractOnlyBoundaryCells,
|
||||
|
@ -68,7 +68,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
bool extractInside = true;
|
||||
|
||||
// Output dataset contains input coordinate system and point data
|
||||
@ -77,11 +76,12 @@ public:
|
||||
|
||||
// Output data set with cell set containing extracted points
|
||||
vtkm::worklet::ExtractPoints extractPoints;
|
||||
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
box,
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
OutCellSetType outCellSet =
|
||||
extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
outDataSet.AddCellSet(outCellSet);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27),
|
||||
@ -100,7 +100,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
bool extractInside = false;
|
||||
|
||||
// Output dataset contains input coordinate system and point data
|
||||
@ -109,11 +108,12 @@ public:
|
||||
|
||||
// Output data set with cell set containing extracted points
|
||||
vtkm::worklet::ExtractPoints extractPoints;
|
||||
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
box,
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
OutCellSetType outCellSet =
|
||||
extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
outDataSet.AddCellSet(outCellSet);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 98),
|
||||
@ -132,7 +132,6 @@ public:
|
||||
// Implicit function
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> center(2.f, 2.f, 2.f);
|
||||
vtkm::FloatDefault radius(1.8f);
|
||||
vtkm::cont::Sphere sphere(center, radius);
|
||||
bool extractInside = true;
|
||||
|
||||
// Output dataset contains input coordinate system and point data
|
||||
@ -141,11 +140,12 @@ public:
|
||||
|
||||
// Output data set with cell set containing extracted points
|
||||
vtkm::worklet::ExtractPoints extractPoints;
|
||||
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
sphere,
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
OutCellSetType outCellSet =
|
||||
extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coords"),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Sphere>(center, radius),
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
outDataSet.AddCellSet(outCellSet);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27),
|
||||
@ -164,7 +164,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
bool extractInside = true;
|
||||
|
||||
// Output dataset contains input coordinate system and point data
|
||||
@ -173,11 +172,12 @@ public:
|
||||
|
||||
// Output data set with cell set containing extracted points
|
||||
vtkm::worklet::ExtractPoints extractPoints;
|
||||
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coordinates"),
|
||||
box,
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
OutCellSetType outCellSet =
|
||||
extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coordinates"),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
outDataSet.AddCellSet(outCellSet);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8),
|
||||
@ -196,7 +196,6 @@ 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::cont::Box box(minPoint, maxPoint);
|
||||
bool extractInside = false;
|
||||
|
||||
// Output dataset contains input coordinate system and point data
|
||||
@ -205,11 +204,12 @@ public:
|
||||
|
||||
// Output data set with cell set containing extracted points
|
||||
vtkm::worklet::ExtractPoints extractPoints;
|
||||
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coordinates"),
|
||||
box,
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
OutCellSetType outCellSet =
|
||||
extractPoints.Run(dataset.GetCellSet(0),
|
||||
dataset.GetCoordinateSystem("coordinates"),
|
||||
vtkm::cont::make_ImplicitFunctionHandle<vtkm::Box>(minPoint, maxPoint),
|
||||
extractInside,
|
||||
DeviceAdapter());
|
||||
outDataSet.AddCellSet(outCellSet);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 3),
|
||||
|
Loading…
Reference in New Issue
Block a user