ENH: enhancements for edgeMesh mergeEdges(), mergePoints()

- filter out degenerate edges
- remove unused points

STYLE: remove unused mergePoints() parameter

STYLE: doxygen for edgeMesh
This commit is contained in:
Mark Olesen
2017-04-21 02:34:37 +02:00
parent 89f2eff565
commit 32a2a23466
4 changed files with 143 additions and 103 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,6 +29,7 @@ License
#include "addToMemberFunctionSelectionTable.H" #include "addToMemberFunctionSelectionTable.H"
#include "ListOps.H" #include "ListOps.H"
#include "EdgeMap.H" #include "EdgeMap.H"
#include "PackedBoolList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -286,16 +287,12 @@ void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
} }
void Foam::edgeMesh::mergePoints void Foam::edgeMesh::mergePoints(const scalar mergeDist)
(
const scalar mergeDist,
labelList& reversePointMap
)
{ {
pointField newPoints; pointField newPoints;
labelList pointMap; labelList pointMap;
bool hasMerged = Foam::mergePoints const bool hasMerged = Foam::mergePoints
( (
points_, points_,
mergeDist, mergeDist,
@ -307,92 +304,107 @@ void Foam::edgeMesh::mergePoints
if (hasMerged) if (hasMerged)
{ {
pointEdgesPtr_.clear(); pointEdgesPtr_.clear(); // connectivity change
points_.transfer(newPoints); points_.transfer(newPoints);
// connectivity changed
pointEdgesPtr_.clear();
// Renumber and make sure e[0] < e[1] (not really necessary)
forAll(edges_, edgeI) forAll(edges_, edgeI)
{ {
edge& e = edges_[edgeI]; edge& e = edges_[edgeI];
label p0 = pointMap[e[0]]; e[0] = pointMap[e[0]];
label p1 = pointMap[e[1]]; e[1] = pointMap[e[1]];
if (p0 < p1)
{
e[0] = p0;
e[1] = p1;
}
else
{
e[0] = p1;
e[1] = p0;
}
}
// Compact using a hashtable and commutative hash of edge.
EdgeMap<label> edgeToLabel(2*edges_.size());
label newEdgeI = 0;
forAll(edges_, edgeI)
{
const edge& e = edges_[edgeI];
if (e[0] != e[1])
{
if (edgeToLabel.insert(e, newEdgeI))
{
newEdgeI++;
}
}
}
edges_.setSize(newEdgeI);
forAllConstIter(EdgeMap<label>, edgeToLabel, iter)
{
edges_[iter()] = iter.key();
} }
} }
this->mergeEdges();
} }
void Foam::edgeMesh::mergeEdges() void Foam::edgeMesh::mergeEdges()
{ {
EdgeMap<label> existingEdges(2*edges_.size()); HashSet<edge, Hash<edge>> uniqEdges(2*edges_.size());
PackedBoolList pointIsUsed(points_.size());
label curEdgeI = 0; label nUniqEdges = 0;
label nUniqPoints = 0;
forAll(edges_, edgeI) forAll(edges_, edgeI)
{ {
const edge& e = edges_[edgeI]; const edge& e = edges_[edgeI];
if (existingEdges.insert(e, curEdgeI)) // Remove degenerate and repeated edges
// - reordering (e[0] < e[1]) is not really necessary
if (e[0] != e[1] && uniqEdges.insert(e))
{ {
curEdgeI++; if (nUniqEdges != edgeI)
{
edges_[nUniqEdges] = e;
}
edges_[nUniqEdges].sort();
++nUniqEdges;
if (pointIsUsed.set(e[0], 1))
{
++nUniqPoints;
}
if (pointIsUsed.set(e[1], 1))
{
++nUniqPoints;
}
} }
} }
if (debug) if (debug)
{ {
Info<< "Merging duplicate edges: " Info<< "Merging duplicate edges: "
<< edges_.size() - existingEdges.size() << (edges_.size() - nUniqEdges)
<< " edges will be deleted." << endl; << " edges will be deleted, "
<< (points_.size() - nUniqPoints)
<< " unused points will be removed." << endl;
} }
edges_.setSize(existingEdges.size()); if (nUniqEdges < edges_.size())
forAllConstIter(EdgeMap<label>, existingEdges, iter)
{ {
edges_[iter()] = iter.key(); pointEdgesPtr_.clear(); // connectivity change
edges_.setSize(nUniqEdges); // truncate
}
if (nUniqPoints < points_.size())
{
pointEdgesPtr_.clear(); // connectivity change
// build a oldToNew point-map and rewrite the points.
// We can do this simultaneously since the point order is unchanged
// and we are only effectively eliminating some entries.
labelList pointMap(points_.size(), -1);
label newId = 0;
forAll(pointMap, pointi)
{
if (pointIsUsed[pointi])
{
pointMap[pointi] = newId;
if (newId < pointi)
{
// copy down
points_[newId] = points_[pointi];
}
++newId;
}
}
points_.setSize(newId);
// Renumber edges - already sorted (above)
forAll(edges_, edgeI)
{
edge& e = edges_[edgeI];
e[0] = pointMap[e[0]];
e[1] = pointMap[e[1]];
}
} }
// connectivity changed
pointEdgesPtr_.clear();
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,8 +59,8 @@ class Ostream;
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
class edgeMesh; class edgeMesh;
Istream& operator>>(Istream&, edgeMesh&); Istream& operator>>(Istream& is, edgeMesh& em);
Ostream& operator<<(Ostream&, const edgeMesh&); Ostream& operator<<(Ostream& os, const edgeMesh& em);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -108,7 +108,7 @@ public:
// Static // Static
//- Can we read this file format? //- Can we read this file format?
static bool canRead(const fileName&, const bool verbose=false); static bool canRead(const fileName& name, const bool verbose=false);
//- Can we read this file format? //- Can we read this file format?
static bool canReadType(const word& ext, const bool verbose=false); static bool canReadType(const word& ext, const bool verbose=false);
@ -126,26 +126,23 @@ public:
edgeMesh(); edgeMesh();
//- Construct from components //- Construct from components
edgeMesh(const pointField&, const edgeList&); edgeMesh(const pointField& points, const edgeList& edges);
//- Construct by transferring components (points, edges). //- Construct by transferring components (points, edges).
edgeMesh edgeMesh
( (
const Xfer<pointField>&, const Xfer<pointField>& pointLst,
const Xfer<edgeList>& const Xfer<edgeList>& edgeLst
); );
//- Construct as copy //- Construct as copy
edgeMesh(const edgeMesh&); edgeMesh(const edgeMesh& em);
//- Construct from file name (uses extension to determine type) //- Construct from file name (uses extension to determine type)
edgeMesh(const fileName&); edgeMesh(const fileName& name);
//- Construct from file name (uses extension to determine type) //- Construct from file name (uses extension to determine type)
edgeMesh(const fileName&, const word& ext); edgeMesh(const fileName& name, const word& ext);
//- Construct from Istream
edgeMesh(Istream&);
// Declare run-time constructor selection table // Declare run-time constructor selection table
@ -167,12 +164,12 @@ public:
//- Select constructed from filename (explicit extension) //- Select constructed from filename (explicit extension)
static autoPtr<edgeMesh> New static autoPtr<edgeMesh> New
( (
const fileName&, const fileName& name,
const word& ext const word& ext
); );
//- Select constructed from filename (implicit extension) //- Select constructed from filename (implicit extension)
static autoPtr<edgeMesh> New(const fileName&); static autoPtr<edgeMesh> New(const fileName& name);
//- Destructor //- Destructor
@ -195,7 +192,7 @@ public:
); );
//- Write to file //- Write to file
static void write(const fileName&, const edgeMesh&); static void write(const fileName& name, const edgeMesh& mesh);
// Member Functions // Member Functions
@ -204,15 +201,15 @@ public:
void transfer(edgeMesh&); void transfer(edgeMesh&);
//- Transfer contents to the Xfer container //- Transfer contents to the Xfer container
Xfer<edgeMesh > xfer(); Xfer<edgeMesh> xfer();
// Read // Read
//- Read from file. Chooses reader based on explicit extension //- Read from file. Chooses reader based on explicit extension
bool read(const fileName&, const word& ext); bool read(const fileName& name, const word& ext);
//- Read from file. Chooses reader based on detected extension //- Read from file. Chooses reader based on detected extension
virtual bool read(const fileName&); virtual bool read(const fileName& name);
// Access // Access
@ -245,13 +242,13 @@ public:
); );
//- Scale points. A non-positive factor is ignored //- Scale points. A non-positive factor is ignored
virtual void scalePoints(const scalar); virtual void scalePoints(const scalar scaleFactor);
//- Merge common points (points within mergeDist). Return map from //- Geometric merge points (points within mergeDist) prior to
// old to new points. // automatically calling mergeEdges().
virtual void mergePoints(const scalar mergeDist, labelList&); virtual void mergePoints(const scalar mergeDist);
//- Merge duplicate edges //- Merge duplicate edges and eliminate unused points.
virtual void mergeEdges(); virtual void mergeEdges();
@ -268,12 +265,12 @@ public:
// Member Operators // Member Operators
inline void operator=(const edgeMesh&); inline void operator=(const edgeMesh& rhs);
// Ostream Operator // Ostream Operator
friend Ostream& operator<<(Ostream&, const edgeMesh&); friend Ostream& operator<<(Ostream& os, const edgeMesh& em);
friend Istream& operator>>(Istream&, edgeMesh&); friend Istream& operator>>(Istream& is, edgeMesh& em);
}; };

