| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright Contributors to the OpenVDB Project | ||
| 2 | // SPDX-License-Identifier: MPL-2.0 | ||
| 3 | |||
| 4 | #ifndef OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED | ||
| 5 | #define OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED | ||
| 6 | |||
| 7 | #include "Math.h" // for math::isApproxEqual() and math::Tolerance() | ||
| 8 | #include "Vec3.h" | ||
| 9 | #include <algorithm> // for std::min(), std::max() | ||
| 10 | #include <cmath> // for std::abs() | ||
| 11 | #include <iostream> | ||
| 12 | #include <limits> | ||
| 13 | #include <type_traits> | ||
| 14 | |||
| 15 | |||
| 16 | namespace openvdb { | ||
| 17 | OPENVDB_USE_VERSION_NAMESPACE | ||
| 18 | namespace OPENVDB_VERSION_NAME { | ||
| 19 | namespace math { | ||
| 20 | |||
| 21 | /// @brief Axis-aligned bounding box | ||
| 22 | template<typename Vec3T> | ||
| 23 | class BBox | ||
| 24 | { | ||
| 25 | public: | ||
| 26 | using Vec3Type = Vec3T; | ||
| 27 | using ValueType = Vec3T; | ||
| 28 | using VectorType = Vec3T; | ||
| 29 | using ElementType = typename Vec3Type::ValueType; | ||
| 30 | |||
| 31 | /// @brief The default constructor creates an invalid bounding box. | ||
| 32 | BBox(); | ||
| 33 | /// @brief Construct a bounding box that exactly encloses the given | ||
| 34 | /// minimum and maximum points. | ||
| 35 | BBox(const Vec3T& xyzMin, const Vec3T& xyzMax); | ||
| 36 | /// @brief Construct a bounding box that exactly encloses the given | ||
| 37 | /// minimum and maximum points. | ||
| 38 | /// @details If @a sorted is false, sort the points by their | ||
| 39 | /// @e x, @e y and @e z components. | ||
| 40 | BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted); | ||
| 41 | /// @brief Contruct a cubical bounding box from a minimum coordinate | ||
| 42 | /// and an edge length. | ||
| 43 | /// @note Inclusive for integral <b>ElementType</b>s | ||
| 44 | BBox(const Vec3T& xyzMin, const ElementType& length); | ||
| 45 | |||
| 46 | /// @brief Construct a bounding box that exactly encloses two points, | ||
| 47 | /// whose coordinates are given by an array of six values, | ||
| 48 | /// <i>x<sub>1</sub></i>, <i>y<sub>1</sub></i>, <i>z<sub>1</sub></i>, | ||
| 49 | /// <i>x<sub>2</sub></i>, <i>y<sub>2</sub></i> and <i>z<sub>2</sub></i>. | ||
| 50 | /// @details If @a sorted is false, sort the points by their | ||
| 51 | /// @e x, @e y and @e z components. | ||
| 52 | explicit BBox(const ElementType* xyz, bool sorted = true); | ||
| 53 | |||
| 54 | BBox(const BBox&) = default; | ||
| 55 | BBox& operator=(const BBox&) = default; | ||
| 56 | |||
| 57 | /// @brief Sort the mininum and maximum points of this bounding box | ||
| 58 | /// by their @e x, @e y and @e z components. | ||
| 59 | void sort(); | ||
| 60 | |||
| 61 | /// @brief Return a const reference to the minimum point of this bounding box. | ||
| 62 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2649 | const Vec3T& min() const { return mMin; } |
| 63 | /// @brief Return a const reference to the maximum point of this bounding box. | ||
| 64 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2649 | const Vec3T& max() const { return mMax; } |
| 65 | /// @brief Return a non-const reference to the minimum point of this bounding box. | ||
| 66 | ✗ | Vec3T& min() { return mMin; } | |
| 67 | /// @brief Return a non-const reference to the maximum point of this bounding box. | ||
| 68 | Vec3T& max() { return mMax; } | ||
| 69 | |||
| 70 | /// @brief Return @c true if this bounding box is identical to the given bounding box. | ||
| 71 | bool operator==(const BBox& rhs) const; | ||
| 72 | /// @brief Return @c true if this bounding box differs from the given bounding box. | ||
| 73 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | bool operator!=(const BBox& rhs) const { return !(*this == rhs); } |
| 74 | |||
| 75 | /// @brief Return @c true if this bounding box is empty, i.e., it has no (positive) volume. | ||
| 76 | bool empty() const; | ||
| 77 | /// @brief Return @c true if this bounding box has (positive) volume. | ||
| 78 | bool hasVolume() const { return !this->empty(); } | ||
| 79 | /// @brief Return @c true if this bounding box has (positive) volume. | ||
| 80 | operator bool() const { return !this->empty(); } | ||
| 81 | |||
| 82 | /// @brief Return @c true if all components of the minimum point are less than | ||
| 83 | /// or equal to the corresponding components of the maximum point. | ||
| 84 | /// @details This is equivalent to testing whether this bounding box has nonnegative volume. | ||
| 85 | /// @note For floating-point <b>ElementType</b>s a tolerance is used for this test. | ||
| 86 | bool isSorted() const; | ||
| 87 | |||
| 88 | /// @brief Return the center point of this bounding box. | ||
| 89 | Vec3d getCenter() const; | ||
| 90 | |||
| 91 | /// @brief Return the extents of this bounding box, i.e., the length along each axis. | ||
| 92 | /// @note Inclusive for integral <b>ElementType</b>s | ||
| 93 | Vec3T extents() const; | ||
| 94 | /// @brief Return the index (0, 1 or 2) of the longest axis. | ||
| 95 | 3 | size_t maxExtent() const { return MaxIndex(mMax - mMin); } | |
| 96 | /// @brief Return the index (0, 1 or 2) of the shortest axis. | ||
| 97 | 3 | size_t minExtent() const { return MinIndex(mMax - mMin); } | |
| 98 | |||
| 99 | /// @brief Return the volume enclosed by this bounding box. | ||
| 100 |
5/8✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 17 times.
|
32 | ElementType volume() const { Vec3T e = this->extents(); return e[0] * e[1] * e[2]; } |
| 101 | |||
| 102 | /// @brief Return @c true if the given point is inside this bounding box. | ||
| 103 | bool isInside(const Vec3T& xyz) const; | ||
| 104 | /// @brief Return @c true if the given bounding box is inside this bounding box. | ||
| 105 | bool isInside(const BBox&) const; | ||
| 106 | /// @brief Return @c true if the given bounding box overlaps with this bounding box. | ||
| 107 | bool hasOverlap(const BBox&) const; | ||
| 108 | /// @brief Return @c true if the given bounding box overlaps with this bounding box. | ||
| 109 | bool intersects(const BBox& other) const { return hasOverlap(other); } | ||
| 110 | |||
| 111 | /// @brief Pad this bounding box. | ||
| 112 | void expand(ElementType padding); | ||
| 113 | /// @brief Expand this bounding box to enclose the given point. | ||
| 114 | void expand(const Vec3T& xyz); | ||
| 115 | /// @brief Union this bounding box with the given bounding box. | ||
| 116 | void expand(const BBox&); | ||
| 117 | /// @brief Union this bounding box with the cubical bounding box with | ||
| 118 | /// minimum point @a xyzMin and the given edge length. | ||
| 119 | /// @note Inclusive for integral <b>ElementType</b>s | ||
| 120 | void expand(const Vec3T& xyzMin, const ElementType& length); | ||
| 121 | |||
| 122 | /// @brief Translate this bounding box by | ||
| 123 | /// (<i>t<sub>x</sub></i>, <i>t<sub>y</sub></i>, <i>t<sub>z</sub></i>). | ||
| 124 | void translate(const Vec3T& t); | ||
| 125 | |||
| 126 | /// @brief Apply a map to this bounding box. | ||
| 127 | template<typename MapType> | ||
| 128 | BBox applyMap(const MapType& map) const; | ||
| 129 | /// @brief Apply the inverse of a map to this bounding box | ||
| 130 | template<typename MapType> | ||
| 131 | BBox applyInverseMap(const MapType& map) const; | ||
| 132 | |||
| 133 | /// @brief Unserialize this bounding box from the given stream. | ||
| 134 | ✗ | void read(std::istream& is) { mMin.read(is); mMax.read(is); } | |
| 135 | /// @brief Serialize this bounding box to the given stream. | ||
| 136 | ✗ | void write(std::ostream& os) const { mMin.write(os); mMax.write(os); } | |
| 137 | |||
| 138 | private: | ||
| 139 | Vec3T mMin, mMax; | ||
| 140 | }; // class BBox | ||
| 141 | |||
| 142 | |||
| 143 | //////////////////////////////////////// | ||
| 144 | |||
| 145 | |||
| 146 | template<typename Vec3T> | ||
| 147 | inline | ||
| 148 | 7 | BBox<Vec3T>::BBox(): | |
| 149 | mMin( std::numeric_limits<ElementType>::max()), | ||
| 150 | mMax(-std::numeric_limits<ElementType>::max()) | ||
| 151 | { | ||
| 152 | } | ||
| 153 | |||
| 154 | template<typename Vec3T> | ||
| 155 | inline | ||
| 156 | 9743793 | BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax): | |
| 157 |
16/22✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
|
9743779 | mMin(xyzMin), mMax(xyzMax) |
| 158 | { | ||
| 159 | } | ||
| 160 | |||
| 161 | template<typename Vec3T> | ||
| 162 | inline | ||
| 163 | BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted): | ||
| 164 | mMin(xyzMin), mMax(xyzMax) | ||
| 165 | { | ||
| 166 | if (!sorted) this->sort(); | ||
| 167 | } | ||
| 168 | |||
| 169 | template<typename Vec3T> | ||
| 170 | inline | ||
| 171 | BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length): | ||
| 172 | mMin(xyzMin), mMax(xyzMin) | ||
| 173 | { | ||
| 174 | // min and max are inclusive for integral ElementType | ||
| 175 | const ElementType size = std::is_integral<ElementType>::value ? length-1 : length; | ||
| 176 | mMax[0] += size; | ||
| 177 | mMax[1] += size; | ||
| 178 | mMax[2] += size; | ||
| 179 | } | ||
| 180 | |||
| 181 | template<typename Vec3T> | ||
| 182 | inline | ||
| 183 | BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted): | ||
| 184 | mMin(xyz[0], xyz[1], xyz[2]), | ||
| 185 | mMax(xyz[3], xyz[4], xyz[5]) | ||
| 186 | { | ||
| 187 | if (!sorted) this->sort(); | ||
| 188 | } | ||
| 189 | |||
| 190 | |||
| 191 | //////////////////////////////////////// | ||
| 192 | |||
| 193 | |||
| 194 | template<typename Vec3T> | ||
| 195 | inline bool | ||
| 196 | BBox<Vec3T>::empty() const | ||
| 197 | { | ||
| 198 | if (std::is_integral<ElementType>::value) { | ||
| 199 | // min and max are inclusive for integral ElementType | ||
| 200 | return (mMin[0] > mMax[0] || mMin[1] > mMax[1] || mMin[2] > mMax[2]); | ||
| 201 | } | ||
| 202 |
21/90✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 8 times.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 8 times.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 8 times.
✓ Branch 24 taken 8 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 8 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 8 times.
✓ Branch 30 taken 8 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 8 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 8 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
|
64 | return mMin[0] >= mMax[0] || mMin[1] >= mMax[1] || mMin[2] >= mMax[2]; |
| 203 | } | ||
| 204 | |||
| 205 | |||
| 206 | template<typename Vec3T> | ||
| 207 | inline bool | ||
| 208 | 3 | BBox<Vec3T>::operator==(const BBox& rhs) const | |
| 209 | { | ||
| 210 | if (std::is_integral<ElementType>::value) { | ||
| 211 | return mMin == rhs.min() && mMax == rhs.max(); | ||
| 212 | } else { | ||
| 213 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | return math::isApproxEqual(mMin, rhs.min()) && math::isApproxEqual(mMax, rhs.max()); |
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | |||
| 218 | template<typename Vec3T> | ||
| 219 | inline void | ||
| 220 | BBox<Vec3T>::sort() | ||
| 221 | { | ||
| 222 | Vec3T tMin(mMin), tMax(mMax); | ||
| 223 | for (int i = 0; i < 3; ++i) { | ||
| 224 | mMin[i] = std::min(tMin[i], tMax[i]); | ||
| 225 | mMax[i] = std::max(tMin[i], tMax[i]); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | template<typename Vec3T> | ||
| 231 | inline bool | ||
| 232 | BBox<Vec3T>::isSorted() const | ||
| 233 | { | ||
| 234 | if (std::is_integral<ElementType>::value) { | ||
| 235 | return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]); | ||
| 236 | } else { | ||
| 237 | ElementType t = math::Tolerance<ElementType>::value(); | ||
| 238 |
4/6✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
|
48 | return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t)); |
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | template<typename Vec3T> | ||
| 244 | inline Vec3d | ||
| 245 | BBox<Vec3T>::getCenter() const | ||
| 246 | { | ||
| 247 | return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5; | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | template<typename Vec3T> | ||
| 252 | inline Vec3T | ||
| 253 | BBox<Vec3T>::extents() const | ||
| 254 | { | ||
| 255 | if (std::is_integral<ElementType>::value) { | ||
| 256 | return (mMax - mMin) + Vec3T(1, 1, 1); | ||
| 257 | } else { | ||
| 258 | return (mMax - mMin); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | //////////////////////////////////////// | ||
| 263 | |||
| 264 | |||
| 265 | template<typename Vec3T> | ||
| 266 | inline bool | ||
| 267 |
2/2✓ Branch 0 taken 15398762 times.
✓ Branch 1 taken 1558396 times.
|
16957158 | BBox<Vec3T>::isInside(const Vec3T& xyz) const |
| 268 | { | ||
| 269 | if (std::is_integral<ElementType>::value) { | ||
| 270 | return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] && | ||
| 271 | xyz[1] >= mMin[1] && xyz[1] <= mMax[1] && | ||
| 272 | xyz[2] >= mMin[2] && xyz[2] <= mMax[2]; | ||
| 273 | } else { | ||
| 274 | ElementType t = math::Tolerance<ElementType>::value(); | ||
| 275 |
2/2✓ Branch 0 taken 12877618 times.
✓ Branch 1 taken 2521144 times.
|
15398762 | return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) && |
| 276 |
4/4✓ Branch 0 taken 10014829 times.
✓ Branch 1 taken 2862789 times.
✓ Branch 2 taken 6648940 times.
✓ Branch 3 taken 3365889 times.
|
12877618 | xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) && |
| 277 |
6/6✓ Branch 0 taken 15398762 times.
✓ Branch 1 taken 1558396 times.
✓ Branch 2 taken 5855243 times.
✓ Branch 3 taken 793697 times.
✓ Branch 4 taken 1063960 times.
✓ Branch 5 taken 4791283 times.
|
23606098 | xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t); |
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | |||
| 282 | template<typename Vec3T> | ||
| 283 | inline bool | ||
| 284 |
2/2✓ Branch 0 taken 19652 times.
✓ Branch 1 taken 13126 times.
|
32778 | BBox<Vec3T>::isInside(const BBox& b) const |
| 285 | { | ||
| 286 | if (std::is_integral<ElementType>::value) { | ||
| 287 | return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] && | ||
| 288 | b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] && | ||
| 289 | b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2]; | ||
| 290 | } else { | ||
| 291 | ElementType t = math::Tolerance<ElementType>::value(); | ||
| 292 |
2/2✓ Branch 0 taken 768 times.
✓ Branch 1 taken 18884 times.
|
19652 | return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] && |
| 293 |
4/4✓ Branch 0 taken 220 times.
✓ Branch 1 taken 548 times.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 186 times.
|
768 | (b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] && |
| 294 |
5/6✓ Branch 0 taken 19652 times.
✓ Branch 1 taken 13126 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
32812 | (b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2]; |
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | |||
| 299 | template<typename Vec3T> | ||
| 300 | inline bool | ||
| 301 |
2/2✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 18384 times.
|
32898 | BBox<Vec3T>::hasOverlap(const BBox& b) const |
| 302 | { | ||
| 303 | if (std::is_integral<ElementType>::value) { | ||
| 304 | return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] && | ||
| 305 | mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] && | ||
| 306 | mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2]; | ||
| 307 | } else { | ||
| 308 | ElementType t = math::Tolerance<ElementType>::value(); | ||
| 309 |
2/2✓ Branch 0 taken 2758 times.
✓ Branch 1 taken 11756 times.
|
14514 | return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) && |
| 310 |
4/4✓ Branch 0 taken 2235 times.
✓ Branch 1 taken 523 times.
✓ Branch 2 taken 1208 times.
✓ Branch 3 taken 1027 times.
|
2758 | mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) && |
| 311 |
5/6✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 18384 times.
✓ Branch 2 taken 1208 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1109 times.
✓ Branch 5 taken 99 times.
|
34106 | mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t); |
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | |||
| 316 | //////////////////////////////////////// | ||
| 317 | |||
| 318 | |||
| 319 | template<typename Vec3T> | ||
| 320 | inline void | ||
| 321 | 49 | BBox<Vec3T>::expand(ElementType dx) | |
| 322 | { | ||
| 323 | dx = std::abs(dx); | ||
| 324 |
2/2✓ Branch 0 taken 147 times.
✓ Branch 1 taken 49 times.
|
196 | for (int i = 0; i < 3; ++i) { |
| 325 | 147 | mMin[i] -= dx; | |
| 326 | 147 | mMax[i] += dx; | |
| 327 | } | ||
| 328 | 49 | } | |
| 329 | |||
| 330 | |||
| 331 | template<typename Vec3T> | ||
| 332 | inline void | ||
| 333 | 545330 | BBox<Vec3T>::expand(const Vec3T& xyz) | |
| 334 | { | ||
| 335 |
2/2✓ Branch 0 taken 1635990 times.
✓ Branch 1 taken 545330 times.
|
2181320 | for (int i = 0; i < 3; ++i) { |
| 336 |
4/4✓ Branch 0 taken 414873 times.
✓ Branch 1 taken 1221117 times.
✓ Branch 2 taken 349117 times.
✓ Branch 3 taken 1286873 times.
|
2050863 | mMin[i] = std::min(mMin[i], xyz[i]); |
| 337 |
2/2✓ Branch 0 taken 349117 times.
✓ Branch 1 taken 1286873 times.
|
1985107 | mMax[i] = std::max(mMax[i], xyz[i]); |
| 338 | } | ||
| 339 | 545330 | } | |
| 340 | |||
| 341 | |||
| 342 | template<typename Vec3T> | ||
| 343 | inline void | ||
| 344 | BBox<Vec3T>::expand(const BBox& b) | ||
| 345 | { | ||
| 346 | for (int i = 0; i < 3; ++i) { | ||
| 347 | mMin[i] = std::min(mMin[i], b.min()[i]); | ||
| 348 | mMax[i] = std::max(mMax[i], b.max()[i]); | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | template<typename Vec3T> | ||
| 353 | inline void | ||
| 354 | BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length) | ||
| 355 | { | ||
| 356 | const ElementType size = std::is_integral<ElementType>::value ? length-1 : length; | ||
| 357 | for (int i = 0; i < 3; ++i) { | ||
| 358 | mMin[i] = std::min(mMin[i], xyzMin[i]); | ||
| 359 | mMax[i] = std::max(mMax[i], xyzMin[i] + size); | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | |||
| 364 | template<typename Vec3T> | ||
| 365 | inline void | ||
| 366 | BBox<Vec3T>::translate(const Vec3T& dx) | ||
| 367 | { | ||
| 368 | mMin += dx; | ||
| 369 | mMax += dx; | ||
| 370 | } | ||
| 371 | |||
| 372 | template<typename Vec3T> | ||
| 373 | template<typename MapType> | ||
| 374 | inline BBox<Vec3T> | ||
| 375 | BBox<Vec3T>::applyMap(const MapType& map) const | ||
| 376 | { | ||
| 377 | using Vec3R = Vec3<double>; | ||
| 378 | BBox<Vec3T> bbox; | ||
| 379 | bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMin[2]))); | ||
| 380 | bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMax[2]))); | ||
| 381 | bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMin[2]))); | ||
| 382 | bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMin[2]))); | ||
| 383 | bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMin[2]))); | ||
| 384 | bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMax[2]))); | ||
| 385 | bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMax[2]))); | ||
| 386 | bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMax[2]))); | ||
| 387 | return bbox; | ||
| 388 | } | ||
| 389 | |||
| 390 | template<typename Vec3T> | ||
| 391 | template<typename MapType> | ||
| 392 | inline BBox<Vec3T> | ||
| 393 | BBox<Vec3T>::applyInverseMap(const MapType& map) const | ||
| 394 | { | ||
| 395 | using Vec3R = Vec3<double>; | ||
| 396 | BBox<Vec3T> bbox; | ||
| 397 | bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMin[2]))); | ||
| 398 | bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMax[2]))); | ||
| 399 | bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMin[2]))); | ||
| 400 | bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMin[2]))); | ||
| 401 | bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMin[2]))); | ||
| 402 | bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMax[2]))); | ||
| 403 | bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMax[2]))); | ||
| 404 | bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMax[2]))); | ||
| 405 | return bbox; | ||
| 406 | } | ||
| 407 | |||
| 408 | //////////////////////////////////////// | ||
| 409 | |||
| 410 | |||
| 411 | template<typename Vec3T> | ||
| 412 | inline std::ostream& | ||
| 413 | ✗ | operator<<(std::ostream& os, const BBox<Vec3T>& b) | |
| 414 | { | ||
| 415 | ✗ | os << b.min() << " -> " << b.max(); | |
| 416 | ✗ | return os; | |
| 417 | } | ||
| 418 | |||
| 419 | } // namespace math | ||
| 420 | } // namespace OPENVDB_VERSION_NAME | ||
| 421 | } // namespace openvdb | ||
| 422 | |||
| 423 | #endif // OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED | ||
| 424 |