Skip to content
Snippets Groups Projects
Commit d86b2344 authored by Stefen Guzik's avatar Stefen Guzik
Browse files

- stores sorted order of vertex addresses
- added Equal, Less, and Hash function objects for MFace and MFace*
parent 09139c8e
Branches
Tags
Loading
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
// //
// Please report all bugs and problems to <gmsh@geuz.org>. // Please report all bugs and problems to <gmsh@geuz.org>.
#include <functional>
#include <vector> #include <vector>
#include "MVertex.h" #include "MVertex.h"
#include "SVector3.h" #include "SVector3.h"
#include "Numeric.h" #include "Numeric.h"
#include "Context.h" #include "Context.h"
#include "Hash.h"
extern Context_T CTX; extern Context_T CTX;
...@@ -32,6 +34,8 @@ extern Context_T CTX; ...@@ -32,6 +34,8 @@ extern Context_T CTX;
class MFace { class MFace {
private: private:
MVertex *_v[4]; MVertex *_v[4];
char _si[4]; // sorted indices
public: public:
MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3=0) MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3=0)
{ {
...@@ -49,16 +53,60 @@ class MFace { ...@@ -49,16 +53,60 @@ class MFace {
else{ else{
_v[0] = v0; _v[1] = v1; _v[2] = v2; _v[3] = v3; _v[0] = v0; _v[1] = v1; _v[2] = v2; _v[3] = v3;
} }
// This is simply an unrolled insertion sort (hopefully fast). Note that if
// _v[3] == 0, _v[3] is not sorted.
if(_v[1] < _v[0]) {
_si[0] = 1;
_si[1] = 0;
}
else {
_si[0] = 0;
_si[1] = 1;
}
if(_v[2] < _v[int(_si[1])]) {
_si[2] = _si[1];
if(_v[2] < _v[int(_si[0])]) {
_si[1] = _si[0];
_si[0] = 2;
}
else
_si[1] = 2;
}
else
_si[2] = 2;
if( _v[3] && _v[3] < _v[int(_si[2])]) {
_si[3] = _si[2];
if(_v[3] < _v[int(_si[1])]) {
_si[2] = _si[1];
if(_v[3] < _v[int(_si[0])]) {
_si[1] = _si[0];
_si[0] = 3;
}
else
_si[1] = 3;
}
else
_si[2] = 3;
}
else
_si[3] = 3;
} }
inline int getNumVertices() const { return _v[3] ? 4 : 3; } inline int getNumVertices() const { return _v[3] ? 4 : 3; }
inline MVertex *getVertex(int i) const { return _v[i]; } inline MVertex *getVertex(const int i) const { return _v[i]; }
void getOrderedVertices(std::vector<MVertex*> &verts) inline MVertex *getSortedVertex(const int i) const { return _v[int(_si[i])]; }
void getOrderedVertices(std::vector<MVertex*> &verts) const
{ {
for(int i = 0; i < getNumVertices(); i++) for(int i = 0; i < getNumVertices(); i++)
verts.push_back(getVertex(i)); verts.push_back(getSortedVertex(i));
std::sort(verts.begin(), verts.end()); }
void getOrderedVertices(const MVertex **const verts) const
{
verts[0] = getSortedVertex(0);
verts[1] = getSortedVertex(1);
verts[2] = getSortedVertex(2);
verts[3] = getSortedVertex(3);
} }
SVector3 normal() SVector3 normal() const
{ {
double n[3]; double n[3];
normal3points(_v[0]->x(), _v[0]->y(), _v[0]->z(), normal3points(_v[0]->x(), _v[0]->y(), _v[0]->z(),
...@@ -66,7 +114,7 @@ class MFace { ...@@ -66,7 +114,7 @@ class MFace {
_v[2]->x(), _v[2]->y(), _v[2]->z(), n); _v[2]->x(), _v[2]->y(), _v[2]->z(), n);
return SVector3(n[0], n[1], n[2]); return SVector3(n[0], n[1], n[2]);
} }
SPoint3 barycenter() SPoint3 barycenter() const
{ {
SPoint3 p(0., 0., 0.); SPoint3 p(0., 0., 0.);
int n = getNumVertices(); int n = getNumVertices();
...@@ -83,4 +131,73 @@ class MFace { ...@@ -83,4 +131,73 @@ class MFace {
} }
}; };
//--The following function objects compare the addresses of the mesh vertices.
//--Equal, Less, and a Hash are defined.
struct Equal_Face : public std::binary_function<MFace, MFace, bool> {
bool operator()(const MFace &f1, const MFace &f2) const
{
return (f1.getSortedVertex(0) == f2.getSortedVertex(0) &&
f1.getSortedVertex(1) == f2.getSortedVertex(1) &&
f1.getSortedVertex(2) == f2.getSortedVertex(2) &&
f1.getSortedVertex(3) == f2.getSortedVertex(3));
}
};
struct Equal_FacePtr : public std::binary_function<MFace*, MFace*, bool> {
bool operator()(const MFace *const f1, const MFace *const f2) const
{
return (f1->getSortedVertex(0) == f2->getSortedVertex(0) &&
f1->getSortedVertex(1) == f2->getSortedVertex(1) &&
f1->getSortedVertex(2) == f2->getSortedVertex(2) &&
f1->getSortedVertex(3) == f2->getSortedVertex(3));
}
};
struct Less_Face : public std::binary_function<MFace, MFace, bool> {
bool operator()(const MFace &f1, const MFace &f2) const
{
if(f1.getSortedVertex(0) < f2.getSortedVertex(0)) return true;
if(f1.getSortedVertex(0) > f2.getSortedVertex(0)) return false;
if(f1.getSortedVertex(1) < f2.getSortedVertex(1)) return true;
if(f1.getSortedVertex(1) > f2.getSortedVertex(1)) return false;
if(f1.getSortedVertex(2) < f2.getSortedVertex(2)) return true;
if(f1.getSortedVertex(2) > f2.getSortedVertex(2)) return false;
if(f1.getSortedVertex(3) < f2.getSortedVertex(3)) return true;
return false;
}
};
struct Less_FacePtr : public std::binary_function<MFace*, MFace*, bool> {
bool operator()(const MFace *const f1, const MFace *const f2) const
{
if(f1->getSortedVertex(0) < f2->getSortedVertex(0)) return true;
if(f1->getSortedVertex(0) > f2->getSortedVertex(0)) return false;
if(f1->getSortedVertex(1) < f2->getSortedVertex(1)) return true;
if(f1->getSortedVertex(1) > f2->getSortedVertex(1)) return false;
if(f1->getSortedVertex(2) < f2->getSortedVertex(2)) return true;
if(f1->getSortedVertex(2) > f2->getSortedVertex(2)) return false;
if(f1->getSortedVertex(3) < f2->getSortedVertex(3)) return true;
return false;
}
};
struct Hash_Face : public std::unary_function<MFace, size_t> {
size_t operator()(const MFace &f) const
{
const MVertex *v[4];
f.getOrderedVertices(v);
return HashFNV1a<sizeof(MVertex*[4])>::eval(v);
}
};
struct Hash_FacePtr : public std::unary_function<MFace*, size_t> {
size_t operator()(const MFace *const f) const
{
const MVertex *v[4];
f->getOrderedVertices(v);
return HashFNV1a<sizeof(MVertex*[4])>::eval(v);
}
};
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment