2.12. Implicit Functions

VTK‑m’s implicit functions are objects that are constructed with values representing 3D spatial coordinates that often describe a shape. Each implicit function is typically defined by the surface formed where the value of the function is equal to 0. All implicit functions implement Value() and Gradient() methods that describe the orientation of a provided point with respect to the implicit function’s shape.

The Value() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::FloatDefault representing the orientation of the point with respect to the implicit function’s shape. Negative scalar values represent vector points inside of the implicit function’s shape. Positive scalar values represent vector points outside the implicit function’s shape. Zero values represent vector points that lie on the surface of the implicit function.

The Gradient() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::Vec3f representing the pointing direction from the implicit function’s shape. Gradient calculations are more object shape specific. It is advised to look at the individual shape implementations for specific implicit functions.

Implicit functions are useful when trying to clip regions from a dataset. For example, it is possible to use vtkm::filter::contour::ClipWithImplicitFunction to remove a region in a provided dataset according to the shape of an implicit function. See Section 2.7.3.4 (Clip with Implicit Function) for more information on clipping with implicit functions.

VTK‑m has implementations of various implicit functions provided by the following subclasses.

2.12.1. Plane

vtkm::Plane defines an infinite plane. The plane is defined by a pair of vtkm::Vec3f values that represent the origin, which is any point on the plane, and a normal, which is a vector that is tangent to the plane. These are set with the vtkm::Plane::SetOrigin() and vtkm::Plane::SetNormal() methods, respectively. Planes extend infinitely from the origin point in the direction perpendicular form the Normal. An example vtkm::Plane is shown in Figure 2.13.

_images/ImplicitPlane.png

Figure 2.13 Visual Representation of an Implicit Plane. The red dot and arrow represent the origin and normal of the plane, respectively. For demonstrative purposes the plane as shown with limited area, but in actuality the plane extends infinitely.

template<typename CoordType = vtkm::FloatDefault>
class Plane : public vtkm::internal::ImplicitFunctionBase<Plane>

Represent a plane with a base point (origin) and normal vector.

Implicit function for a plane.

A plane is defined by a point in the plane and a normal to the plane. The normal does not have to be a unit vector. The implicit function will still evaluate to 0 at the plane, but the values outside the plane (and the gradient) will be scaled by the length of the normal vector.

Public Functions

Plane()

Construct a default plane whose base point is the origin and whose normal is (0,0,1)

Plane(const Vector &origin, const Vector &normal, CoordType tol2 = static_cast<CoordType>(1e-8f))

Construct a plane with the given origin and normal.

inline bool IsValid() const

Return true if the plane’s normal is well-defined to within the given tolerance.

CoordType DistanceTo(const Vector &point) const

Return the signed distance from the plane to the point.

Vector ClosestPoint(const Vector &point) const

Return the closest point in the plane to the given point.

template<bool IsTwoSided>
bool Intersect(const Ray<CoordType, 3, IsTwoSided> &ray, CoordType &parameter, Vector &point, bool &lineInPlane, CoordType tol = CoordType(1e-6f)) const

Intersect this plane with the ray (or line if the ray is two-sided).

Returns true if there is a non-degenrate intersection (i.e., an isolated point of intersection). Returns false if there is no intersection or if the intersection is degenerate (i.e., the entire ray/line lies in the plane). In the latter case, lineInPlane will be true upon exit.

If this method returns true, then parameter will be set to a number indicating where along the ray/line the plane hits and point will be set to that location. If the input is a ray, the parameter will be non-negative.

bool Intersect(const LineSegment<CoordType> &segment, CoordType &parameter, bool &lineInPlane) const

Intersect this plane with the line segment.

Returns true if there is a non-degenrate intersection (i.e., an isolated point of intersection). Returns false if there is no intersection or if the intersection is degenerate (i.e., the entire line segment lies in the plane). In the latter case, lineInPlane will be true upon exit.

If this method returns true, then parameter will be set to a number in [0,1] indicating where along the line segment the plane hits.

bool Intersect(const LineSegment<CoordType> &segment, CoordType &parameter, Vector &point, bool &lineInPlane) const

Intersect this plane with the line segment.

Returns true if there is a non-degenrate intersection (i.e., an isolated point of intersection). Returns false if there is no intersection or if the intersection is degenerate (i.e., the entire line segment lines in the plane). In the latter case, lineInPlane will be true upon exit.

If this method returns true, then parameter will be set to a number in [0,1] indicating where along the line segment the plane hits and point will be set to that location.