View File

@ -454,6 +454,34 @@ Foam::extendedEdgeMesh::extendedEdgeMesh(Istream& is)
} }
Foam::extendedEdgeMesh::extendedEdgeMesh
(
const pointField& points,
const edgeList& edges
)
:
edgeMesh(points, edges),
concaveStart_(0),
mixedStart_(0),
nonFeatureStart_(0),
internalStart_(0),
flatStart_(0),
openStart_(0),
multipleStart_(0),
normals_(0),
normalVolumeTypes_(0),
edgeDirections_(0),
normalDirections_(0),
edgeNormals_(0),
featurePointNormals_(0),
featurePointEdges_(0),
regionEdges_(0),
pointTree_(),
edgeTree_(),
edgeTreesByType_()
{}
Foam::extendedEdgeMesh::extendedEdgeMesh Foam::extendedEdgeMesh::extendedEdgeMesh
( (
const Xfer<pointField>& pointLst, const Xfer<pointField>& pointLst,

View File

@ -250,7 +250,7 @@ public:
static label nEdgeTypes; static label nEdgeTypes;
//- Can we read this file format? //- Can we read this file format?
static bool canRead(const fileName&, const bool verbose=false); static bool canRead(const fileName& name, const bool verbose=false);
//- Can we read this file format? //- Can we read this file format?
static bool canReadType(const word& ext, const bool verbose=false); static bool canReadType(const word& ext, const bool verbose=false);
@ -268,7 +268,7 @@ public:
extendedEdgeMesh(); extendedEdgeMesh();
//- Construct as copy //- Construct as copy
explicit extendedEdgeMesh(const extendedEdgeMesh&); explicit extendedEdgeMesh(const extendedEdgeMesh& fem);
//- Construct from file name (uses extension to determine type) //- Construct from file name (uses extension to determine type)
extendedEdgeMesh(const fileName&); extendedEdgeMesh(const fileName&);
@ -277,13 +277,16 @@ public:
extendedEdgeMesh(const fileName&, const word& ext); extendedEdgeMesh(const fileName&, const word& ext);
//- Construct from Istream //- Construct from Istream
extendedEdgeMesh(Istream&); extendedEdgeMesh(Istream& is);
//- Construct from components
extendedEdgeMesh(const pointField& points, const edgeList& edges);
//- Construct by transferring components (points, edges) //- Construct by transferring components (points, edges)
extendedEdgeMesh extendedEdgeMesh
( (
const Xfer<pointField>&, const Xfer<pointField>& pointLst,
const Xfer<edgeList>& const Xfer<edgeList>& edgeLst
); );
//- Construct given a surface with selected edges,points //- Construct given a surface with selected edges,points
@ -346,12 +349,12 @@ public:
//- Select constructed from filename (explicit extension) //- Select constructed from filename (explicit extension)
static autoPtr<extendedEdgeMesh> New static autoPtr<extendedEdgeMesh> New
( (
const fileName&, const fileName& name,
const word& ext const word& ext
); );
//- Select constructed from filename (implicit extension) //- Select constructed from filename (implicit extension)
static autoPtr<extendedEdgeMesh> New(const fileName&); static autoPtr<extendedEdgeMesh> New(const fileName& name);
//- Destructor //- Destructor
@ -509,16 +512,16 @@ public:
// Edit // Edit
//- Transfer the contents of the argument and annul the argument //- Transfer the contents of the argument and annul the argument
void transfer(extendedEdgeMesh&); void transfer(extendedEdgeMesh& mesh);
//- Transfer contents to the Xfer container //- Transfer contents to the Xfer container
Xfer<extendedEdgeMesh > xfer(); Xfer<extendedEdgeMesh> xfer();
//- Clear all storage //- Clear all storage
virtual void clear(); virtual void clear();
//- Add extendedEdgeMesh. No filtering of duplicates. //- Add extendedEdgeMesh. No filtering of duplicates.
void add(const extendedEdgeMesh&); void add(const extendedEdgeMesh& fem);
//- Flip normals. All concave become convex, all internal external //- Flip normals. All concave become convex, all internal external
// etc. // etc.
@ -527,8 +530,8 @@ public:
//- Update with derived geometry //- Update with derived geometry
void autoMap void autoMap
( (
const pointField&, const pointField& subPoints,
const edgeList&, const edgeList& subEdges,
const labelList& pointMap, const labelList& pointMap,
const labelList& edgeMap const labelList& edgeMap
); );
@ -565,10 +568,10 @@ public:
// Read // Read
//- Read from file. Chooses reader based on explicit extension //- Read from file. Chooses reader based on explicit extension
bool read(const fileName&, const word& ext); bool read(const fileName& name, const word& ext);
//- Read from file. Chooses reader based on detected extension //- Read from file. Chooses reader based on detected extension
virtual bool read(const fileName&); virtual bool read(const fileName& name);
// Write // Write