ENH: single/double value reset method for MinMax

- resets min/max to be identical to the specified value,
  which can be more convenient (and slightly more efficient) than doing
  a full reset followed by add()

- additional MinMax intersects() query, which works like overlaps()
  but with exclusive checks at the ends

- provide MinMax::operator&=() to replace (unused) intersect() method

ENH: single/double value reset method for boundBox

- boundBox::operator&=() to replace (rarely used) intersect() method.
  Deprecate boundBox::intersect() to avoid confusion with various
  intersects() method

COMP: provide triangleFwd.H
This commit is contained in:
Mark Olesen
2022-10-17 10:33:24 +02:00
parent c973066646
commit 21f037e3a0
11 changed files with 191 additions and 87 deletions

View File

@ -44,7 +44,7 @@ using namespace Foam;
template<class T> template<class T>
Ostream& printInfo(const MinMax<T>& range) Ostream& printInfo(const MinMax<T>& range)
{ {
Info<< range << " valid=" << range.valid() << " span=" << range.span(); Info<< range << " good=" << range.good() << " span=" << range.span();
return Info; return Info;
} }

View File

@ -44,7 +44,7 @@ using namespace Foam;
template<class T> template<class T>
Ostream& printInfo(const MinMax<T>& range) Ostream& printInfo(const MinMax<T>& range)
{ {
Info<< range << " valid=" << range.valid(); Info<< range << " good=" << range.good();
return Info; return Info;
} }

View File

@ -197,15 +197,6 @@ Foam::boundBox Foam::boundBox::returnReduce(const boundBox& bb)
} }
bool Foam::boundBox::intersect(const boundBox& bb)
{
min_ = ::Foam::max(min_, bb.min_);
max_ = ::Foam::min(max_, bb.max_);
return valid();
}
bool Foam::boundBox::intersects(const plane& pln) const bool Foam::boundBox::intersects(const plane& pln) const
{ {
// Require a full 3D box // Require a full 3D box
@ -290,6 +281,15 @@ Foam::point Foam::boundBox::nearest(const point& p) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::boundBox::operator&=(const boundBox& bb)
{
min_ = ::Foam::max(min_, bb.min_);
max_ = ::Foam::min(max_, bb.max_);
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb) Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)

View File

@ -35,6 +35,9 @@ Note
bounding box. Points can be added later and the bounding box will grow to bounding box. Points can be added later and the bounding box will grow to
include them. include them.
SeeAlso
Foam::treeBoundBox
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Foam_boundBox_H #ifndef Foam_boundBox_H
@ -164,7 +167,10 @@ public:
inline bool empty() const; inline bool empty() const;
//- Bounding box is non-inverted. //- Bounding box is non-inverted.
inline bool valid() const; inline bool good() const;
//- Bounding box is non-inverted - same as good().
bool valid() const { return good(); }
//- Minimum describing the bounding box //- Minimum describing the bounding box
inline const point& min() const noexcept; inline const point& min() const noexcept;
@ -227,6 +233,12 @@ public:
//- Reset to an inverted box //- Reset to an inverted box
inline void reset(); inline void reset();
//- Reset min/max to be identical to the specified point
inline void reset(const point& pt);
//- Reset min/max to specified values
inline void reset(const point& min, const point& max);
//- Same as reset() - reset to an inverted box //- Same as reset() - reset to an inverted box
void clear() { reset(); } void clear() { reset(); }
@ -288,10 +300,6 @@ public:
// Query // Query
//- Intersection (union) with the second box.
// The return value is true if the intersection is non-empty.
bool intersect(const boundBox& bb);
//- Does plane intersect this bounding box. //- Does plane intersect this bounding box.
// There is an intersection if the plane segments the corner points // There is an intersection if the plane segments the corner points
// \note the results are unreliable when plane coincides almost // \note the results are unreliable when plane coincides almost
@ -372,7 +380,11 @@ public:
// Member Operators // Member Operators
//- Restrict min/max to union with other box.
void operator&=(const boundBox& bb);
//- Extend box to include the second box, as per the add() method. //- Extend box to include the second box, as per the add() method.
// Can be used in a reduction operation.
void operator+=(const boundBox& bb) { add(bb); } void operator+=(const boundBox& bb) { add(bb); }
@ -384,6 +396,12 @@ public:
// Housekeeping // Housekeeping
//- Deprecated(2022-10) - use 'operator&=' to avoid confusion with
//- other intersects() methods.
// \deprecated(2022-10) - use 'operator&='
FOAM_DEPRECATED_FOR(2022-10, "boundBox::operator&=(const boundBox&)")
bool intersect(const boundBox& bb) { *this &= bb; return good(); }
//- Identical to centre() //- Identical to centre()
point midpoint() const { return centre(); } point midpoint() const { return centre(); }
}; };

