ENH: boundBox improvements (#2609)

- construct boundBox from Pair<point> of min/max limits,
  make sortable

- additional bounding box intersections (linePointRef), add noexcept

- templated access for boundBox hex-corners
  (used to avoid temporary point field).
  Eg, unrolled plane/bound-box intersection with early exit

- bounding box grow() to expand box by absolute amounts
  Eg,

      bb.grow(ROOTVSMALL);   // Or: bb.grow(point::uniform(ROOTVSMALL));
  vs
      bb.min() -= point::uniform(ROOTVSMALL);
      bb.max() += point::uniform(ROOTVSMALL);

- treeBoundBox bounding box extend with two or three parameters.
  The three parameter version includes grow(...) for reduced writing.
  Eg,

      bb = bb.extend(rndGen, 1e-4, ROOTVSMALL);

  vs
      bb = bb.extend(rndGen, 1e-4);
      bb.min() -= point::uniform(ROOTVSMALL);
      bb.max() += point::uniform(ROOTVSMALL);

  This also permits use as const variables or parameter passing.
  Eg,

      const treeBoundBox bb
      (
          treeBoundBox(some_points).extend(rndGen, 1e-4, ROOTVSMALL)
      );
This commit is contained in:
Mark Olesen
2022-10-07 15:12:50 +02:00
parent 81b1c5021f
commit 61deacd24d
20 changed files with 473 additions and 269 deletions

View File

@ -1,7 +1,2 @@
EXE_INC = \ /* EXE_INC = */
-I$(LIB_SRC)/finiteVolume/lnInclude \ /* EXE_LIBS = */
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,7 +31,8 @@ Description
#include "argList.H" #include "argList.H"
#include "Time.H" #include "Time.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "boundBox.H" #include "line.H"
#include "Random.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "cellModel.H" #include "cellModel.H"
#include "bitSet.H" #include "bitSet.H"
@ -84,7 +85,20 @@ int main(int argc, char *argv[])
else else
{ {
bb = cube(0, 1); bb = cube(0, 1);
Info<<"starting box: " << bb << endl; Info<< "starting box: " << bb << endl;
Info<< "corner: " << bb.hexCorner<0>() << nl
<< "corner: " << bb.hexCorner<7>() << nl
<< "corner: " << bb.hexCorner<6>() << endl;
linePoints ln1(bb.max(), bb.centre());
Info<< "line: " << ln1 << " box: " << ln1.box() << endl;
Info<< "box: " << boundBox(ln1.box()) << endl;
Info<< "corner: " << bb.hexCorner<0>() << nl
<< "corner: " << bb.hexCorner<7>() << nl
<< "corner: " << bb.hexCorner<6>() << endl;
point pt(Zero); point pt(Zero);
bb.add(pt); bb.add(pt);
@ -147,6 +161,25 @@ int main(int argc, char *argv[])
Info<< "box is now => " << box1 << endl; Info<< "box is now => " << box1 << endl;
} }
List<boundBox> boxes(12);
{
Random rndGen(12345);
for (auto& bb : boxes)
{
bb = cube
(
rndGen.position<scalar>(-10, 10),
rndGen.position<scalar>(0, 5)
);
}
Info<< "boxes: " << boxes << endl;
Foam::sort(boxes);
Info<< "sorted: " << boxes << endl;
}
return 0; return 0;
} }

View File

@ -64,13 +64,8 @@ int main(int argc, char *argv[])
// Slightly extended bb. Slightly off-centred just so on symmetric // Slightly extended bb. Slightly off-centred just so on symmetric
// geometry there are less face/edge aligned items. // geometry there are less face/edge aligned items.
treeBoundBox bb treeBoundBox bb(efem.points());
( bb.grow(ROOTVSMALL);
efem.points()
);
bb.min() -= point::uniform(ROOTVSMALL);
bb.max() += point::uniform(ROOTVSMALL);
labelList allEdges(identity(efem.edges().size())); labelList allEdges(identity(efem.edges().size()));

View File

