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.
|
39 |
bj |
18 |
Manifold keeps lists of the entities making up a halfedge mesh
|
|
|
19 |
and provides basic functions for creating new faces, halfedges
|
|
|
20 |
and vertices. There are also primitive operations for editing
|
|
|
21 |
such as edge collapse. */
|
155 |
jab |
22 |
class Manifold
|
158 |
jab |
23 |
{
|
|
|
24 |
std::list<Vertex> vertex_db;
|
|
|
25 |
std::list<Face> face_db;
|
|
|
26 |
std::list<HalfEdge> halfedge_db;
|
39 |
bj |
27 |
|
158 |
jab |
28 |
bool erase_immediately;
|
|
|
29 |
std::vector<VertexIter> unused_vertices;
|
|
|
30 |
std::vector<FaceIter> unused_faces;
|
|
|
31 |
std::vector<HalfEdgeIter> unused_halfedges;
|
39 |
bj |
32 |
|
|
|
33 |
|
158 |
jab |
34 |
/** Remove a face if it contains only two edges.
|
|
|
35 |
This is an auxiliary function called from collapse_halfedge. */
|
|
|
36 |
void remove_face_if_degenerate(HalfEdgeIter);
|
39 |
bj |
37 |
|
158 |
jab |
38 |
/** Empty copy constructor.
|
|
|
39 |
Copying a manifold will not work, since faces, vertices, and
|
|
|
40 |
halfedges contain iterators pointing to other faces, vertices,
|
|
|
41 |
and halfedges. These pointers would need to be changed if the
|
|
|
42 |
mesh were copied. In other words, we would need to walk the
|
|
|
43 |
entire mesh. This may be required but it should not be an
|
|
|
44 |
operation that is easily invoked by calling the copy constructor.
|
|
|
45 |
Hence, this operator is made private. */
|
|
|
46 |
Manifold(const Manifold&) {}
|
|
|
47 |
|
|
|
48 |
/** Empty assignment operator.
|
|
|
49 |
The assignment operator is private for the same reason that the
|
|
|
50 |
copy constructor is private. */
|
|
|
51 |
const Manifold& operator=(const Manifold&) {return *this;}
|
|
|
52 |
|
39 |
bj |
53 |
public:
|
|
|
54 |
|
158 |
jab |
55 |
/// Construct an empty manifold.
|
|
|
56 |
Manifold(): erase_immediately(true) {}
|
39 |
bj |
57 |
|
158 |
jab |
58 |
/** Return the bounding box of the manifold. The arguments pmin and pmax
|
|
|
59 |
will contain the extreme corners of the box when the function
|
|
|
60 |
returns. */
|
|
|
61 |
void get_bbox(CGLA::Vec3f& pmin, CGLA::Vec3f& pmax);
|
39 |
bj |
62 |
|
158 |
jab |
63 |
/** Get a bounding sphere. When the function returns c contains the
|
|
|
64 |
centre and r the radius. */
|
|
|
65 |
void get_bsphere(CGLA::Vec3f& c, float& r);
|
39 |
bj |
66 |
|
158 |
jab |
67 |
/// Return the number of faces.
|
|
|
68 |
size_t no_faces() const {return face_db.size();}
|
39 |
bj |
69 |
|
158 |
jab |
70 |
/// Return the number of halfedges.
|
|
|
71 |
size_t no_halfedges() const {return halfedge_db.size();}
|
39 |
bj |
72 |
|
158 |
jab |
73 |
/// Return the number of vertices
|
|
|
74 |
size_t no_vertices() const {return vertex_db.size();}
|
39 |
bj |
75 |
|
158 |
jab |
76 |
/** Create a new vertex.
|
|
|
77 |
The argument is the position of the vertex, and the
|
|
|
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 |
*/
|
|
|
82 |
VertexIter create_vertex(const CGLA::Vec3f& pos)
|
|
|
83 |
{
|
|
|
84 |
vertex_db.push_back(Vertex(pos));
|
|
|
85 |
return --vertex_db.end();
|
|
|
86 |
}
|
39 |
bj |
87 |
|
158 |
jab |
88 |
/** Create a new face.
|
|
|
89 |
An iterator to the face is returned. When a face f is initially
|
|
|
90 |
created, is_used(f) will return false. */
|
|
|
91 |
FaceIter create_face()
|
|
|
92 |
{
|
|
|
93 |
face_db.push_back(Face());
|
|
|
94 |
return --face_db.end();
|
|
|
95 |
}
|
39 |
bj |
96 |
|
158 |
jab |
97 |
/** Create a new halfedge. An iterator to the halfedge is returned.
|
|
|
98 |
When h is initially created, is_used(h) returns false. */
|
|
|
99 |
HalfEdgeIter create_halfedge()
|
|
|
100 |
{
|
|
|
101 |
halfedge_db.push_back(HalfEdge());
|
|
|
102 |
return --halfedge_db.end();
|
|
|
103 |
}
|
39 |
bj |
104 |
|
158 |
jab |
105 |
/// Clear the manifold - removing all data.
|
|
|
106 |
void clear();
|
39 |
bj |
107 |
|
158 |
jab |
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();
|
39 |
bj |
113 |
|
|
|
114 |
|
158 |
jab |
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.
|
39 |
bj |
125 |
|
158 |
jab |
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).
|
39 |
bj |
129 |
|
158 |
jab |
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 |
}
|
39 |
bj |
140 |
|
158 |
jab |
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.
|
39 |
bj |
145 |
|
158 |
jab |
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 |
}
|
113 |
jab |
153 |
|
158 |
jab |
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 |
}
|
136 |
jab |
163 |
|
158 |
jab |
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 |
}
|
113 |
jab |
173 |
|
158 |
jab |
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 |
}
|
113 |
jab |
183 |
|
158 |
jab |
184 |
/** Erase halfedge h.
|
|
|
185 |
In general, you should never call this function but use the
|
|
|
186 |
collapse_halfedge function instead since blindly erasing geometry
|
|
|
187 |
is most likely to invalidate the Mesh. Quite possibly this function
|
|
|
188 |
will be removed from the public interface.
|
|
|
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
|
|
|
195 |
takes place.
|
|
|
196 |
*/
|
|
|
197 |
void erase_halfedge(HalfEdgeIter h);
|
113 |
jab |
198 |
|
158 |
jab |
199 |
/** Erase vertex v.
|
|
|
200 |
In general, you should never call this function but use the
|
|
|
201 |
collapse_halfedge function to collapse the vertex away.
|
|
|
202 |
Blindly erasing is extremely likely to invalidate the
|
|
|
203 |
Mesh. Quite possibly this function will be removed from the
|
|
|
204 |
public interface.
|
113 |
jab |
205 |
|
158 |
jab |
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,
|
|
|
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.
|
|
|
212 |
*/
|
|
|
213 |
void erase_vertex(VertexIter v);
|
113 |
jab |
214 |
|
|
|
215 |
|
158 |
jab |
216 |
/** Erase face f.
|
|
|
217 |
In general, you should never call this function but use
|
|
|
218 |
collapse_halfedge in conjunction with other functions to
|
|
|
219 |
remove the face through (Euler) operations which preserve
|
|
|
220 |
the mesh in a valid state.
|
|
|
221 |
Blindly erasing is extremely likely to invalidate the
|
|
|
222 |
Mesh. Quite possibly this function will be removed from the
|
|
|
223 |
public interface.
|
113 |
jab |
224 |
|
158 |
jab |
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
|
|
|
230 |
takes place.
|
|
|
231 |
*/
|
|
|
232 |
void erase_face(FaceIter f);
|
113 |
jab |
233 |
|
158 |
jab |
234 |
/// Return iterator pointing to the first halfedge.
|
|
|
235 |
HalfEdgeIter halfedges_begin() { return halfedge_db.begin();}
|
136 |
jab |
236 |
|
158 |
jab |
237 |
/// Return iterator pointing to beyond the last halfedge.
|
|
|
238 |
HalfEdgeIter halfedges_end() { return halfedge_db.end(); }
|
133 |
jab |
239 |
|
158 |
jab |
240 |
/// Return iterator pointing to the first vertex.
|
|
|
241 |
VertexIter vertices_begin() { return vertex_db.begin();}
|
39 |
bj |
242 |
|
158 |
jab |
243 |
/// Return iterator pointing to beyond the last vertex.
|
|
|
244 |
VertexIter vertices_end() { return vertex_db.end(); }
|
39 |
bj |
245 |
|
158 |
jab |
246 |
/// Return iterator pointing to the first face.
|
|
|
247 |
FaceIter faces_begin() { return face_db.begin(); }
|
39 |
bj |
248 |
|
158 |
jab |
249 |
/// Return iterator pointing to beyond the last face.
|
|
|
250 |
FaceIter faces_end() { return face_db.end(); }
|
39 |
bj |
251 |
|
158 |
jab |
252 |
/** \brief HalfEdge collapse precondition.
|
136 |
jab |
253 |
|
158 |
jab |
254 |
The argument h is the halfedge we want to collapse.
|
39 |
bj |
255 |
|
158 |
jab |
256 |
If this function does not return true, it is illegal to collapse
|
|
|
257 |
h. The reason is that the collapse would violate the manifold property
|
|
|
258 |
of the mesh.
|
39 |
bj |
259 |
|
158 |
jab |
260 |
The test is as follows.
|
39 |
bj |
261 |
|
158 |
jab |
262 |
1. For the two vertices adjacent to the edge, we generate
|
|
|
263 |
a list of all their neighbouring vertices. We then generate a
|
|
|
264 |
list of the vertices that occur in both these lists. That is,
|
|
|
265 |
we find all vertices connected by edges to both endpoints
|
|
|
266 |
of the edge and store these in a list.
|
39 |
bj |
267 |
|
158 |
jab |
268 |
2. For both faces incident on the edge, check whether they
|
|
|
269 |
are triangular. If this is the case, the face will be removed,
|
|
|
270 |
and it is ok that the the third vertex is connected to both
|
|
|
271 |
endpoints. Thus the third vertex in such a face is removed
|
|
|
272 |
from the list generated in 1.
|
39 |
bj |
273 |
|
158 |
jab |
274 |
3. If the list is now empty, all is well. Otherwise, there
|
|
|
275 |
would be a vertex in the new mesh with two edges connecting
|
|
|
276 |
it to the same vertex. Return false.
|
39 |
bj |
277 |
|
158 |
jab |
278 |
4. TETRAHEDRON TEST:
|
|
|
279 |
If the valency of both vertices is
|
|
|
280 |
three, and the incident faces are triangles, we also disallow
|
|
|
281 |
the operation. Reason: It introduces a vertex of valency two
|
|
|
282 |
and if the final two polygons incident on the vertices
|
|
|
283 |
that are adjacent to the edge being collapsed are triangles, then
|
|
|
284 |
the construction will collapse
|
39 |
bj |
285 |
|
158 |
jab |
286 |
5. VALENCY 4 TEST:
|
|
|
287 |
If a face adjacent to the edge being collapsed is a triangle,
|
|
|
288 |
it will disappear, and the valency of the final vertex beloning to
|
|
|
289 |
this edge will be reduced by one. Hence this valency should be at
|
|
|
290 |
least 4. A valency three vertex will be reduced to a valency two
|
|
|
291 |
vertex which is considered illegal.
|
39 |
bj |
292 |
|
158 |
jab |
293 |
6. PREVENT MERGING HOLES:
|
|
|
294 |
We do not want to collapse an edge if its end points are boundary
|
|
|
295 |
vertices, but its two adjacent faces are not NULL faces, because
|
|
|
296 |
in that case we create a vertex where two holes meet. A non manifold
|
|
|
297 |
situation. */
|
|
|
298 |
bool collapse_precond(HalfEdgeIter h);
|
39 |
bj |
299 |
|
158 |
jab |
300 |
/** Collapse the halfedge h.
|
|
|
301 |
|
|
|
302 |
The argument h is the halfedge being removed. The vertex
|
|
|
303 |
v=h->opp->vert is the one being removed while h->vert survives.
|
|
|
304 |
|
|
|
305 |
The final argument is a boolean indicating whether the vertex
|
|
|
306 |
that survives the collapse should have a position which is the
|
|
|
307 |
average of its own position and the vertex that is removed.
|
|
|
308 |
By default false meaning that the surviving vertex retains it
|
|
|
309 |
position.
|
|
|
310 |
|
|
|
311 |
This function is not guaranteed to keep the mesh sane unless,
|
|
|
312 |
collapse_precond has returned true !!
|
|
|
313 |
*/
|
|
|
314 |
void collapse_halfedge(HalfEdgeIter h, bool=false);
|
|
|
315 |
|
|
|
316 |
/** Split a face.
|
|
|
317 |
The face, f, is split by connecting two
|
|
|
318 |
vertices v0 and v1 (the next two arguments). The vertices of
|
|
|
319 |
the old face between v0 and v1 (in counter clockwise order)
|
|
|
320 |
continue to belong to f. The vertices between v1 and
|
|
|
321 |
v0 belong to the new face. An iterator to the new face is
|
|
|
322 |
returned. */
|
|
|
323 |
FaceIter split_face(FaceIter f, VertexIter v0, VertexIter v1);
|
|
|
324 |
|
|
|
325 |
/** Insert a new vertex on halfedge h.
|
|
|
326 |
The new halfedge is insterted as the previous edge to h.
|
|
|
327 |
An iterator to the inserted vertex is returned. */
|
|
|
328 |
VertexIter Manifold::split_edge(HalfEdgeIter h);
|
|
|
329 |
|
|
|
330 |
/** Triangulate a polygonal face by repeatedly calling split_face.
|
|
|
331 |
Triangulate iteratively splits triangles off a polygon. The first
|
|
|
332 |
triangle split off is the one connecting f->last->vert and
|
|
|
333 |
f->last->next->next->vert.
|
|
|
334 |
*/
|
|
|
335 |
void triangulate(FaceIter f);
|
|
|
336 |
|
|
|
337 |
/** Triangulate a polygon, f, by inserting a vertex at the barycenter.
|
|
|
338 |
All vertices in f are connected to the new vertex.
|
|
|
339 |
The word "safe" means that it is less likely to create flipped
|
|
|
340 |
triangles than the normal triangulate. On the other hand, it
|
|
|
341 |
introduces more vertices and probably makes the triangles more
|
|
|
342 |
acute. This function simply calls face_insert_point.
|
|
|
343 |
|
|
|
344 |
The inserted vertex is returned.
|
|
|
345 |
*/
|
|
|
346 |
VertexIter safe_triangulate(FaceIter f);
|
|
|
347 |
|
|
|
348 |
/** Insert a new vertex, v, in a face, f.
|
|
|
349 |
This operation splits an N-gon into N triangles.
|
|
|
350 |
In the current implementation the original face is erased.
|
|
|
351 |
This means that the iterator is not valid after the function
|
|
|
352 |
returns.
|
|
|
353 |
*/
|
|
|
354 |
void face_insert_point(FaceIter f, VertexIter v);
|
|
|
355 |
|
|
|
356 |
/** Merges two faces into a single polygon. The first face is f. The
|
|
|
357 |
second face is adjacent to f along the halfedge h. This function
|
|
|
358 |
returns true if the merging was possible and false
|
|
|
359 |
otherwise. Currently merge only fails if the mesh is already
|
|
|
360 |
illegal. Thus it should, in fact, never fail. */
|
|
|
361 |
bool merge_faces(FaceIter f, HalfEdgeIter h);
|
|
|
362 |
|
|
|
363 |
/** Flip an edge h. Returns false if flipping cannot be performed.
|
|
|
364 |
This is either because one of the two adjacent faces is not
|
|
|
365 |
a triangle, or because either end point has valency three or
|
|
|
366 |
because the vertices that will be connected already are. */
|
|
|
367 |
bool flip(HalfEdgeIter h);
|
|
|
368 |
|
|
|
369 |
/** Performs a series of tests to check that this is a valid manifold.
|
|
|
370 |
This function is not rigorously constructed but seems to catch
|
|
|
371 |
all problems so far. The function returns true if the mesh is
|
|
|
372 |
valid and false otherwise.
|
|
|
373 |
*/
|
|
|
374 |
bool is_valid();
|
|
|
375 |
|
|
|
376 |
/** Give each vertex a unique id corresponding to its iterator
|
|
|
377 |
position */
|
|
|
378 |
void enumerate_vertices();
|
|
|
379 |
|
|
|
380 |
/** Give each halfedge a unique id corresponding to its iterator
|
|
|
381 |
position */
|
|
|
382 |
void enumerate_halfedges();
|
|
|
383 |
|
|
|
384 |
/** Give each face a unique id corresponding to its iterator
|
|
|
385 |
position */
|
|
|
386 |
void enumerate_faces();
|
|
|
387 |
|
|
|
388 |
};
|
|
|
389 |
|
|
|
390 |
|
39 |
bj |
391 |
}
|
|
|
392 |
#endif
|