ENH: various enhancements for edge.
- support edge-ordering on construction, and additional methods: - sort(), sorted(), unitVec(), collapse() - null constructor initializes with -1, for consistency with face, triFace and since it is generally much more useful that way. - add some methods that allow edges to used somewhat more like hashes. - count(), found(), insert(), erase() Here is possible way to use that: edge someEdge; // initializes with '-1' for both entries if (someEdge.insert(pt1)) { // added a new point label } ... later // unmark point on edge someEdge.erase(pt2); -- STYLE: - use UList<point> instead of pointField for edge methods for flexibility. The pointField include is retained, however, since many other routines may be relying on it being included via edge.H
This commit is contained in:
parent
32a2a23466
commit
f2304f7c0b
3
applications/test/edges/Make/files
Normal file
3
applications/test/edges/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-edges.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-edges
|
0
applications/test/edges/Make/options
Normal file
0
applications/test/edges/Make/options
Normal file
114
applications/test/edges/Test-edges.C
Normal file
114
applications/test/edges/Test-edges.C
Normal file
@ -0,0 +1,114 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
Test-edges
|
||||
|
||||
Description
|
||||
Simple tests for edges
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "edgeList.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
void printInfo(const edge& e)
|
||||
{
|
||||
Info<< "edge: " << e << " count:" << e.count() << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
edge e1;
|
||||
printInfo(e1);
|
||||
Info<<"has '2'? " << e1.found(2) << endl;
|
||||
|
||||
edge e2(1, 2);
|
||||
printInfo(e2);
|
||||
Info<<"has '2'? " << e2.found(2) << endl;
|
||||
|
||||
edge e3{2, 3};
|
||||
printInfo(e3);
|
||||
Info<<"has '2'? " << e3.found(2) << endl;
|
||||
|
||||
edge e4(4, 4);
|
||||
printInfo(e4);
|
||||
Info<<"has '2'? " << e4.found(2) << endl;
|
||||
|
||||
Info<<"collapse? -> " << e4.collapse() << endl;
|
||||
printInfo(e4);
|
||||
|
||||
Info<< e3 << " connects " << e2 << " => " << e2.connects(e3) << endl;
|
||||
|
||||
Info<< nl << "hash-like functionality" << nl;
|
||||
|
||||
// doesn't work e4 = -1;
|
||||
e4.start() = e4.end() = -1;
|
||||
|
||||
printInfo(e4);
|
||||
for (label i : {2, -1, 2, 1, 4, 1, 2, 3})
|
||||
{
|
||||
bool ok = e4.insert(i);
|
||||
Info<< "insert(" << i << ") = " << ok << " resulting ";
|
||||
printInfo(e4);
|
||||
}
|
||||
|
||||
for (label i : {-1, 0, 1, 3})
|
||||
{
|
||||
bool ok = e4.erase(i);
|
||||
Info<< "erase(" << i << ") = " << ok << " resulting ";
|
||||
printInfo(e4);
|
||||
}
|
||||
|
||||
for (label i : {-1, 0, 1, 3})
|
||||
{
|
||||
bool ok = e4.insert(i);
|
||||
Info<< "insert(" << i << ") = " << ok << " resulting ";
|
||||
printInfo(e4);
|
||||
}
|
||||
e4.flip();
|
||||
Info<< "flipped ";
|
||||
printInfo(e4);
|
||||
|
||||
for (label i : {-1, 0, 1, 3})
|
||||
{
|
||||
bool ok = e4.erase(i);
|
||||
Info<< "erase(" << i << ") = " << ok << " resulting ";
|
||||
printInfo(e4);
|
||||
}
|
||||
|
||||
e4.sort();
|
||||
Info<< "sorted ";
|
||||
printInfo(e4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -70,17 +70,23 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor for lists
|
||||
//- Construct null with invalid point labels (-1)
|
||||
inline edge();
|
||||
|
||||
//- Construct from components
|
||||
inline edge(const label a, const label b);
|
||||
inline edge(const label from, const label to);
|
||||
|
||||
//- Construct, optionally sorted with start less-than end
|
||||
inline edge(const label from, const label to, const bool doSort);
|
||||
|
||||
//- Construct from FixedList
|
||||
inline edge(const FixedList<label, 2>&);
|
||||
inline edge(const FixedList<label, 2>& lst);
|
||||
|
||||
//- Construct, optionally sorted with start less-than end
|
||||
inline edge(const FixedList<label, 2>& lst, const bool doSort);
|
||||
|
||||
//- Construct from Istream
|
||||
inline edge(Istream&);
|
||||
inline edge(Istream& is);
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -97,11 +103,45 @@ public:
|
||||
//- Return end vertex label
|
||||
inline label& end();
|
||||
|
||||
//- Given one vertex, return the other
|
||||
inline label otherVertex(const label a) const;
|
||||
//- Do the edges share a common vertex index?
|
||||
inline bool connects(const edge& other) const;
|
||||
|
||||
//- Return common vertex
|
||||
inline label commonVertex(const edge& a) const;
|
||||
//- Return vertex common with otherEdge or -1 on failure
|
||||
inline label commonVertex(const edge& other) const;
|
||||
|
||||
//- Given one vertex index, return the other one.
|
||||
inline label otherVertex(const label index) const;
|
||||
|
||||
//- 'Collapse' edge by marking duplicate point labels.
|
||||
// Duplicates point labels are marked with '-1'.
|
||||
// (the lower vertex is retained).
|
||||
// Return the collapsed size.
|
||||
inline label collapse();
|
||||
|
||||
//- Return true if point label is found in edge
|
||||
// No special treatment for '-1'.
|
||||
inline bool found(const label index) const;
|
||||
|
||||
//- Return the number of unique, valid (non -1) point labels.
|
||||
// Similar to a HashTable::size().
|
||||
inline label count() const;
|
||||
|
||||
//- Insert the index if it did not previously exist on the edge.
|
||||
// Returns true on success. A negative label never inserts.
|
||||
// Similar to a HashTable::insert().
|
||||
inline bool insert(const label index);
|
||||
|
||||
//- Remove an existing index from the edge and set its location to '-1'.
|
||||
// Returns true on success. A negative label never removes.
|
||||
// Similar to a HashTable::erase().
|
||||
inline bool erase(const label index);
|
||||
|
||||
|
||||
//- True if the edge is sorted such that start is less-than end
|
||||
inline bool sorted() const;
|
||||
|
||||
//- Sort start/end that start is less-than end
|
||||
inline void sort();
|
||||
|
||||
//- Flip the edge in-place.
|
||||
inline void flip();
|
||||
@ -110,23 +150,26 @@ public:
|
||||
inline edge reverseEdge() const;
|
||||
|
||||
//- Return centre (centroid)
|
||||
inline point centre(const pointField&) const;
|
||||
inline point centre(const UList<point>& pts) const;
|
||||
|
||||
//- Return the vector (end - start)
|
||||
inline vector vec(const pointField&) const;
|
||||
inline vector vec(const UList<point>& pts) const;
|
||||
|
||||
//- Return the unit vector (end - start)
|
||||
inline vector unitVec(const UList<point>& pts) const;
|
||||
|
||||
//- Return scalar magnitude
|
||||
inline scalar mag(const pointField&) const;
|
||||
inline scalar mag(const UList<point>& pts) const;
|
||||
|
||||
//- Return edge line
|
||||
inline linePointRef line(const pointField&) const;
|
||||
inline linePointRef line(const UList<point>& pts) const;
|
||||
|
||||
//- Compare edges
|
||||
// Returns:
|
||||
// - 0: different
|
||||
// - +1: identical
|
||||
// - -1: same edge, but different orientation
|
||||
static inline int compare(const edge&, const edge&);
|
||||
static inline int compare(const edge& a, const edge& b);
|
||||
|
||||
|
||||
// Friend Operators
|
||||
|
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,11 +28,6 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// return
|
||||
// - 0: different
|
||||
// - +1: identical
|
||||
// - -1: same edge, but different orientation
|
||||
inline int Foam::edge::compare(const edge& a, const edge& b)
|
||||
{
|
||||
if (a[0] == b[0] && a[1] == b[1])
|
||||
@ -53,20 +48,52 @@ inline int Foam::edge::compare(const edge& a, const edge& b)
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::edge::edge()
|
||||
:
|
||||
FixedList<label, 2>(-1)
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::edge::edge(const label a, const label b)
|
||||
inline Foam::edge::edge(const label from, const label to)
|
||||
{
|
||||
start() = a;
|
||||
end() = b;
|
||||
start() = from;
|
||||
end() = to;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::edge::edge(const FixedList<label, 2>& a)
|
||||
inline Foam::edge::edge(const label from, const label to, const bool doSort)
|
||||
{
|
||||
start() = a[0];
|
||||
end() = a[1];
|
||||
if (doSort && from > to)
|
||||
{
|
||||
start() = to;
|
||||
end() = from;
|
||||
}
|
||||
else
|
||||
{
|
||||
start() = from;
|
||||
end() = to;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline Foam::edge::edge(const FixedList<label, 2>& lst)
|
||||
{
|
||||
start() = lst[0];
|
||||
end() = lst[1];
|
||||
}
|
||||
|
||||
|
||||
inline Foam::edge::edge(const FixedList<label, 2>& lst, const bool doSort)
|
||||
{
|
||||
if (doSort && lst[0] > lst[1])
|
||||
{
|
||||
start() = lst[1];
|
||||
end() = lst[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
start() = lst[0];
|
||||
end() = lst[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -100,13 +127,43 @@ inline Foam::label& Foam::edge::end()
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::edge::otherVertex(const label a) const
|
||||
inline bool Foam::edge::found(const label index) const
|
||||
{
|
||||
if (a == start())
|
||||
return (index == start() || index == end());
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::edge::connects(const edge& other) const
|
||||
{
|
||||
return (other.found(this->start()) || other.found(this->end()));
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::edge::commonVertex(const edge& other) const
|
||||
{
|
||||
if (other.found(this->start()))
|
||||
{
|
||||
return this->start();
|
||||
}
|
||||
else if (other.found(this->end()))
|
||||
{
|
||||
return this->end();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No shared vertex.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::edge::otherVertex(const label index) const
|
||||
{
|
||||
if (index == start())
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else if (a == end())
|
||||
else if (index == end())
|
||||
{
|
||||
return start();
|
||||
}
|
||||
@ -118,20 +175,112 @@ inline Foam::label Foam::edge::otherVertex(const label a) const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::edge::commonVertex(const edge& a) const
|
||||
inline Foam::label Foam::edge::collapse()
|
||||
{
|
||||
if (start() == a.start() || start() == a.end())
|
||||
// Cannot resize FixedList, so mark duplicates with '-1'
|
||||
// (the lower vertex is retained)
|
||||
// catch any '-1' (eg, if called multiple times)
|
||||
|
||||
label n = 2;
|
||||
if (start() == end() || end() == -1)
|
||||
{
|
||||
return start();
|
||||
end() = -1;
|
||||
--n;
|
||||
}
|
||||
else if (end() == a.start() || end() == a.end())
|
||||
if (start() == -1)
|
||||
{
|
||||
return end();
|
||||
--n;
|
||||
}
|
||||
else
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::edge::count() const
|
||||
{
|
||||
label n = 2;
|
||||
if (start() == end() || end() == -1)
|
||||
{
|
||||
// No shared vertex.
|
||||
return -1;
|
||||
--n;
|
||||
}
|
||||
|
||||
if (start() == -1)
|
||||
{
|
||||
--n;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::edge::insert(const label index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
// Can never insert invalid point labels.
|
||||
// Use direct assignment for that.
|
||||
return false;
|
||||
}
|
||||
else if (start() == -1)
|
||||
{
|
||||
// Store at [0], if not duplicate of [1]
|
||||
if (index != end())
|
||||
{
|
||||
start() = index;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (end() == -1)
|
||||
{
|
||||
// Store at [1], if not duplicate of [0]
|
||||
if (index != start())
|
||||
{
|
||||
end() = index;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::edge::erase(const label index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
// Can never remove invalid point labels!
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
if (index == start())
|
||||
{
|
||||
start() = -1;
|
||||
++n;
|
||||
}
|
||||
|
||||
// Automatically handle duplicates, should not have been there anyhow
|
||||
if (index == end())
|
||||
{
|
||||
end() = -1;
|
||||
++n;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::edge::sorted() const
|
||||
{
|
||||
return (start() < end());
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::edge::sort()
|
||||
{
|
||||
if (start() > end())
|
||||
{
|
||||
flip();
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,27 +297,36 @@ inline Foam::edge Foam::edge::reverseEdge() const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::point Foam::edge::centre(const pointField& p) const
|
||||
inline Foam::point Foam::edge::centre(const UList<point>& pts) const
|
||||
{
|
||||
return 0.5*(p[start()] + p[end()]);
|
||||
return 0.5*(pts[start()] + pts[end()]);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::vector Foam::edge::vec(const pointField& p) const
|
||||
inline Foam::vector Foam::edge::vec(const UList<point>& pts) const
|
||||
{
|
||||
return p[end()] - p[start()];
|
||||
return pts[end()] - pts[start()];
|
||||
}
|
||||
|
||||
|
||||
inline Foam::scalar Foam::edge::mag(const pointField& p) const
|
||||
inline Foam::vector Foam::edge::unitVec(const UList<point>& pts) const
|
||||
{
|
||||
return ::Foam::mag(vec(p));
|
||||
Foam::vector v = pts[end()] - pts[start()];
|
||||
v /= ::Foam::mag(v) + VSMALL;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::linePointRef Foam::edge::line(const pointField& p) const
|
||||
inline Foam::scalar Foam::edge::mag(const UList<point>& pts) const
|
||||
{
|
||||
return linePointRef(p[start()], p[end()]);
|
||||
return ::Foam::mag(vec(pts));
|
||||
}
|
||||
|
||||
|
||||
inline Foam::linePointRef Foam::edge::line(const UList<point>& pts) const
|
||||
{
|
||||
return linePointRef(pts[start()], pts[end()]);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user