Subversion Repositories gelsvn

Rev

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