RangeId3.h 5 KB
Newer Older
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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 11 12
//  Copyright 2017 UT-Battelle, LLC.
//  Copyright 2017 Los Alamos National Security.
//
13
//  Under the terms of Contract DE-NA0003525 with NTESS,
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
//  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_RangeId3_h
#define vtk_m_RangeId3_h

#include <vtkm/RangeId.h>

namespace vtkm
{

/// \brief Represent 3D integer range.
///
/// \c vtkm::RangeId3 is a helper class for representing a 3D range of integer
/// values. The typical use of this class is to express a box of indices
/// in the x, y, and z directions.
///
/// \c RangeId3 also contains several helper functions for computing and
/// maintaining the range.
///
struct RangeId3
{
  vtkm::RangeId X;
  vtkm::RangeId Y;
  vtkm::RangeId Z;

  RangeId3() = default;

  VTKM_EXEC_CONT
  RangeId3(const vtkm::RangeId& xrange, const vtkm::RangeId& yrange, const vtkm::RangeId& zrange)
    : X(xrange)
    , Y(yrange)
    , Z(zrange)
  {
  }

  VTKM_EXEC_CONT
  RangeId3(vtkm::Id minX, vtkm::Id maxX, vtkm::Id minY, vtkm::Id maxY, vtkm::Id minZ, vtkm::Id maxZ)
    : X(vtkm::RangeId(minX, maxX))
    , Y(vtkm::RangeId(minY, maxY))
    , Z(vtkm::RangeId(minZ, maxZ))
  {
  }

  /// Initialize range with an array of 6 values in the order xmin, xmax,
  /// ymin, ymax, zmin, zmax.
  ///
  VTKM_EXEC_CONT
  explicit RangeId3(const vtkm::Id range[6])
    : X(vtkm::RangeId(range[0], range[1]))
    , Y(vtkm::RangeId(range[2], range[3]))
    , Z(vtkm::RangeId(range[4], range[5]))
  {
  }

  /// Initialize range with the minimum and the maximum corners
  ///
  VTKM_EXEC_CONT
  RangeId3(const vtkm::Id3& min, const vtkm::Id3& max)
    : X(vtkm::RangeId(min[0], max[0]))
    , Y(vtkm::RangeId(min[1], max[1]))
    , Z(vtkm::RangeId(min[2], max[2]))
  {
  }

  /// \b Determine if the range is non-empty.
  ///
  /// \c IsNonEmpty returns true if the range is non-empty.
  ///
  VTKM_EXEC_CONT
  bool IsNonEmpty() const
  {
    return (this->X.IsNonEmpty() && this->Y.IsNonEmpty() && this->Z.IsNonEmpty());
  }

  /// \b Determines if an Id3 value is within the range.
  ///
  VTKM_EXEC_CONT
  bool Contains(const vtkm::Id3& val) const
  {
    return (this->X.Contains(val[0]) && this->Y.Contains(val[1]) && this->Z.Contains(val[2]));
  }

  /// \b Returns the center of the range.
  ///
  /// \c Center computes the middle of the range.
  ///
  VTKM_EXEC_CONT
  vtkm::Id3 Center() const
  {
    return vtkm::Id3(this->X.Center(), this->Y.Center(), this->Z.Center());
  }

  VTKM_EXEC_CONT
  vtkm::Id3 Dimensions() const
  {
    return vtkm::Id3(this->X.Length(), this->Y.Length(), this->Z.Length());
  }

  /// \b Expand range to include a value.
  ///
  /// This version of \c Include expands the range just enough to include the
  /// given value. If the range already include this value, 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 range to include other range.
  ///
  /// This version of \c Include expands the range just enough to include
luz.paz's avatar
luz.paz committed
133
  /// the other range. Essentially it is the union of the two ranges.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
  ///
  VTKM_EXEC_CONT
  void Include(const vtkm::RangeId3& range)
  {
    this->X.Include(range.X);
    this->Y.Include(range.Y);
    this->Z.Include(range.Z);
  }

  /// \b Return the union of this and another range.
  ///
  /// This is a nondestructive form of \c Include.
  ///
  VTKM_EXEC_CONT
  vtkm::RangeId3 Union(const vtkm::RangeId3& other) const
  {
    vtkm::RangeId3 unionRangeId3(*this);
    unionRangeId3.Include(other);
    return unionRangeId3;
  }

  /// \b Operator for union
  ///
  VTKM_EXEC_CONT
  vtkm::RangeId3 operator+(const vtkm::RangeId3& other) const { return this->Union(other); }

  VTKM_EXEC_CONT
  bool operator==(const vtkm::RangeId3& range) const
  {
    return ((this->X == range.X) && (this->Y == range.Y) && (this->Z == range.Z));
  }

  VTKM_EXEC_CONT
  bool operator!=(const vtkm::RangeId3& range) const
  {
    return ((this->X != range.X) || (this->Y != range.Y) || (this->Z != range.Z));
  }
};

} // namespace vtkm

/// Helper function for printing range during testing
///
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::RangeId3& range)
{
  return stream << "{ X:" << range.X << ", Y:" << range.Y << ", Z:" << range.Z << " }";
}

#endif //vtk_m_RangeId3_h