Subversion Repositories gelsvn

Rev

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

Rev 133 Rev 136
Line 25... Line 25...
25
		std::list<Face> face_db;
25
		std::list<Face> face_db;
26
		std::list<HalfEdge> halfedge_db;
26
		std::list<HalfEdge> halfedge_db;
27
 
27
 
28
		/** Remove a face if it contains only two edges.
28
		/** Remove a face if it contains only two edges.
29
				This is an auxiliary function called from collapse_halfedge. */
29
				This is an auxiliary function called from collapse_halfedge. */
30
		void remove_face_if_degenerate(HalfEdgeIter fi);
30
		void remove_face_if_degenerate(HalfEdgeIter);
31
 
31
 
32
		/** Empty copy constructor.
32
		/** Empty copy constructor.
33
				Copying a manifold will not work, since faces, vertices, and
33
				Copying a manifold will not work, since faces, vertices, and
34
				halfedges contain iterators pointing to other faces, vertices,
34
				halfedges contain iterators pointing to other faces, vertices,
35
				and halfedges. These pointers would need to be changed if the 
35
				and halfedges. These pointers would need to be changed if the 
36
				mesh were copied. In other words, we would need to walk the
36
				mesh were copied. In other words, we would need to walk the
37
				entire mesh. This may be required but it should not be an 
37
				entire mesh. This may be required but it should not be an 
38
				operation that is easily invoked by calling the copy constructor.
38
				operation that is easily invoked by calling the copy constructor.
39
				Hence, this operator is made private.		*/
39
				Hence, this operator is made private.		*/
40
		Manifold(const Manifold& m2) {}
40
		Manifold(const Manifold&) {}
41
 
41
 
42
		/** Empty assignment operator.
42
		/** Empty assignment operator.
43
				The assignment operator is private for the same reason that the
43
				The assignment operator is private for the same reason that the
44
				copy constructor is private. */
44
				copy constructor is private. */
45
		const Manifold& operator=(const Manifold& m2) {}
45
		const Manifold& operator=(const Manifold&) {return *this;}
46
 
46
 
47
		public:
47
		public:
48
	
48
	
49
		/// Construct an empty manifold.
49
		/// Construct an empty manifold.
50
		Manifold() {}
50
		Manifold() {}
51
 
51
 
52
		/// Return the bounding box of the manifold.
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
		 */
53
		void get_bbox(CGLA::Vec3f&, CGLA::Vec3f&);
55
		void get_bbox(CGLA::Vec3f& pmin, CGLA::Vec3f& pmax);
54
 
56
 
-
 
57
		/** Get a bounding sphere. When the function returns c contains the 
55
		/// Get a bounding sphere
58
				centre and r the radius. */ 
56
    void get_bsphere(CGLA::Vec3f& c, float& r);
59
    void get_bsphere(CGLA::Vec3f& c, float& r);
57
 
60
 
58
		/// Clear the manifold - removing all data.
61
		/// Clear the manifold - removing all data.
59
		void clear()
62
		void clear()
60
		{
63
		{
Line 62... Line 65...
62
			face_db.clear();
65
			face_db.clear();
63
			halfedge_db.clear();
66
			halfedge_db.clear();
64
		}
67
		}
65
 
68
 
66
		/// Return the number of faces.
69
		/// Return the number of faces.
67
		int no_faces() const {return face_db.size();}
70
		size_t no_faces() const {return face_db.size();}
68
 
71
 
69
		/// Return the number of halfedges.
72
		/// Return the number of halfedges.
70
		int no_halfedges() const {return halfedge_db.size();}
73
		size_t no_halfedges() const {return halfedge_db.size();}
71
 
74
 
72
		/// Return the number of vertices
75
		/// Return the number of vertices
73
		int no_vertices() const {return vertex_db.size();}
76
		size_t no_vertices() const {return vertex_db.size();}
74
 
77
 
75
		/// Create a new vertex at a given position.
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. */
76
		VertexIter create_vertex(const CGLA::Vec3f& pos)
81
		VertexIter create_vertex(const CGLA::Vec3f& pos)
77
		{
82
		{
78
			vertex_db.push_back(Vertex(pos));
83
			vertex_db.push_back(Vertex(pos));
79
			return --vertex_db.end();
84
			return --vertex_db.end();
80
		}
85
		}
81
 
86
 
82
		/// Create a new face 
87
		/** Create a new face. 
-
 
88
				An iterator to the face is returned. */
83
		FaceIter create_face()
89
		FaceIter create_face()
84
		{
90
		{
85
			face_db.push_back(Face());
91
			face_db.push_back(Face());
86
			return --face_db.end();
92
			return --face_db.end();
87
		}
93
		}
