Commit 32a2a234 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

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

- filter out degenerate edges
- remove unused points

STYLE: remove unused mergePoints() parameter

STYLE: doxygen for edgeMesh
parent 89f2eff5
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -29,6 +29,7 @@ License
#include "addToMemberFunctionSelectionTable.H"
#include "ListOps.H"
#include "EdgeMap.H"
#include "PackedBoolList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -286,16 +287,12 @@ void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
}
void Foam::edgeMesh::mergePoints
(
const scalar mergeDist,
labelList& reversePointMap
)
void Foam::edgeMesh::mergePoints(const scalar mergeDist)
{
pointField newPoints;
labelList pointMap;
bool hasMerged = Foam::mergePoints
const bool hasMerged = Foam::mergePoints
(
points_,
mergeDist,
......@@ -307,92 +304,107 @@ void Foam::edgeMesh::mergePoints
if (hasMerged)
{
pointEdgesPtr_.clear();
pointEdgesPtr_.clear(); // connectivity change
points_.transfer(newPoints);
// connectivity changed
pointEdgesPtr_.clear();
// Renumber and make sure e[0] < e[1] (not really necessary)
forAll(edges_, edgeI)
{
edge& e = edges_[edgeI];
label p0 = pointMap[e[0]];
label p1 = 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();
e[0] = pointMap[e[0]];
e[1] = pointMap[e[1]];
}
}
this->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)
{
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)
{
Info<< "Merging duplicate edges: "
<< edges_.size() - existingEdges.size()
<< " edges will be deleted." << endl;
<< (edges_.size() - nUniqEdges)
<< " edges will be deleted, "
<< (points_.size() - nUniqPoints)
<< " unused points will be removed." << endl;
}
edges_.setSize(existingEdges.size());
if (nUniqEdges < edges_.size())
{
pointEdgesPtr_.clear(); // connectivity change
edges_.setSize(nUniqEdges); // truncate
}
forAllConstIter(EdgeMap<label>, existingEdges, iter)
if (nUniqPoints < points_.size())
{
edges_[iter()] = iter.key();
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();
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -59,8 +59,8 @@ class Ostream;
// Forward declaration of friend functions and operators
class edgeMesh;
Istream& operator>>(Istream&, edgeMesh&);
Ostream& operator<<(Ostream&, const edgeMesh&);
Istream& operator>>(Istream& is, edgeMesh& em);
Ostream& operator<<(Ostream& os, const edgeMesh& em);
/*---------------------------------------------------------------------------*\
......@@ -108,7 +108,7 @@ public:
// Static
//- 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?
static bool canReadType(const word& ext, const bool verbose=false);
......@@ -126,26 +126,23 @@ public:
edgeMesh();
//- Construct from components
edgeMesh(const pointField&, const edgeList&);
edgeMesh(const pointField& points, const edgeList& edges);
//- Construct by transferring components (points, edges).
edgeMesh
(
const Xfer<pointField>&,
const Xfer<edgeList>&
const Xfer<pointField>& pointLst,
const Xfer<edgeList>& edgeLst
);
//- Construct as copy
edgeMesh(const edgeMesh&);
edgeMesh(const edgeMesh& em);
//- 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)
edgeMesh(const fileName&, const word& ext);
//- Construct from Istream
edgeMesh(Istream&);
edgeMesh(const fileName& name, const word& ext);
// Declare run-time constructor selection table
......@@ -167,12 +164,12 @@ public:
//- Select constructed from filename (explicit extension)
static autoPtr<edgeMesh> New
(
const fileName&,
const fileName& name,
const word& ext
);
//- Select constructed from filename (implicit extension)
static autoPtr<edgeMesh> New(const fileName&);
static autoPtr<edgeMesh> New(const fileName& name);
//- Destructor
......@@ -195,7 +192,7 @@ public:
);
//- Write to file
static void write(const fileName&, const edgeMesh&);
static void write(const fileName& name, const edgeMesh& mesh);
// Member Functions
......@@ -204,15 +201,15 @@ public:
void transfer(edgeMesh&);
//- Transfer contents to the Xfer container
Xfer<edgeMesh > xfer();
Xfer<edgeMesh> xfer();
// Read
//- 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
virtual bool read(const fileName&);
virtual bool read(const fileName& name);
// Access
......@@ -245,13 +242,13 @@ public:
);
//- 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
// old to new points.
virtual void mergePoints(const scalar mergeDist, labelList&);
//- Geometric merge points (points within mergeDist) prior to
// automatically calling mergeEdges().
virtual void mergePoints(const scalar mergeDist);
//- Merge duplicate edges
//- Merge duplicate edges and eliminate unused points.
virtual void mergeEdges();
......@@ -268,12 +265,12 @@ public:
// Member Operators
inline void operator=(const edgeMesh&);
inline void operator=(const edgeMesh& rhs);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const edgeMesh&);
friend Istream& operator>>(Istream&, edgeMesh&);
friend Ostream& operator<<(Ostream& os, const edgeMesh& em);
friend Istream& operator>>(Istream& is, edgeMesh& em);
};
......
......@@ -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
(
const Xfer<pointField>& pointLst,
......
......@@ -250,7 +250,7 @@ public:
static label nEdgeTypes;
//- 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?
static bool canReadType(const word& ext, const bool verbose=false);
......@@ -268,7 +268,7 @@ public:
extendedEdgeMesh();
//- Construct as copy
explicit extendedEdgeMesh(const extendedEdgeMesh&);
explicit extendedEdgeMesh(const extendedEdgeMesh& fem);
//- Construct from file name (uses extension to determine type)
extendedEdgeMesh(const fileName&);
......@@ -277,13 +277,16 @@ public:
extendedEdgeMesh(const fileName&, const word& ext);
//- Construct from Istream
extendedEdgeMesh(Istream&);
extendedEdgeMesh(Istream& is);
//- Construct from components
extendedEdgeMesh(const pointField& points, const edgeList& edges);
//- Construct by transferring components (points, edges)
extendedEdgeMesh
(
const Xfer<pointField>&,
const Xfer<edgeList>&
const Xfer<pointField>& pointLst,
const Xfer<edgeList>& edgeLst
);
//- Construct given a surface with selected edges,points
......@@ -346,12 +349,12 @@ public:
//- Select constructed from filename (explicit extension)
static autoPtr<extendedEdgeMesh> New
(
const fileName&,
const fileName& name,
const word& ext
);
//- Select constructed from filename (implicit extension)
static autoPtr<extendedEdgeMesh> New(const fileName&);
static autoPtr<extendedEdgeMesh> New(const fileName& name);
//- Destructor
......@@ -509,16 +512,16 @@ public:
// Edit
//- Transfer the contents of the argument and annul the argument
void transfer(extendedEdgeMesh&);
void transfer(extendedEdgeMesh& mesh);
//- Transfer contents to the Xfer container
Xfer<extendedEdgeMesh > xfer();
Xfer<extendedEdgeMesh> xfer();
//- Clear all storage
virtual void clear();
//- Add extendedEdgeMesh. No filtering of duplicates.
void add(const extendedEdgeMesh&);
void add(const extendedEdgeMesh& fem);
//- Flip normals. All concave become convex, all internal external
// etc.
......@@ -527,8 +530,8 @@ public:
//- Update with derived geometry
void autoMap
(
const pointField&,
const edgeList&,
const pointField& subPoints,
const edgeList& subEdges,
const labelList& pointMap,
const labelList& edgeMap
);
......@@ -565,10 +568,10 @@ public:
// Read
//- 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
virtual bool read(const fileName&);
virtual bool read(const fileName& name);
// Write
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment