Subversion Repositories gelsvn

Rev

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

Rev 113 Rev 133
1
#ifndef __MANIFOLD_H
1
#ifndef __MANIFOLD_H
2
#define __MANIFOLD_H
2
#define __MANIFOLD_H
3
 
3
 
4
#include <vector>
4
#include <vector>
5
#include <list>
5
#include <list>
6
#include <map>
6
#include <map>
7
 
7
 
8
#include "Vertex.h"
8
#include "Vertex.h"
9
#include "HalfEdge.h"
9
#include "HalfEdge.h"
10
#include "Face.h"
10
#include "Face.h"
11
 
11
 
12
namespace HMesh
12
namespace HMesh
13
{
13
{
14
	class VertexCirculator;
14
	class VertexCirculator;
15
	class FaceCirculator;
15
	class FaceCirculator;
16
 
16
 
17
	/** \brief A Data structure representing an open or closed manifold.
17
	/** \brief A Data structure representing an open or closed manifold.
18
 
-
 
19
			Manifold keeps lists of the entities making up a halfedge mesh
18
			Manifold keeps lists of the entities making up a halfedge mesh
20
			and provides basic functions for creating new faces, halfedges
19
			and provides basic functions for creating new faces, halfedges
21
			and vertices. There are also primitive operations for editing 
20
			and vertices. There are also primitive operations for editing 
22
			such as edge collapse. */
21
			such as edge collapse. */
23
	struct Manifold
22
	struct Manifold
24
	{
23
	{
25
		std::list<Vertex> vertex_db;
24
		std::list<Vertex> vertex_db;
26
		std::list<Face> face_db;
25
		std::list<Face> face_db;
27
		std::list<HalfEdge> halfedge_db;
26
		std::list<HalfEdge> halfedge_db;
28
 
27
 
29
		/** Remove a face if it contains only two edges.
28
		/** Remove a face if it contains only two edges.
30
 
-
 
31
		This is an auxiliary function called from collapse_halfedge. */
29
				This is an auxiliary function called from collapse_halfedge. */
32
		void remove_face_if_degenerate(HalfEdgeIter fi);
30
		void remove_face_if_degenerate(HalfEdgeIter fi);
33
 
31
 
34
		/** Empty copy constructor.
32
		/** Empty copy constructor.
35
				
-
 
36
		Copying a manifold will not work, since faces, vertices, and
33
				Copying a manifold will not work, since faces, vertices, and
37
				halfedges contain iterators pointing to other faces, vertices,
34
				halfedges contain iterators pointing to other faces, vertices,
38
				and halfedges. These pointers would need to be changed if the 
35
				and halfedges. These pointers would need to be changed if the 
39
				mesh were copied. In other words, we would need to walk the
36
				mesh were copied. In other words, we would need to walk the
40
				entire mesh. This may be required but it should not be an 
37
				entire mesh. This may be required but it should not be an 
41
				operation that is easily invoked by calling the copy constructor.
38
				operation that is easily invoked by calling the copy constructor.
42
				Hence, this operator is made private.		*/
39
				Hence, this operator is made private.		*/
43
		Manifold(const Manifold& m2) {}
40
		Manifold(const Manifold& m2) {}
44
 
41
 
45
		/** Empty assignment operator.
42
		/** Empty assignment operator.
46
				
-
 
47
		The assignment operator is private for the same reason that the
43
				The assignment operator is private for the same reason that the
48
				copy constructor is private. */
44
				copy constructor is private. */
49
		const Manifold& operator=(const Manifold& m2) {}
45
		const Manifold& operator=(const Manifold& m2) {}
50
 
46
 
51
		public:
47
		public:
52
	
48
	
53
		/// Construct an empty manifold.
49
		/// Construct an empty manifold.
54
		Manifold() {}
50
		Manifold() {}
55
 
51
 
56
		/// Return the bounding box of the manifold.
52
		/// Return the bounding box of the manifold.
57
		void get_bbox(CGLA::Vec3f&, CGLA::Vec3f&);
53
		void get_bbox(CGLA::Vec3f&, CGLA::Vec3f&);
58
 
54
 
59
		/// Get a bounding sphere
55
		/// Get a bounding sphere
60
    void get_bsphere(CGLA::Vec3f& c, float& r);
56
    void get_bsphere(CGLA::Vec3f& c, float& r);
61
 
57
 
62
		/// Clear the manifold - removing all data.
58
		/// Clear the manifold - removing all data.
63
		void clear()
59
		void clear()
64
		{
60
		{
65
			vertex_db.clear();
61
			vertex_db.clear();
66
			face_db.clear();
62
			face_db.clear();
67
			halfedge_db.clear();
63
			halfedge_db.clear();
68
		}
64
		}
69
 
65
 
70
		/// Return the number of faces.
66
		/// Return the number of faces.
71
		int no_faces() const {return face_db.size();}
67
		int no_faces() const {return face_db.size();}
72
 
68
 
73
		/// Return the number of halfedges.
69
		/// Return the number of halfedges.
74
		int no_halfedges() const {return halfedge_db.size();}
70
		int no_halfedges() const {return halfedge_db.size();}
75
 
71
 
76
		/// Return the number of vertices
72
		/// Return the number of vertices
77
		int no_vertices() const {return vertex_db.size();}
73
		int no_vertices() const {return vertex_db.size();}
78
 
74
 
79
		/// Create a new vertex at a given position.
75
		/// Create a new vertex at a given position.
80
		VertexIter create_vertex(const CGLA::Vec3f& pos)
76
		VertexIter create_vertex(const CGLA::Vec3f& pos)
81
		{
77
		{
82
			vertex_db.push_back(Vertex(pos));
78
			vertex_db.push_back(Vertex(pos));
83
			return --vertex_db.end();
79
			return --vertex_db.end();
84
		}
80
		}
85
 
81
 
86
		/// Create a new face 
82
		/// Create a new face 
87
		FaceIter create_face()
83
		FaceIter create_face()
88
		{
84
		{
89
			face_db.push_back(Face());
85
			face_db.push_back(Face());
90
			return --face_db.end();
86
			return --face_db.end();
91
		}
87
		}
92
 
88
 
93
		/// Create a new halfedge.
89
		/// Create a new halfedge.
94
		HalfEdgeIter create_halfedge()
90
		HalfEdgeIter create_halfedge()
95
		{
91
		{
96
			halfedge_db.push_back(HalfEdge());
92
			halfedge_db.push_back(HalfEdge());
97
			return --halfedge_db.end();
93
			return --halfedge_db.end();
98
		}
94
		}
99
 
95
 
100
		/// Erase halfedge. Assumes it is safe to do so. Use with care.
96
		/// Erase halfedge. Assumes it is safe to do so. Use with care.
101
		void erase_halfedge(HalfEdgeIter he)
97
		void erase_halfedge(HalfEdgeIter he)
102
		{
98
		{
103
			halfedge_db.erase(he);
99
			halfedge_db.erase(he);
104
		}
100
		}
105
 
101
 
106
		/// Erase vertex. Assumes it is safe to do so. Use with care.
102
		/// Erase vertex. Assumes it is safe to do so. Use with care.
107
		void erase_vertex(VertexIter v)
103
		void erase_vertex(VertexIter v)
108
		{
104
		{
109
			vertex_db.erase(v);
105
			vertex_db.erase(v);
110
		}
106
		}
111
	
107
	
112
		/// Erase face. Assumes it is safe to do so. Use with care.
108
		/// Erase face. Assumes it is safe to do so. Use with care.
113
		void erase_face(FaceIter f)
109
		void erase_face(FaceIter f)
114
		{
110
		{
115
			face_db.erase(f);
111
			face_db.erase(f);
116
		}
112
		}
117
 
113
 
118
		/// Return iterator pointing to the first halfedge.
114
		/// Return iterator pointing to the first halfedge.
119
		HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
115
		HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
120
 
116
 
121
		/// Return iterator pointing to beyond the last halfedge.
117
		/// Return iterator pointing to beyond the last halfedge.
122
		HalfEdgeIter halfedges_end() { return halfedge_db.end(); }
118
		HalfEdgeIter halfedges_end() { return halfedge_db.end(); }
123
	
119
	
124
		/// Return iterator pointing to the first vertex.
120
		/// Return iterator pointing to the first vertex.
125
		VertexIter vertices_begin() { return vertex_db.begin();}
121
		VertexIter vertices_begin() { return vertex_db.begin();}
126
 
122
 
127
		/// Return iterator pointing to beyond the last vertex.
123
		/// Return iterator pointing to beyond the last vertex.
128
		VertexIter vertices_end() { return vertex_db.end(); }
124
		VertexIter vertices_end() { return vertex_db.end(); }
129
 
125
 
130
		/// Return iterator pointing to the first face.
126
		/// Return iterator pointing to the first face.
131
		FaceIter faces_begin() { return face_db.begin();	}
127
		FaceIter faces_begin() { return face_db.begin();	}
132
 
128
 
133
		/// Return iterator pointing to beyond the last face.
129
		/// Return iterator pointing to beyond the last face.
134
		FaceIter faces_end() { return face_db.end(); }
130
		FaceIter faces_end() { return face_db.end(); }
135
 
131
 
136
		/** \brief HalfEdge collapse precondition. 
132
		/** \brief HalfEdge collapse precondition. 
137
 
133
 
138
				If this function does not return true, it is illegal to collapse
134
				If this function does not return true, it is illegal to collapse
139
				the halfedge given as second arg. The reason is that the collapse
135
				the halfedge given as second arg. The reason is that the collapse
140
				would violate the manifold property of the mesh.
136
				would violate the manifold property of the mesh.
141
 
137
 
142
				The test is as follows.
138
				The test is as follows.
143
 
139
 
144
				1. For the two vertices adjacent to the edge, we generate
140
				1. For the two vertices adjacent to the edge, we generate
145
				a list of all their neighbouring vertices. We then generate a 
141
				a list of all their neighbouring vertices. We then generate a 
146
				list of the vertices that occur in both these lists. That is, 
142
				list of the vertices that occur in both these lists. That is, 
147
				we find all vertices connected by edges to both endpoints
143
				we find all vertices connected by edges to both endpoints
148
				of the edge and store these in a list.
144
				of the edge and store these in a list.
149
 
145
 
150
				2. For both faces incident on the edge, check whether they
146
				2. For both faces incident on the edge, check whether they
151
				are triangular. If this is the case, the face will be removed,
147
				are triangular. If this is the case, the face will be removed,
152
				and it is ok that the the third vertex is connected to both 
148
				and it is ok that the the third vertex is connected to both 
153
				endpoints. Thus the third vertex in such a face is removed
149
				endpoints. Thus the third vertex in such a face is removed
154
				from the list generated in 1.
150
				from the list generated in 1.
155
 
151
 
156
				3. If the list is now empty, all is well. Otherwise, there
152
				3. If the list is now empty, all is well. Otherwise, there
157
				would be a vertex in the new mesh with two edges connecting
153
				would be a vertex in the new mesh with two edges connecting
158
				it to the same vertex. Return false.
154
				it to the same vertex. Return false.
159
 
155
 
160
				4. TETRAHEDRON TEST:
156
				4. TETRAHEDRON TEST:
161
				If the valency of both vertices is 
157
				If the valency of both vertices is 
162
				three, and the incident faces are triangles, we also disallow
158
				three, and the incident faces are triangles, we also disallow
163
				the operation. Reason: It introduces a vertex of valency two
159
				the operation. Reason: It introduces a vertex of valency two
164
				and if the final two polygons incident on the vertices 
160
				and if the final two polygons incident on the vertices 
165
				that are adjacent to the edge being collapsed are triangles, then
161
				that are adjacent to the edge being collapsed are triangles, then
166
				the construction will collapse
162
				the construction will collapse
167
 
163
 
168
				5. VALENCY 4 TEST:
164
				5. VALENCY 4 TEST:
169
				If a face adjacent to the edge being collapsed is a triangle,
165
				If a face adjacent to the edge being collapsed is a triangle,
170
				it will disappear, and the valency of the final vertex beloning to
166
				it will disappear, and the valency of the final vertex beloning to
171
				this edge will be reduced by one. Hence this valency should be at
167
				this edge will be reduced by one. Hence this valency should be at
172
				least 4. A valency three vertex will be reduced to a valency two
168
				least 4. A valency three vertex will be reduced to a valency two
173
				vertex which is considered illegal.
169
				vertex which is considered illegal.
174
 
170
 
175
				6. PREVENT MERGING HOLES:
171
				6. PREVENT MERGING HOLES:
176
				We do not want to collapse an edge if its end points are boundary
172
				We do not want to collapse an edge if its end points are boundary
177
				vertices, but its two adjacent faces are not NULL faces, because
173
				vertices, but its two adjacent faces are not NULL faces, because
178
				in that case we create a vertex where two holes meet. A non manifold
174
				in that case we create a vertex where two holes meet. A non manifold
179
				situation.	*/
175
				situation.	*/
180
		bool collapse_precond(VertexIter, HalfEdgeIter);
176
		bool collapse_precond(VertexIter, HalfEdgeIter);
181
		
177
		
182
		/** Collapse the halfedge given as second argument. 
178
		/** Collapse the halfedge given as second argument. 
-
 
179
				The first argument is the vertex that is being removed. The
-
 
180
				second is a halfedge pointing away from that vertex.
183
 
181
 
184
		The first argument
182
				The final argument is a boolean indicating whether the vertex
185
				is the vertex that is being removed. The second is a halfedge pointing
183
				that survives the collapse should have a position which is the
186
				away from that vertex. This function is not guaranteed
184
				average of its own position and the vertex that is removed.
-
 
185
				By default false.
-
 
186
 
-
 
187
				This function is not guaranteed to keep the mesh sane unless,
187
				to keep the mesh sane unless, collapse_precond has returned true. */
188
				collapse_precond has returned true.
-
 
189
		*/
188
		void collapse_halfedge(VertexIter, HalfEdgeIter, bool=false);
190
		void collapse_halfedge(VertexIter, HalfEdgeIter, bool=false);
189
 
191
 
-
 
192
		/** Split a face.
190
		/** Split a face (first argument) by connecting two vertices (the
193
		    The face given as first argument is split by connecting two
191
				next two arguments). */
194
				vertices (the next two arguments). */
192
		FaceIter split_face(FaceIter, VertexIter, VertexIter);
195
		FaceIter split_face(FaceIter, VertexIter, VertexIter);
193
 
196
 
194
		/** Insert a new vertex on the halfedge given as argument. */
197
		/** Insert a new vertex on the halfedge given as argument.
-
 
198
				The new halfedge is insterted as the previous edge to the one
-
 
199
				given as argument.
-
 
200
		*/
195
		VertexIter Manifold::split_edge(HalfEdgeIter h);
201
		VertexIter Manifold::split_edge(HalfEdgeIter h);
196
 
202
 
197
		/** Triangulate a polygonal face by repeatedly calling splitface. */
203
		/** Triangulate a polygonal face by repeatedly calling split_face. 
-
 
204
				Triangulate iteratively splits triangles off a polygon. The first 
-
 
205
				triangle split off is the one connecting f->last->vert and
-
 
206
				f->last->next->next->vert.
-
 
207
		*/
198
		void triangulate(FaceIter);
208
		void triangulate(FaceIter);
199
 
209
 
200
		/** Triangulate a polygon by inserting a vertex at the barycenter and 
210
		/** Triangulate a polygon by inserting a vertex at the barycenter and 
201
				connecting all vertices to this vertex. */
211
				connecting all vertices to this vertex. 
-
 
212
				
-
 
213
				The word "safe" means that it is less likely to create flipped
-
 
214
				triangles than the normal triangulate. On the other hand, it 
-
 
215
				introduces more vertices and probably makes the triangles more
-
 
216
				acute.
-
 
217
				
-
 
218
				This function simply calls face_insert_point.
-
 
219
		*/
202
		VertexIter safe_triangulate(FaceIter f);
220
		VertexIter safe_triangulate(FaceIter f);
203
 
221
 
204
		/** Insert a new vertex (second arg.) in a face (first arg.).
222
		/** Insert a new vertex (second arg.) in a face (first arg.).
205
				This operation splits an N-gon into N triangles. */
223
				This operation splits an N-gon into N triangles.
-
 
224
				In the current implementation the original face is erased. 
-
 
225
				This means that the iterator is not valid after the function
-
 
226
				returns. 
-
 
227
		*/
206
		void face_insert_point(FaceIter f, VertexIter);
228
		void face_insert_point(FaceIter f, VertexIter);
207
 
229
 
208
		/** Merges two faces into a single polygon. The first face is the first
230
		/** Merges two faces into a single polygon. The first face is the first
209
				argument. The second face is adjacent to the first along the
231
				argument. The second face is adjacent to the first along the
210
				halfedge given as second argument. */
232
				halfedge given as second argument. */
211
		bool merge_faces(FaceIter f, HalfEdgeIter h);
233
		bool merge_faces(FaceIter f, HalfEdgeIter h);
212
 
234
 
213
		/** flips an edge. Returns false if flipping cannot be performed.
235
		/** Flip an edge. Returns false if flipping cannot be performed.
214
				This is either because one of the two adjacent faces is not
236
				This is either because one of the two adjacent faces is not
215
				a triangle, or because either end point has valency three or
237
				a triangle, or because either end point has valency three or
216
				because the vertices that will be connected already are. */
238
				because the vertices that will be connected already are. */
217
		bool flip(HalfEdgeIter);
239
		bool flip(HalfEdgeIter);
218
 
240
 
219
		/** Performs a series of tests to check that this is a valid manifold.
241
		/** Performs a series of tests to check that this is a valid manifold.
220
				This function is not rigorously constructed but seems to catch
242
				This function is not rigorously constructed but seems to catch
221
				all problems so far. */
243
				all problems so far. */
222
		bool is_valid();
244
		bool is_valid();
223
 
245
 
224
		/** Give each vertex a unique id corresponding to its iterator 
246
		/** Give each vertex a unique id corresponding to its iterator 
225
				position */
247
				position */
226
		void enumerate_vertices();
248
		void enumerate_vertices();
227
 
249
 
228
		/** Give each halfedge a unique id corresponding to its iterator 
250
		/** Give each halfedge a unique id corresponding to its iterator 
229
				position */
251
				position */
230
		void enumerate_halfedges();
252
		void enumerate_halfedges();
231
 
253
 
232
		/** Give each face a unique id corresponding to its iterator 
254
		/** Give each face a unique id corresponding to its iterator 
233
				position */
255
				position */
234
		void enumerate_faces();
256
		void enumerate_faces();
235
		
257
		
236
	};
258
	};
237
 
259
 
238
 
260
 
239
}
261
}
240
#endif
262
#endif
241
 
263