bool Intersect(const Plane<CoordType> &other, Ray<CoordType, 3, true> &ray, bool &coincident, CoordType tol2 = static_cast<CoordType>(1e-6f)) const

Intersect this plane with another plane.

Returns true if there is a non-degenrate intersection (i.e., a line of intersection). Returns false if there is no intersection or if the intersection is degenerate (i.e., the planes are coincident). In the latter case, coincident will be true upon exit and segment will unmodified.

If this method returns true, then the resulting segment will have its base point on the line of intersection and its second point will be a unit length away in the direction of the cross produce of the input plane normals (this plane crossed with the other).

The tolerance tol is the minimum squared length of the cross-product of the two plane normals. It is also compared to the squared distance of the base point of other away from this plane when considering whether the planes are coincident.

inline explicit Plane(const Vector &normal = {0, 0, 1})

Construct a plane through the origin with the given normal.

inline Plane(const Vector &origin, const Vector &normal)

Construct a plane through the given point with the given normal.

inline void SetOrigin(const Vector &origin)

Specify the origin of the plane.

The origin can be any point on the plane.

inline void SetNormal(const Vector &normal)

Specify the normal vector to the plane.

The magnitude of the plane does not matter (so long as it is more than zero) in terms of the location of the plane where the implicit function equals 0. However, if offsets away from the plane matter then the magnitude determines the scale of the value away from the plane.

inline const Vector &GetOrigin() const

Specify the origin of the plane.

The origin can be any point on the plane.

inline const Vector &GetNormal() const

Specify the normal vector to the plane.

The magnitude of the plane does not matter (so long as it is more than zero) in terms of the location of the plane where the implicit function equals 0. However, if offsets away from the plane matter then the magnitude determines the scale of the value away from the plane.

inline Scalar Value(const Vector &point) const

Evaluate the value of the implicit function.

The Value() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::FloatDefault representing the orientation of the point with respect to the implicit function’s shape. Negative scalar values represent vector points inside of the implicit function’s shape. Positive scalar values represent vector points outside the implicit function’s shape. Zero values represent vector points that lie on the surface of the implicit function.

inline Vector Gradient(const Vector&) const

Evaluate the gradient of the implicit function.

The Gradient() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::Vec3f representing the pointing direction from the implicit function’s shape. Gradient calculations are more object shape specific. It is advised to look at the individual shape implementations for specific implicit functions.

2.12.2. Sphere

vtkm::Sphere defines a sphere. The vtkm::Sphere is defined by a center location and a radius, which are set with the vtkm::Sphere::SetCenter() and vtkm::Sphere::SetRadius() methods, respectively. An example vtkm::Sphere is shown in Figure 2.14.

_images/ImplicitSphere.png

Figure 2.14 Visual Representation of an Implicit Sphere. The red dot represents the center of the sphere. The radius is the length of any line (like the blue one shown here) that extends from the center in any direction to the surface.

template<typename CoordType = vtkm::FloatDefault, int Dim = 3>
class Sphere : public vtkm::internal::ImplicitFunctionBase<Sphere>

Represent a sphere of the given Dimension.

Implicit function for a sphere.

If a constructor is given an invalid specification, then the Radius of the resulting sphere will be -1.

A sphere is defined by its center and a radius.

The value of the sphere implicit function is the square of the distance from the center biased by the radius (so the surface of the sphere is at value 0).

Public Functions

Sphere()

Construct a default sphere (unit radius at the origin).

Sphere(const Vector &center, CoordType radius)

Construct a sphere from a center point and radius.

inline bool IsValid() const

Return true if the sphere is valid (i.e., has a strictly positive radius).

bool Contains(const Vector &point, CoordType tol2 = 0.f) const

Return whether the point lies strictly inside the sphere.

int Classify(const Vector &point, CoordType tol2 = 0.f) const

Classify a point as inside (-1), on (0), or outside (+1) of the sphere.

The tolerance tol2 is the maximum allowable difference in squared magnitude between the squared radius and the squared distance between the point and Center.

inline explicit Sphere(Scalar radius = 0.5)

Construct a sphere with center at (0,0,0) and the given radius.

inline Sphere(Vector center, Scalar radius)

Construct a sphere with the given center and radius.

inline void SetRadius(Scalar radius)

Specify the radius of the sphere.

inline void SetCenter(const Vector &center)

Specify the center of the sphere.

inline Scalar GetRadius() const

Specify the radius of the sphere.

inline const Vector &GetCenter() const

Specify the center of the sphere.

inline Scalar Value(const Vector &point) const

Evaluate the value of the implicit function.

