ENH: searchableSurface: added boundingSphere member function

This commit is contained in:
mattijs 2013-07-19 11:24:50 +01:00
parent 102805befe
commit 68167d2373
16 changed files with 317 additions and 60 deletions

View File

@ -249,6 +249,41 @@ Foam::tmp<Foam::pointField> Foam::searchableBox::coordinates() const
}
void Foam::searchableBox::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(size());
radiusSqr.setSize(size());
radiusSqr = 0.0;
const pointField pts(treeBoundBox::points());
const faceList& fcs = treeBoundBox::faces;
forAll(fcs, i)
{
const face& f = fcs[i];
centres[i] = f.centre(pts);
forAll(f, fp)
{
const point& pt = pts[f[fp]];
radiusSqr[i] = Foam::max
(
radiusSqr[i],
Foam::magSqr(pt-centres[i])
);
}
}
// Add a bit to make sure all points are tested inside
radiusSqr += Foam::sqr(SMALL);
}
Foam::tmp<Foam::pointField> Foam::searchableBox::points() const
{
return treeBoundBox::points();

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -129,6 +129,14 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;

View File

@ -47,6 +47,23 @@ Foam::tmp<Foam::pointField> Foam::searchableCylinder::coordinates() const
}
void Foam::searchableCylinder::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(1);
centres[0] = 0.5*(point1_ + point2_);
radiusSqr.setSize(1);
radiusSqr[0] = Foam::magSqr(point1_-centres[0]) + Foam::sqr(radius_);
// Add a bit to make sure all points are tested inside
radiusSqr += Foam::sqr(SMALL);
}
Foam::tmp<Foam::pointField> Foam::searchableCylinder::points() const
{
tmp<pointField> tPts(new pointField(2));

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -154,6 +154,14 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -134,6 +134,20 @@ const Foam::wordList& Foam::searchablePlane::regions() const
}
void Foam::searchablePlane::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(1);
centres[0] = refPoint();
radiusSqr.setSize(1);
radiusSqr[0] = Foam::sqr(GREAT);
}
void Foam::searchablePlane::findNearest
(
const pointField& samples,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -130,6 +130,15 @@ public:
return tCtrs;
}
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
// Note: radius limited to sqr(GREAT)
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -274,6 +274,71 @@ const Foam::wordList& Foam::searchablePlate::regions() const
}
Foam::tmp<Foam::pointField> Foam::searchablePlate::coordinates() const
{
return tmp<pointField>(new pointField(1, origin_ + 0.5*span_));
}
void Foam::searchablePlate::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(1);
centres[0] = origin_ + 0.5*span_;
radiusSqr.setSize(1);
radiusSqr[0] = Foam::magSqr(0.5*span_);
// Add a bit to make sure all points are tested inside
radiusSqr += Foam::sqr(SMALL);
}
Foam::tmp<Foam::pointField> Foam::searchablePlate::points() const
{
tmp<pointField> tPts(new pointField(4));
pointField& pts = tPts();
pts[0] = origin_;
pts[2] = origin_ + span_;
if (span_.x() < span_.y() && span_.x() < span_.z())
{
pts[1] = origin_ + point(0, span_.y(), 0);
pts[3] = origin_ + point(0, 0, span_.z());
}
else if (span_.y() < span_.z())
{
pts[1] = origin_ + point(span_.x(), 0, 0);
pts[3] = origin_ + point(0, 0, span_.z());
}
else
{
pts[1] = origin_ + point(span_.x(), 0, 0);
pts[3] = origin_ + point(0, span_.y(), 0);
}
return tPts;
}
bool Foam::searchablePlate::overlaps(const boundBox& bb) const
{
return
(
(origin_.x() + span_.x()) >= bb.min().x()
&& origin_.x() <= bb.max().x()
&& (origin_.y() + span_.y()) >= bb.min().y()
&& origin_.y() <= bb.max().y()
&& (origin_.z() + span_.z()) >= bb.min().z()
&& origin_.z() <= bb.max().z()
);
}
void Foam::searchablePlate::findNearest
(
const pointField& samples,

View File

@ -145,53 +145,21 @@ public:
//- Get representative set of element coordinates
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const
{
tmp<pointField> tCtrs(new pointField(1, origin_ + 0.5*span_));
return tCtrs;
}
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const
{
tmp<pointField> tPts(new pointField(4));
pointField& pts = tPts();
pts[0] = origin_;
pts[2] = origin_ + span_;
if (span_.x() < span_.y() && span_.x() < span_.z())
{
pts[1] = origin_ + point(0, span_.y(), 0);
pts[3] = origin_ + point(0, 0, span_.z());
}
else if (span_.y() < span_.z())
{
pts[1] = origin_ + point(span_.x(), 0, 0);
pts[3] = origin_ + point(0, 0, span_.z());
}
else
{
pts[1] = origin_ + point(span_.x(), 0, 0);
pts[3] = origin_ + point(0, span_.y(), 0);
}
return tPts;
}
virtual tmp<pointField> points() const;
//- Does any part of the surface overlap the supplied bound box?
virtual bool overlaps(const boundBox& bb) const
{
return
(
(origin_.x() + span_.x()) >= bb.min().x()
&& origin_.x() <= bb.max().x()
&& (origin_.y() + span_.y()) >= bb.min().y()
&& origin_.y() <= bb.max().y()
&& (origin_.z() + span_.z()) >= bb.min().z()
&& origin_.z() <= bb.max().z()
);
}
virtual bool overlaps(const boundBox& bb) const;
// Multiple point queries.

View File

@ -185,6 +185,23 @@ const Foam::wordList& Foam::searchableSphere::regions() const
void Foam::searchableSphere::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(1);
centres[0] = centre_;
radiusSqr.setSize(1);
radiusSqr[0] = Foam::sqr(radius_);
// Add a bit to make sure all points are tested inside
radiusSqr += Foam::sqr(SMALL);
}
void Foam::searchableSphere::findNearest
(
const pointField& samples,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -60,7 +60,7 @@ private:
//- Centre point
const point centre_;
//- Radius squared
//- Radius
const scalar radius_;
//- Names of regions
@ -139,6 +139,14 @@ public:
return tCtrs;
}
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const
{

View File

@ -190,6 +190,14 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const = 0;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const = 0;
//- Get the points that define the surface.
virtual tmp<pointField> points() const = 0;

View File

@ -354,6 +354,42 @@ Foam::searchableSurfaceCollection::coordinates() const
}
void Foam::searchableSurfaceCollection::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres.setSize(size());
radiusSqr.setSize(centres.size());
// Append individual coordinates
label coordI = 0;
forAll(subGeom_, surfI)
{
scalar maxScale = cmptMax(scale_[surfI]);
pointField subCentres;
scalarField subRadiusSqr;
subGeom_[surfI].boundingSpheres(subCentres, subRadiusSqr);
forAll(subCentres, i)
{
centres[coordI++] = transform_[surfI].globalPosition
(
cmptMultiply
(
subCentres[i],
scale_[surfI]
)
);
radiusSqr[coordI++] = maxScale*subRadiusSqr[i];
}
}
}
Foam::tmp<Foam::pointField>
Foam::searchableSurfaceCollection::points() const
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -176,6 +176,14 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;

