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 = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,7 +31,8 @@ Description
#include "argList.H"
#include "Time.H"
#include "polyMesh.H"
#include "boundBox.H"
#include "line.H"
#include "Random.H"
#include "treeBoundBox.H"
#include "cellModel.H"
#include "bitSet.H"
@ -84,7 +85,20 @@ int main(int argc, char *argv[])
else
{
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);
bb.add(pt);
@ -147,6 +161,25 @@ int main(int argc, char *argv[])
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;
}

View File

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

View File

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

View File

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

View File

@ -52,14 +52,14 @@ void Foam::AABBTree<Type>::writeOBJ
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;
}
}
else
{
for (const face& f : bb.faces)
for (const face& f : treeBoundBox::faces)
{
os << 'f';
for (const label fpi : f)

View File

@ -28,8 +28,8 @@ License
#include "boundBox.H"
#include "PstreamReduceOps.H"
#include "tmp.H"
#include "plane.H"
#include "triangle.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -69,6 +69,17 @@ const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundBox::boundBox(const boundBox& bb, const bool doReduce)
:
boundBox(bb)
{
if (doReduce)
{
reduce();
}
}
Foam::boundBox::boundBox(const UList<point>& points, bool doReduce)
:
boundBox()
@ -117,19 +128,19 @@ Foam::boundBox::boundBox
Foam::tmp<Foam::pointField> Foam::boundBox::points() const
{
auto tpt = tmp<pointField>::New(8);
auto& pt = tpt.ref();
auto tpts = tmp<pointField>::New(8);
auto& pts = tpts.ref();
pt[0] = min_; // min-x, min-y, min-z
pt[1] = point(max_.x(), min_.y(), min_.z()); // max-x, min-y, min-z
pt[2] = point(max_.x(), max_.y(), min_.z()); // max-x, max-y, min-z
pt[3] = point(min_.x(), max_.y(), min_.z()); // min-x, max-y, min-z
pt[4] = point(min_.x(), min_.y(), max_.z()); // min-x, min-y, max-z
pt[5] = point(max_.x(), min_.y(), max_.z()); // max-x, min-y, max-z
pt[6] = max_; // max-x, max-y, max-z
pt[7] = point(min_.x(), max_.y(), max_.z()); // min-x, max-y, max-z
pts[0] = hexCorner<0>();
pts[1] = hexCorner<1>();
pts[2] = hexCorner<2>();
pts[3] = hexCorner<3>();
pts[4] = hexCorner<4>();
pts[5] = hexCorner<5>();
pts[6] = hexCorner<6>();
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();
if (facei > 5)
{
FatalErrorInFunction
<< "face should be [0..5]"
<< abort(FatalError);
}
switch (facei)
{
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 4: pt.z() = min().z(); break; // 4: z-min, back
case 5: pt.z() = max().z(); break; // 5: z-max, front
default:
{
FatalErrorInFunction
<< "Face:" << int(facei) << " should be [0..5]"
<< abort(FatalError);
}
}
return pt;
}
void Foam::boundBox::inflate(const scalar s)
{
const vector ext = vector::one*s*mag();
min_ -= ext;
max_ += ext;
}
void Foam::boundBox::reduce()
{
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)
{
min_ = ::Foam::max(min_, bb.min_);
@ -205,25 +214,29 @@ bool Foam::boundBox::intersects(const plane& pln) const
return false;
}
bool above = false;
bool below = false;
// Check as below(1) or above(2) - stop when it cuts both
int side = 0;
tmp<pointField> tpts(points());
const auto& pts = tpts();
for (const point& p : pts)
{
if (pln.sideOfPlane(p) == plane::FRONT)
{
above = true;
}
else
{
below = true;
}
#undef doLocalCode
#define doLocalCode(Idx) \
{ \
side |= (pln.whichSide(hexCorner<Idx>()) == plane::BACK ? 1 : 2); \
if (side == 3) return true; /* Both below and above: done */ \
}
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
const scalar surfPtx = Foam::max(Foam::min(pt.x(), max_.x()), min_.x());
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());
return point(surfPtx, surfPty, surfPtz);
return point
(
Foam::min(Foam::max(p.x(), min_.x()), max_.x()),
Foam::min(Foam::max(p.y(), min_.y()), max_.y()),
Foam::min(Foam::max(p.z(), min_.z()), max_.z())
);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,11 +37,12 @@ Note
\*---------------------------------------------------------------------------*/
#ifndef boundBox_H
#define boundBox_H
#ifndef Foam_boundBox_H
#define Foam_boundBox_H
#include "pointField.H"
#include "faceList.H"
#include "Pair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,7 +52,7 @@ namespace Foam
// Forward Declarations
class boundBox;
class plane;
template<class T> class tmp;
template<class T> class MinMax;
Istream& operator>>(Istream& is, boundBox& bb);
Ostream& operator<<(Ostream& os, const boundBox& bb);
@ -63,7 +64,7 @@ Ostream& operator<<(Ostream& os, const boundBox& bb);
class boundBox
{
// Private data
// Private Data
//- Minimum and maximum points describing the bounding box
point min_, max_;
@ -93,17 +94,35 @@ public:
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();
//- Construct a bounding box containing a single initial point
inline explicit boundBox(const point& pt);
//- Copy construct
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);
///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
// Does parallel communication (doReduce = true)
explicit boundBox(const UList<point>& points, bool doReduce = true);
@ -134,7 +153,7 @@ public:
);
//- Construct from Istream
inline boundBox(Istream& is);
inline explicit boundBox(Istream& is);
// Member Functions
@ -148,23 +167,20 @@ public:
inline bool valid() const;
//- Minimum describing the bounding box
inline const point& min() const;
inline const point& min() const noexcept;
//- Maximum describing the bounding box
inline const point& max() const;
inline const point& max() const noexcept;
//- Minimum describing the bounding box, non-const access
inline point& min();
inline point& min() noexcept;
//- Maximum describing the bounding box, non-const access
inline point& max();
inline point& max() noexcept;
//- The centre (midpoint) of the bounding box
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)
inline vector span() const;
@ -184,12 +200,17 @@ public:
inline scalar avgDim() const;
//- Count the number of positive, non-zero dimensions.
// \return -1 if any dimensions are negative,
// 0 = 0D (point),
// 1 = 1D (line aligned with an axis),
// 2 = 2D (plane aligned with an axis),
// 3 = 3D (box)
inline label nDim() const;
// \return
// - -1 : if any dimensions are negative
// - 0 : 0D (point)
// - 1 : 1D (line aligned with an axis)
// - 2 : 2D (plane aligned with an axis)
// - 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
tmp<pointField> points() const;
@ -203,8 +224,11 @@ public:
// Manipulate
//- Clear bounding box and make it an inverted box
inline void clear();
//- Reset to an inverted box
inline void reset();
//- Same as reset() - reset to an inverted box
void clear() { reset(); }
//- Extend to include the second box.
inline void add(const boundBox& bb);
@ -242,12 +266,25 @@ public:
const IntContainer& indices
);
//- Inflate box by factor*mag(span) in all dimensions
void inflate(const scalar s);
//- Expand box by adjusting min/max by specified amount
//- 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();
//- Perform a reduction on a copy and return the result
static boundBox returnReduce(const boundBox& bb);
// Query
@ -330,19 +367,25 @@ public:
//- Return the nearest point on the boundBox to the supplied point.
// If point is inside the boundBox then the point is returned
// unchanged.
point nearest(const point& pt) const;
point nearest(const point& p) const;
// Member Operators
//- 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 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 * * * * * * * * * * * * * //
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 |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,6 +28,73 @@ License
#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 * * * * * * * * * * * * * * //
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),
max_(pt)
min_(p),
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)
{
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_;
}
inline const Foam::point& Foam::boundBox::max() const
inline const Foam::point& Foam::boundBox::max() const noexcept
{
return max_;
}
inline Foam::point& Foam::boundBox::min()
inline Foam::point& Foam::boundBox::min() noexcept
{
return min_;
}
inline Foam::point& Foam::boundBox::max()
inline Foam::point& Foam::boundBox::max() noexcept
{
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
{
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)
{
@ -181,7 +249,7 @@ inline Foam::label Foam::boundBox::nDim() const
}
inline void Foam::boundBox::clear()
inline void Foam::boundBox::reset()
{
min_ = invertedBox.min();
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
{
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>
inline Foam::treeBoundBox Foam::tetrahedron<Point, PointRef>::bounds() const
{
Pair<point> bb(tetrahedron<Point, PointRef>::box());
return treeBoundBox(bb.first(), bb.second());
return treeBoundBox(box());
}
inline Foam::treeBoundBox Foam::tetPoints::bounds() const
{
Pair<point> bb(tetPoints::box());
return treeBoundBox(bb.first(), bb.second());
return treeBoundBox(box());
}

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,13 +61,10 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef treeBoundBox_H
#define treeBoundBox_H
#ifndef Foam_treeBoundBox_H
#define Foam_treeBoundBox_H
#include "boundBox.H"
#include "direction.H"
#include "pointField.H"
#include "faceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -77,9 +74,14 @@ namespace Foam
// Forward Declarations
class Random;
class treeBoundBox;
Istream& operator>>(Istream& is, treeBoundBox& bb);
Ostream& operator<<(Ostream& os, const treeBoundBox& bb);
// List types
typedef List<treeBoundBox> treeBoundBoxList; //!< A List of treeBoundBox
/*---------------------------------------------------------------------------*\
Class treeBoundBox Declaration
\*---------------------------------------------------------------------------*/
@ -116,7 +118,7 @@ public:
//- Bits used for face encoding
enum faceBit : direction
{
NOFACE = 0,
NOFACE = 0, //!< 0: none
LEFTBIT = 0x1 << LEFT, //!< 1: x-min, left
RIGHTBIT = 0x1 << RIGHT, //!< 2: x-max, right
BOTTOMBIT = 0x1 << BOTTOM, //!< 4: y-min, bottom
@ -155,20 +157,41 @@ public:
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
//- 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
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);
///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.
// Local processor domain only (no reduce as in boundBox)
explicit treeBoundBox(const UList<point>& points);
@ -187,12 +210,11 @@ public:
const FixedList<label, N>& indices
);
//- Construct from Istream
inline treeBoundBox(Istream& is);
inline explicit treeBoundBox(Istream& is);
// Member functions
// Member Functions
// Access
@ -266,9 +288,12 @@ public:
FixedList<direction, 8>& octantOrder
) const;
//- Overlaps other bounding box?
//- Overlaps with other bounding box, sphere etc?
using boundBox::overlaps;
//- intersects other bounding box, sphere etc?
using boundBox::intersects;
//- Intersects segment; set point to intersection position and face,
// return true if intersection found.
// (pt argument used during calculation even if not intersecting).
@ -295,6 +320,9 @@ public:
point& pt
) 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?
using boundBox::contains;
@ -334,8 +362,17 @@ public:
// and guarantees in any direction s*mag(span) minimum width
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 Ostream& operator<<(Ostream& os, const treeBoundBox& bb);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,21 +31,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::treeBoundBox::treeBoundBox()
inline Foam::treeBoundBox::treeBoundBox(const point& p)
:
boundBox()
{}
inline Foam::treeBoundBox::treeBoundBox(const boundBox& bb)
:
boundBox(bb)
{}
inline Foam::treeBoundBox::treeBoundBox(const point& pt)
:
boundBox(pt)
boundBox(p)
{}
@ -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)
:
boundBox(is)
@ -234,7 +228,7 @@ inline Foam::direction Foam::treeBoundBox::subOctant
inline void Foam::treeBoundBox::searchOrder
(
const point& pt,
FixedList<direction,8>& octantOrder
FixedList<direction, 8>& octantOrder
) const
{
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
(
Random& rndGen,
@ -332,7 +336,7 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend
vector newSpan = bb.span();
// Make 3D
scalar minSpan = s * Foam::mag(newSpan);
const scalar minSpan = s * Foam::mag(newSpan);
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 * * * * * * * * * * * * * * //
inline bool Foam::operator==(const treeBoundBox& a, const treeBoundBox& b)

View File

@ -1,52 +1,10 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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.
// Compatibility include.
// treeBoundBoxList typedef included in treeBoundBox.H (OCT-2022)
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
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
#ifndef FoamCompat_treeBoundBoxList_H
#define FoamCompat_treeBoundBoxList_H
#include "treeBoundBox.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef List<treeBoundBox> treeBoundBoxList;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,6 @@ License
#include "triangleFuncs.H"
#include "triangle.H"
#include "pointField.H"
#include "treeBoundBox.H"
#include "SortableList.H"
#include "boolList.H"
@ -150,9 +149,7 @@ bool Foam::triangleFuncs::intersectAxesBundle
bool Foam::triangleFuncs::intersectBb
(
const point& p0,
const point& p1,
const point& p2,
const triPointRef& tri,
const treeBoundBox& cubeBb
)
{
@ -160,14 +157,10 @@ bool Foam::triangleFuncs::intersectBb
// to above intersectAxesBundle. However this function is not fully
// correct and misses intersection between some triangles.
{
const triPointRef tri(p0, p1, p2);
const edgeList& es = treeBoundBox::edges;
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& end = points[e[1]];
@ -188,20 +181,27 @@ bool Foam::triangleFuncs::intersectBb
// Intersect triangle edges with bounding box
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 |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,6 +39,7 @@ SourceFiles
#define Foam_triangleFuncs_H
#include "pointField.H"
#include "triangle.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -87,6 +88,15 @@ public:
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.
// \return true if any bounding box faces intersect the triangle,
// returns false if the triangle is inside the bounding box

View File

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