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
|
\\ / 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.
|
this->mergeEdges();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
@ -209,10 +206,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);
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,7 +512,7 @@ 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();
|
||||||
@ -518,7 +521,7 @@ public:
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user