88
 
94
 
89
		/// Create a new halfedge.
95
  	/** Create a new halfedge. An iterator to the halfedge is returned. */
90
		HalfEdgeIter create_halfedge()
96
		HalfEdgeIter create_halfedge()
91
		{
97
		{
92
			halfedge_db.push_back(HalfEdge());
98
			halfedge_db.push_back(HalfEdge());
93
			return --halfedge_db.end();
99
			return --halfedge_db.end();
94
		}
100
		}
95
 
101
 
96
		/// Erase halfedge. Assumes it is safe to do so. Use with care.
102
		/// Erase halfedge h. Assumes it is safe to do so. Use with care.
97
		void erase_halfedge(HalfEdgeIter he)
103
		void erase_halfedge(HalfEdgeIter h)
98
		{
104
		{
99
			halfedge_db.erase(he);
105
			halfedge_db.erase(h);
100
		}
106
		}
101
 
107
 
102
		/// Erase vertex. Assumes it is safe to do so. Use with care.
108
		/// Erase vertex v. Assumes it is safe to do so. Use with care.
103
		void erase_vertex(VertexIter v)
109
		void erase_vertex(VertexIter v)
104
		{
110
		{
105
			vertex_db.erase(v);
111
			vertex_db.erase(v);
106
		}
112
		}
107
	
113
	
108
		/// Erase face. Assumes it is safe to do so. Use with care.
114
		/// Erase face f. Assumes it is safe to do so. Use with care.
109
		void erase_face(FaceIter f)
115
		void erase_face(FaceIter f)
110
		{
116
		{
111
			face_db.erase(f);
117
			face_db.erase(f);
112
		}
118
		}
113
 
119
 
Line 129... Line 135...
129
		/// Return iterator pointing to beyond the last face.
135
		/// Return iterator pointing to beyond the last face.
130
		FaceIter faces_end() { return face_db.end(); }
136
		FaceIter faces_end() { return face_db.end(); }
131
 
137
 
132
		/** \brief HalfEdge collapse precondition. 
138
		/** \brief HalfEdge collapse precondition. 
133
 
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
 
134
				If this function does not return true, it is illegal to collapse
143
				If this function does not return true, it is illegal to collapse
135
				the halfedge given as second arg. The reason is that the collapse
144
				h. The reason is that the collapse would violate the manifold property
136
				would violate the manifold property of the mesh.
145
				of the mesh.
137
 
146
 
138
				The test is as follows.
147
				The test is as follows.
139
 
148
 
140
				1. For the two vertices adjacent to the edge, we generate
149
				1. For the two vertices adjacent to the edge, we generate
141
				a list of all their neighbouring vertices. We then generate a 
150
				a list of all their neighbouring vertices. We then generate a 
Line 171... Line 180...
171
				6. PREVENT MERGING HOLES:
180
				6. PREVENT MERGING HOLES:
172
				We do not want to collapse an edge if its end points are boundary
181
				We do not want to collapse an edge if its end points are boundary
173
				vertices, but its two adjacent faces are not NULL faces, because
182
				vertices, but its two adjacent faces are not NULL faces, because
174
				in that case we create a vertex where two holes meet. A non manifold
183
				in that case we create a vertex where two holes meet. A non manifold
175
				situation.	*/
184
				situation.	*/
176
		bool collapse_precond(VertexIter, HalfEdgeIter);
185
		bool collapse_precond(VertexIter v, HalfEdgeIter h);
177
		
186
		
178
		/** Collapse the halfedge given as second argument. 
187
		/** Collapse the halfedge h.
-
 
188
 
179
				The first argument is the vertex that is being removed. The
189
				The first argument, v, is the vertex that is being removed. The
180
				second is a halfedge pointing away from that vertex.
190
				second, h, is a halfedge pointing away from that vertex.
181
 
191
 
182
				The final argument is a boolean indicating whether the vertex
192
				The final argument is a boolean indicating whether the vertex
183
				that survives the collapse should have a position which is the
193
				that survives the collapse should have a position which is the
184
				average of its own position and the vertex that is removed.
194
				average of its own position and the vertex that is removed.
185
				By default false.
195
				By default false.
186
 
196
 
187
				This function is not guaranteed to keep the mesh sane unless,
197
				This function is not guaranteed to keep the mesh sane unless,
188
				collapse_precond has returned true.
198
				collapse_precond has returned true.
189
		*/
199
		*/
190
		void collapse_halfedge(VertexIter, HalfEdgeIter, bool=false);
200
		void collapse_halfedge(VertexIter v, HalfEdgeIter h, bool=false);
191
 
201
 