The Value() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::FloatDefault representing the orientation of the point with respect to the implicit function’s shape. Negative scalar values represent vector points inside of the implicit function’s shape. Positive scalar values represent vector points outside the implicit function’s shape. Zero values represent vector points that lie on the surface of the implicit function.

inline Vector Gradient(const Vector &point) const

Evaluate the gradient of the implicit function.

The Gradient() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::Vec3f representing the pointing direction from the implicit function’s shape. Gradient calculations are more object shape specific. It is advised to look at the individual shape implementations for specific implicit functions.

2.12.3. Cylinder

vtkm::Cylinder defines a cylinder that extends infinitely along its axis. The cylinder is defined with a center point, a direction of the center axis, and a radius, which are set with vtkm::Cylinder::SetCenter(), vtkm::Cylinder::SetAxis(), and vtkm::Cylinder::SetRadius(), respectively. An example vtkm::Cylinder is shown in Figure 2.15 with set origin, radius, and axis values.

_images/ImplicitCylinder.png

Figure 2.15 Visual Representation of an Implicit Cylinder. The red dot represents the center value, and the red arrow represents the vector that points in the direction of the axis. The radius is the length of any line (like the blue one shown here) that extends perpendicular from the axis to the surface.

class Cylinder : public vtkm::internal::ImplicitFunctionBase<Cylinder>

Implicit function for a cylinder.

Cylinder computes the implicit function and function gradient for a cylinder using F(r)=r^2-Radius^2. By default the Cylinder is centered at the origin and the axis of rotation is along the y-axis. You can redefine the center and axis of rotation by setting the Center and Axis data members.

Note that the cylinder is infinite in extent.

Public Functions

inline Cylinder()

Construct cylinder radius of 0.5; centered at origin with axis along y coordinate axis.

inline Cylinder(const Vector &axis, Scalar radius)

Construct a cylinder with the given axis and radius.

The cylinder is centered at the origin.

inline Cylinder(const Vector &center, const Vector &axis, Scalar radius)

Construct a cylinder at the given center, axis, and radius.

inline void SetCenter(const Vector &center)

Specify the center of the cylinder.

The axis of the cylinder goes through the center.

inline void SetAxis(const Vector &axis)

Specify the direction of the axis of the cylinder.

inline void SetRadius(Scalar radius)

Specify the radius of the cylinder.

inline Scalar Value(const Vector &point) const

Evaluate the value of the implicit function.

The Value() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::FloatDefault representing the orientation of the point with respect to the implicit function’s shape. Negative scalar values represent vector points inside of the implicit function’s shape. Positive scalar values represent vector points outside the implicit function’s shape. Zero values represent vector points that lie on the surface of the implicit function.

inline Vector Gradient(const Vector &point) const

Evaluate the gradient of the implicit function.

The Gradient() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::Vec3f representing the pointing direction from the implicit function’s shape. Gradient calculations are more object shape specific. It is advised to look at the individual shape implementations for specific implicit functions.

2.12.4. Box

vtkm::Box defines an axis-aligned box. The box is defined with a pair of vtkm::Vec3f values that represent the minimum point coordinates and maximum point coordinates, which are set with vtkm::Box::SetMinPoint() and vtkm::Box::SetMaxPoint(), respectively. The vtkm::Box is the shape enclosed by intersecting axis-parallel lines drawn from each point. Alternately, the vtkm::Box can be specified with a vtkm::Bounds object using the vtkm::Box::SetBounds() method. An example vtkm::Box is shown in Figure 2.16.

_images/ImplicitBox.png

Figure 2.16 Visual Representation of an Implicit Box. The red dots represent the minimum and maximum points.

class Box : public vtkm::internal::ImplicitFunctionBase<Box>

Implicit function for a box.

Box computes the implicit function and/or gradient for a axis-aligned bounding box. Each side of the box is orthogonal to all other sides meeting along shared edges and all faces are orthogonal to the x-y-z coordinate axes.

Public Functions

inline Box()

Construct box with center at (0,0,0) and each side of length 1.0.

inline Box(const Vector &minPoint, const Vector &maxPoint)

Construct a box with the specified minimum and maximum point.

inline Box(Scalar xmin, Scalar xmax, Scalar ymin, Scalar ymax, Scalar zmin, Scalar zmax)

Construct a box with the specified minimum and maximum point.

inline Box(const vtkm::Bounds &bounds)

Construct a box that encompasses the given bounds.

inline void SetMinPoint(const Vector &point)

Specify the minimum coordinate of the box.

