Subversion Repositories gelsvn

Rev

Rev 155 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
39 bj 1
#ifndef __MANIFOLD_H
2
#define __MANIFOLD_H
3
 
4
#include <vector>
5
#include <list>
6
#include <map>
7
 
8
#include "Vertex.h"
9
#include "HalfEdge.h"
10
#include "Face.h"
11
 
12
namespace HMesh
13
{
14
	class VertexCirculator;
15
	class FaceCirculator;
16
 
89 jab 17
	/** \brief A Data structure representing an open or closed manifold.
39 bj 18
			Manifold keeps lists of the entities making up a halfedge mesh
19
			and provides basic functions for creating new faces, halfedges
20
			and vertices. There are also primitive operations for editing 
21
			such as edge collapse. */
155 jab 22
	class Manifold
158 jab 23
		{
24
			std::list<Vertex> vertex_db;
25
			std::list<Face> face_db;
26
			std::list<HalfEdge> halfedge_db;
39 bj 27
 
158 jab 28
			bool erase_immediately;
29
			std::vector<VertexIter> unused_vertices;
30
			std::vector<FaceIter> unused_faces;
31
			std::vector<HalfEdgeIter> unused_halfedges;
39 bj 32
 
33
 
158 jab 34
			/** Remove a face if it contains only two edges.
35
					This is an auxiliary function called from collapse_halfedge. */
36
			void remove_face_if_degenerate(HalfEdgeIter);
39 bj 37
 
158 jab 38
			/** Empty copy constructor.
39
					Copying a manifold will not work, since faces, vertices, and
40
					halfedges contain iterators pointing to other faces, vertices,
41
					and halfedges. These pointers would need to be changed if the 
42
					mesh were copied. In other words, we would need to walk the
43
					entire mesh. This may be required but it should not be an 
44
					operation that is easily invoked by calling the copy constructor.
45
					Hence, this operator is made private.		*/
46
			Manifold(const Manifold&) {}
47
 
48
			/** Empty assignment operator.
49
					The assignment operator is private for the same reason that the
50
					copy constructor is private. */
51
			const Manifold& operator=(const Manifold&) {return *this;}
52
 
39 bj 53
		public:
54
 
158 jab 55
			/// Construct an empty manifold.
56
			Manifold(): erase_immediately(true) {}
39 bj 57
 
158 jab 58
			/** Return the bounding box of the manifold. The arguments pmin and pmax
59
					will contain the extreme corners of the box when the function 
60
					returns.	*/
61
			void get_bbox(CGLA::Vec3f& pmin, CGLA::Vec3f& pmax);
39 bj 62
 
158 jab 63
			/** Get a bounding sphere. When the function returns c contains the
64
					centre and r the radius. */ 
65
			void get_bsphere(CGLA::Vec3f& c, float& r);
39 bj 66
 
158 jab 67
			/// Return the number of faces.
68
			size_t no_faces() const {return face_db.size();}
39 bj 69
 
158 jab 70
			/// Return the number of halfedges.
71
			size_t no_halfedges() const {return halfedge_db.size();}
39 bj 72
 
158 jab 73
			/// Return the number of vertices
74
			size_t no_vertices() const {return vertex_db.size();}
39 bj 75
 
158 jab 76
			/** Create a new vertex.
77
					The argument is the position of the vertex, and the 
78
					function returns an iterator pointing to the vertex.
79
					When a vertex v is initially created, is_used(v) will
80
					return false.
81
			*/
82
			VertexIter create_vertex(const CGLA::Vec3f& pos)
83
				{
84
					vertex_db.push_back(Vertex(pos));
85
					return --vertex_db.end();
86
				}
39 bj 87
 
158 jab 88
			/** Create a new face.
89
					An iterator to the face is returned. When a face f is initially
90
					created, is_used(f) will return false. */
91
			FaceIter create_face()
92
				{
93
					face_db.push_back(Face());
94
					return --face_db.end();
95
				}
39 bj 96
 
158 jab 97
			/** Create a new halfedge. An iterator to the halfedge is returned.
98
					When h is initially created, is_used(h) returns false. */
99
			HalfEdgeIter create_halfedge()
100
				{
101
					halfedge_db.push_back(HalfEdge());
102
					return --halfedge_db.end();
103
				}
39 bj 104
 
158 jab 105
			/// Clear the manifold - removing all data.
106
			void clear();
39 bj 107
 
158 jab 108
			/** Remove unused vertices, edges and faces from the database.
109
					If delayed_erase mode is enabled, then until this function 
110
					has been called, erased vertices, edges, and faces are just marked
111
					as unused but not removed from their respective lists. */
112
			void remove_unused();
39 bj 113
 
114
 
158 jab 115
			/** Delay the actual removal of vertices, faces, and edges that
116
					are erased.  In many cases, it is a problem if one cannot
117
					test whether a vertex, halfedge, or face indicated by an
118
					iterator is in use or has been removed from the mesh. One
119
					solution to this problem is to delay the actual removal of
120
					the vertex, edge or face. Instead when calling, say,
121
					erase_face(f), all the iterators of f are assigned the
122
					appropriate NULL value to indicate that they are not
123
					pointing at anything, and f is added to a vector of faces
124
					that need to be physically removed from the face_db.
39 bj 125
 
158 jab 126
					Since f is not erased, all iterators pointing at f remain
127
					valid! And, importantly, it is possible to test whether f is
128
					in use by calling is_used(f).
39 bj 129
 
158 jab 130
					When remove_unused is called, the physical removal takes
131
					place. Calling immediate_erase switches Manifold back to the
132
					state where entities are removed as soon as the appropriate
133
					erase function is called, and at the same time calls
134
					remove_unused.
135
			*/
136
			void delayed_erase()
137
				{
138
					erase_immediately = false;
139
				}
39 bj 140
 
158 jab 141
			/** Immediately remove erased entities.
142
					Calling immediate_erase switches Manifold back to the state
143
					where entities are removed as soon as the appropriate erase
144
					function is called.
39 bj 145
 
158 jab 146
					See delayed_erase for more details, and note that
147
					immediate_erase is the default mode.  */
148
			void immediate_erase()
149
				{
150
					erase_immediately = true;
151
					remove_unused();
152
				}
113 jab 153
 
158 jab 154
			/** Test whether the vertex indicated by the argument v is used.
155
					This function returns true if the vertex appears to have a 
156
					valid outgoing halfedge iterator. */
157
			bool is_used(VertexIter v) const
158
				{
159
					if(v->he == NULL_HALFEDGE_ITER)
160
						return false;
161
					return true;
162
				}
136 jab 163
 
158 jab 164
			/** Test whether the face indicated by the argument f is used.
165
					This function returns true if the face appears to have a 
166
					valid halfedge iterator. */
167
			bool is_used(FaceIter f) const
168
				{
169
					if(f->last == NULL_HALFEDGE_ITER)
170
						return false;
171
					return true;
172
				}
113 jab 173
 
158 jab 174
			/** Test whether the halfedge indicated by the argument h is used.
175
					This function returns true if the halfedge appears to have a 
176
					valid vertex iterator. */
177
			bool is_used(HalfEdgeIter h) const
178
				{
179
					if(h->vert == NULL_VERTEX_ITER)
180
						return false;
181
					return true;
182
				}
113 jab 183
 
158 jab 184
			/** Erase halfedge h. 
185
					In general, you should never call this function but use the 
186
					collapse_halfedge function instead since blindly erasing geometry
187
					is most likely to invalidate the Mesh. Quite possibly this function
188
					will be removed from the public interface. 
189
 
190
					Note that if delayed_erase has been called, this function does
191
					not immediately remove anything from the mesh. Instead the halfedge
192
					is reset to its initial state. Thus, iterators are not invalidated,
193
					and it is possible to test whether h is used calling:
194
					is_used(h). when remove_unused is called, the actual removal
195
					takes place.
196
			*/
197
			void erase_halfedge(HalfEdgeIter h);
113 jab 198
 
158 jab 199
			/** Erase vertex v.
200
					In general, you should never call this function but use the 
201
					collapse_halfedge function to collapse the vertex away.
202
					Blindly erasing is extremely likely to invalidate the
203
					Mesh. Quite possibly this function will be removed from the
204
					public interface. 
113 jab 205
 
158 jab 206
					Note that if delayed_erase has been called, this function does
207
					not immediately remove anything from the mesh. Instead the halfedge
208
					is reset to its initial state. Thus, iterators are not invalidated,
209
					and it is possible to test whether v is used calling:
210
					is_used(v). when remove_unused is called, the actual removal
211
					takes place.
212
			*/
213
			void erase_vertex(VertexIter v);
113 jab 214
 
215
 
158 jab 216
			/** Erase face f.
217
					In general, you should never call this function but use 
218
					collapse_halfedge in conjunction with other functions to
219
					remove the face through (Euler) operations which preserve
220
					the mesh in a valid state.
221
					Blindly erasing is extremely likely to invalidate the
222
					Mesh. Quite possibly this function will be removed from the
223
					public interface. 
113 jab 224
 
158 jab 225
					Note that if delayed_erase has been called, this function does
226
					not immediately remove anything from the mesh. Instead the face
227
					is reset to its initial state. Thus, iterators are not invalidated,
228
					and it is possible to test whether f is used calling:
229
					is_used(f). when remove_unused is called, the actual removal
230
					takes place.
231
			*/
232
			void erase_face(FaceIter f);
113 jab 233
 
158 jab 234
			/// Return iterator pointing to the first halfedge.
235
			HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
136 jab 236
 
158 jab 237
			/// Return iterator pointing to beyond the last halfedge.
238
			HalfEdgeIter halfedges_end() { return halfedge_db.end(); }
133 jab 239
 
158 jab 240
			/// Return iterator pointing to the first vertex.
241
			VertexIter vertices_begin() { return vertex_db.begin();}
39 bj 242
 
158 jab 243
			/// Return iterator pointing to beyond the last vertex.
244
			VertexIter vertices_end() { return vertex_db.end(); }
39 bj 245
 
158 jab 246
			/// Return iterator pointing to the first face.
247
			FaceIter faces_begin() { return face_db.begin();	}
39 bj 248
 
158 jab 249
			/// Return iterator pointing to beyond the last face.
250
			FaceIter faces_end() { return face_db.end(); }
39 bj 251
 
158 jab 252
			/** \brief HalfEdge collapse precondition.
136 jab 253
 
158 jab 254
			The argument h is the halfedge we want to collapse. 
39 bj 255
 
158 jab 256
			If this function does not return true, it is illegal to collapse
257
			h. The reason is that the collapse would violate the manifold property
258
			of the mesh.
39 bj 259
 
158 jab 260
			The test is as follows.
39 bj 261
 
158 jab 262
			1. For the two vertices adjacent to the edge, we generate
263
			a list of all their neighbouring vertices. We then generate a 
264
			list of the vertices that occur in both these lists. That is, 
265
			we find all vertices connected by edges to both endpoints
266
			of the edge and store these in a list.
39 bj 267
 
158 jab 268
			2. For both faces incident on the edge, check whether they
269
			are triangular. If this is the case, the face will be removed,
270
			and it is ok that the the third vertex is connected to both 
271
			endpoints. Thus the third vertex in such a face is removed
272
			from the list generated in 1.
39 bj 273
 
158 jab 274
			3. If the list is now empty, all is well. Otherwise, there
275
			would be a vertex in the new mesh with two edges connecting
276
			it to the same vertex. Return false.
39 bj 277
 
158 jab 278
			4. TETRAHEDRON TEST:
279
			If the valency of both vertices is 
280
			three, and the incident faces are triangles, we also disallow
281
			the operation. Reason: It introduces a vertex of valency two
282
			and if the final two polygons incident on the vertices 
283
			that are adjacent to the edge being collapsed are triangles, then
284
			the construction will collapse
39 bj 285
 
158 jab 286
			5. VALENCY 4 TEST:
287
			If a face adjacent to the edge being collapsed is a triangle,
288
			it will disappear, and the valency of the final vertex beloning to
289
			this edge will be reduced by one. Hence this valency should be at
290
			least 4. A valency three vertex will be reduced to a valency two
291
			vertex which is considered illegal.
39 bj 292
 
158 jab 293
			6. PREVENT MERGING HOLES:
294
			We do not want to collapse an edge if its end points are boundary
295
			vertices, but its two adjacent faces are not NULL faces, because
296
			in that case we create a vertex where two holes meet. A non manifold
297
			situation.	*/
298
			bool collapse_precond(HalfEdgeIter h);
39 bj 299
 
158 jab 300
			/** Collapse the halfedge h.
301
 
302
			The argument h is the halfedge being removed. The vertex 
303
			v=h->opp->vert is the one being removed while h->vert survives.
304
 
305
			The final argument is a boolean indicating whether the vertex
306
			that survives the collapse should have a position which is the
307
			average of its own position and the vertex that is removed.
308
			By default false meaning that the surviving vertex retains it 
309
			position.
310
 
311
			This function is not guaranteed to keep the mesh sane unless,
312
			collapse_precond has returned true !!
313
			*/
314
			void collapse_halfedge(HalfEdgeIter h, bool=false);
315
 
316
			/** Split a face.
317
					The face, f, is split by connecting two
318
					vertices v0 and v1 (the next two arguments). The vertices of
319
					the old face between v0 and v1 (in counter clockwise order) 
320
					continue to belong to f. The vertices between v1 and 
321
					v0 belong to the new face. An iterator to the new face is 
322
					returned. */
323
			FaceIter split_face(FaceIter f, VertexIter v0, VertexIter v1);
324
 
325
			/** Insert a new vertex on halfedge h.
326
					The new halfedge is insterted as the previous edge to h.
327
					An iterator to the inserted vertex is	returned. */
328
			VertexIter Manifold::split_edge(HalfEdgeIter h);
329
 
330
			/** Triangulate a polygonal face by repeatedly calling split_face.
331
					Triangulate iteratively splits triangles off a polygon. The first 
332
					triangle split off is the one connecting f->last->vert and
333
					f->last->next->next->vert.
334
			*/
335
			void triangulate(FaceIter f);
336
 
337
			/** Triangulate a polygon, f, by inserting a vertex at the barycenter.
338
					All vertices in f are connected to the new vertex.				
339
					The word "safe" means that it is less likely to create flipped
340
					triangles than the normal triangulate. On the other hand, it 
341
					introduces more vertices and probably makes the triangles more
342
					acute. This function simply calls face_insert_point.
343
 
344
					The inserted vertex is returned.
345
			*/
346
			VertexIter safe_triangulate(FaceIter f);
347
 
348
			/** Insert a new vertex, v, in a face, f.
349
					This operation splits an N-gon into N triangles.
350
					In the current implementation the original face is erased. 
351
					This means that the iterator is not valid after the function
352
					returns. 
353
			*/
354
			void face_insert_point(FaceIter f, VertexIter v);
355
 
356
			/** Merges two faces into a single polygon. The first face is f.  The
357
					second face is adjacent to f along the halfedge h. This function
358
					returns true if the merging was possible and false
359
					otherwise. Currently merge only fails if the mesh is already
360
					illegal. Thus it should, in fact, never fail. */
361
			bool merge_faces(FaceIter f, HalfEdgeIter h);
362
 
363
			/** Flip an edge h. Returns false if flipping cannot be performed.
364
					This is either because one of the two adjacent faces is not
365
					a triangle, or because either end point has valency three or
366
					because the vertices that will be connected already are. */
367
			bool flip(HalfEdgeIter h);
368
 
369
			/** Performs a series of tests to check that this is a valid manifold.
370
					This function is not rigorously constructed but seems to catch
371
					all problems so far. The function returns true if the mesh is 
372
					valid and false otherwise.
373
			*/
374
			bool is_valid();
375
 
376
			/** Give each vertex a unique id corresponding to its iterator
377
					position */
378
			void enumerate_vertices();
379
 
380
			/** Give each halfedge a unique id corresponding to its iterator
381
					position */
382
			void enumerate_halfedges();
383
 
384
			/** Give each face a unique id corresponding to its iterator
385
					position */
386
			void enumerate_faces();
387
 
388
		};
389
 
390
 
39 bj 391
}
392
#endif