View File

@ -135,30 +135,19 @@ inline Foam::boundBox::boundBox(Istream& is)
inline bool Foam::boundBox::empty() const inline bool Foam::boundBox::empty() const
{ {
// Check each component for max < min // Is empty/invalid if any component has (max < min), ie, !(min <= max)
for (direction dir = 0; dir < vector::nComponents; ++dir) return
{ (
if (max_[dir] < min_[dir]) (max_.x() < min_.x())
{ || (max_.y() < min_.y())
return true; || (max_.z() < min_.z())
} );
}
return false;
} }
inline bool Foam::boundBox::valid() const inline bool Foam::boundBox::good() const
{ {
// Check each component for max < min return !empty();
for (direction dir = 0; dir < vector::nComponents; ++dir)
{
if (max_[dir] < min_[dir])
{
return false;
}
}
return true;
} }
@ -256,6 +245,20 @@ inline void Foam::boundBox::reset()
} }
inline void Foam::boundBox::reset(const point& pt)
{
min_ = pt;
max_ = pt;
}
inline void Foam::boundBox::reset(const point& min, const point& max)
{
min_ = min;
max_ = max;
}
inline void Foam::boundBox::add(const boundBox& bb) inline void Foam::boundBox::add(const boundBox& bb)
{ {
min_ = ::Foam::min(min_, bb.min_); min_ = ::Foam::min(min_, bb.min_);
@ -310,9 +313,9 @@ inline bool Foam::boundBox::overlaps(const boundBox& bb) const
{ {
return return
( (
bb.max_.x() >= min_.x() && bb.min_.x() <= max_.x() min_.x() <= bb.max_.x() && bb.min_.x() <= max_.x()
&& bb.max_.y() >= min_.y() && bb.min_.y() <= max_.y() && min_.y() <= bb.max_.y() && bb.min_.y() <= max_.y()
&& bb.max_.z() >= min_.z() && bb.min_.z() <= max_.z() && min_.z() <= bb.max_.z() && bb.min_.z() <= max_.z()
); );
} }

View File

@ -40,8 +40,8 @@ SourceFiles
#ifndef Foam_triangle_H #ifndef Foam_triangle_H
#define Foam_triangle_H #define Foam_triangle_H
#include "triangleFwd.H"
#include "intersection.H" #include "intersection.H"
#include "point.H"
#include "vector.H" #include "vector.H"
#include "tensor.H" #include "tensor.H"
#include "pointHit.H" #include "pointHit.H"
@ -62,8 +62,6 @@ namespace Foam
// Forward Declarations // Forward Declarations
class plane; class plane;
template<class Point, class PointRef> class triangle;
template<class Point, class PointRef> template<class Point, class PointRef>
inline Istream& operator>>(Istream&, triangle<Point, PointRef>&); inline Istream& operator>>(Istream&, triangle<Point, PointRef>&);
@ -71,12 +69,6 @@ template<class Point, class PointRef>
inline Ostream& operator<<(Ostream&, const triangle<Point, PointRef>&); inline Ostream& operator<<(Ostream&, const triangle<Point, PointRef>&);
// Common Typedefs
//- A triangle using referred points
typedef triangle<point, const point&> triPointRef;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class triPoints Declaration Class triPoints Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 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/>.
Typedef
Foam::triPointRef
Description
A triangle using referred points
\*---------------------------------------------------------------------------*/
#ifndef Foam_triangleFwd_H
#define Foam_triangleFwd_H
#include "point.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
template<class Point, class PointRef> class triangle;
// Common Typedefs
//- A triangle using referred points
typedef triangle<point, const point&> triPointRef;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -202,23 +202,31 @@ public:
//- Range is empty if it is inverted //- Range is empty if it is inverted
inline bool empty() const; inline bool empty() const;
//- Range is valid if it is not inverted //- Range is non-inverted
inline bool valid() const; inline bool good() const;
//- Range is non-inverted
bool valid() const { return good(); }
//- Reset to an inverted (invalid) range //- Reset to an inverted (invalid) range
inline void reset(); inline void reset();
//- Reset min/max to be identical to the specified value
inline void reset(const T& val);
//- Reset min/max to specified values
inline void reset(const T& minVal, const T& maxVal);
//- Same as reset() - reset to an inverted (invalid) range //- Same as reset() - reset to an inverted (invalid) range
void clear() { reset(); } void clear() { reset(); }
// Testing / Query // Testing / Query
//- Intersect (union) with the second range. //- Test if the ranges intersect (exclusive check)
// \return True if the resulting intersection is non-empty. inline bool intersects(const MinMax<T>& b) const;
inline bool intersect(const MinMax<T>& b);
//- Test if the ranges overlap //- Test if ranges overlap/touch (inclusive check)
inline bool overlaps(const MinMax<T>& b) const; inline bool overlaps(const MinMax<T>& b) const;
//- Compares the min/max range with the specified value. //- Compares the min/max range with the specified value.
@ -228,7 +236,7 @@ public:
// - +1: range (min) is greater than value // - +1: range (min) is greater than value
inline int compare(const T& val) const; inline int compare(const T& val) const;
//- True if the value is within the range //- True if the value is within the range (inclusive check)
inline bool contains(const T& val) const; inline bool contains(const T& val) const;
//- If out of range, return the respective min/max limits, otherwise //- If out of range, return the respective min/max limits, otherwise
@ -258,6 +266,9 @@ public:
//- Identical to contains(), for use as a predicate. //- Identical to contains(), for use as a predicate.
inline bool operator()(const T& val) const; inline bool operator()(const T& val) const;
//- Restrict min/max range to union with other range
inline MinMax<T>& operator&=(const MinMax<T>& b);
//- Extend min/max range to include other range //- Extend min/max range to include other range
// Can be used in a reduction operation. // Can be used in a reduction operation.
inline MinMax<T>& operator+=(const MinMax<T>& b); inline MinMax<T>& operator+=(const MinMax<T>& b);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -156,14 +156,15 @@ inline Foam::scalar Foam::MinMax<T>::mag() const
template<class T> template<class T>
inline bool Foam::MinMax<T>::empty() const inline bool Foam::MinMax<T>::empty() const
{ {
// Is empty/invalid if (max < min), ie, !(min <= max)
return (max() < min()); return (max() < min());
} }
template<class T> template<class T>
inline bool Foam::MinMax<T>::valid() const inline bool Foam::MinMax<T>::good() const
{ {
return !(max() < min()); return !empty();
} }
@ -176,12 +177,26 @@ inline void Foam::MinMax<T>::reset()
template<class T> template<class T>
inline bool Foam::MinMax<T>::intersect(const MinMax<T>& b) inline void Foam::MinMax<T>::reset(const T& val)
{ {
min() = ::Foam::max(min(), b.min()); min() = val;
max() = ::Foam::min(max(), b.max()); max() = val;
}
return valid();
template<class T>
inline void Foam::MinMax<T>::reset(const T& minVal, const T& maxVal)
{
min() = minVal;
max() = maxVal;
}
template<class T>
inline bool Foam::MinMax<T>::intersects(const MinMax<T>& b) const
{
const MinMax<T>& a = *this;
return (a.min() < b.max() && b.min() < a.max());
} }
@ -196,7 +211,7 @@ inline bool Foam::MinMax<T>::overlaps(const MinMax<T>& b) const
template<class T> template<class T>
inline int Foam::MinMax<T>::compare(const T& val) const inline int Foam::MinMax<T>::compare(const T& val) const
{ {
if (valid()) if (good())
{ {
if (max() < val) if (max() < val)
{ {
@ -215,14 +230,14 @@ inline int Foam::MinMax<T>::compare(const T& val) const
template<class T> template<class T>
inline bool Foam::MinMax<T>::contains(const T& val) const inline bool Foam::MinMax<T>::contains(const T& val) const
{ {
return (valid() && !compare(val)); return good() && !(val < min() || max() < val);
} }
template<class T> template<class T>
inline const T& Foam::MinMax<T>::clip(const T& val) const inline const T& Foam::MinMax<T>::clip(const T& val) const
{ {
if (valid()) if (good())
{ {
if (val < min()) if (val < min())
{ {
@ -241,7 +256,7 @@ inline const T& Foam::MinMax<T>::clip(const T& val) const
template<class T> template<class T>
inline bool Foam::MinMax<T>::inplaceClip(T& val) const inline bool Foam::MinMax<T>::inplaceClip(T& val) const
{ {
if (valid()) if (good())
{ {
if (val < min()) if (val < min())
{ {
@ -309,7 +324,7 @@ inline bool Foam::MinMax<T>::operator()(const T& val) const
// //
// // Remove overlapping portion, but cannot create a 'hole' in the middle // // Remove overlapping portion, but cannot create a 'hole' in the middle
// //
// if (!a.valid() || !b.valid()) // if (a.empty() || b.empty())
// { // {
// // Invalid range(s): no-op // // Invalid range(s): no-op
// } // }
@ -328,6 +343,16 @@ inline bool Foam::MinMax<T>::operator()(const T& val) const
// } // }
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::operator&=(const MinMax<T>& b)
{
min() = ::Foam::max(min(), b.min());
max() = ::Foam::min(max(), b.max());
return *this;
}
template<class T> template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::operator+=(const MinMax<T>& b) inline Foam::MinMax<T>& Foam::MinMax<T>::operator+=(const MinMax<T>& b)
{ {

View File

@ -32,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef MinMaxOps_H #ifndef Foam_MinMaxOps_H
#define MinMaxOps_H #define Foam_MinMaxOps_H
#include "MinMax.H" #include "MinMax.H"
#include "VectorSpace.H" #include "VectorSpace.H"

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-2021 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -632,10 +632,16 @@ bool Foam::sampledMeshedSurface::update()
// Calculate surface and mesh overlap bounding box // Calculate surface and mesh overlap bounding box
treeBoundBox bb(surface_.points(), surface_.meshPoints()); treeBoundBox bb(surface_.points(), surface_.meshPoints());
// Check for overlap with (global!) mesh bb // Restrict surface to (global!) mesh bound box
const bool intersect = bb.intersect(mesh().bounds()); bb &= mesh().bounds();
if (!intersect) if (bb.good())
{
// Extend a bit
bb.grow(0.5*bb.span());
bb.inflate(1e-6);
}
else
{ {
// Surface and mesh do not overlap at all. Guarantee a valid // Surface and mesh do not overlap at all. Guarantee a valid
// bounding box so we don't get any 'invalid bounding box' errors. // bounding box so we don't get any 'invalid bounding box' errors.
@ -645,20 +651,8 @@ bool Foam::sampledMeshedSurface::update()
<< " does not overlap bounding box of mesh " << mesh().bounds() << " does not overlap bounding box of mesh " << mesh().bounds()
<< endl; << endl;
bb = treeBoundBox(mesh().bounds()); bb.reset(mesh().bounds().centre());
const vector span(bb.span()); bb.grow(1e-6*mesh().bounds().span());
bb.min() += (0.5-1e-6)*span;
bb.max() -= (0.5-1e-6)*span;
}
else
{
// Extend a bit
const vector span(bb.span());
bb.min() -= 0.5*span;
bb.max() += 0.5*span;
bb.inflate(1e-6);
} }
// Mesh search engine, no triangulation of faces. // Mesh search engine, no triangulation of faces.