Subversion Repositories gelsvn

Rev

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

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