192
		/** Split a face.
202
		/** Split a face.
193
		    The face given as first argument is split by connecting two
203
		    The face, f, is split by connecting two
194
				vertices (the next two arguments). */
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. */
195
		FaceIter split_face(FaceIter, VertexIter, VertexIter);
209
		FaceIter split_face(FaceIter f, VertexIter v0, VertexIter v1);
196
 
210
 
197
		/** Insert a new vertex on the halfedge given as argument.
211
		/** Insert a new vertex on halfedge h.
198
				The new halfedge is insterted as the previous edge to the one
212
				The new halfedge is insterted as the previous edge to h.
199
				given as argument.
213
				An iterator to the inserted vertex is	returned. */
200
		*/
-
 
201
		VertexIter Manifold::split_edge(HalfEdgeIter h);
214
		VertexIter Manifold::split_edge(HalfEdgeIter h);
202
 
215
 
203
		/** Triangulate a polygonal face by repeatedly calling split_face. 
216
		/** Triangulate a polygonal face by repeatedly calling split_face. 
204
				Triangulate iteratively splits triangles off a polygon. The first 
217
				Triangulate iteratively splits triangles off a polygon. The first 
205
				triangle split off is the one connecting f->last->vert and
218
				triangle split off is the one connecting f->last->vert and
206
				f->last->next->next->vert.
219
				f->last->next->next->vert.
207
		*/
220
		*/
208
		void triangulate(FaceIter);
221
		void triangulate(FaceIter f);
209
 
222
 
210
		/** Triangulate a polygon by inserting a vertex at the barycenter and 
223
		/** Triangulate a polygon, f, by inserting a vertex at the barycenter.
211
				connecting all vertices to this vertex. 
224
				All vertices in f are connected to the new vertex.				
212
				
-
 
213
				The word "safe" means that it is less likely to create flipped
225
				The word "safe" means that it is less likely to create flipped
214
				triangles than the normal triangulate. On the other hand, it 
226
				triangles than the normal triangulate. On the other hand, it 
215
				introduces more vertices and probably makes the triangles more
227
				introduces more vertices and probably makes the triangles more
216
				acute.
228
				acute. This function simply calls face_insert_point.
217
				
229
 
218
				This function simply calls face_insert_point.
230
				The inserted vertex is returned.
219
		*/
231
		*/
220
		VertexIter safe_triangulate(FaceIter f);
232
		VertexIter safe_triangulate(FaceIter f);
221
 
233
 
222
		/** Insert a new vertex (second arg.) in a face (first arg.).
234
		/** Insert a new vertex, v, in a face, f.
223
				This operation splits an N-gon into N triangles.
235
				This operation splits an N-gon into N triangles.
224
				In the current implementation the original face is erased. 
236
				In the current implementation the original face is erased. 
225
				This means that the iterator is not valid after the function
237
				This means that the iterator is not valid after the function
226
				returns. 
238
				returns. 
227
		*/
239
		*/
228
		void face_insert_point(FaceIter f, VertexIter);
240
		void face_insert_point(FaceIter f, VertexIter v);
229
 
241
 
230
		/** Merges two faces into a single polygon. The first face is the first
242
		/** Merges two faces into a single polygon. The first face is f.  The
231
				argument. The second face is adjacent to the first along 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
232
				halfedge given as second argument. */
246
				illegal. Thus it should, in fact, never fail. */
233
		bool merge_faces(FaceIter f, HalfEdgeIter h);
247
		bool merge_faces(FaceIter f, HalfEdgeIter h);
234
 
248
 
235
		/** Flip an edge. Returns false if flipping cannot be performed.
249
		/** Flip an edge h. Returns false if flipping cannot be performed.
236
				This is either because one of the two adjacent faces is not
250
				This is either because one of the two adjacent faces is not
237
				a triangle, or because either end point has valency three or
251
				a triangle, or because either end point has valency three or
238
				because the vertices that will be connected already are. */
252
				because the vertices that will be connected already are. */
239
		bool flip(HalfEdgeIter);
253
		bool flip(HalfEdgeIter h);
240
 
254
 
241
		/** Performs a series of tests to check that this is a valid manifold.
255
		/** Performs a series of tests to check that this is a valid manifold.
242
				This function is not rigorously constructed but seems to catch
256
				This function is not rigorously constructed but seems to catch
-
 
257
				all problems so far. The function returns true if the mesh is 
243
				all problems so far. */
258
				valid and false otherwise.
-
 
259
		*/
244
		bool is_valid();
260
		bool is_valid();
245
 
261
 
246
		/** Give each vertex a unique id corresponding to its iterator 
262
		/** Give each vertex a unique id corresponding to its iterator 
247
				position */
263
				position */
248
		void enumerate_vertices();
264
		void enumerate_vertices();