@ -605,7 +605,7 @@ Foam::conformationSurfaces::conformationSurfaces
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::conformationSurfaces::overlaps(const treeBoundBox& bb) const bool Foam::conformationSurfaces::overlaps(const boundBox& bb) const
{ {
forAll(surfaces_, s) forAll(surfaces_, s)
{ {

View File

@ -188,7 +188,7 @@ public:
//- Check if the supplied bound box overlaps any part of any of //- Check if the supplied bound box overlaps any part of any of
// the surfaces // the surfaces
bool overlaps(const treeBoundBox& bb) const; bool overlaps(const boundBox& bb) const;
//- Check if points are inside surfaces to conform to //- Check if points are inside surfaces to conform to
Field<bool> inside(const pointField& samplePts) const; Field<bool> inside(const pointField& samplePts) const;

View File

@ -52,14 +52,14 @@ void Foam::AABBTree<Type>::writeOBJ
if (writeLinesOnly) if (writeLinesOnly)
{ {
for (const edge& e : bb.edges) for (const edge& e : treeBoundBox::edges)
{ {
os << "l " << e[0] + vertI + 1 << ' ' << e[1] + vertI + 1 << nl; os << "l " << e[0] + vertI + 1 << ' ' << e[1] + vertI + 1 << nl;
} }
} }
else else
{ {
for (const face& f : bb.faces) for (const face& f : treeBoundBox::faces)
{ {
os << 'f'; os << 'f';
for (const label fpi : f) for (const label fpi : f)

View File

@ -28,8 +28,8 @@ License
#include "boundBox.H" #include "boundBox.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
#include "tmp.H"
#include "plane.H" #include "plane.H"
#include "triangle.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -69,6 +69,17 @@ const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundBox::boundBox(const boundBox& bb, const bool doReduce)
:
boundBox(bb)
{
if (doReduce)
{
reduce();
}
}
Foam::boundBox::boundBox(const UList<point>& points, bool doReduce) Foam::boundBox::boundBox(const UList<point>& points, bool doReduce)
: :
boundBox() boundBox()
@ -117,19 +128,19 @@ Foam::boundBox::boundBox
Foam::tmp<Foam::pointField> Foam::boundBox::points() const Foam::tmp<Foam::pointField> Foam::boundBox::points() const
{ {
auto tpt = tmp<pointField>::New(8); auto tpts = tmp<pointField>::New(8);
auto& pt = tpt.ref(); auto& pts = tpts.ref();
pt[0] = min_; // min-x, min-y, min-z pts[0] = hexCorner<0>();
pt[1] = point(max_.x(), min_.y(), min_.z()); // max-x, min-y, min-z pts[1] = hexCorner<1>();
pt[2] = point(max_.x(), max_.y(), min_.z()); // max-x, max-y, min-z pts[2] = hexCorner<2>();
pt[3] = point(min_.x(), max_.y(), min_.z()); // min-x, max-y, min-z pts[3] = hexCorner<3>();
pt[4] = point(min_.x(), min_.y(), max_.z()); // min-x, min-y, max-z pts[4] = hexCorner<4>();
pt[5] = point(max_.x(), min_.y(), max_.z()); // max-x, min-y, max-z pts[5] = hexCorner<5>();
pt[6] = max_; // max-x, max-y, max-z pts[6] = hexCorner<6>();
pt[7] = point(min_.x(), max_.y(), max_.z()); // min-x, max-y, max-z pts[7] = hexCorner<7>();
return tpt; return tpts;
} }
@ -151,13 +162,6 @@ Foam::point Foam::boundBox::faceCentre(const direction facei) const
{ {
point pt = boundBox::centre(); point pt = boundBox::centre();
if (facei > 5)
{
FatalErrorInFunction
<< "face should be [0..5]"
<< abort(FatalError);
}
switch (facei) switch (facei)
{ {
case 0: pt.x() = min().x(); break; // 0: x-min, left case 0: pt.x() = min().x(); break; // 0: x-min, left
@ -166,21 +170,18 @@ Foam::point Foam::boundBox::faceCentre(const direction facei) const
case 3: pt.y() = max().y(); break; // 3: y-max, top case 3: pt.y() = max().y(); break; // 3: y-max, top
case 4: pt.z() = min().z(); break; // 4: z-min, back case 4: pt.z() = min().z(); break; // 4: z-min, back
case 5: pt.z() = max().z(); break; // 5: z-max, front case 5: pt.z() = max().z(); break; // 5: z-max, front
default:
{
FatalErrorInFunction
<< "Face:" << int(facei) << " should be [0..5]"
<< abort(FatalError);
}
} }
return pt; return pt;
} }
void Foam::boundBox::inflate(const scalar s)
{
const vector ext = vector::one*s*mag();
min_ -= ext;
max_ += ext;
}
void Foam::boundBox::reduce() void Foam::boundBox::reduce()
{ {
Foam::reduce(min_, minOp<point>()); Foam::reduce(min_, minOp<point>());
@ -188,6 +189,14 @@ void Foam::boundBox::reduce()
} }
Foam::boundBox Foam::boundBox::returnReduce(const boundBox& bb)
{
boundBox work(bb);
work.reduce();
return work;
}
bool Foam::boundBox::intersect(const boundBox& bb) bool Foam::boundBox::intersect(const boundBox& bb)
{ {
min_ = ::Foam::max(min_, bb.min_); min_ = ::Foam::max(min_, bb.min_);
@ -205,25 +214,29 @@ bool Foam::boundBox::intersects(const plane& pln) const
return false; return false;
} }
bool above = false; // Check as below(1) or above(2) - stop when it cuts both
bool below = false; int side = 0;
tmp<pointField> tpts(points()); #undef doLocalCode
const auto& pts = tpts(); #define doLocalCode(Idx) \
{ \
for (const point& p : pts) side |= (pln.whichSide(hexCorner<Idx>()) == plane::BACK ? 1 : 2); \
{ if (side == 3) return true; /* Both below and above: done */ \
if (pln.sideOfPlane(p) == plane::FRONT)
{
above = true;
}
else
{
below = true;
}
} }
return (above && below); // Each box corner
doLocalCode(0);
doLocalCode(1);
doLocalCode(2);
doLocalCode(3);
doLocalCode(4);
doLocalCode(5);
doLocalCode(6);
doLocalCode(7);
#undef doLocalCode
return false;
} }
@ -265,14 +278,15 @@ bool Foam::boundBox::containsAny(const UList<point>& points) const
} }
Foam::point Foam::boundBox::nearest(const point& pt) const Foam::point Foam::boundBox::nearest(const point& p) const
{ {
// Clip the point to the range of the bounding box // Clip the point to the range of the bounding box
const scalar surfPtx = Foam::max(Foam::min(pt.x(), max_.x()), min_.x()); return point
const scalar surfPty = Foam::max(Foam::min(pt.y(), max_.y()), min_.y()); (
const scalar surfPtz = Foam::max(Foam::min(pt.z(), max_.z()), min_.z()); Foam::min(Foam::max(p.x(), min_.x()), max_.x()),
Foam::min(Foam::max(p.y(), min_.y()), max_.y()),
return point(surfPtx, surfPty, surfPtz); Foam::min(Foam::max(p.z(), min_.z()), max_.z())
);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,11 +37,12 @@ Note
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef boundBox_H #ifndef Foam_boundBox_H
#define boundBox_H #define Foam_boundBox_H
#include "pointField.H" #include "pointField.H"
#include "faceList.H" #include "faceList.H"
#include "Pair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,7 +52,7 @@ namespace Foam
// Forward Declarations // Forward Declarations
class boundBox; class boundBox;
class plane; class plane;
template<class T> class tmp; template<class T> class MinMax;
Istream& operator>>(Istream& is, boundBox& bb); Istream& operator>>(Istream& is, boundBox& bb);
Ostream& operator<<(Ostream& os, const boundBox& bb); Ostream& operator<<(Ostream& os, const boundBox& bb);
@ -63,7 +64,7 @@ Ostream& operator<<(Ostream& os, const boundBox& bb);
class boundBox class boundBox
{ {
// Private data // Private Data
//- Minimum and maximum points describing the bounding box //- Minimum and maximum points describing the bounding box
point min_, max_; point min_, max_;
@ -93,17 +94,35 @@ public:
static const FixedList<vector, 6> faceNormals; static const FixedList<vector, 6> faceNormals;
// Constructors // Standard (Generated) Methods
//- Construct without any points - an inverted bounding box //- Default construct: an inverted bounding box
inline boundBox(); inline boundBox();
//- Construct a bounding box containing a single initial point //- Copy construct
inline explicit boundBox(const point& pt); boundBox(const boundBox&) = default;
//- Construct from components //- Copy assignment
boundBox& operator=(const boundBox&) = default;
// Constructors
//- Copy construct with specified global reduction
boundBox(const boundBox& bb, bool doReduce);
//- Construct a bounding box containing a single initial point
inline explicit boundBox(const point& p);
//- Construct from bound box min/max points
inline boundBox(const point& min, const point& max); inline boundBox(const point& min, const point& max);
///TBD: Construct from bound box min/max points
///inline explicit boundBox(const MinMax<point>& bb);
//- Construct from bound box min/max points
inline explicit boundBox(const Pair<point>& bb);
//- Construct as the bounding box of the given points //- Construct as the bounding box of the given points
// Does parallel communication (doReduce = true) // Does parallel communication (doReduce = true)
explicit boundBox(const UList<point>& points, bool doReduce = true); explicit boundBox(const UList<point>& points, bool doReduce = true);
@ -134,7 +153,7 @@ public:
); );
//- Construct from Istream //- Construct from Istream
inline boundBox(Istream& is); inline explicit boundBox(Istream& is);
// Member Functions // Member Functions
@ -148,23 +167,20 @@ public:
inline bool valid() const; inline bool valid() const;
//- Minimum describing the bounding box //- Minimum describing the bounding box
inline const point& min() const; inline const point& min() const noexcept;
//- Maximum describing the bounding box //- Maximum describing the bounding box
inline const point& max() const; inline const point& max() const noexcept;
//- Minimum describing the bounding box, non-const access //- Minimum describing the bounding box, non-const access
inline point& min(); inline point& min() noexcept;
//- Maximum describing the bounding box, non-const access //- Maximum describing the bounding box, non-const access
inline point& max(); inline point& max() noexcept;
//- The centre (midpoint) of the bounding box //- The centre (midpoint) of the bounding box
inline point centre() const; inline point centre() const;
//- The midpoint (centre) of the bounding box. Identical to centre()
inline point midpoint() const;
//- The bounding box span (from minimum to maximum) //- The bounding box span (from minimum to maximum)
inline vector span() const; inline vector span() const;
@ -184,12 +200,17 @@ public:
inline scalar avgDim() const; inline scalar avgDim() const;
//- Count the number of positive, non-zero dimensions. //- Count the number of positive, non-zero dimensions.
// \return -1 if any dimensions are negative, // \return
// 0 = 0D (point), // - -1 : if any dimensions are negative
// 1 = 1D (line aligned with an axis), // - 0 : 0D (point)
// 2 = 2D (plane aligned with an axis), // - 1 : 1D (line aligned with an axis)
// 3 = 3D (box) // - 2 : 2D (plane aligned with an axis)
inline label nDim() const; // - 3 : 3D (box)
inline int nDim() const;
//- Return corner point [0..7] corresponding to a 'hex' cell
template<direction CornerNumber>
inline point hexCorner() const;
//- Corner points in an order corresponding to a 'hex' cell //- Corner points in an order corresponding to a 'hex' cell
tmp<pointField> points() const; tmp<pointField> points() const;
@ -203,8 +224,11 @@ public:
// Manipulate // Manipulate
//- Clear bounding box and make it an inverted box //- Reset to an inverted box
inline void clear(); inline void reset();
//- Same as reset() - reset to an inverted box
void clear() { reset(); }
//- Extend to include the second box. //- Extend to include the second box.
inline void add(const boundBox& bb); inline void add(const boundBox& bb);
@ -242,12 +266,25 @@ public:
const IntContainer& indices const IntContainer& indices
); );
//- Inflate box by factor*mag(span) in all dimensions //- Expand box by adjusting min/max by specified amount
void inflate(const scalar s); //- in each dimension
inline void grow(const scalar delta);
//- Parallel reduction of min/max values //- Expand box by adjusting min/max by specified amounts
inline void grow(const vector& delta);
//- Expand box by factor*mag(span) in all dimensions
inline void inflate(const scalar factor);
// Parallel
//- Inplace parallel reduction of min/max values
void reduce(); void reduce();
//- Perform a reduction on a copy and return the result
static boundBox returnReduce(const boundBox& bb);
// Query // Query
@ -330,19 +367,25 @@ public:
//- Return the nearest point on the boundBox to the supplied point. //- Return the nearest point on the boundBox to the supplied point.
// If point is inside the boundBox then the point is returned // If point is inside the boundBox then the point is returned
// unchanged. // unchanged.
point nearest(const point& pt) const; point nearest(const point& p) const;
// Member Operators // Member Operators
//- Extend box to include the second box, as per the add() method. //- Extend box to include the second box, as per the add() method.
inline void operator+=(const boundBox& bb); void operator+=(const boundBox& bb) { add(bb); }
// IOstream operator // IOstream Operators
friend Istream& operator>>(Istream& is, boundBox& bb); friend Istream& operator>>(Istream& is, boundBox& bb);
friend Ostream& operator<<(Ostream& os, const boundBox& bb); friend Ostream& operator<<(Ostream& os, const boundBox& bb);
// Housekeeping
//- Identical to centre()
point midpoint() const { return centre(); }
}; };
@ -360,8 +403,44 @@ template<> struct is_contiguous_scalar<boundBox>
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
inline bool operator==(const boundBox& a, const boundBox& b); inline bool operator==(const boundBox& a, const boundBox& b)
inline bool operator!=(const boundBox& a, const boundBox& b); {
return (a.min() == b.min() && a.max() == b.max());
}
inline bool operator!=(const boundBox& a, const boundBox& b)
{
return !(a == b);
}
inline bool operator<(const boundBox& a, const boundBox& b)
{
return
(
a.min() < b.min()
|| (!(b.min() < a.min()) && a.max() < b.max())
);
}
inline bool operator<=(const boundBox& a, const boundBox& b)
{
return !(b < a);
}
inline bool operator>(const boundBox& a, const boundBox& b)
{
return (b < a);
}
inline bool operator>=(const boundBox& a, const boundBox& b)
{
return !(a < b);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +28,73 @@ License
#include "boundBox.H" #include "boundBox.H"
// * * * * * * * * * * * * * Geometrical Information * * * * * * * * * * * * //
namespace Foam
{
// Box corners as per hex cellmodel
template<>
inline Foam::point Foam::boundBox::hexCorner<0>() const
{
return min_;
}
template<>
inline Foam::point Foam::boundBox::hexCorner<1>() const
{
return point(max_.x(), min_.y(), min_.z());
}
template<>
inline Foam::point Foam::boundBox::hexCorner<2>() const
{
return point(max_.x(), max_.y(), min_.z());
}
template<>
inline Foam::point Foam::boundBox::hexCorner<3>() const
{
return point(min_.x(), max_.y(), min_.z());
}
template<>
inline Foam::point Foam::boundBox::hexCorner<4>() const
{
return point(min_.x(), min_.y(), max_.z());
}
template<>
inline Foam::point Foam::boundBox::hexCorner<5>() const
{
return point(max_.x(), min_.y(), max_.z());
}
template<>
inline Foam::point Foam::boundBox::hexCorner<6>() const
{
return max_;
}
template<>
inline Foam::point Foam::boundBox::hexCorner<7>() const
{
return point(min_.x(), max_.y(), max_.z());
}
} // End namespace Foam
// Non-specialized version is compile-time disabled
template<Foam::direction CornerNumber>
inline Foam::point Foam::boundBox::hexCorner() const
{
static_assert(CornerNumber < 8, "Corner index [0..7]");
return point();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::boundBox::boundBox() inline Foam::boundBox::boundBox()
@ -37,10 +104,10 @@ inline Foam::boundBox::boundBox()
{} {}
inline Foam::boundBox::boundBox(const point& pt) inline Foam::boundBox::boundBox(const point& p)
: :
min_(pt), min_(p),
max_(pt) max_(p)
{} {}
@ -51,6 +118,13 @@ inline Foam::boundBox::boundBox(const point& min, const point& max)
{} {}
inline Foam::boundBox::boundBox(const Pair<point>& bb)
:
min_(bb.first()),
max_(bb.second())
{}
inline Foam::boundBox::boundBox(Istream& is) inline Foam::boundBox::boundBox(Istream& is)
{ {
operator>>(is, *this); operator>>(is, *this);
@ -88,25 +162,25 @@ inline bool Foam::boundBox::valid() const
} }
inline const Foam::point& Foam::boundBox::min() const inline const Foam::point& Foam::boundBox::min() const noexcept
{ {
return min_; return min_;
} }
inline const Foam::point& Foam::boundBox::max() const inline const Foam::point& Foam::boundBox::max() const noexcept
{ {
return max_; return max_;
} }
inline Foam::point& Foam::boundBox::min() inline Foam::point& Foam::boundBox::min() noexcept
{ {
return min_; return min_;
} }
inline Foam::point& Foam::boundBox::max() inline Foam::point& Foam::boundBox::max() noexcept
{ {
return max_; return max_;
} }
@ -118,12 +192,6 @@ inline Foam::point Foam::boundBox::centre() const
} }
inline Foam::point Foam::boundBox::midpoint() const
{
return this->centre();
}
inline Foam::vector Foam::boundBox::span() const inline Foam::vector Foam::boundBox::span() const
{ {
return (max_ - min_); return (max_ - min_);
@ -160,9 +228,9 @@ inline Foam::scalar Foam::boundBox::avgDim() const
} }
inline Foam::label Foam::boundBox::nDim() const inline int Foam::boundBox::nDim() const
{ {
label ngood = 0; int ngood = 0;
for (direction dir = 0; dir < vector::nComponents; ++dir) for (direction dir = 0; dir < vector::nComponents; ++dir)
{ {
@ -181,7 +249,7 @@ inline Foam::label Foam::boundBox::nDim() const
} }
inline void Foam::boundBox::clear() inline void Foam::boundBox::reset()
{ {
min_ = invertedBox.min(); min_ = invertedBox.min();
max_ = invertedBox.max(); max_ = invertedBox.max();
@ -218,6 +286,26 @@ inline void Foam::boundBox::add(const tmp<pointField>& tpoints)
} }
inline void Foam::boundBox::grow(const scalar delta)
{
min_.x() -= delta; min_.y() -= delta; min_.z() -= delta;
max_.x() += delta; max_.y() += delta; max_.z() += delta;
}
inline void Foam::boundBox::grow(const vector& delta)
{
min_ -= delta;
max_ += delta;
}
inline void Foam::boundBox::inflate(const scalar factor)
{
grow(factor*mag());
}
inline bool Foam::boundBox::overlaps(const boundBox& bb) const inline bool Foam::boundBox::overlaps(const boundBox& bb) const
{ {
return return
@ -296,26 +384,4 @@ inline bool Foam::boundBox::containsInside(const point& pt) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void Foam::boundBox::operator+=(const boundBox& bb)
{
add(bb);
}
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
inline bool Foam::operator==(const boundBox& a, const boundBox& b)
{
return (a.min() == b.min()) && (a.max() == b.max());
}
inline bool Foam::operator!=(const boundBox& a, const boundBox& b)
{
return !(a == b);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -174,15 +174,13 @@ inline Foam::Pair<Foam::point> Foam::tetPoints::box() const
template<class Point, class PointRef> template<class Point, class PointRef>
inline Foam::treeBoundBox Foam::tetrahedron<Point, PointRef>::bounds() const inline Foam::treeBoundBox Foam::tetrahedron<Point, PointRef>::bounds() const
{ {
Pair<point> bb(tetrahedron<Point, PointRef>::box()); return treeBoundBox(box());
return treeBoundBox(bb.first(), bb.second());
} }
inline Foam::treeBoundBox Foam::tetPoints::bounds() const inline Foam::treeBoundBox Foam::tetPoints::bounds() const
{ {
Pair<point> bb(tetPoints::box()); return treeBoundBox(box());
return treeBoundBox(bb.first(), bb.second());
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,6 +30,7 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Point order using octant points
const Foam::faceList Foam::treeBoundBox::faces const Foam::faceList Foam::treeBoundBox::faces
({ ({
face({0, 4, 6, 2}), // 0: x-min, left face({0, 4, 6, 2}), // 0: x-min, left
@ -40,6 +41,7 @@ const Foam::faceList Foam::treeBoundBox::faces
face({4, 5, 7, 6}) // 5: z-max, front face({4, 5, 7, 6}) // 5: z-max, front
}); });
// Point order using octant points
const Foam::edgeList Foam::treeBoundBox::edges const Foam::edgeList Foam::treeBoundBox::edges
({ ({
{0, 1}, // 0 {0, 1}, // 0
@ -118,7 +120,7 @@ Foam::treeBoundBox Foam::treeBoundBox::subBbox
if (octant > 7) if (octant > 7)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "octant should be [0..7]" << "octant:" << int(octant) << " should be [0..7]"
<< abort(FatalError); << abort(FatalError);
} }
@ -188,7 +190,7 @@ bool Foam::treeBoundBox::intersects
pt = start; pt = start;
// Allow maximum of 3 clips. // Allow maximum of 3 clips.
for (label i = 0; i < 4; ++i) for (direction i = 0; i < 4; ++i)
{ {
direction ptBits = posBits(pt); direction ptBits = posBits(pt);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -61,13 +61,10 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef treeBoundBox_H #ifndef Foam_treeBoundBox_H
#define treeBoundBox_H #define Foam_treeBoundBox_H
#include "boundBox.H" #include "boundBox.H"
#include "direction.H"
#include "pointField.H"
#include "faceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -77,9 +74,14 @@ namespace Foam
// Forward Declarations // Forward Declarations
class Random; class Random;
class treeBoundBox; class treeBoundBox;
Istream& operator>>(Istream& is, treeBoundBox& bb); Istream& operator>>(Istream& is, treeBoundBox& bb);
Ostream& operator<<(Ostream& os, const treeBoundBox& bb); Ostream& operator<<(Ostream& os, const treeBoundBox& bb);
// List types
typedef List<treeBoundBox> treeBoundBoxList; //!< A List of treeBoundBox
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class treeBoundBox Declaration Class treeBoundBox Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -116,7 +118,7 @@ public:
//- Bits used for face encoding //- Bits used for face encoding
enum faceBit : direction enum faceBit : direction
{ {
NOFACE = 0, NOFACE = 0, //!< 0: none
LEFTBIT = 0x1 << LEFT, //!< 1: x-min, left LEFTBIT = 0x1 << LEFT, //!< 1: x-min, left
RIGHTBIT = 0x1 << RIGHT, //!< 2: x-max, right RIGHTBIT = 0x1 << RIGHT, //!< 2: x-max, right
BOTTOMBIT = 0x1 << BOTTOM, //!< 4: y-min, bottom BOTTOMBIT = 0x1 << BOTTOM, //!< 4: y-min, bottom
@ -155,20 +157,41 @@ public:
static const edgeList edges; static const edgeList edges;
// Standard (Generated) Methods
//- Default construct: an inverted bounding box
treeBoundBox() = default;
//- Copy construct
treeBoundBox(const treeBoundBox&) = default;
//- Copy assignment
treeBoundBox& operator=(const treeBoundBox&) = default;
//- Copy construct from a boundBox
explicit treeBoundBox(const boundBox& bb) : boundBox(bb) {}
//- Copy assignment from a boundBox
void operator=(const boundBox& bb)
{
static_cast<boundBox&>(*this) = bb;
}
// Constructors // Constructors
//- Construct without any points - an inverted bounding box
inline treeBoundBox();
//- Construct from a boundBox
inline explicit treeBoundBox(const boundBox& bb);
//- Construct a bounding box containing a single initial point //- Construct a bounding box containing a single initial point
inline explicit treeBoundBox(const point& pt); inline explicit treeBoundBox(const point& p);
//- Construct from components //- Construct from bound box min/max points
inline treeBoundBox(const point& min, const point& max); inline treeBoundBox(const point& min, const point& max);
///TBD: Construct from bound box min/max points
///inline explicit treeBoundBox(const MinMax<point>& bb);
//- Construct from bound box min/max points
inline explicit treeBoundBox(const Pair<point>& bb);
//- Construct as the bounding box of the given pointField. //- Construct as the bounding box of the given pointField.
// Local processor domain only (no reduce as in boundBox) // Local processor domain only (no reduce as in boundBox)
explicit treeBoundBox(const UList<point>& points); explicit treeBoundBox(const UList<point>& points);
@ -187,12 +210,11 @@ public:
const FixedList<label, N>& indices const FixedList<label, N>& indices
); );
//- Construct from Istream //- Construct from Istream
inline treeBoundBox(Istream& is); inline explicit treeBoundBox(Istream& is);
// Member functions // Member Functions
// Access // Access
@ -266,9 +288,12 @@ public:
FixedList<direction, 8>& octantOrder FixedList<direction, 8>& octantOrder
) const; ) const;
//- Overlaps other bounding box? //- Overlaps with other bounding box, sphere etc?
using boundBox::overlaps; using boundBox::overlaps;
//- intersects other bounding box, sphere etc?
using boundBox::intersects;
//- Intersects segment; set point to intersection position and face, //- Intersects segment; set point to intersection position and face,
// return true if intersection found. // return true if intersection found.
// (pt argument used during calculation even if not intersecting). // (pt argument used during calculation even if not intersecting).
@ -295,6 +320,9 @@ public:
point& pt point& pt
) const; ) const;
//- Like above but does not return faces point is on
inline bool intersects(const linePointRef& ln, point& pt) const;
//- Contains point or other bounding box? //- Contains point or other bounding box?
using boundBox::contains; using boundBox::contains;
@ -334,8 +362,17 @@ public:
// and guarantees in any direction s*mag(span) minimum width // and guarantees in any direction s*mag(span) minimum width
inline treeBoundBox extend(Random& rndGen, const scalar s) const; inline treeBoundBox extend(Random& rndGen, const scalar s) const;
//- As per two parameter version but with additional
//- grow() by given amount in each dimension
inline treeBoundBox extend
(
Random& rndGen,
const scalar s,
const scalar delta
) const;
// IOstream operator
// IOstream Operators
friend Istream& operator>>(Istream& is, treeBoundBox& bb); friend Istream& operator>>(Istream& is, treeBoundBox& bb);
friend Ostream& operator<<(Ostream& os, const treeBoundBox& bb); friend Ostream& operator<<(Ostream& os, const treeBoundBox& bb);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,21 +31,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::treeBoundBox::treeBoundBox() inline Foam::treeBoundBox::treeBoundBox(const point& p)
: :
boundBox() boundBox(p)
{}
inline Foam::treeBoundBox::treeBoundBox(const boundBox& bb)
:
boundBox(bb)
{}
inline Foam::treeBoundBox::treeBoundBox(const point& pt)
:
boundBox(pt)
{} {}
@ -55,6 +43,12 @@ inline Foam::treeBoundBox::treeBoundBox(const point& min, const point& max)
{} {}
inline Foam::treeBoundBox::treeBoundBox(const Pair<point>& bb)
:
boundBox(bb)
{}
inline Foam::treeBoundBox::treeBoundBox(Istream& is) inline Foam::treeBoundBox::treeBoundBox(Istream& is)
: :
boundBox(is) boundBox(is)
@ -234,7 +228,7 @@ inline Foam::direction Foam::treeBoundBox::subOctant
inline void Foam::treeBoundBox::searchOrder inline void Foam::treeBoundBox::searchOrder
( (
const point& pt, const point& pt,
FixedList<direction,8>& octantOrder FixedList<direction, 8>& octantOrder
) const ) const
{ {
vector dist = centre() - pt; vector dist = centre() - pt;
@ -321,6 +315,16 @@ inline void Foam::treeBoundBox::searchOrder
} }
inline bool Foam::treeBoundBox::intersects
(
const linePointRef& ln,
point& pt
) const
{
return intersects(ln.start(), ln.end(), pt);
}
inline Foam::treeBoundBox Foam::treeBoundBox::extend inline Foam::treeBoundBox Foam::treeBoundBox::extend
( (
Random& rndGen, Random& rndGen,
@ -332,7 +336,7 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend
vector newSpan = bb.span(); vector newSpan = bb.span();
// Make 3D // Make 3D
scalar minSpan = s * Foam::mag(newSpan); const scalar minSpan = s * Foam::mag(newSpan);
for (direction dir = 0; dir < vector::nComponents; ++dir) for (direction dir = 0; dir < vector::nComponents; ++dir)
{ {
@ -346,6 +350,20 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend
} }
inline Foam::treeBoundBox Foam::treeBoundBox::extend
(
Random& rndGen,
const scalar factor,
const scalar delta
) const
{
treeBoundBox bb(extend(rndGen, factor));
bb.grow(delta);
return bb;
}
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
inline bool Foam::operator==(const treeBoundBox& a, const treeBoundBox& b) inline bool Foam::operator==(const treeBoundBox& a, const treeBoundBox& b)

View File

@ -1,52 +1,10 @@
/*---------------------------------------------------------------------------*\ // Compatibility include.
========= | // treeBoundBoxList typedef included in treeBoundBox.H (OCT-2022)
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it #ifndef FoamCompat_treeBoundBoxList_H
under the terms of the GNU General Public License as published by #define FoamCompat_treeBoundBoxList_H
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::treeBoundBoxList
Description
List of bounding boxes.
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef treeBoundBoxList_H
#define treeBoundBoxList_H
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef List<treeBoundBox> treeBoundBoxList;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif

View File

@ -964,8 +964,6 @@ Foam::labelList Foam::boundaryMesh::getNearest
labelList nearestBFacei(pMesh.nBoundaryFaces()); labelList nearestBFacei(pMesh.nBoundaryFaces());
treeBoundBox tightest;
const scalar searchDimSqr = magSqr(searchSpan); const scalar searchDimSqr = magSqr(searchSpan);
forAll(nearestBFacei, patchFacei) forAll(nearestBFacei, patchFacei)

View File

@ -75,13 +75,10 @@ void Foam::processorLODs::box::writeBoxes
// Write the points // Write the points
const pointField pts(bb.points()); const pointField pts(bb.points());
for (const point& p : pts) meshTools::writeOBJ(os, pts);
{
meshTools::writeOBJ(os, p);
}
// Write the box faces // Write the box faces
for (const face& f : bb.faces) for (const face& f : treeBoundBox::faces)
{ {
os << 'f'; os << 'f';
for (const label fpi : f) for (const label fpi : f)

View File

@ -197,7 +197,8 @@ void Foam::tetOverlapVolume::cellCellOverlapMinDecomp
meshA.points()[pt0I], meshA.points()[pt0I],
meshA.points()[pt1I] meshA.points()[pt1I]
); );
const treeBoundBox tetABb(tetA.bounds());
const treeBoundBox tetAbb(tetA.bounds());
// Loop over tets of cellB // Loop over tets of cellB
forAll(cFacesB, cFB) forAll(cFacesB, cFB)
@ -243,7 +244,10 @@ void Foam::tetOverlapVolume::cellCellOverlapMinDecomp
meshB.points()[pt0I], meshB.points()[pt0I],
meshB.points()[pt1I] meshB.points()[pt1I]
); );
if (!tetB.bounds().overlaps(tetABb))
const treeBoundBox tetBbb(tetB.bounds());
if (!tetBbb.overlaps(tetAbb))
{ {
continue; continue;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,7 +28,6 @@ License
#include "triangleFuncs.H" #include "triangleFuncs.H"
#include "triangle.H" #include "triangle.H"
#include "pointField.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "SortableList.H" #include "SortableList.H"
#include "boolList.H" #include "boolList.H"
@ -150,9 +149,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
bool Foam::triangleFuncs::intersectBb bool Foam::triangleFuncs::intersectBb
( (
const point& p0, const triPointRef& tri,
const point& p1,
const point& p2,
const treeBoundBox& cubeBb const treeBoundBox& cubeBb
) )
{ {
@ -160,14 +157,10 @@ bool Foam::triangleFuncs::intersectBb
// to above intersectAxesBundle. However this function is not fully // to above intersectAxesBundle. However this function is not fully
// correct and misses intersection between some triangles. // correct and misses intersection between some triangles.
{ {
const triPointRef tri(p0, p1, p2);
const edgeList& es = treeBoundBox::edges;
const pointField points(cubeBb.points()); const pointField points(cubeBb.points());
forAll(es, i) for (const edge& e : treeBoundBox::edges)
{ {
const edge& e = es[i];
const point& start = points[e[0]]; const point& start = points[e[0]];
const point& end = points[e[1]]; const point& end = points[e[1]];
@ -188,20 +181,27 @@ bool Foam::triangleFuncs::intersectBb
// Intersect triangle edges with bounding box // Intersect triangle edges with bounding box
point pInter; point pInter;
if (cubeBb.intersects(p0, p1, pInter))
{
return true;
}
if (cubeBb.intersects(p1, p2, pInter))
{
return true;
}
if (cubeBb.intersects(p2, p0, pInter))
{
return true;
}
return false; return
(
cubeBb.intersects(tri.a(), tri.b(), pInter)
|| cubeBb.intersects(tri.b(), tri.c(), pInter)
|| cubeBb.intersects(tri.c(), tri.a(), pInter)
);
}
bool Foam::triangleFuncs::intersectBb
(
const point& p0,
const point& p1,
const point& p2,
const treeBoundBox& cubeBb
)
{
const triPointRef tri(p0, p1, p2);
return intersectBb(tri, cubeBb);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,6 +39,7 @@ SourceFiles
#define Foam_triangleFuncs_H #define Foam_triangleFuncs_H
#include "pointField.H" #include "pointField.H"
#include "triangle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -87,6 +88,15 @@ public:
point& pInter point& pInter
); );
//- Intersect triangle with bounding box.
// \return true if any bounding box faces intersect the triangle,
// returns false if the triangle is inside the bounding box
static bool intersectBb
(
const triPointRef& tri,
const treeBoundBox& cubeBb
);
//- Intersect triangle with bounding box. //- Intersect triangle with bounding box.
// \return true if any bounding box faces intersect the triangle, // \return true if any bounding box faces intersect the triangle,
// returns false if the triangle is inside the bounding box // returns false if the triangle is inside the bounding box

View File

@ -356,7 +356,7 @@ bool Foam::distributedTriSurfaceMesh::read()
//outsideVolType_ = volumeType::UNKNOWN; //outsideVolType_ = volumeType::UNKNOWN;
//if (surfaceClosed_) //if (surfaceClosed_)
//{ //{
// point outsidePt(localBb.max()+localBb.midpoint()); // point outsidePt(localBb.max()+localBb.centre());
// List<volumeType> outsideVolTypes; // List<volumeType> outsideVolTypes;
// triSurfaceMesh::getVolumeType // triSurfaceMesh::getVolumeType
// ( // (
@ -1539,7 +1539,7 @@ void Foam::distributedTriSurfaceMesh::collectLeafMids
// No data in this octant. Set type for octant acc. to the mid // No data in this octant. Set type for octant acc. to the mid
// of its bounding box. // of its bounding box.
const treeBoundBox subBb = nod.bb_.subBbox(octant); const treeBoundBox subBb = nod.bb_.subBbox(octant);
midPoints.append(subBb.midpoint()); midPoints.append(subBb.centre());
} }
} }
} }