inline void SetMaxPoint(const Vector &point)

Specify the maximum coordinate of the box.

inline const Vector &GetMinPoint() const

Specify the minimum coordinate of the box.

inline const Vector &GetMaxPoint() const

Specify the maximum coordinate of the box.

inline void SetBounds(const vtkm::Bounds &bounds)

Specify the size and location of the box by the bounds it encompasses.

inline vtkm::Bounds GetBounds() const

Specify the size and location of the box by the bounds it encompasses.

inline Scalar Value(const Vector &point) const

Evaluate the value of the implicit function.

The Value() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::FloatDefault representing the orientation of the point with respect to the implicit function’s shape. Negative scalar values represent vector points inside of the implicit function’s shape. Positive scalar values represent vector points outside the implicit function’s shape. Zero values represent vector points that lie on the surface of the implicit function.

inline Vector Gradient(const Vector &point) const

Evaluate the gradient of the implicit function.

The Gradient() method for an implicit function takes a vtkm::Vec3f and returns a vtkm::Vec3f representing the pointing direction from the implicit function’s shape. Gradient calculations are more object shape specific. It is advised to look at the individual shape implementations for specific implicit functions.

2.12.5. Frustum

vtkm::Frustum defines a hexahedral region with potentially oblique faces. A vtkm::Frustum is typically used to define the tapered region of space visible in a perspective camera projection. The frustum is defined by the 6 planes that make up its 6 faces. Each plane is defined by a point and a normal vector, which are set with vtkm::Frustum::SetPlane() and vtkm::Frustum::SetNormal(), respectively. Parameters for all 6 planes can be set at once using the vtkm::Frustum::SetPlanes() and vtkm::Frustum::SetNormals() methods. Alternately, the vtkm::Frustum can be defined by the 8 points at the vertices of the enclosing hexahedron using the vtkm::Frustum::CreateFromPoints() method. The points given to vtkm::Frustum::CreateFromPoints() must be in hex-cell order where the first four points are assumed to be a plane, and the last four points are assumed to be a plane. An example vtkm::Frustum is shown in Figure 2.17.

_images/ImplicitFrustum.png

Figure 2.17 Visual Representation of an Implicit Frustum. The red dots and arrows represent the points and normals defining each enclosing plane. The blue dots represent the 8 vertices, which can also be used to define the frustum.

class Frustum : public vtkm::internal::ImplicitFunctionBase<Frustum>

Implicit function for a frustum.

2.12.6. General Implicit Functions

It is often the case when creating code that uses an implicit function that you do not know which implicit function will be desired. For example, the vtkm::filter::contour::ClipWithImplicitFunction filter can be used with any of the implicit functions described here (vtkm::Plane, vtkm::Sphere, etc.).

To handle conditions where you want to support multiple implicit functions simultaneously, VTK‑m provides vtkm::ImplicitFunctionGeneral. Any of the implicit functions described in this chapter can be copied to a vtkm::ImplicitFunctionGeneral, which will behave like the specified function. The following example shows shows passing a vtkm::Sphere to vtkm::filter::contour::ClipWithImplicitFunction, which internally uses vtkm::ImplicitFunctionGeneral to manage the implicit function types.

Example 2.64 Passing an implicit function to a filter.
1  // Parameters needed for implicit function
2  vtkm::Sphere implicitFunction(vtkm::make_Vec(1, 0, 1), 0.5);
3
4  // Create an instance of a clip filter with this implicit function.
5  vtkm::filter::contour::ClipWithImplicitFunction clip;
6  clip.SetImplicitFunction(implicitFunction);
class ImplicitFunctionGeneral : public vtkm::ImplicitFunctionMultiplexer<vtkm::Box, vtkm::Cylinder, vtkm::Frustum, vtkm::Plane, vtkm::Sphere, vtkm::MultiPlane<3>>

Implicit function that can switch among known implicit function types.

ImplicitFunctionGeneral can behave as any of the predefined implicit functions provided by VTK-m. This is helpful when the type of implicit function is not known at compile time. For example, say you want a filter that can operate on an implicit function. Rather than compile separate versions of the filter, one for each type of implicit function, you can compile the filter once for ImplicitFunctionGeneral and then set the desired implicit function at runtime.

To use ImplicitFunctionGeneral, simply create the actual implicit function that you want to use, and then set the ImplicitFunctionGeneral to that concrete implicit function object.

ImplicitFunctionGeneral currently supports vtkm::Box, vtkm::Cylinder, vtkm::Frustum, vtkm::Plane, and vtkm::Sphere.