vtk-m/vtkm/Bounds.h
2017-05-25 07:51:37 -04:00

194 lines
5.6 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_Bounds_h
#define vtk_m_Bounds_h
#include <vtkm/Range.h>
namespace vtkm
{
/// \brief Represent an axis-aligned 3D bounds in space.
///
/// \c vtkm::Bounds is a helper class for representing the axis-aligned box
/// representing some region in space. The typical use of this class is to
/// express the containing box of some geometry. The box is specified as ranges
/// in the x, y, and z directions.
///
/// \c Bounds also contains several helper functions for computing and
/// maintaining the bounds.
///
struct Bounds
{
vtkm::Range X;
vtkm::Range Y;
vtkm::Range Z;
VTKM_EXEC_CONT
Bounds() {}
VTKM_EXEC_CONT
Bounds(const vtkm::Range& xRange, const vtkm::Range& yRange, const vtkm::Range& zRange)
: X(xRange)
, Y(yRange)
, Z(zRange)
{
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
VTKM_EXEC_CONT Bounds(const T1& minX, const T2& maxX, const T3& minY, const T4& maxY,
const T5& minZ, const T6& maxZ)
: X(vtkm::Range(minX, maxX))
, Y(vtkm::Range(minY, maxY))
, Z(vtkm::Range(minZ, maxZ))
{
}
/// Initialize bounds with an array of 6 values in the order xmin, xmax,
/// ymin, ymax, zmin, zmax.
///
template <typename T>
VTKM_EXEC_CONT explicit Bounds(const T bounds[6])
: X(vtkm::Range(bounds[0], bounds[1]))
, Y(vtkm::Range(bounds[2], bounds[3]))
, Z(vtkm::Range(bounds[4], bounds[5]))
{
}
/// Initialize bounds with the minimum corner point and the maximum corner
/// point.
///
template <typename T>
VTKM_EXEC_CONT Bounds(const vtkm::Vec<T, 3>& minPoint, const vtkm::Vec<T, 3>& maxPoint)
: X(vtkm::Range(minPoint[0], maxPoint[0]))
, Y(vtkm::Range(minPoint[1], maxPoint[1]))
, Z(vtkm::Range(minPoint[2], maxPoint[2]))
{
}
VTKM_EXEC_CONT
const vtkm::Bounds& operator=(const vtkm::Bounds& src)
{
this->X = src.X;
this->Y = src.Y;
this->Z = src.Z;
return *this;
}
/// \b Determine if the bounds are valid (i.e. has at least one valid point).
///
/// \c IsNonEmpty returns true if the bounds contain some valid points. If
/// the bounds are any real region, even if a single point or it expands to
/// infinity, true is returned.
///
VTKM_EXEC_CONT
bool IsNonEmpty() const
{
return (this->X.IsNonEmpty() && this->Y.IsNonEmpty() && this->Z.IsNonEmpty());
}
/// \b Determines if a point coordinate is within the bounds.
///
template <typename T>
VTKM_EXEC_CONT bool Contains(const vtkm::Vec<T, 3>& point) const
{
return (this->X.Contains(point[0]) && this->Y.Contains(point[1]) && this->Z.Contains(point[2]));
}
/// \b Returns the center of the range.
///
/// \c Center computes the point at the middle of the bounds. If the bounds
/// are empty, the results are undefined.
///
VTKM_EXEC_CONT
vtkm::Vec<vtkm::Float64, 3> Center() const
{
return vtkm::Vec<vtkm::Float64, 3>(this->X.Center(), this->Y.Center(), this->Z.Center());
}
/// \b Expand bounds to include a point.
///
/// This version of \c Include expands the bounds just enough to include the
/// given point coordinates. If the bounds already include this point, then
/// nothing is done.
///
template <typename T>
VTKM_EXEC_CONT void Include(const vtkm::Vec<T, 3>& point)
{
this->X.Include(point[0]);
this->Y.Include(point[1]);
this->Z.Include(point[2]);
}
/// \b Expand bounds to include other bounds.
///
/// This version of \c Include expands these bounds just enough to include
/// that of another bounds. Esentially it is the union of the two bounds.
///
VTKM_EXEC_CONT
void Include(const vtkm::Bounds& bounds)
{
this->X.Include(bounds.X);
this->Y.Include(bounds.Y);
this->Z.Include(bounds.Z);
}
/// \b Return the union of this and another bounds.
///
/// This is a nondestructive form of \c Include.
///
VTKM_EXEC_CONT
vtkm::Bounds Union(const vtkm::Bounds& otherBounds) const
{
vtkm::Bounds unionBounds(*this);
unionBounds.Include(otherBounds);
return unionBounds;
}
/// \b Operator for union
///
VTKM_EXEC_CONT
vtkm::Bounds operator+(const vtkm::Bounds& otherBounds) const { return this->Union(otherBounds); }
VTKM_EXEC_CONT
bool operator==(const vtkm::Bounds& bounds) const
{
return ((this->X == bounds.X) && (this->Y == bounds.Y) && (this->Z == bounds.Z));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::Bounds& bounds) const
{
return ((this->X != bounds.X) || (this->Y != bounds.Y) || (this->Z != bounds.Z));
}
};
} // namespace vtkm
/// Helper function for printing bounds during testing
///
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::Bounds& bounds)
{
return stream << "{ X:" << bounds.X << ", Y:" << bounds.Y << ", Z:" << bounds.Z << " }";
}
#endif //vtk_m_Bounds_h