Subversion Repositories gelsvn

Rev

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

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