Commit 722d23f5 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: additional methods/operators for boundBox (related to #196)

- Constructor for bounding box of a single point.

- add(boundBox), add(point) ...
  -> Extend box to enclose the second box or point(s).

  Eg,
      bb.add(pt);
  vs.
      bb.min() = Foam::min(bb.min(), pt);
      bb.max() = Foam::max(bb.max(), pt);

Also works with other bounding boxes.
  Eg,
      bb.add(bb2);
      // OR
      bb += bb2;
  vs.
      bb.min() = Foam::min(bb.min(), bb2.min());
      bb.max() = Foam::max(bb.max(), bb2.max());

'+=' operator allows the reduction to be used in parallel
gather/scatter operations.

A global '+' operator is not currently needed.

Note: may be useful in the future to have a 'clear()' method
that resets to a zero-sized (inverted) box.

STYLE: make many bounding box constructors explicit
parent 17d76e62
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -40,8 +40,8 @@ boundBox cube(scalar start, scalar width)
{
return boundBox
(
point(start, start, start),
point(start + width, start + width, start + width)
point::uniform(start),
point::uniform(start + width)
);
}
......@@ -59,10 +59,19 @@ int main(int argc, char *argv[])
Info<<"boundBox faces: " << boundBox::faces << endl;
Info<<"hex faces: " << hex.modelFaces() << endl;
Info<<"tree-bb faces: " << treeBoundBox::faces << endl;
Info<<"tree-bb edges: " << treeBoundBox::edges << endl;
boundBox bb = boundBox::greatBox;
Info<<"great box: " << bb << endl;
// bb.clear();
// Info<<"zero box: " << bb << endl;
bb = boundBox::invertedBox;
Info<<"invalid box: " << bb << endl;
Info<< nl << endl;
if (Pstream::parRun())
{
bb = cube(Pstream::myProcNo(), 1.1);
......@@ -71,6 +80,48 @@ int main(int argc, char *argv[])
bb.reduce();
Pout<<"reduced: " << bb << endl;
}
else
{
bb = cube(0, 1);
Info<<"starting box: " << bb << endl;
point pt(Zero);
bb.add(pt);
Info<<"enclose point " << pt << " -> " << bb << endl;
pt = point(0,1.5,0.5);
bb.add(pt);
Info<<"enclose point " << pt << " -> " << bb << endl;
pt = point(5,2,-2);
bb.add(pt);
Info<<"enclose point " << pt << " -> " << bb << endl;
// restart with same points
bb = boundBox::invertedBox;
bb.add(point(1,1,1));
bb.add(point::zero);
bb.add(point(0,1.5,0.5));
bb.add(point(5,2,-2));
Info<<"repeated " << bb << endl;
boundBox box1 = cube(0, 1);
boundBox box2 = cube(0, 0.75);
boundBox box3 = cube(0.5, 1);
boundBox box4 = cube(-1, 0.5);
Info<<"union of " << box1 << " and " << box2 << " => ";
box1.add(box2);
Info<< box1 << endl;
box1.add(box3);
Info<<"union with " << box3 << " => " << box1 << endl;
box1.add(box4);
Info<<"union with " << box4 << " => " << box1 << endl;
}
return 0;
}
......
......@@ -66,14 +66,14 @@ int main(int argc, char *argv[])
pointField newPoints(mesh.points());
const point half(0.5*(meshBb.min() + meshBb.max()));
const point half = meshBb.midpoint();
forAll(newPoints, pointi)
{
point& pt = newPoints[pointi];
// expand around half
pt.y() += pt.y() - half.y();
pt.y() += pt.y() - half.y();
}
mesh.movePoints(newPoints);
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -719,17 +719,13 @@ void Foam::backgroundMeshDecomposition::buildPatchAndTree()
Pstream::gatherList(allBackgroundMeshBounds_);
Pstream::scatterList(allBackgroundMeshBounds_);
point bbMin(GREAT, GREAT, GREAT);
point bbMax(-GREAT, -GREAT, -GREAT);
// find global bounding box
globalBackgroundBounds_ = treeBoundBox::invertedBox;
forAll(allBackgroundMeshBounds_, proci)
{
bbMin = min(bbMin, allBackgroundMeshBounds_[proci].min());
bbMax = max(bbMax, allBackgroundMeshBounds_[proci].max());
globalBackgroundBounds_.add(allBackgroundMeshBounds_[proci]);
}
globalBackgroundBounds_ = treeBoundBox(bbMin, bbMax);
if (false)
{
OFstream fStr
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -558,18 +558,11 @@ Foam::label Foam::checkTopology
if (allGeometry)
{
const pointField& pts = pp.points();
const labelList& mp = pp.meshPoints();
if (returnReduce(mp.size(), sumOp<label>()) > 0)
{
boundBox bb(point::max, point::min);
forAll(mp, i)
{
bb.min() = min(bb.min(), pts[mp[i]]);
bb.max() = max(bb.max(), pts[mp[i]]);
}
bb.reduce();
boundBox bb(pp.points(), mp, true); // reduce
Info<< ' ' << bb;
}
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -336,10 +336,7 @@ boundBox procBounds
)
);
boundBox domainBb(points, false);
bb.min() = min(bb.min(), domainBb.min());
bb.max() = max(bb.max(), domainBb.max());
bb.add(points);
}
return bb;
......
......@@ -49,33 +49,23 @@ const Foam::faceList Foam::boundBox::faces
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::boundBox::calculate(const UList<point>& points, const bool doReduce)
void Foam::boundBox::calculate(const UList<point>& points, bool doReduce)
{
if (points.empty())
{
min_ = Zero;
max_ = Zero;
if (doReduce && Pstream::parRun())
{
// Use values that get overwritten by reduce minOp, maxOp below
min_ = point(VGREAT, VGREAT, VGREAT);
max_ = point(-VGREAT, -VGREAT, -VGREAT);
// Values that get overwritten by subsequent reduce operation
operator=(invertedBox);
}
}
else
{
min_ = points[0];
max_ = points[0];
for (label i = 1; i < points.size(); i++)
{
min_ = ::Foam::min(min_, points[i]);
max_ = ::Foam::max(max_, points[i]);
}
operator=(invertedBox);
add(points);
}
// Reduce parallel information
// Parallel reduction
if (doReduce)
{
reduce();
......@@ -85,7 +75,7 @@ void Foam::boundBox::calculate(const UList<point>& points, const bool doReduce)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundBox::boundBox(const UList<point>& points, const bool doReduce)
Foam::boundBox::boundBox(const UList<point>& points, bool doReduce)
:
min_(Zero),
max_(Zero)
......@@ -94,13 +84,13 @@ Foam::boundBox::boundBox(const UList<point>& points, const bool doReduce)
}
Foam::boundBox::boundBox(const tmp<pointField>& points, const bool doReduce)
Foam::boundBox::boundBox(const tmp<pointField>& tpoints, bool doReduce)
:
min_(Zero),
max_(Zero)
{
calculate(points(), doReduce);
points.clear();
calculate(tpoints(), doReduce);
tpoints.clear();
}
......@@ -108,7 +98,7 @@ Foam::boundBox::boundBox
(
const UList<point>& points,
const labelUList& indices,
const bool doReduce
bool doReduce
)
:
min_(Zero),
......@@ -118,24 +108,17 @@ Foam::boundBox::boundBox
{
if (doReduce && Pstream::parRun())
{
// Use values that get overwritten by reduce minOp, maxOp below
min_ = point(VGREAT, VGREAT, VGREAT);
max_ = point(-VGREAT, -VGREAT, -VGREAT);
// Values that get overwritten by subsequent reduce operation
operator=(invertedBox);
}
}
else
{
min_ = points[indices[0]];
max_ = points[indices[0]];
for (label i=1; i < indices.size(); ++i)
{
min_ = ::Foam::min(min_, points[indices[i]]);
max_ = ::Foam::max(max_, points[indices[i]]);
}
operator=(invertedBox);
add(points, indices);
}
// Reduce parallel information
// Parallel reduction
if (doReduce)
{
reduce();
......@@ -147,8 +130,8 @@ Foam::boundBox::boundBox
Foam::tmp<Foam::pointField> Foam::boundBox::points() const
{
tmp<pointField> tPts = tmp<pointField>(new pointField(8));
pointField& pt = tPts.ref();
tmp<pointField> tpoints = tmp<pointField>(new pointField(8));
pointField& pt = tpoints.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
......@@ -159,13 +142,13 @@ Foam::tmp<Foam::pointField> Foam::boundBox::points() const
pt[6] = max_; // max-x, max-y, max-z
pt[7] = point(min_.x(), max_.y(), max_.z()); // min-x, max-y, max-z
return tPts;
return tpoints;
}
void Foam::boundBox::inflate(const scalar s)
{
vector ext = vector::one*s*mag();
const vector ext = vector::one*s*mag();
min_ -= ext;
max_ += ext;
......@@ -179,6 +162,15 @@ void Foam::boundBox::reduce()
}
bool Foam::boundBox::intersect(const boundBox& bb)
{
min_ = ::Foam::max(min_, bb.min_);
max_ = ::Foam::min(max_, bb.max_);
return !empty();
}
bool Foam::boundBox::contains(const UList<point>& points) const
{
if (points.empty())
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -60,22 +60,19 @@ class boundBox
{
// Private data
//- Minimum and maximum describing the bounding box
//- Minimum and maximum points describing the bounding box
point min_, max_;
// Private Member Functions
//- Calculate the bounding box from the given points.
// Does parallel communication (doReduce = true)
void calculate(const UList<point>&, const bool doReduce = true);
void calculate(const UList<point>& points, bool doReduce = true);
public:
// Static data members
//- The great value used for greatBox and invertedBox
static const scalar great;
//- A very large boundBox: min/max == -/+ VGREAT
static const boundBox greatBox;
......@@ -91,46 +88,52 @@ public:
//- Construct null, setting points to zero
inline boundBox();
//- Construct a bounding box containing a single initial point
explicit inline boundBox(const point& pt);
//- Construct from components
inline boundBox(const point& min, const point& max);
//- Construct as the bounding box of the given points
// Does parallel communication (doReduce = true)
boundBox(const UList<point>&, const bool doReduce = true);
explicit boundBox(const UList<point>& points, bool doReduce = true);
//- Construct as the bounding box of the given temporary pointField.
// Does parallel communication (doReduce = true)
boundBox(const tmp<pointField>&, const bool doReduce = true);
explicit boundBox(const tmp<pointField>& tpoints, bool doReduce = true);
//- Construct bounding box as subset of the pointField.
//- Construct bounding box as an indirect subset of the points.
// The indices could be from cell/face etc.
// Does parallel communication (doReduce = true)
boundBox
(
const UList<point>&,
const UList<point>& points,
const labelUList& indices,
const bool doReduce = true
bool doReduce = true
);
//- Construct bounding box as subset of the pointField.
//- Construct bounding box as an indirect subset of the points.
// The indices could be from edge/triFace etc.
// Does parallel communication (doReduce = true)
template<unsigned Size>
boundBox
(
const UList<point>&,
const UList<point>& points,
const FixedList<label, Size>& indices,
const bool doReduce = true
bool doReduce = true
);
//- Construct from Istream
inline boundBox(Istream&);
inline boundBox(Istream& is);
// Member functions
// Access
//- Bounding box is inverted, contains no points.
inline bool empty() const;
//- Minimum describing the bounding box
inline const point& min() const;
......@@ -170,83 +173,130 @@ public:
// Manipulate
//- Extend to include the second box.
inline void add(const boundBox& bb);
//- Extend to include the point.
inline void add(const point& pt);
//- Extend to include the points.
inline void add(const UList<point>& points);
//- Extend to include the points from the temporary point field.
inline void add(const tmp<pointField>& tpoints);
//- Extend to include the subset of the point field.
// The indices could be from cell/face etc.
inline void add
(
const UList<point>& points,
const labelUList& indices
);
//- Extend to include the points.
template<unsigned Size>
void add(const FixedList<point, Size>& points);
//- Extend to include the subset of the point field.
// The indices could be from edge/triFace etc.
template<unsigned Size>
void add
(
const UList<point>& points,
const FixedList<label, Size>& indices
);
//- Inflate box by factor*mag(span) in all dimensions
void inflate(const scalar s);
//- Parallel reduction of min/max values
void reduce();
//- Intersection (union) with the second box.
// The return value is true if the intersection is non-empty.
bool intersect(const boundBox& bb);
// Query
//- Overlaps/touches boundingBox?
inline bool overlaps(const boundBox&) const;
inline bool overlaps(const boundBox& bb) const;
//- Overlaps boundingSphere (centre + sqr(radius))?
inline bool overlaps(const point&, const scalar radiusSqr) const;
inline bool overlaps
(
const point& centre,
const scalar radiusSqr
) const;
//- Contains point? (inside or on edge)
inline bool contains(const point&) const;
inline bool contains(const point& pt) const;
//- Fully contains other boundingBox?
inline bool contains(const boundBox&) const;
inline bool contains(const boundBox& bb) const;
//- Contains point? (inside only)
inline bool containsInside(const point&) const;
inline bool containsInside(const point& pt) const;
//- Contains all of the points? (inside or on edge)
bool contains(const UList<point>&) const;
bool contains(const UList<point>& points) const;
//- Contains all of the points? (inside or on edge)
//- Contains all of the subset of points? (inside or on edge)
bool contains
(
const UList<point>&,
const UList<point>& points,
const labelUList& indices
) const;
//- Contains all of the points? (inside or on edge)
//- Contains all of the subset of points? (inside or on edge)
template<unsigned Size>
bool contains
(
const UList<point>&,
const UList<point>& points,
const FixedList<label, Size>& indices
) const;
//- Contains any of the points? (inside or on edge)
bool containsAny(const UList<point>&) const;
bool containsAny(const UList<point>& points) const;
//- Contains any of the points? (inside or on edge)
//- Contains any of the subset of points? (inside or on edge)
bool containsAny
(
const UList<point>&,
const UList<point>& points,
const labelUList& indices
) const;
//- Contains any of the points? (inside or on edge)
//- Contains any of the subset of points? (inside or on edge)
template<unsigned Size>
bool containsAny
(
const UList<point>&,
const UList<point>& points,
const FixedList<label, Size>& indices
) const;
//- 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&) const;
point nearest(const point& pt) const;
// Member Operators
//- Extend box to include the second box, as per the add() method.
inline void operator+=(const boundBox& bb);
// Friend Operators
inline friend bool operator==(const boundBox&, const boundBox&);
inline friend bool operator!=(const boundBox&, const boundBox&);
inline friend bool operator==(const boundBox& a, const boundBox& b);
inline friend bool operator!=(const boundBox& a, const boundBox& b);
// IOstream operator
friend Istream& operator>>(Istream&, boundBox&);
friend Ostream& operator<<(Ostream&, const boundBox&);
friend Istream& operator>>(Istream& is, boundBox& bb);
friend Ostream& operator<<(Ostream& os, const boundBox& bb);
};
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "boundBox.H"
#include "pointField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......@@ -36,6 +35,13 @@ inline Foam::boundBox::boundBox()
{}