Bounds.h 5.71 KB
Newer Older
Kenneth Moreland's avatar
Kenneth Moreland committed
1 2 3 4 5 6 7 8
//============================================================================
//  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.
//
9
//  Copyright 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
Kenneth Moreland's avatar
Kenneth Moreland committed
10 11 12
//  Copyright 2016 UT-Battelle, LLC.
//  Copyright 2016 Los Alamos National Security.
//
13
//  Under the terms of Contract DE-NA0003525 with NTESS,
Kenneth Moreland's avatar
Kenneth Moreland committed
14 15 16 17 18 19 20 21 22 23 24 25
//  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>

26 27
namespace vtkm
{
Kenneth Moreland's avatar
Kenneth Moreland committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

/// \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;

45
  VTKM_EXEC_CONT
46
  Bounds() {}
Kenneth Moreland's avatar
Kenneth Moreland committed
47

48 49
  Bounds(const Bounds&) = default;

50
  VTKM_EXEC_CONT
51 52 53 54 55 56 57 58
  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>
59 60 61 62 63 64
  VTKM_EXEC_CONT Bounds(const T1& minX,
                        const T2& maxX,
                        const T3& minY,
                        const T4& maxY,
                        const T5& minZ,
                        const T6& maxZ)
65 66 67 68 69
    : X(vtkm::Range(minX, maxX))
    , Y(vtkm::Range(minY, maxY))
    , Z(vtkm::Range(minZ, maxZ))
  {
  }
Kenneth Moreland's avatar
Kenneth Moreland committed
70 71 72 73

  /// Initialize bounds with an array of 6 values in the order xmin, xmax,
  /// ymin, ymax, zmin, zmax.
  ///
74 75 76 77 78 79 80
  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]))
  {
  }
Kenneth Moreland's avatar
Kenneth Moreland committed
81 82 83 84

  /// Initialize bounds with the minimum corner point and the maximum corner
  /// point.
  ///
85 86 87 88 89 90 91
  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]))
  {
  }
Kenneth Moreland's avatar
Kenneth Moreland committed
92

93
  vtkm::Bounds& operator=(const vtkm::Bounds& src) = default;
Kenneth Moreland's avatar
Kenneth Moreland committed
94 95 96 97 98 99 100

  /// \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.
  ///
101
  VTKM_EXEC_CONT
Kenneth Moreland's avatar
Kenneth Moreland committed
102 103
  bool IsNonEmpty() const
  {
104
    return (this->X.IsNonEmpty() && this->Y.IsNonEmpty() && this->Z.IsNonEmpty());
Kenneth Moreland's avatar
Kenneth Moreland committed
105 106 107 108
  }

  /// \b Determines if a point coordinate is within the bounds.
  ///
109 110
  template <typename T>
  VTKM_EXEC_CONT bool Contains(const vtkm::Vec<T, 3>& point) const
Kenneth Moreland's avatar
Kenneth Moreland committed
111
  {
112
    return (this->X.Contains(point[0]) && this->Y.Contains(point[1]) && this->Z.Contains(point[2]));
Kenneth Moreland's avatar
Kenneth Moreland committed
113 114
  }

115 116 117 118 119
  /// \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.
  ///
120
  VTKM_EXEC_CONT
121
  vtkm::Vec<vtkm::Float64, 3> Center() const
122
  {
123
    return vtkm::Vec<vtkm::Float64, 3>(this->X.Center(), this->Y.Center(), this->Z.Center());
124 125
  }

Kenneth Moreland's avatar
Kenneth Moreland committed
126 127 128 129 130 131
  /// \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.
  ///
132 133
  template <typename T>
  VTKM_EXEC_CONT void Include(const vtkm::Vec<T, 3>& point)
Kenneth Moreland's avatar
Kenneth Moreland committed
134 135 136 137 138 139 140 141 142
  {
    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
luz.paz's avatar
luz.paz committed
143
  /// that of another bounds. Essentially it is the union of the two bounds.
Kenneth Moreland's avatar
Kenneth Moreland committed
144
  ///
145
  VTKM_EXEC_CONT
146
  void Include(const vtkm::Bounds& bounds)
Kenneth Moreland's avatar
Kenneth Moreland committed
147 148 149 150 151 152 153 154 155 156
  {
    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.
  ///
157
  VTKM_EXEC_CONT
158
  vtkm::Bounds Union(const vtkm::Bounds& otherBounds) const
Kenneth Moreland's avatar
Kenneth Moreland committed
159 160 161 162 163 164 165 166
  {
    vtkm::Bounds unionBounds(*this);
    unionBounds.Include(otherBounds);
    return unionBounds;
  }

  /// \b Operator for union
  ///
167
  VTKM_EXEC_CONT
168
  vtkm::Bounds operator+(const vtkm::Bounds& otherBounds) const { return this->Union(otherBounds); }
Kenneth Moreland's avatar
Kenneth Moreland committed
169

170
  VTKM_EXEC_CONT
171
  bool operator==(const vtkm::Bounds& bounds) const
Kenneth Moreland's avatar
Kenneth Moreland committed
172
  {
173
    return ((this->X == bounds.X) && (this->Y == bounds.Y) && (this->Z == bounds.Z));
Kenneth Moreland's avatar
Kenneth Moreland committed
174 175
  }

176
  VTKM_EXEC_CONT
177
  bool operator!=(const vtkm::Bounds& bounds) const
Kenneth Moreland's avatar
Kenneth Moreland committed
178
  {
179
    return ((this->X != bounds.X) || (this->Y != bounds.Y) || (this->Z != bounds.Z));
Kenneth Moreland's avatar
Kenneth Moreland committed
180 181 182 183 184
  }
};

} // namespace vtkm

185 186
/// Helper function for printing bounds during testing
///
187
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::Bounds& bounds)
188
{
189
  return stream << "{ X:" << bounds.X << ", Y:" << bounds.Y << ", Z:" << bounds.Z << " }";
190 191
}

Kenneth Moreland's avatar
Kenneth Moreland committed
192
#endif //vtk_m_Bounds_h