-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvertex.cpp
More file actions
80 lines (66 loc) · 2.15 KB
/
vertex.cpp
File metadata and controls
80 lines (66 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2021 Joren Brunekreef, Daniel Nemeth and Andrzej Görlich
#include <vector>
#include <unordered_map>
#include <algorithm>
#include "vertex.hpp"
#include "tetra.hpp"
bool Vertex::neighborsVertex(Vertex::Label v) {
Vertex::Label vc = *this;
if (v == vc) return false;
auto t = tetra;
std::unordered_map<int, bool> done;
done.reserve(v->cnum);
std::vector<Tetra::Label> current = {t};
std::vector<Tetra::Label> next = {};
do {
for (auto tc : current) {
for (auto tcn : tc->tnbr) {
if (!tcn->hasVertex(vc)) continue;
if (done.find(tcn) == done.end()) {
if (tcn->hasVertex(v)) return true;
done[tcn] = true;
next.push_back(tcn);
}
}
}
current = next;
next.clear();
} while (current.size() > 0);
return false;
}
/**
* Returns if the vertex itself forms a triangle with vertices v0 and v1.
* @param startingTetra tetrahedron that contains edge (v0, v1)
* @throw Requires vertex itself, v0, and v1 to be all distinct.
*/
bool Vertex::formsTriangle(Tetra::Label startingTetra, Vertex::Label v0, Vertex::Label v1) {
Vertex::Label vc = *this;
// TODO: Assertions could be removed for optimization
// Assuming a proper simplicial manifold, so triangle required distinct vertices
assert(v0 != vc);
assert(v1 != vc);
assert(v0 != v1);
// Requires startingTetra to contain edge (v0, v1)
assert(startingTetra->hasEdge(v0, v1) && "startingTetra does not contain edge" );
std::unordered_map<int, bool> explored;
explored.reserve(v0->cnum);
std::vector<Tetra::Label> currentBuffer = {startingTetra};
std::vector<Tetra::Label> nextBuffer = {};
// Perform breadth-first search around edge (v0,v1)
do {
for (auto currentTetra : currentBuffer) {
for (auto neighbourTetra : currentTetra->tnbr) {
// Stay around edge (v0, v1)
if (!neighbourTetra->hasEdge(v0, v1)) continue;
// Only explore new tetras
if (explored.find(neighbourTetra) != explored.end()) continue;
if (neighbourTetra->hasVertex(vc)) return true;
explored[neighbourTetra] = true;
nextBuffer.push_back(neighbourTetra);
}
}
currentBuffer = nextBuffer;
nextBuffer.clear();
} while (currentBuffer.size() > 0);
return false;
}