mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -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());
|
||||
|
||||
forAllConstIter(EdgeMap<label>, existingEdges, iter)
|
||||
if (nUniqEdges < edges_.size())
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user