Subversion Repositories gelsvn

Rev

Rev 39 | Rev 113 | 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.
18
 
39 bj 19
			Manifold keeps lists of the entities making up a halfedge mesh
20
			and provides basic functions for creating new faces, halfedges
21
			and vertices. There are also primitive operations for editing 
22
			such as edge collapse. */
23
	struct Manifold
24
	{
25
		std::list<Vertex> vertex_db;
26
		std::list<Face> face_db;
27
		std::list<HalfEdge> halfedge_db;
28
 
89 jab 29
		/** Remove a face if it contains only two edges.
30
 
31
		This is an auxiliary function called from collapse_halfedge. */
39 bj 32
		void remove_face_if_degenerate(HalfEdgeIter fi);
33
 
89 jab 34
		/** Empty copy constructor.
35
 
36
		Copying a manifold will not work, since faces, vertices, and
39 bj 37
				halfedges contain iterators pointing to other faces, vertices,
38
				and halfedges. These pointers would need to be changed if the 
39
				mesh were copied. In other words, we would need to walk the
40
				entire mesh. This may be required but it should not be an 
41
				operation that is easily invoked by calling the copy constructor.
42
				Hence, this operator is made private.		*/
43
		Manifold(const Manifold& m2) {}
44
 
89 jab 45
		/** Empty assignment operator.
46
 
47
		The assignment operator is private for the same reason that the
39 bj 48
				copy constructor is private. */
49
		const Manifold& operator=(const Manifold& m2) {}
50
 
51
		public:
52
 
53
		/// Construct an empty manifold.
54
		Manifold() {}
55
 
56
		/// Return the bounding box of the manifold.
57
		void get_bbox(CGLA::Vec3f&, CGLA::Vec3f&);
58
 
59
		/// Get a bounding sphere
60
    void get_bsphere(CGLA::Vec3f& c, float& r);
61
 
62
		/// Clear the manifold - removing all data.
63
		void clear()
64
		{
65
			vertex_db.clear();
66
			face_db.clear();
67
			halfedge_db.clear();
68
		}
69
 
70
		/// Return the number of faces.
71
		int no_faces() const {return face_db.size();}
72
 
73
		/// Return the number of halfedges.
74
		int no_halfedges() const {return halfedge_db.size();}
75
 
76
		/// Return the number of vertices
77
		int no_vertices() const {return vertex_db.size();}
78
 
79
		/// Create a new vertex at a given position.
80
		VertexIter create_vertex(const CGLA::Vec3f& pos)
81
		{
82
			vertex_db.push_back(Vertex(pos));
83
			return --vertex_db.end();
84
		}
85
 
86
		/// Create a new face 
87
		FaceIter create_face()
88
		{
89
			face_db.push_back(Face());
90
			return --face_db.end();
91
		}
92
 
93
		/// Create a new halfedge.
94
		HalfEdgeIter create_halfedge()
95
		{
96
			halfedge_db.push_back(HalfEdge());
97
			return --halfedge_db.end();
98
		}
99
 
100
		/// Erase halfedge. Assumes it is safe to do so. Use with care.
101
		void erase_halfedge(HalfEdgeIter he)
102
		{
103
			halfedge_db.erase(he);
104
		}
105
 
106
		/// Erase vertex. Assumes it is safe to do so. Use with care.
107
		void erase_vertex(VertexIter v)
108
		{
109
			vertex_db.erase(v);
110
		}
111
 
112
		/// Erase face. Assumes it is safe to do so. Use with care.
113
		void erase_face(FaceIter f)
114
		{
115
			face_db.erase(f);
116
		}
117
 
118
		/// Return iterator pointing to the first halfedge.
119
		HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
120
 
121
		/// Return iterator pointing to beyond the last halfedge.
122
		HalfEdgeIter halfedges_end() { return halfedge_db.end(); }
123
 
124
		/// Return iterator pointing to the first vertex.
125
		VertexIter vertices_begin() { return vertex_db.begin();}
126
 
127
		/// Return iterator pointing to beyond the last vertex.
128
		VertexIter vertices_end() { return vertex_db.end(); }
129
 
130
		/// Return iterator pointing to the first face.
131
		FaceIter faces_begin() { return face_db.begin();	}
132
 
133
		/// Return iterator pointing to beyond the last face.
134
		FaceIter faces_end() { return face_db.end(); }
135
 
136
		/** HalfEdge collapse precondition. 
137
				If this function does not return true, it is illegal to collapse
138
				the halfedge given as second arg. The reason is that the collapse
139
				would violate the manifold property of the mesh. */
140
		bool collapse_precond(VertexIter, HalfEdgeIter);
141
 
142
		/** Collapse the halfedge given as second argument. The first argument
143
				is the vertex that is being removed. This function is not guaranteed
144
				to keep the mesh sane unless, collapse_precond has returned true. */
145
		void collapse_halfedge(VertexIter, HalfEdgeIter, bool=false);
146
 
147
		/** Split a face (first argument) by connecting two vertices (the
148
				next two arguments). */
149
		FaceIter split_face(FaceIter, VertexIter, VertexIter);
150
 
151
		/** Insert a new vertex on the halfedge given as argument. */
152
		VertexIter Manifold::split_edge(HalfEdgeIter h);
153
 
154
		/** Triangulate a polygonal face by repeatedly calling splitface. */
155
		void triangulate(FaceIter);
156
 
157
		/** Triangulate a polygon by inserting a vertex at the barycenter and 
158
				connecting all vertices to this vertex. */
159
		VertexIter safe_triangulate(FaceIter f);
160
 
161
		/** Insert a new vertex (second arg.) in a face (first arg.).
162
				This operation splits an N-gon into N triangles. */
163
		void face_insert_point(FaceIter f, VertexIter);
164
 
165
		/** Merges two faces into a single polygon. The first face is the first
166
				argument. The second face is adjacent to the first along the
167
				halfedge given as second argument. */
168
		bool merge_faces(FaceIter f, HalfEdgeIter h);
169
 
170
		/** flips an edge. Returns false if flipping cannot be performed.
171
				This is either because one of the two adjacent faces is not
172
				a triangle, or because either end point has valency three or
173
				because the vertices that will be connected already are. */
174
		bool flip(HalfEdgeIter);
175
 
176
		/** Performs a series of tests to check that this is a valid manifold.
177
				This function is not rigorously constructed but seems to catch
178
				all problems so far. */
179
		bool is_valid();
180
 
181
		/** Give each vertex a unique id corresponding to its iterator 
182
				position */
183
		void enumerate_vertices();
184
 
185
		/** Give each halfedge a unique id corresponding to its iterator 
186
				position */
187
		void enumerate_halfedges();
188
 
189
		/** Give each face a unique id corresponding to its iterator 
190
				position */
191
		void enumerate_faces();
192
 
193
	};
194
 
195
 
196
}
197
#endif