forked from nissmar/VSA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanchors.cpp
183 lines (166 loc) · 5.68 KB
/
anchors.cpp
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "anchors.h"
bool vector_contains(vector<int> v, int key) {
return count(v.begin(), v.end(), key);
}
bool vector_contains(vector<double> v, double key) {
return count(v.begin(), v.end(), key);
}
int find_first_edge(HalfedgeDS he, int v, int r, MatrixXi R) {
int edge = he.getOpposite(he.getEdge(v));
while (R(he.getFace(edge),0)!=r || R(he.getFace(he.getOpposite(edge)),0)==r) {
edge = he.getNext(he.getOpposite(edge));
}
return edge;
}
int find_next_edge(HalfedgeDS he, int edge, int r, MatrixXi R) {
edge = he.getNext(edge);
while (R(he.getFace(he.getOpposite(edge)),0)==r) {
edge = he.getNext(he.getOpposite(edge));
}
return edge;
}
list <int> explore_boundary(HalfedgeDS he, int v, int r, MatrixXi R) {
list <int> bound;
int edge = find_first_edge(he,v,r,R);
int new_v = he.getTarget(edge);
bound.push_back(new_v);
while (new_v != v) {
edge = find_next_edge(he,edge,r,R);
new_v = he.getTarget(edge);
bound.push_back(new_v);
}
return bound;
}
int add_anchors_on_edge(HalfedgeDS he, int anchor, int r, MatrixXi R, MatrixXd V, VectorXi& anchors, MatrixXd Proxies, double treshold) {
// modifies anchors to add anchors on edge
int k = 0; //number of new anchors
// find all anchors of the region R
list<int> anchors_list;
int fedge = find_first_edge(he,anchor,r,R);
int edge = fedge;
int new_anchor = he.getTarget(edge);
while (new_anchor != anchor) {
if (anchors(new_anchor)==1) anchors_list.push_back(new_anchor);
edge = find_next_edge(he,edge,r,R);
new_anchor = he.getTarget(edge);
}
anchors_list.push_back(anchor);
// go through each pair of anchor
edge = fedge;
int r2;
while (!anchors_list.empty()) {
new_anchor = anchors_list.front();
anchors_list.pop_front();
int new_v = he.getTarget(edge);
double max_d = 0;
int max_v = -1;
while (new_v!= new_anchor) {
edge = find_next_edge(he,edge,r,R);
r2 = R(he.getFace(he.getOpposite(edge)),0);
new_v = he.getTarget(edge);
double dist = distance_projection(V, Proxies, anchor, new_anchor,new_v,r,r2);
if (dist>max_d) {
max_d = dist;
max_v = new_v;
}
}
if (max_d>treshold) { // treshold
anchors(max_v) = 1;
k++;
}
anchor = new_anchor;
}
return k;
}
vector<int> find_anchors_on_region(HalfedgeDS he, int anchor, int r, MatrixXi R, VectorXi anchors) {
// modifies anchors to add anchors on edge
int k = 0; //number of new anchors
// find all anchors of the region R
vector<int> anchors_vector;
anchors_vector.push_back(anchor);
int fedge = find_first_edge(he,anchor,r,R);
int edge = fedge;
int new_anchor = he.getTarget(edge);
while (new_anchor != anchor) {
if (anchors(new_anchor)==1) {
anchors_vector.push_back(new_anchor);
}
edge = find_next_edge(he,edge,r,R);
new_anchor = he.getTarget(edge);
}
return anchors_vector;
}
vector<int> find_vertex_proxies(HalfedgeDS he, int v, MatrixXi R) {
vector<int> vp;
int proxy;
int edge = he.getEdge(v);
proxy = R(he.getFace(edge),0);
vp.push_back(proxy);
int pedge = he.getOpposite(he.getNext(edge));
while (pedge != edge) {
proxy = R(he.getFace(pedge),0);
if (!vector_contains(vp,proxy)) {
vp.push_back(proxy);
}
pedge = he.getOpposite(he.getNext(pedge));
}
return vp;
}
vector<vector<int>> anchor_points(HalfedgeDS he, MatrixXi R, MatrixXd V, MatrixXd Proxies, double treshold) {
int n = V.rows();
int p = Proxies.rows()/2;
vector<vector<int>> vertex_proxies(n); //list of proxies
VectorXi anchors;
VectorXi seen;
seen.setZero(p);
anchors.setZero(n);
int k=0; // number of anchors
// find for each vertex its list of proxies
for (int i=0;i<n;i++) {
vertex_proxies[i] = find_vertex_proxies(he,i,R);
// add anchor if vertex has 3+ proxies
if (vertex_proxies[i].size()>2) {
anchors(i) = 1;
k++;
}
}
// add anchors between existing ones
int r,kv;
for (int i=0;i<n;i++) {
if (vertex_proxies[i].size()>2) {
// to show the max deviation
for(size_t m = 0; m < vertex_proxies[i].size(); m++) {
r = vertex_proxies[i][m];
if (seen(r)==0) {
seen(r)=1;
kv = add_anchors_on_edge(he,i,r,R,V,anchors, Proxies,treshold);
while (kv>0) {
k += kv;
kv = add_anchors_on_edge(he,i,r,R,V,anchors, Proxies,treshold);
}
}
}
}
}
seen.setZero(p);
// return list of polygons
vector<vector<int>> polys_anchors;
vector<int> void_vector;
for (int i=0;i<p;i++) polys_anchors.push_back(void_vector);
for (int i=0;i<n;i++) {
if (vertex_proxies[i].size()>2) {
for(size_t m = 0; m < vertex_proxies[i].size(); m++) {
r = vertex_proxies[i][m];
// if (seen(r)==0) {
// seen(r)=1;
// polys_anchors[r] = find_anchors_on_region(he,i,r,R,anchors);
// }
if (!vector_contains(polys_anchors[r],i)) {
vector<int> new_anchors = find_anchors_on_region(he,i,r,R,anchors);
polys_anchors[r].insert( polys_anchors[r].end(), new_anchors.begin(), new_anchors.end() );
}
}
}
}
return polys_anchors;
}