View File

@ -156,6 +156,17 @@ public:
return surface().coordinates();
}
//- Get bounding spheres (centre and radius squared), one per element.
// Any point on element is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
surface().boundingSpheres(centres, radiusSqr);
}
//- Get the points that define the surface.
virtual tmp<pointField> points() const
{

View File

@ -145,10 +145,12 @@ bool Foam::triSurfaceMesh::addFaceToEdge
bool Foam::triSurfaceMesh::isSurfaceClosed() const
{
const pointField& pts = triSurface::points();
// Construct pointFaces. Let's hope surface has compact point
// numbering ...
labelListList pointFaces;
invertManyToMany(points()().size(), *this, pointFaces);
invertManyToMany(pts.size(), *this, pointFaces);
// Loop over all faces surrounding point. Count edges emanating from point.
// Every edge should be used by two faces exactly.
@ -241,7 +243,9 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
minQuality_(-1),
surfaceClosed_(-1)
{
bounds() = boundBox(points());
const pointField& pts = triSurface::points();
bounds() = boundBox(pts);
}
@ -287,7 +291,9 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
minQuality_(-1),
surfaceClosed_(-1)
{
bounds() = boundBox(points());
const pointField& pts = triSurface::points();
bounds() = boundBox(pts);
}
@ -347,7 +353,9 @@ Foam::triSurfaceMesh::triSurfaceMesh
triSurface::scalePoints(scaleFactor);
}
bounds() = boundBox(points());
const pointField& pts = triSurface::points();
bounds() = boundBox(pts);
// Have optional minimum quality for normal calculation
if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
@ -393,6 +401,34 @@ Foam::tmp<Foam::pointField> Foam::triSurfaceMesh::coordinates() const
}
void Foam::triSurfaceMesh::boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const
{
centres = coordinates();
radiusSqr.setSize(size());
radiusSqr = 0.0;
const pointField& pts = triSurface::points();
forAll(*this, faceI)
{
const labelledTri& f = triSurface::operator[](faceI);
const point& fc = centres[faceI];
forAll(f, fp)
{
const point& pt = pts[f[fp]];
radiusSqr[faceI] = max(radiusSqr[faceI], Foam::magSqr(fc-pt));
}
}
// Add a bit to make sure all points are tested inside
radiusSqr += Foam::sqr(SMALL);
}
Foam::tmp<Foam::pointField> Foam::triSurfaceMesh::points() const
{
return triSurface::points();
@ -606,6 +642,7 @@ void Foam::triSurfaceMesh::getNormal
) const
{
const triSurface& s = static_cast<const triSurface&>(*this);
const pointField& pts = s.points();
normal.setSize(info.size());
@ -621,9 +658,9 @@ void Foam::triSurfaceMesh::getNormal
if (info[i].hit())
{
label faceI = info[i].index();
normal[i] = s[faceI].normal(points());
normal[i] = s[faceI].normal(pts);
scalar qual = s[faceI].tri(points()).quality();
scalar qual = s[faceI].tri(pts).quality();
if (qual < minQuality_)
{
@ -633,11 +670,11 @@ void Foam::triSurfaceMesh::getNormal
forAll(fFaces, j)
{
label nbrI = fFaces[j];
scalar nbrQual = s[nbrI].tri(points()).quality();
scalar nbrQual = s[nbrI].tri(pts).quality();
if (nbrQual > qual)
{
qual = nbrQual;
normal[i] = s[nbrI].normal(points());
normal[i] = s[nbrI].normal(pts);
}
}
}
@ -662,7 +699,7 @@ void Foam::triSurfaceMesh::getNormal
//normal[i] = faceNormals()[faceI];
//- Uncached
normal[i] = s[faceI].normal(points());
normal[i] = s[faceI].normal(pts);
normal[i] /= mag(normal[i]) + VSMALL;
}
else

View File

@ -187,6 +187,14 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const;
//- Get bounding spheres (centre and radius squared). Any point
// on surface is guaranteed to be inside.
virtual void boundingSpheres
(
pointField& centres,
scalarField& radiusSqr
) const;
//- Get the points that define the surface.
virtual tmp<pointField> points() const;