Subversion Repositories gelsvn

Rev

Rev 155 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 155 Rev 158
Line 23... Line 23...
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;
-
 
29
			std::vector<VertexIter> unused_vertices;
-
 
30
			std::vector<FaceIter> unused_faces;
-
 
31
			std::vector<HalfEdgeIter> unused_halfedges;
-
 
32
 
-
 
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
 
32
		/** Empty copy constructor.
38
			/** Empty copy constructor.
Line 45... Line 51...
45
		const Manifold& operator=(const Manifold&) {return *this;}
51
			const Manifold& operator=(const Manifold&) {return *this;}
46
 
52
 
47
		public:
53
		public:
48
	
54
 
49
		/// Construct an empty manifold.
55
			/// Construct an empty manifold.
50
		Manifold() {}
56
			Manifold(): erase_immediately(true) {}
51
 
57
 
52
  	/** Return the bounding box of the manifold. The arguments pmin and pmax
58
			/** 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.
59
					will contain the extreme corners of the box when the function 
54
		 */
60
					returns.	*/
55
		void get_bbox(CGLA::Vec3f& pmin, CGLA::Vec3f& pmax);
61
			void get_bbox(CGLA::Vec3f& pmin, CGLA::Vec3f& pmax);
56
 
62
 
57
		/** Get a bounding sphere. When the function returns c contains the 
63
			/** Get a bounding sphere. When the function returns c contains the
58
				centre and r the radius. */ 
64
					centre and r the radius. */ 
59
    void get_bsphere(CGLA::Vec3f& c, float& r);
65
			void get_bsphere(CGLA::Vec3f& c, float& r);
60
 
66
 
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.
67
			/// Return the number of faces.
70
		size_t no_faces() const {return face_db.size();}
68
			size_t no_faces() const {return face_db.size();}
71
 
69
 
72
		/// Return the number of halfedges.
70
			/// Return the number of halfedges.
73
		size_t no_halfedges() const {return halfedge_db.size();}
71
			size_t no_halfedges() const {return halfedge_db.size();}
Line 75... Line 73...
75
		/// Return the number of vertices
73
			/// Return the number of vertices
76
		size_t no_vertices() const {return vertex_db.size();}
74
			size_t no_vertices() const {return vertex_db.size();}
77
 
75
 
78
		/** Create a new vertex. 
76
			/** Create a new vertex.
79
				The argument is the position of the vertex, and the 
77
					The argument is the position of the vertex, and the 
80
				function returns an iterator pointing to the vertex. */
78
					function returns an iterator pointing to the vertex.
-
 
79
					When a vertex v is initially created, is_used(v) will
-
 
80
					return false.
-
 
81
			*/
81
		VertexIter create_vertex(const CGLA::Vec3f& pos)
82
			VertexIter create_vertex(const CGLA::Vec3f& pos)
82
		{
83
				{
83
			vertex_db.push_back(Vertex(pos));
84
					vertex_db.push_back(Vertex(pos));
84
			return --vertex_db.end();
85
					return --vertex_db.end();
85
		}
86
				}
86
 
87
 
87
		/** Create a new face. 
88
			/** Create a new face.
88
				An iterator to the face is returned. */
89
					An iterator to the face is returned. When a face f is initially
-
 
90
					created, is_used(f) will return false. */
89
		FaceIter create_face()
91
			FaceIter create_face()
90
		{
92
				{
91
			face_db.push_back(Face());
93
					face_db.push_back(Face());
92
			return --face_db.end();
94
					return --face_db.end();
93
		}
95
				}
94
 
96
 
95
  	/** Create a new halfedge. An iterator to the halfedge is returned. */
97
			/** Create a new halfedge. An iterator to the halfedge is returned.
-
 
98
					When h is initially created, is_used(h) returns false. */
96
		HalfEdgeIter create_halfedge()
99
			HalfEdgeIter create_halfedge()
97
		{
100
				{
98
			halfedge_db.push_back(HalfEdge());
101
					halfedge_db.push_back(HalfEdge());
99
			return --halfedge_db.end();
102
					return --halfedge_db.end();
100
		}
103
				}
101
 
104
 
-
 
105
			/// Clear the manifold - removing all data.
-
 
106
			void clear();
-
 
107
 
-
 
108
			/** Remove unused vertices, edges and faces from the database.
-
 
109
					If delayed_erase mode is enabled, then until this function 
-
 
110
					has been called, erased vertices, edges, and faces are just marked
-
 
111
					as unused but not removed from their respective lists. */
-
 
112
			void remove_unused();
-
 
113
 
-
 
114
 
-
 
115
			/** Delay the actual removal of vertices, faces, and edges that
-
 
116
					are erased.  In many cases, it is a problem if one cannot
-
 
117
					test whether a vertex, halfedge, or face indicated by an
-
 
118
					iterator is in use or has been removed from the mesh. One
-
 
119
					solution to this problem is to delay the actual removal of
-
 
120
					the vertex, edge or face. Instead when calling, say,
-
 
121
					erase_face(f), all the iterators of f are assigned the
-
 
122
					appropriate NULL value to indicate that they are not
-
 
123
					pointing at anything, and f is added to a vector of faces
-
 
124
					that need to be physically removed from the face_db.
-
 
125
 
-
 
126
					Since f is not erased, all iterators pointing at f remain
-
 
127
					valid! And, importantly, it is possible to test whether f is
-
 
128
					in use by calling is_used(f).
-
 
129
 
-
 
130
					When remove_unused is called, the physical removal takes
-
 
131
					place. Calling immediate_erase switches Manifold back to the
-
 
132
					state where entities are removed as soon as the appropriate
-
 
133
					erase function is called, and at the same time calls
-
 
134
					remove_unused.
-
 
135
			*/
-
 
