ENH: improved treeDataPoint subset handling (#1359)

- reverse mapping for the original point ids. This can be useful
  when searching a subset of points, but needing to store access to
  the original point index.

- move constructor.

- Allow use/not-use subset as an optional constructor argument for
  more convenient caller logic.
This commit is contained in:
Mark Olesen
2019-07-08 11:20:44 +02:00
committed by Andrew Heather
parent 84bc1cc8a8
commit b8ccbbdf67
10 changed files with 141 additions and 104 deletions

View File

@ -170,12 +170,7 @@ bool Foam::treeDataEdge::overlaps
const scalar distSqr = sqr(nearHit.distance()); const scalar distSqr = sqr(nearHit.distance());
if (distSqr <= radiusSqr) return (distSqr <= radiusSqr);
{
return true;
}
return false;
} }
@ -191,15 +186,13 @@ void Foam::treeDataEdge::findNearestOp::operator()
{ {
const treeDataEdge& shape = tree_.shapes(); const treeDataEdge& shape = tree_.shapes();
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i];
const edge& e = shape.edges()[shape.edgeLabels()[index]]; const edge& e = shape.edges()[shape.edgeLabels()[index]];
pointHit nearHit = e.line(shape.points()).nearestDist(sample); pointHit nearHit = e.line(shape.points()).nearestDist(sample);
scalar distSqr = sqr(nearHit.distance()); const scalar distSqr = sqr(nearHit.distance());
if (distSqr < nearestDistSqr) if (distSqr < nearestDistSqr)
{ {
@ -227,10 +220,8 @@ void Foam::treeDataEdge::findNearestOp::operator()
// Best so far // Best so far
scalar nearestDistSqr = magSqr(linePoint - nearestPoint); scalar nearestDistSqr = magSqr(linePoint - nearestPoint);
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i];
const edge& e = shape.edges()[shape.edgeLabels()[index]]; const edge& e = shape.edges()[shape.edgeLabels()[index]];
// Note: could do bb test ? Worthwhile? // Note: could do bb test ? Worthwhile?

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation | Copyright (C) 2011-2015 OpenFOAM Foundation
@ -55,13 +55,13 @@ template<class Type> class indexedOctree;
class treeDataEdge class treeDataEdge
{ {
// Static data // Static Data
//- Tolerance on linear dimensions //- Tolerance on linear dimensions
static scalar tol; static scalar tol;
// Private data // Private Data
//- Reference to edgeList //- Reference to edgeList
const edgeList& edges_; const edgeList& edges_;
@ -145,7 +145,8 @@ public:
// Constructors // Constructors
//- Construct from selected edges. !Holds references to edges and points //- Construct from selected edges.
// \note Holds references to edges and points!
treeDataEdge treeDataEdge
( (
const bool cacheBb, const bool cacheBb,
@ -155,7 +156,7 @@ public:
); );
//- Construct from selected edges, transferring contents. //- Construct from selected edges, transferring contents.
// !Holds references to edges and points // \note Holds references to edges and points!
treeDataEdge treeDataEdge
( (
const bool cacheBb, const bool cacheBb,
@ -189,8 +190,8 @@ public:
return edgeLabels_.size(); return edgeLabels_.size();
} }
//- Get representative point cloud for all shapes inside //- Representative point cloud for all shapes inside
// (one point per shape) //- (one point per shape)
pointField shapePoints() const; pointField shapePoints() const;

View File

@ -479,10 +479,8 @@ void Foam::treeDataFace::findNearestOp::operator()
{ {
const treeDataFace& shape = tree_.shapes(); const treeDataFace& shape = tree_.shapes();
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i];
const face& f = shape.mesh().faces()[shape.faceLabels()[index]]; const face& f = shape.mesh().faces()[shape.faceLabels()[index]];
pointHit nearHit = f.nearestPoint(sample, shape.mesh().points()); pointHit nearHit = f.nearestPoint(sample, shape.mesh().points());

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -50,8 +50,6 @@ namespace Foam
{ {
// Forward declaration of classes // Forward declaration of classes
//class primitiveMesh;
//template<class Type> class indexedOctree;
class polyPatch; class polyPatch;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -60,13 +58,13 @@ class polyPatch;
class treeDataFace class treeDataFace
{ {
// Static data // Static Data
//- Tolerance on linear dimensions //- Tolerance on linear dimensions
static scalar tolSqr; static scalar tolSqr;
// Private data // Private Data
const primitiveMesh& mesh_; const primitiveMesh& mesh_;
@ -133,8 +131,8 @@ public:
findIntersectOp(const indexedOctree<treeDataFace>& tree); findIntersectOp(const indexedOctree<treeDataFace>& tree);
//- Calculate intersection of triangle with ray. Sets result //- Calculate intersection of triangle with ray.
// accordingly // Sets result accordingly
bool operator() bool operator()
( (
const label index, const label index,
@ -152,7 +150,6 @@ public:
// Constructors // Constructors
//- Construct from mesh, copying subset of faces //- Construct from mesh, copying subset of faces
//- Construct from mesh and subset of faces.
treeDataFace treeDataFace
( (
const bool cacheBb, const bool cacheBb,
@ -194,8 +191,8 @@ public:
return faceLabels_.size(); return faceLabels_.size();
} }
//- Get representative point cloud for all shapes inside //- Representative point cloud for all shapes inside
// (one point per shape) //- (one point per shape)
pointField shapePoints() const; pointField shapePoints() const;

View File

@ -50,12 +50,26 @@ Foam::treeDataPoint::treeDataPoint(const pointField& points)
Foam::treeDataPoint::treeDataPoint Foam::treeDataPoint::treeDataPoint
( (
const pointField& points, const pointField& points,
const labelList& pointLabels const labelUList& pointLabels,
const bool useSubsetPoints
) )
: :
points_(points), points_(points),
pointLabels_(pointLabels), pointLabels_(pointLabels),
useSubset_(true) useSubset_(useSubsetPoints)
{}
Foam::treeDataPoint::treeDataPoint
(
const pointField& points,
labelList&& pointLabels,
const bool useSubsetPoints
)
:
points_(points),
pointLabels_(std::move(pointLabels)),
useSubset_(useSubsetPoints)
{} {}
@ -104,8 +118,7 @@ bool Foam::treeDataPoint::overlaps
const treeBoundBox& cubeBb const treeBoundBox& cubeBb
) const ) const
{ {
label pointi = (useSubset_ ? pointLabels_[index] : index); return cubeBb.contains(shapePoint(index));
return cubeBb.contains(points_[pointi]);
} }
@ -116,14 +129,7 @@ bool Foam::treeDataPoint::overlaps
const scalar radiusSqr const scalar radiusSqr
) const ) const
{ {
label pointi = (useSubset_ ? pointLabels_[index] : index); return (magSqr(shapePoint(index) - centre) <= radiusSqr);
if (magSqr(points_[pointi] - centre) <= radiusSqr)
{
return true;
}
return false;
} }
@ -139,19 +145,11 @@ void Foam::treeDataPoint::findNearestOp::operator()
{ {
const treeDataPoint& shape = tree_.shapes(); const treeDataPoint& shape = tree_.shapes();
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i]; const point& pt = shape.shapePoint(index);
label pointi =
(
shape.useSubset()
? shape.pointLabels()[index]
: index
);
const point& pt = shape.points()[pointi]; const scalar distSqr = magSqr(pt - sample);
scalar distSqr = magSqr(pt - sample);
if (distSqr < nearestDistSqr) if (distSqr < nearestDistSqr)
{ {
@ -183,23 +181,15 @@ void Foam::treeDataPoint::findNearestOp::operator()
nearestDistSqr = magSqr(linePoint - nearestPoint); nearestDistSqr = magSqr(linePoint - nearestPoint);
} }
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i]; const point& shapePt = shape.shapePoint(index);
label pointi =
(
shape.useSubset()
? shape.pointLabels()[index]
: index
);
const point& shapePt = shape.points()[pointi];
if (tightest.contains(shapePt)) if (tightest.contains(shapePt))
{ {
// Nearest point on line // Nearest point on line
pointHit pHit = ln.nearestDist(shapePt); pointHit pHit = ln.nearestDist(shapePt);
scalar distSqr = sqr(pHit.distance()); const scalar distSqr = sqr(pHit.distance());
if (distSqr < nearestDistSqr) if (distSqr < nearestDistSqr)
{ {

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2013 OpenFOAM Foundation | Copyright (C) 2011-2013 OpenFOAM Foundation
@ -52,16 +52,16 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes // Forward declarations
template<class Type> class indexedOctree; template<class Type> class indexedOctree;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class treeDataPoint Declaration Class treeDataPoint Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class treeDataPoint class treeDataPoint
{ {
// Private data // Private Data
const pointField& points_; const pointField& points_;
@ -110,8 +110,8 @@ public:
findIntersectOp(const indexedOctree<treeDataPoint>& tree); findIntersectOp(const indexedOctree<treeDataPoint>& tree);
//- Calculate intersection of triangle with ray. Sets result //- Calculate intersection of triangle with ray.
// accordingly // Sets result accordingly
bool operator() bool operator()
( (
const label index, const label index,
@ -128,17 +128,45 @@ public:
// Constructors // Constructors
//- Construct from pointField. Holds reference! //- Construct from pointField
treeDataPoint(const pointField&); // \note Holds reference to the points!
explicit treeDataPoint(const pointField& points);
//- Construct from subset of pointField. Holds reference! //- Construct from subset of pointField, copies point ids
treeDataPoint(const pointField&, const labelList&); // \note Holds reference to the points!
treeDataPoint
(
const pointField& points,
const labelUList& pointLabels,
const bool useSubsetPoints = true
);
//- Construct from subset of pointField, moves point ids
// \note Holds reference to the points!
treeDataPoint
(
const pointField& points,
labelList&& pointLabels,
const bool useSubsetPoints = true
);
// Member Functions // Member Functions
// Access // Access
//- An empty effective point field?
inline bool empty() const
{
return
(
useSubset_
? pointLabels_.empty()
: points_.empty()
);
}
//- The effective point field size
inline label size() const inline label size() const
{ {
return return
@ -149,23 +177,48 @@ public:
); );
} }
//- The original point field
inline const pointField& points() const
{
return points_;
}
//- The original point ids
inline const labelList& pointLabels() const inline const labelList& pointLabels() const
{ {
return pointLabels_; return pointLabels_;
} }
const pointField& points() const //- Use a subset of points
{ inline bool useSubset() const
return points_;
}
bool useSubset() const
{ {
return useSubset_; return useSubset_;
} }
//- Get representative point cloud for all shapes inside //- The original (non-subset) point label
// (one point per shape) inline label pointLabel(const label index) const
{
return
(
useSubset_ && index >= 0
? pointLabels_[index]
: index
);
}
//- Point at specified index
inline const point& shapePoint(const label index) const
{
return
(
useSubset_
? points_[pointLabels_[index]]
: points_[index]
);
}
//- Representative point cloud for all shapes inside
//- (one point per shape)
pointField shapePoints() const; pointField shapePoints() const;
@ -175,8 +228,8 @@ public:
// Only makes sense for closed surfaces. // Only makes sense for closed surfaces.
volumeType getVolumeType volumeType getVolumeType
( (
const indexedOctree<treeDataPoint>&, const indexedOctree<treeDataPoint>& os,
const point& const point& sample
) const; ) const;
//- Does (bb of) shape at index overlap bb //- Does (bb of) shape at index overlap bb
@ -193,6 +246,15 @@ public:
const point& centre, const point& centre,
const scalar radiusSqr const scalar radiusSqr
) const; ) const;
// Member Operators
//- The point at the specified index
inline const point& operator[](const label index) const
{
return shapePoint(index);
}
}; };

View File

@ -475,13 +475,12 @@ void Foam::treeDataPrimitivePatch<PatchType>::findNearestOp::operator()
const pointField& points = patch.points(); const pointField& points = patch.points();
forAll(indices, i) for (const label index : indices)
{ {
const label index = indices[i];
const typename PatchType::FaceType& f = patch[index]; const typename PatchType::FaceType& f = patch[index];
pointHit nearHit = f.nearestPoint(sample, points); const pointHit nearHit = f.nearestPoint(sample, points);
scalar distSqr = sqr(nearHit.distance()); const scalar distSqr = sqr(nearHit.distance());
if (distSqr < nearestDistSqr) if (distSqr < nearestDistSqr)
{ {

View File

@ -130,8 +130,8 @@ public:
findIntersectOp(const indexedOctree<treeDataPrimitivePatch>& tree); findIntersectOp(const indexedOctree<treeDataPrimitivePatch>& tree);
//- Calculate intersection of any face with ray. Sets result //- Calculate intersection of any face with ray.
// accordingly. Used to find first intersection. // Sets result accordingly. Used to find first intersection.
bool operator() bool operator()
( (
const label index, const label index,
@ -156,8 +156,8 @@ public:
DynamicList<label>& shapeMask DynamicList<label>& shapeMask
); );
//- Calculate intersection of unique face with ray. Sets result //- Calculate intersection of unique face with ray.
// accordingly. Used to find all faces. // Sets result accordingly. Used to find all faces.
bool operator() bool operator()
( (
const label index, const label index,
@ -182,8 +182,8 @@ public:
const label edgeID const label edgeID
); );
//- Calculate intersection of face with edge of patch. Excludes //- Calculate intersection of face with edge of patch.
// faces that use edgeID. Used to find self intersection. // Excludes faces that use edgeID. Used to find self intersection.
bool operator() bool operator()
( (
const label index, const label index,
@ -214,8 +214,8 @@ public:
return patch_.size(); return patch_.size();
} }
//- Get representative point cloud for all shapes inside //- Representative point cloud for all shapes inside
// (one point per shape) //- (one point per shape)
pointField shapePoints() const; pointField shapePoints() const;
//- Return access to the underlying patch //- Return access to the underlying patch

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation | Copyright (C) 2011-2016 OpenFOAM Foundation
@ -38,7 +38,7 @@ Foam::volumeType Foam::treeDataPrimitivePatch<Foam::triSurface>::getVolumeType
) const ) const
{ {
// Find nearest face to sample // Find nearest face to sample
pointIndexHit info = oc.findNearest(sample, sqr(GREAT)); const pointIndexHit info = oc.findNearest(sample, sqr(GREAT));
if (info.index() == -1) if (info.index() == -1)
{ {
@ -48,9 +48,9 @@ Foam::volumeType Foam::treeDataPrimitivePatch<Foam::triSurface>::getVolumeType
} }
// Get actual intersection point on face // Get actual intersection point on face
label facei = info.index(); const label facei = info.index();
triSurfaceTools::sideType t = triSurfaceTools::surfaceSide const triSurfaceTools::sideType t = triSurfaceTools::surfaceSide
( (
patch_, patch_,
sample, sample,

View File

@ -61,7 +61,6 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //