Subversion Repositories gelsvn

Rev

Rev 24 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 24 Rev 26
1
#include <queue>
1
#include <queue>
2
#include <vector>
2
#include <vector>
3
 
3
 
4
#include "triangulate.h"
4
#include "triangulate.h"
5
#include "HMesh/VertexCirculator.h"
5
#include "HMesh/VertexCirculator.h"
6
#include "HMesh/FaceCirculator.h"
6
#include "HMesh/FaceCirculator.h"
7
 
7
 
8
using namespace std;
8
using namespace std;
9
using namespace CGLA;
9
using namespace CGLA;
10
using namespace HMesh;
10
using namespace HMesh;
11
 
11
 
12
namespace HMeshUtil
12
namespace HMeshUtil
13
{
13
{
14
  void get_candidates(const VertexIter& v,
14
  void get_candidates(const VertexIter& v,
15
											vector<HalfEdgeIter>& candidates)
15
											vector<HalfEdgeIter>& candidates)
16
											
16
											
17
											
17
											
18
  {
18
  {
19
    vector<VertexIter> vertices;
19
    vector<VertexIter> vertices;
20
    vector<HalfEdgeIter> hedges;
20
    vector<HalfEdgeIter> hedges;
21
						
21
						
22
    VertexCirculator vc(v);
22
    VertexCirculator vc(v);
23
    for(;!vc.end();++vc)
23
    for(;!vc.end();++vc)
24
      {
24
      {
25
				vertices.push_back(vc.get_vertex());
25
				vertices.push_back(vc.get_vertex());
26
				hedges.push_back(vc.get_halfedge());
26
				hedges.push_back(vc.get_halfedge());
27
      }
27
      }
28
    int N = vc.no_steps();
28
    int N = vc.no_steps();
29
    vector<VertexIter> vertices_check(vertices);
29
    vector<VertexIter> vertices_check(vertices);
30
    assert(N==vertices.size());
30
    assert(N==vertices.size());
31
 
31
 
32
    for(int i=N-1;i>=0;--i)
32
    for(int i=N-1;i>=0;--i)
33
      {
33
      {
34
				HalfEdgeIter h = hedges[i]->next;
34
				HalfEdgeIter h = hedges[i]->next;
35
				while(h->vert != vertices[(i+N-1)%N])
35
				while(h->vert != vertices[(i+N-1)%N])
36
					{
36
					{
37
						if(find(vertices_check.begin(),vertices_check.end(), 
37
						if(find(vertices_check.begin(),vertices_check.end(), 
38
										h->vert) == vertices_check.end())
38
										h->vert) == vertices_check.end())
39
							candidates.push_back(h);
39
							candidates.push_back(h);
40
						h = h->next;
40
						h = h->next;
-
 
41
						
-
 
42
						// TODO : does not compile in debug mode in visual studio
41
						assert(h!=v);
43
						assert(h!=v);
42
					}
44
					}
43
      }
45
      }
44
  }
46
  }
45
 
47
 
46
  float curv(const Vec3f& p, std::vector<Vec3f>& vec)
48
  float curv(const Vec3f& p, std::vector<Vec3f>& vec)
47
  {
49
  {
48
    int N = vec.size();
50
    int N = vec.size();
49
    std::vector<Vec3f> normals;
51
    std::vector<Vec3f> normals;
50
    for(int i=0;i<N;++i)
52
    for(int i=0;i<N;++i)
51
      {
53
      {
52
				
54
				
53
				Vec3f norm = normalize(cross(vec[i]-p, vec[(i+1)%N]-p));
55
				Vec3f norm = normalize(cross(vec[i]-p, vec[(i+1)%N]-p));
54
				normals.push_back(norm);
56
				normals.push_back(norm);
55
      }
57
      }
56
    float alpha = 0;
58
    float alpha = 0;
57
    for(int i=0;i<N;++i)
59
    for(int i=0;i<N;++i)
58
      {
60
      {
59
				alpha += (vec[i]-p).length()*acos(dot(normals[i],normals[(i+1)%N]));
61
				alpha += (vec[i]-p).length()*acos(dot(normals[i],normals[(i+1)%N]));
60
      }
62
      }
61
    return alpha;
63
    return alpha;
62
  }
64
  }
63
 
65
 
64
  float get_badness(const VertexIter& v, const VertexIter& n)
66
  float get_badness(const VertexIter& v, const VertexIter& n)
65
  {
67
  {
66
    vector<HalfEdgeIter> hedges;
68
    vector<HalfEdgeIter> hedges;
67
						
69
						
68
    VertexCirculator vc(v);
70
    VertexCirculator vc(v);
69
    for(;!vc.end();++vc)
71
    for(;!vc.end();++vc)
70
      hedges.push_back(vc.get_halfedge());
72
      hedges.push_back(vc.get_halfedge());
71
 
73
 
72
    vector<Vec3f> one_ring;
74
    vector<Vec3f> one_ring;
73
    vector<Vec3f> one_ring_n;
75
    vector<Vec3f> one_ring_n;
74
    int N = vc.no_steps();
76
    int N = vc.no_steps();
75
    for(int i=N-1;i>=0;--i)
77
    for(int i=N-1;i>=0;--i)
76
      {
78
      {
77
				HalfEdgeIter h = hedges[i];
79
				HalfEdgeIter h = hedges[i];
78
				h = h->next;
80
				h = h->next;
79
				while(h->vert != v)
81
				while(h->vert != v)
80
					{
82
					{
81
						one_ring.push_back(h->vert->get_pos());
83
						one_ring.push_back(h->vert->get_pos());
82
						if(h->vert != n)
84
						if(h->vert != n)
83
							one_ring_n.push_back(h->vert->get_pos());
85
							one_ring_n.push_back(h->vert->get_pos());
84
						h = h->next;
86
						h = h->next;
85
					}
87
					}
86
      }
88
      }
87
    return curv(v->get_pos(),one_ring)-curv(v->get_pos(),one_ring_n);
89
    return curv(v->get_pos(),one_ring)-curv(v->get_pos(),one_ring_n);
88
  }
90
  }
89
 
91
 
90
 
92
 
91
  const CGLA::Vec3f get_normal(const VertexIter& v)
93
  const CGLA::Vec3f get_normal(const VertexIter& v)
92
  {
94
  {
93
 
95
 
94
    vector<HalfEdgeIter> hedges;
96
    vector<HalfEdgeIter> hedges;
95
						
97
						
96
    VertexCirculator vc(v);
98
    VertexCirculator vc(v);
97
    for(;!vc.end();++vc)
99
    for(;!vc.end();++vc)
98
      hedges.push_back(vc.get_halfedge());
100
      hedges.push_back(vc.get_halfedge());
99
 
101
 
100
    vector<Vec3f> one_ring;
102
    vector<Vec3f> one_ring;
101
    int N = vc.no_steps();
103
    int N = vc.no_steps();
102
    for(int i=N-1;i>=0;--i)
104
    for(int i=N-1;i>=0;--i)
103
      {
105
      {
104
				HalfEdgeIter h = hedges[i];
106
				HalfEdgeIter h = hedges[i];
105
				h = h->next;
107
				h = h->next;
106
				while(h->vert != v)
108
				while(h->vert != v)
107
					{
109
					{
108
						one_ring.push_back(h->vert->get_pos());
110
						one_ring.push_back(h->vert->get_pos());
109
						h = h->next;
111
						h = h->next;
110
					}
112
					}
111
      }
113
      }
112
    Vec3f norm(0);
114
    Vec3f norm(0);
113
    N= one_ring.size();
115
    N= one_ring.size();
114
    Vec3f p0 = v->get_pos();
116
    Vec3f p0 = v->get_pos();
115
    for(int i=0;i<N;++i)
117
    for(int i=0;i<N;++i)
116
      {
118
      {
117
				Vec3f p1 = one_ring[i];
119
				Vec3f p1 = one_ring[i];
118
				Vec3f p2 = one_ring[(i+1)%N];
120
				Vec3f p2 = one_ring[(i+1)%N];
119
				Vec3f e0 = normalize(p1-p0);
121
				Vec3f e0 = normalize(p1-p0);
120
				Vec3f e1 = normalize(p2-p0);
122
				Vec3f e1 = normalize(p2-p0);
121
				norm += cross(e0,e1)*acos(dot(e0,e1));
123
				norm += cross(e0,e1)*acos(dot(e0,e1));
122
      }
124
      }
123
    return normalize(norm);
125
    return normalize(norm);
124
  }
126
  }
125
 
127
 
126
  void safe_triangulate(Manifold& m)
128
  void safe_triangulate(Manifold& m)
127
  {
129
  {
128
    vector<FaceIter> fv;
130
    vector<FaceIter> fv;
129
    for(FaceIter  fi=m.faces_begin(); fi != m.faces_end(); ++fi)
131
    for(FaceIter  fi=m.faces_begin(); fi != m.faces_end(); ++fi)
130
      fv.push_back(fi);
132
      fv.push_back(fi);
131
    for(int i=0;i<fv.size();++i)
133
    for(int i=0;i<fv.size();++i)
132
      m.safe_triangulate(fv[i]);
134
      m.safe_triangulate(fv[i]);
133
  }
135
  }
134
 
136
 
135
  void triangulate(Manifold& m)
137
  void triangulate(Manifold& m)
136
  {
138
  {
137
    vector<FaceIter> fv;
139
    vector<FaceIter> fv;
138
    for(FaceIter  fi=m.faces_begin(); fi != m.faces_end(); ++fi)
140
    for(FaceIter  fi=m.faces_begin(); fi != m.faces_end(); ++fi)
139
      fv.push_back(fi);
141
      fv.push_back(fi);
140
    for(int i=0;i<fv.size();++i)
142
    for(int i=0;i<fv.size();++i)
141
      m.triangulate(fv[i]);
143
      m.triangulate(fv[i]);
142
  }
144
  }
143
 
145
 
144
  struct PotentialEdge
146
  struct PotentialEdge
145
  {
147
  {
146
    int time_tag;
148
    int time_tag;
147
    float badness;
149
    float badness;
148
    FaceIter f;
150
    FaceIter f;
149
    VertexIter v0, v1;
151
    VertexIter v0, v1;
150
  };
152
  };
151
 
153
 
152
  bool operator>(const PotentialEdge& e0, const PotentialEdge& e1)
154
  bool operator>(const PotentialEdge& e0, const PotentialEdge& e1)
153
  {
155
  {
154
    return e0.badness>e1.badness;
156
    return e0.badness>e1.badness;
155
  }
157
  }
156
 
158
 
157
  typedef std::priority_queue<PotentialEdge,
159
  typedef std::priority_queue<PotentialEdge,
158
															std::vector<PotentialEdge>,
160
															std::vector<PotentialEdge>,
159
															std::greater<PotentialEdge> > 
161
															std::greater<PotentialEdge> > 
160
  PotentialEdgeQueue;
162
  PotentialEdgeQueue;
161
 
163
 
162
  void insert_potential_edges(const VertexIter& v,
164
  void insert_potential_edges(const VertexIter& v,
163
															PotentialEdgeQueue& pot_edges)
165
															PotentialEdgeQueue& pot_edges)
164
  {
166
  {
165
    vector<Vec3f> one_ring;
167
    vector<Vec3f> one_ring;
166
    vector<HalfEdgeIter> candidates;
168
    vector<HalfEdgeIter> candidates;
167
    get_candidates(v, candidates);
169
    get_candidates(v, candidates);
168
 
170
 
169
    Vec3f p0 = v->get_pos();
171
    Vec3f p0 = v->get_pos();
170
    Vec3f norm = get_normal(v);
172
    Vec3f norm = get_normal(v);
171
    int n = candidates.size();
173
    int n = candidates.size();
172
    for(int i=0;i<n;++i)
174
    for(int i=0;i<n;++i)
173
      {
175
      {
174
				VertexIter v_n = candidates[i]->vert;
176
				VertexIter v_n = candidates[i]->vert;
175
				Vec3f edir = normalize(v_n->get_pos()-p0);
177
				Vec3f edir = normalize(v_n->get_pos()-p0);
176
				Vec3f norm_n = get_normal(v_n);
178
				Vec3f norm_n = get_normal(v_n);
177
				float bad = sqr(dot(edir, norm));
179
				float bad = sqr(dot(edir, norm));
178
				float bad_n = sqr(dot(edir, norm_n));
180
				float bad_n = sqr(dot(edir, norm_n));
179
						
181
						
180
				PotentialEdge pot;
182
				PotentialEdge pot;
181
 
183
 
182
				/* So if the edge between two vertices is not orthogonal to 
184
				/* So if the edge between two vertices is not orthogonal to 
183
					 their normals, the badness is increased. Badness is also
185
					 their normals, the badness is increased. Badness is also
184
					 increased if the normals are very different. */
186
					 increased if the normals are very different. */
185
 
187
 
186
				pot.badness = bad+bad_n - dot(norm_n,norm);
188
				pot.badness = bad+bad_n - dot(norm_n,norm);
187
				pot.time_tag = v->touched;
189
				pot.time_tag = v->touched;
188
				pot.v0 = v;
190
				pot.v0 = v;
189
				pot.v1 = candidates[i]->vert;
191
				pot.v1 = candidates[i]->vert;
190
				pot.f = candidates[i]->face;
192
				pot.f = candidates[i]->face;
191
						
193
						
192
				pot_edges.push(pot);
194
				pot_edges.push(pot);
193
      }
195
      }
194
  }
196
  }
195
 
197
 
196
										
198
										
197
  void create_candidates(Manifold& m, PotentialEdgeQueue& pot_edges)
199
  void create_candidates(Manifold& m, PotentialEdgeQueue& pot_edges)
198
  {
200
  {
199
    for(VertexIter v= m.vertices_begin(); v!= m.vertices_end();++v)
201
    for(VertexIter v= m.vertices_begin(); v!= m.vertices_end();++v)
200
      {
202
      {
201
				v->touched = 0;
203
				v->touched = 0;
202
				insert_potential_edges(v, pot_edges);
204
				insert_potential_edges(v, pot_edges);
203
      }
205
      }
204
  }
206
  }
205
 
207
 
206
	
208
	
207
 
209
 
208
 
210
 
209
  void curvature_triangulate(Manifold& m)
211
  void curvature_triangulate(Manifold& m)
210
  {
212
  {
211
    PotentialEdgeQueue pot_edges;
213
    PotentialEdgeQueue pot_edges;
212
 
214
 
213
    // Create candidates
215
    // Create candidates
214
    create_candidates(m,pot_edges);
216
    create_candidates(m,pot_edges);
215
		
217
		
216
    while(!pot_edges.empty())
218
    while(!pot_edges.empty())
217
      {
219
      {
218
				const PotentialEdge& pot_edge = pot_edges.top();
220
				const PotentialEdge& pot_edge = pot_edges.top();
219
 
221
 
220
				// Record all the vertices of the face. We need to 
222
				// Record all the vertices of the face. We need to 
221
				// recompute the candidates.
223
				// recompute the candidates.
222
				std::vector<VertexIter> reeval_vec;
224
				std::vector<VertexIter> reeval_vec;
223
				FaceCirculator fc(pot_edge.f);
225
				FaceCirculator fc(pot_edge.f);
224
				while(!fc.end())
226
				while(!fc.end())
225
					{
227
					{
226
						reeval_vec.push_back(fc.get_vertex());
228
						reeval_vec.push_back(fc.get_vertex());
227
						++fc;
229
						++fc;
228
					}
230
					}
229
 
231
 
230
				VertexIter v0 = pot_edge.v0;
232
				VertexIter v0 = pot_edge.v0;
231
 
233
 
232
				// Make sure that the vertex has not been touched since 
234
				// Make sure that the vertex has not been touched since 
233
				// we created the potential edge. If the vertex has been
235
				// we created the potential edge. If the vertex has been
234
				// touched the candidate edge has either (a) been processed,
236
				// touched the candidate edge has either (a) been processed,
235
				// (b) received a lower priority or (c) become invalid.
237
				// (b) received a lower priority or (c) become invalid.
236
				if(pot_edge.time_tag == v0->touched)
238
				if(pot_edge.time_tag == v0->touched)
237
					{
239
					{
238
						VertexIter v1 = pot_edge.v1;
240
						VertexIter v1 = pot_edge.v1;
239
 
241
 
240
						vector<Vec3f> one_ring;
242
						vector<Vec3f> one_ring;
241
						vector<HalfEdgeIter> candidates;
243
						vector<HalfEdgeIter> candidates;
242
												
244
												
243
						m.split_face(pot_edge.f, v0, v1);
245
						m.split_face(pot_edge.f, v0, v1);
244
 
246
 
245
						// Recompute priorities.
247
						// Recompute priorities.
246
						for(int i=0;i<reeval_vec.size();++i)
248
						for(int i=0;i<reeval_vec.size();++i)
247
							{
249
							{
248
								VertexIter& v = reeval_vec[i];
250
								VertexIter& v = reeval_vec[i];
249
								v->touched++;
251
								v->touched++;
250
								insert_potential_edges(v, pot_edges);
252
								insert_potential_edges(v, pot_edges);
251
							}
253
							}
252
						
254
						
253
					}
255
					}
254
				pot_edges.pop();
256
				pot_edges.pop();
255
      }
257
      }
256
 
258
 
257
  }
259
  }
258
 
260
 
259
}
261
}
260
 
262