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
|