136
			void delayed_erase()
-
 
137
				{
-
 
138
					erase_immediately = false;
-
 
139
				}
-
 
140
 
-
 
141
			/** Immediately remove erased entities.
-
 
142
					Calling immediate_erase switches Manifold back to the state
-
 
143
					where entities are removed as soon as the appropriate erase
-
 
144
					function is called.
-
 
145
 
-
 
146
					See delayed_erase for more details, and note that
-
 
147
					immediate_erase is the default mode.  */
-
 
148
			void immediate_erase()
-
 
149
				{
-
 
150
					erase_immediately = true;
-
 
151
					remove_unused();
-
 
152
				}
-
 
153
 
-
 
154
			/** Test whether the vertex indicated by the argument v is used.
-
 
155
					This function returns true if the vertex appears to have a 
-
 
156
					valid outgoing halfedge iterator. */
-
 
157
			bool is_used(VertexIter v) const
-
 
158
				{
-
 
159
					if(v->he == NULL_HALFEDGE_ITER)
-
 
160
						return false;
-
 
161
					return true;
-
 
162
				}
-
 
163
 
-
 
164
			/** Test whether the face indicated by the argument f is used.
-
 
165
					This function returns true if the face appears to have a 
-
 
166
					valid halfedge iterator. */
-
 
167
			bool is_used(FaceIter f) const
-
 
168
				{
-
 
169
					if(f->last == NULL_HALFEDGE_ITER)
-
 
170
						return false;
-
 
171
					return true;
-
 
172
				}
-
 
173
 
-
 
174
			/** Test whether the halfedge indicated by the argument h is used.
-
 
175
					This function returns true if the halfedge appears to have a 
-
 
176
					valid vertex iterator. */
-
 
177
			bool is_used(HalfEdgeIter h) const
-
 
178
				{
-
 
179
					if(h->vert == NULL_VERTEX_ITER)
-
 
180
						return false;
-
 
181
					return true;
-
 
182
				}
-
 
183
 
102
		/** Erase halfedge h. 
184
			/** Erase halfedge h. 
103
				In general, you should never call this function but use the 
185
					In general, you should never call this function but use the 
104
				collapse_halfedge function instead since blindly erasing geometry
186
					collapse_halfedge function instead since blindly erasing geometry
105
				is most likely to invalidate the Mesh. Quite possibly this function
187
					is most likely to invalidate the Mesh. Quite possibly this function
106
				will be removed from the public interface. */
188
					will be removed from the public interface. 
107
		void erase_halfedge(HalfEdgeIter h)
-
 
108
		{
189
					
-
 
190
					Note that if delayed_erase has been called, this function does
-
 
191
					not immediately remove anything from the mesh. Instead the halfedge
-
 
192
					is reset to its initial state. Thus, iterators are not invalidated,
-
 
193
					and it is possible to test whether h is used calling:
-
 
194
					is_used(h). when remove_unused is called, the actual removal
109
			halfedge_db.erase(h);
195
					takes place.
110
		}
196
			*/
-
 
197
			void erase_halfedge(HalfEdgeIter h);
111
 
198
 
112
		/** Erase vertex v.
199
			/** Erase vertex v.
113
				In general, you should never call this function but use the 
200
					In general, you should never call this function but use the 
114
				collapse_halfedge function to collapse the vertex away.
201
					collapse_halfedge function to collapse the vertex away.
115
				Blindly erasing is extremely likely to invalidate the
202
					Blindly erasing is extremely likely to invalidate the
116
				Mesh. Quite possibly this function will be removed from the
203
					Mesh. Quite possibly this function will be removed from the
117
				public interface. */
204
					public interface. 
-
 
205
 
-
 
206
					Note that if delayed_erase has been called, this function does
-
 
207
					not immediately remove anything from the mesh. Instead the halfedge
-
 
208
					is reset to its initial state. Thus, iterators are not invalidated,
118
		void erase_vertex(VertexIter v)
209
					and it is possible to test whether v is used calling:
-
 
210
					is_used(v). when remove_unused is called, the actual removal
-
 
211
					takes place.
119
		{
212
			*/
120
			vertex_db.erase(v);
213
			void erase_vertex(VertexIter v);
121
		}
214
 
122
	
215
 
123
		/** Erase face f. 
216
			/** Erase face f.
124
				In general, you should never call this function but use 
217
					In general, you should never call this function but use 
125
				collapse_halfedge in conjunction with other functions to
218
					collapse_halfedge in conjunction with other functions to
126
				remove the face through (Euler) operations which preserve
219
					remove the face through (Euler) operations which preserve
127
				the mesh in a valid state.
220
					the mesh in a valid state.
128
				Blindly erasing is extremely likely to invalidate the
221
					Blindly erasing is extremely likely to invalidate the
129
				Mesh. Quite possibly this function will be removed from the
222
					Mesh. Quite possibly this function will be removed from the
130
				public interface. */
223
					public interface. 
-
 
224
 
-
 
225
					Note that if delayed_erase has been called, this function does
-
 
226
					not immediately remove anything from the mesh. Instead the face
-
 
227
					is reset to its initial state. Thus, iterators are not invalidated,
-
 
228
					and it is possible to test whether f is used calling:
-
 
229
					is_used(f). when remove_unused is called, the actual removal
131
		void erase_face(FaceIter f)
230
					takes place.
132
		{
231
			*/
133
			face_db.erase(f);
232
			void erase_face(FaceIter f);
134
		}
-
 
135
 
233
 
136
		/// Return iterator pointing to the first halfedge.
234
			/// Return iterator pointing to the first halfedge.
137
		HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
235
			HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
138
 
236
 
139
		/// Return iterator pointing to beyond the last halfedge.
237
			/// Return iterator pointing to beyond the last halfedge.