Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/openvdb/internal/openvdb/math/BBox.h')
-rw-r--r--extern/openvdb/internal/openvdb/math/BBox.h245
1 files changed, 160 insertions, 85 deletions
diff --git a/extern/openvdb/internal/openvdb/math/BBox.h b/extern/openvdb/internal/openvdb/math/BBox.h
index 0af43d5d732..b3a32a3a48f 100644
--- a/extern/openvdb/internal/openvdb/math/BBox.h
+++ b/extern/openvdb/internal/openvdb/math/BBox.h
@@ -31,7 +31,7 @@
#ifndef OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
#define OPENVDB_MATH_BBOX_HAS_BEEN_INCLUDED
-#include "Math.h" // for isApproxEqual() and tolerance()
+#include "Math.h" // for math::isApproxEqual() and math::Tolerance()
#include "Vec3.h"
#include <ostream>
#include <algorithm> // for min/max
@@ -43,53 +43,93 @@ namespace OPENVDB_VERSION_NAME {
namespace math {
/// @brief Axis-aligned bounding box
-template<class _VectorType>
+template<typename Vec3T>
class BBox
{
public:
- typedef _VectorType VectorType;
- typedef _VectorType ValueType;
- typedef typename _VectorType::ValueType ElementType;
+ typedef Vec3T Vec3Type;
+ typedef Vec3T ValueType;
+ typedef Vec3T VectorType;
+ typedef typename Vec3Type::ValueType ElementType;
+ /// @brief Default constructor creates an invalid BBox
BBox();
- BBox(const VectorType& xyzMin, const VectorType& xyzMax);
- BBox(const VectorType& xyzMin, const VectorType& xyzMax, bool sorted);
+
+ /// @brief Constructor based on a minimum and maximum point.
+ BBox(const Vec3T& xyzMin, const Vec3T& xyzMax);
+
+ /// @brief Constructor based on a minimum and maximum point.
+ /// If sorted is false the points will be sorted by x,y,z component.
+ BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted);
+
/// @brief Contruct a cubical BBox from a minimum coordinate and a
/// single edge length.
/// @note inclusive for integral <tt>ElementType</tt>s
- BBox(const VectorType& xyzMin, const ElementType& length);
+ BBox(const Vec3T& xyzMin, const ElementType& length);
+
+ /// @brief Constructor based on a raw array of six points. If
+ /// sorted is false the points will be sorted by x,y,z component.
explicit BBox(const ElementType* xyz, bool sorted = true);
+
+ /// @brief Copy constructor
BBox(const BBox& other);
+ /// @brief Sort the min/max by x,y,z component.
void sort();
- const VectorType& min() const { return mMin; }
- const VectorType& max() const { return mMax; }
+ /// @brief Return a const reference to the minimum point of the BBox
+ const Vec3T& min() const { return mMin; }
+
+ /// @brief Return a const reference to the maximum point of the BBox
+ const Vec3T& max() const { return mMax; }
+
+ /// @brief Return a non-const reference to the minimum point of the BBox
+ Vec3T& min() { return mMin; }
- VectorType& min() { return mMin; }
- VectorType& max() { return mMax; }
+ /// @brief Return a non-const reference to the maximum point of the BBox
+ Vec3T& max() { return mMax; }
+ /// @brief Return true if the two BBox'es are identical
bool operator==(const BBox& rhs) const;
+
+ /// @brief Return true if the two BBox'es are not identical
bool operator!=(const BBox& rhs) const { return !(*this == rhs); }
+ /// @brief Return true if the BBox is empty, i.e. has no
+ /// (positive) volume.
bool empty() const;
- bool hasVolume() const { return !empty(); }
- operator bool() const { return !empty(); }
+ /// @brief Return true if the BBox has a (positive) volume.
+ bool hasVolume() const { return !this->empty(); }
+
+ /// @brief Return true if the BBox is valid, i.e. as a (positive) volume.
+ operator bool() const { return !this->empty(); }
+
+ /// @brief Return true if the all components of mMin <= mMax,
+ /// i.e. the volume is not negative.
+ /// @note For floating point values a tolerance is used for this test.
bool isSorted() const;
+ /// @brief Return the center point of the BBox
Vec3d getCenter() const;
+ /// @brief Returns the extents of the BBox, i.e. the length per axis
+ /// for floating points values or number of grids per axis points
+ /// integral values.
/// @note inclusive for integral <tt>ElementType</tt>s
- VectorType extents() const;
+ Vec3T extents() const;
- ElementType volume() const { VectorType e = extents(); return e[0] * e[1] * e[2]; }
+ /// @brief Return the volume spanned by this BBox.
+ ElementType volume() const { Vec3T e = this->extents(); return e[0] * e[1] * e[2]; }
/// Return the index (0, 1 or 2) of the longest axis.
- size_t maxExtent() const;
+ size_t maxExtent() const { return MaxIndex(mMax - mMin); }
+
+ /// Return the index (0, 1 or 2) of the shortest axis.
+ size_t minExtent() const { return MinIndex(mMax - mMin); }
/// Return @c true if point (x, y, z) is inside this bounding box.
- bool isInside(const VectorType& xyz) const;
+ bool isInside(const Vec3T& xyz) const;
/// Return @c true if the given bounding box is inside this bounding box.
bool isInside(const BBox&) const;
@@ -99,56 +139,68 @@ public:
/// Pad this bounding box.
void expand(ElementType padding);
+
/// Expand this bounding box to enclose point (x, y, z).
- void expand(const VectorType& xyz);
+ void expand(const Vec3T& xyz);
+
/// Union this bounding box with the given bounding box.
void expand(const BBox&);
// @brief Union this bbox with the cubical bbox defined from xyzMin and
// length
/// @note inclusive for integral <tt>ElementType</tt>s
- void expand(const VectorType& xyzMin, const ElementType& length);
+ void expand(const Vec3T& xyzMin, const ElementType& length);
+
/// Translate this bounding box by \f$(t_x, t_y, t_z)\f$.
- void translate(const VectorType& t);
+ void translate(const Vec3T& t);
+
+ /// Apply a map to this bounding box
+ template<typename MapType>
+ BBox applyMap(const MapType& map) const;
+
+ /// Apply the inverse of a map to this bounding box
+ template<typename MapType>
+ BBox applyInverseMap(const MapType& map) const;
/// Unserialize this bounding box from the given stream.
void read(std::istream& is) { mMin.read(is); mMax.read(is); }
+
/// Serialize this bounding box to the given stream.
void write(std::ostream& os) const { mMin.write(os); mMax.write(os); }
private:
- VectorType mMin, mMax;
+ Vec3T mMin, mMax;
}; // class BBox
////////////////////////////////////////
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox():
- mMin(ElementType(0), ElementType(0), ElementType(0)),
- mMax(ElementType(0), ElementType(0), ElementType(0))
+BBox<Vec3T>::BBox():
+ mMin( std::numeric_limits<ElementType>::max()),
+ mMax(-std::numeric_limits<ElementType>::max())
{
}
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox(const VectorType& xyzMin, const VectorType& xyzMax):
+BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax):
mMin(xyzMin), mMax(xyzMax)
{
}
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox(const VectorType& xyzMin, const VectorType& xyzMax, bool sorted):
+BBox<Vec3T>::BBox(const Vec3T& xyzMin, const Vec3T& xyzMax, bool sorted):
mMin(xyzMin), mMax(xyzMax)
{
if (!sorted) this->sort();
}
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox(const VectorType& xyzMin, const ElementType& length):
+BBox<Vec3T>::BBox(const Vec3T& xyzMin, const ElementType& length):
mMin(xyzMin), mMax(xyzMin)
{
// min and max are inclusive for integral ElementType
@@ -158,9 +210,9 @@ BBox<VectorType>::BBox(const VectorType& xyzMin, const ElementType& length):
mMax[2] += size;
}
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox(const ElementType* xyz, bool sorted):
+BBox<Vec3T>::BBox(const ElementType* xyz, bool sorted):
mMin(xyz[0], xyz[1], xyz[2]),
mMax(xyz[3], xyz[4], xyz[5])
{
@@ -168,9 +220,9 @@ BBox<VectorType>::BBox(const ElementType* xyz, bool sorted):
}
-template<class VectorType>
+template<typename Vec3T>
inline
-BBox<VectorType>::BBox(const BBox& other):
+BBox<Vec3T>::BBox(const BBox& other):
mMin(other.mMin), mMax(other.mMax)
{
}
@@ -179,9 +231,9 @@ BBox<VectorType>::BBox(const BBox& other):
////////////////////////////////////////
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::empty() const
+BBox<Vec3T>::empty() const
{
if (boost::is_integral<ElementType>::value) {
// min and max are inclusive for integral ElementType
@@ -191,9 +243,9 @@ BBox<VectorType>::empty() const
}
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::operator==(const BBox& rhs) const
+BBox<Vec3T>::operator==(const BBox& rhs) const
{
if (boost::is_integral<ElementType>::value) {
return mMin == rhs.min() && mMax == rhs.max();
@@ -203,11 +255,11 @@ BBox<VectorType>::operator==(const BBox& rhs) const
}
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::sort()
+BBox<Vec3T>::sort()
{
- VectorType tMin(mMin), tMax(mMax);
+ Vec3T tMin(mMin), tMax(mMax);
for (size_t i = 0; i < 3; ++i) {
mMin[i] = std::min(tMin[i], tMax[i]);
mMax[i] = std::max(tMin[i], tMax[i]);
@@ -215,63 +267,51 @@ BBox<VectorType>::sort()
}
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::isSorted() const
+BBox<Vec3T>::isSorted() const
{
if (boost::is_integral<ElementType>::value) {
return (mMin[0] <= mMax[0] && mMin[1] <= mMax[1] && mMin[2] <= mMax[2]);
} else {
- ElementType t = tolerance<ElementType>::value();
+ ElementType t = math::Tolerance<ElementType>::value();
return (mMin[0] < (mMax[0] + t) && mMin[1] < (mMax[1] + t) && mMin[2] < (mMax[2] + t));
}
}
-template<class VectorType>
+template<typename Vec3T>
inline Vec3d
-BBox<VectorType>::getCenter() const
+BBox<Vec3T>::getCenter() const
{
return (Vec3d(mMin.asPointer()) + Vec3d(mMax.asPointer())) * 0.5;
}
-template<class VectorType>
-inline VectorType
-BBox<VectorType>::extents() const
+template<typename Vec3T>
+inline Vec3T
+BBox<Vec3T>::extents() const
{
if (boost::is_integral<ElementType>::value) {
- return (mMax - mMin) + VectorType(1, 1, 1);
+ return (mMax - mMin) + Vec3T(1, 1, 1);
} else {
return (mMax - mMin);
}
}
-
-template<class VectorType>
-inline size_t
-BBox<VectorType>::maxExtent() const
-{
- VectorType e = extents();
- if (e[0] > e[1] && e[0] > e[2]) return 0;
- else if (e[1] > e[2]) return 1;
- return 2;
-}
-
-
////////////////////////////////////////
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::isInside(const VectorType& xyz) const
+BBox<Vec3T>::isInside(const Vec3T& xyz) const
{
if (boost::is_integral<ElementType>::value) {
return xyz[0] >= mMin[0] && xyz[0] <= mMax[0] &&
xyz[1] >= mMin[1] && xyz[1] <= mMax[1] &&
xyz[2] >= mMin[2] && xyz[2] <= mMax[2];
} else {
- ElementType t = tolerance<ElementType>::value();
+ ElementType t = math::Tolerance<ElementType>::value();
return xyz[0] > (mMin[0]-t) && xyz[0] < (mMax[0]+t) &&
xyz[1] > (mMin[1]-t) && xyz[1] < (mMax[1]+t) &&
xyz[2] > (mMin[2]-t) && xyz[2] < (mMax[2]+t);
@@ -279,16 +319,16 @@ BBox<VectorType>::isInside(const VectorType& xyz) const
}
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::isInside(const BBox& b) const
+BBox<Vec3T>::isInside(const BBox& b) const
{
if (boost::is_integral<ElementType>::value) {
return b.min()[0] >= mMin[0] && b.max()[0] <= mMax[0] &&
b.min()[1] >= mMin[1] && b.max()[1] <= mMax[1] &&
b.min()[2] >= mMin[2] && b.max()[2] <= mMax[2];
} else {
- ElementType t = tolerance<ElementType>::value();
+ ElementType t = math::Tolerance<ElementType>::value();
return (b.min()[0]-t) > mMin[0] && (b.max()[0]+t) < mMax[0] &&
(b.min()[1]-t) > mMin[1] && (b.max()[1]+t) < mMax[1] &&
(b.min()[2]-t) > mMin[2] && (b.max()[2]+t) < mMax[2];
@@ -296,16 +336,16 @@ BBox<VectorType>::isInside(const BBox& b) const
}
-template<class VectorType>
+template<typename Vec3T>
inline bool
-BBox<VectorType>::hasOverlap(const BBox& b) const
+BBox<Vec3T>::hasOverlap(const BBox& b) const
{
if (boost::is_integral<ElementType>::value) {
return mMax[0] >= b.min()[0] && mMin[0] <= b.max()[0] &&
mMax[1] >= b.min()[1] && mMin[1] <= b.max()[1] &&
mMax[2] >= b.min()[2] && mMin[2] <= b.max()[2];
} else {
- ElementType t = tolerance<ElementType>::value();
+ ElementType t = math::Tolerance<ElementType>::value();
return mMax[0] > (b.min()[0]-t) && mMin[0] < (b.max()[0]+t) &&
mMax[1] > (b.min()[1]-t) && mMin[1] < (b.max()[1]+t) &&
mMax[2] > (b.min()[2]-t) && mMin[2] < (b.max()[2]+t);
@@ -316,9 +356,9 @@ BBox<VectorType>::hasOverlap(const BBox& b) const
////////////////////////////////////////
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::expand(ElementType dx)
+BBox<Vec3T>::expand(ElementType dx)
{
dx = std::abs(dx);
for (size_t i = 0; i < 3; ++i) {
@@ -328,9 +368,9 @@ BBox<VectorType>::expand(ElementType dx)
}
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::expand(const VectorType& xyz)
+BBox<Vec3T>::expand(const Vec3T& xyz)
{
for (size_t i = 0; i < 3; ++i) {
mMin[i] = std::min(mMin[i], xyz[i]);
@@ -339,9 +379,9 @@ BBox<VectorType>::expand(const VectorType& xyz)
}
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::expand(const BBox& b)
+BBox<Vec3T>::expand(const BBox& b)
{
for (size_t i = 0; i < 3; ++i) {
mMin[i] = std::min(mMin[i], b.min()[i]);
@@ -349,9 +389,9 @@ BBox<VectorType>::expand(const BBox& b)
}
}
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::expand(const VectorType& xyzMin, const ElementType& length)
+BBox<Vec3T>::expand(const Vec3T& xyzMin, const ElementType& length)
{
const ElementType size = boost::is_integral<ElementType>::value ? length-1 : length;
for (size_t i = 0; i < 3; ++i) {
@@ -361,21 +401,56 @@ BBox<VectorType>::expand(const VectorType& xyzMin, const ElementType& length)
}
-template<class VectorType>
+template<typename Vec3T>
inline void
-BBox<VectorType>::translate(const VectorType& dx)
+BBox<Vec3T>::translate(const Vec3T& dx)
{
mMin += dx;
mMax += dx;
}
+template<typename Vec3T>
+template<typename MapType>
+inline BBox<Vec3T>
+BBox<Vec3T>::applyMap(const MapType& map) const
+{
+ typedef Vec3<double> Vec3R;
+ BBox<Vec3T> bbox;
+ bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMin[2])));
+ bbox.expand(map.applyMap(Vec3R(mMin[0], mMin[1], mMax[2])));
+ bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMin[2])));
+ bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMin[2])));
+ bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMin[2])));
+ bbox.expand(map.applyMap(Vec3R(mMax[0], mMin[1], mMax[2])));
+ bbox.expand(map.applyMap(Vec3R(mMin[0], mMax[1], mMax[2])));
+ bbox.expand(map.applyMap(Vec3R(mMax[0], mMax[1], mMax[2])));
+ return bbox;
+}
+
+template<typename Vec3T>
+template<typename MapType>
+inline BBox<Vec3T>
+BBox<Vec3T>::applyInverseMap(const MapType& map) const
+{
+ typedef Vec3<double> Vec3R;
+ BBox<Vec3T> bbox;
+ bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMin[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMin[1], mMax[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMin[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMin[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMin[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMin[1], mMax[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMin[0], mMax[1], mMax[2])));
+ bbox.expand(map.applyInverseMap(Vec3R(mMax[0], mMax[1], mMax[2])));
+ return bbox;
+}
////////////////////////////////////////
-template<class VectorType>
+template<typename Vec3T>
inline std::ostream&
-operator<<(std::ostream& os, const BBox<VectorType>& b)
+operator<<(std::ostream& os, const BBox<Vec3T>& b)
{
os << b.min() << " -> " << b.max();
return os;