Subversion Repositories gelsvn

Rev

Rev 136 | Rev 336 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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