Subversion Repositories gelsvn

Rev

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

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