mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
- allows use with any container with begin(), end() and where the "*iterator" dereference returns a label, which is used for indexing into the list of points. This container could be labelUList, bitSet, labelHashSet, etc
319 lines
7.1 KiB
C
319 lines
7.1 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
|
-------------------------------------------------------------------------------
|
|
License
|
|
This file is part of OpenFOAM.
|
|
|
|
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/>.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "boundBox.H"
|
|
#include "PstreamReduceOps.H"
|
|
#include "tmp.H"
|
|
#include "plane.H"
|
|
|
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
|
|
const Foam::boundBox Foam::boundBox::greatBox
|
|
(
|
|
point::uniform(-ROOTVGREAT),
|
|
point::uniform(ROOTVGREAT)
|
|
);
|
|
|
|
const Foam::boundBox Foam::boundBox::invertedBox
|
|
(
|
|
point::uniform(ROOTVGREAT),
|
|
point::uniform(-ROOTVGREAT)
|
|
);
|
|
|
|
const Foam::faceList Foam::boundBox::faces
|
|
({
|
|
// Point and face order as per hex cellmodel
|
|
face({0, 4, 7, 3}), // 0: x-min, left
|
|
face({1, 2, 6, 5}), // 1: x-max, right
|
|
face({0, 1, 5, 4}), // 2: y-min, bottom
|
|
face({3, 7, 6, 2}), // 3: y-max, top
|
|
face({0, 3, 2, 1}), // 4: z-min, back
|
|
face({4, 5, 6, 7}) // 5: z-max, front
|
|
});
|
|
|
|
const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
|
|
({
|
|
vector(-1, 0, 0), // 0: x-min, left
|
|
vector( 1, 0, 0), // 1: x-max, right
|
|
vector( 0, -1, 0), // 2: y-min, bottom
|
|
vector( 0, 1, 0), // 3: y-max, top
|
|
vector( 0, 0, -1), // 4: z-min, back
|
|
vector( 0, 0, 1) // 5: z-max, front
|
|
});
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
|
|
Foam::boundBox::boundBox(const UList<point>& points, bool doReduce)
|
|
:
|
|
boundBox()
|
|
{
|
|
add(points);
|
|
|
|
if (doReduce)
|
|
{
|
|
reduce();
|
|
}
|
|
}
|
|
|
|
|
|
Foam::boundBox::boundBox(const tmp<pointField>& tpoints, bool doReduce)
|
|
:
|
|
boundBox()
|
|
{
|
|
add(tpoints);
|
|
|
|
if (doReduce)
|
|
{
|
|
reduce();
|
|
}
|
|
}
|
|
|
|
|
|
Foam::boundBox::boundBox
|
|
(
|
|
const UList<point>& points,
|
|
const labelUList& indices,
|
|
bool doReduce
|
|
)
|
|
:
|
|
boundBox()
|
|
{
|
|
add(points, indices);
|
|
|
|
if (doReduce)
|
|
{
|
|
reduce();
|
|
}
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
|
|
Foam::tmp<Foam::pointField> Foam::boundBox::points() const
|
|
{
|
|
auto tpt = tmp<pointField>::New(8);
|
|
auto& pt = tpt.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
|
|
|
|
return tpt;
|
|
}
|
|
|
|
|
|
Foam::tmp<Foam::pointField> Foam::boundBox::faceCentres() const
|
|
{
|
|
auto tpts = tmp<pointField>::New(6);
|
|
auto& pts = tpts.ref();
|
|
|
|
forAll(pts, facei)
|
|
{
|
|
pts[facei] = faceCentre(facei);
|
|
}
|
|
|
|
return tpts;
|
|
}
|
|
|
|
|
|
Foam::point Foam::boundBox::faceCentre(const direction facei) const
|
|
{
|
|
point pt = boundBox::midpoint();
|
|
|
|
if (facei > 5)
|
|
{
|
|
FatalErrorInFunction
|
|
<< "face should be [0..5]"
|
|
<< abort(FatalError);
|
|
}
|
|
|
|
switch (facei)
|
|
{
|
|
case 0: pt.x() = min().x(); break; // 0: x-min, left
|
|
case 1: pt.x() = max().x(); break; // 1: x-max, right
|
|
case 2: pt.y() = min().y(); break; // 2: y-min, bottom
|
|
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
|
|
}
|
|
|
|
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>());
|
|
Foam::reduce(max_, maxOp<point>());
|
|
}
|
|
|
|
|
|
bool Foam::boundBox::intersect(const boundBox& bb)
|
|
{
|
|
min_ = ::Foam::max(min_, bb.min_);
|
|
max_ = ::Foam::min(max_, bb.max_);
|
|
|
|
return !empty();
|
|
}
|
|
|
|
|
|
bool Foam::boundBox::intersects(const plane& pln) const
|
|
{
|
|
// Require a full 3D box
|
|
if (nDim() != 3)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool above = false;
|
|
bool below = false;
|
|
|
|
tmp<pointField> tpts(points());
|
|
const auto& pts = tpts();
|
|
|
|
for (const point& p : pts)
|
|
{
|
|
if (pln.sideOfPlane(p) == plane::FRONT)
|
|
{
|
|
above = true;
|
|
}
|
|
else
|
|
{
|
|
below = true;
|
|
}
|
|
}
|
|
|
|
return (above && below);
|
|
}
|
|
|
|
|
|
bool Foam::boundBox::contains(const UList<point>& points) const
|
|
{
|
|
if (points.empty())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
for (const point& p : points)
|
|
{
|
|
if (!contains(p))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool Foam::boundBox::containsAny(const UList<point>& points) const
|
|
{
|
|
if (points.empty())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
for (const point& p : points)
|
|
{
|
|
if (contains(p))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
Foam::point Foam::boundBox::nearest(const point& pt) 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);
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
|
|
|
|
Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
|
|
{
|
|
if (os.format() == IOstream::ASCII)
|
|
{
|
|
os << bb.min_ << token::SPACE << bb.max_;
|
|
}
|
|
else
|
|
{
|
|
os.write
|
|
(
|
|
reinterpret_cast<const char*>(&bb.min_),
|
|
sizeof(boundBox)
|
|
);
|
|
}
|
|
|
|
os.check(FUNCTION_NAME);
|
|
return os;
|
|
}
|
|
|
|
|
|
Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
|
|
{
|
|
if (is.format() == IOstream::ASCII)
|
|
{
|
|
is >> bb.min_ >> bb.max_;
|
|
}
|
|
else
|
|
{
|
|
is.read
|
|
(
|
|
reinterpret_cast<char*>(&bb.min_),
|
|
sizeof(boundBox)
|
|
);
|
|
}
|
|
|
|
is.check(FUNCTION_NAME);
|
|
return is;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|