-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmesh.h
246 lines (214 loc) · 7.07 KB
/
mesh.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#ifndef __MESH_H__
#define __MESH_H__
#include <cstdlib>
#include <vector>
#include "vector3.h"
// classes
class HEdge;
class Vertex;
class Face;
class Mesh;
class OneRingHEdge;
class OneRingVertex;
class FaceEnumeration;
// types
typedef std::vector<HEdge*> HEdgeList;
typedef std::vector<Vertex*> VertexList;
typedef std::vector<Face*> FaceList;
// other helper functions
inline void SetPrevNext(HEdge *e1, HEdge *e2);
inline void SetTwin(HEdge *e1, HEdge *e2);
inline void SetFace(Face *f, HEdge *e);
////////// class HEdge //////////
class HEdge {
private:
HEdge *twin, *prev, *next; // twin/previous/next half edges
Vertex *start; // start vertex
Face *face; // left face
bool boundary; // flag for boundary edge
bool valid;
// it's for count boundary loop use,
// you can use it freely for marking in boundary loop counting
// and connected component counting
bool flag;
public:
/////////////////////////////////////
// constructor
HEdge(bool b=false) {
boundary = b;
twin = prev = next = NULL;
start = NULL;
face = NULL;
flag = false;
valid = true;
}
/////////////////////////////////////
// access functions
HEdge* Twin() const { return twin; }
HEdge* Prev() const { return prev; }
HEdge* Next() const { return next; }
Vertex* Start() const { return start; }
Vertex* End() const { return next->start; } // for convenience
Face* LeftFace() const { return face; }
bool Flag() const { return flag; }
HEdge* SetTwin(HEdge* e) { return twin = e; }
HEdge* SetPrev(HEdge* e) { return prev = e; }
HEdge* SetNext(HEdge* e) { return next = e; }
Vertex* SetStart(Vertex* v) { return start = v; }
Face* SetFace(Face* f) { return face = f; }
bool SetFlag(bool b) { return flag = b; }
bool SetValid(bool b) { return valid = b; }
bool IsBoundary() const { return boundary; }
bool IsValid() const { return valid; }
};
////////// class OneRingHEdge //////////
// this class is use for access the neighbor HALF EDGES
// of a given vertex, please see Vertex::IsBoundary() for its usage
class OneRingHEdge {
private:
HEdge *start, *next;
public:
OneRingHEdge(const Vertex * v); // constructor
HEdge * NextHEdge(); // iterator
};
////////// class OneRingVertex //////////
// this class is use for access the neighbor VERTICES
// of a given vertex, please see Vertex::Valence() for its usage
class OneRingVertex {
private:
OneRingHEdge ring;
public:
OneRingVertex(const Vertex * v) : ring(v) { } // constructor
Vertex * NextVertex() { HEdge *he=ring.NextHEdge(); return (he)?he->End():NULL; } // iterator
};
////////// class Vertex //////////
class Vertex {
private:
Vector3d position; // position (x,y,z) in space
Vector3d normal; // normal vector for smooth shading rendering
Vector3d color; // color value for curvature displaying
HEdge *he; // one of half edge starts with this vertex
int index; // index in the Mesh::vList, DO NOT UPDATE IT
int flag; // 0 for unselected, 1 for selected
bool valid;
public:
vector<HEdge*> adjHEdges; // for reading object only, do not use it in other place
// constructors
Vertex() : he(NULL), flag(0), valid(true) { }
Vertex(const Vector3d & v) : he(NULL), position(v), flag(0), valid(true) { }
Vertex(double x, double y, double z) : he(NULL), position(x,y,z), flag(0), valid(true) { }
// access functions
const Vector3d & Position() const { return position; }
const Vector3d & Normal() const { return normal; }
const Vector3d & Color() const { return color; }
HEdge * HalfEdge() const { return he; }
int Index() const { return index; }
int Flag() const { return flag; }
const Vector3d & SetPosition(const Vector3d & p) { return position = p; }
const Vector3d & SetNormal(const Vector3d & n) { return normal = n; }
const Vector3d & SetColor(const Vector3d & c) { return color = c; }
HEdge * SetHalfEdge(HEdge * he) { return Vertex::he = he; }
int SetIndex(int index) { return Vertex::index = index; }
int SetFlag(int value) { return Vertex::flag = value; }
bool IsValid() const { return valid; }
bool SetValid(bool b) { return valid = b; }
// check for boundary vertex
bool IsBoundary() const {
OneRingHEdge ring(this);
HEdge *curr = NULL;
while (curr=ring.NextHEdge()) if (curr->IsBoundary()) return true;
return false;
}
// compute the valence (# of neighbor vertices)
int Valence() const {
int count = 0;
OneRingVertex ring(this);
Vertex *curr = NULL;
while (curr=ring.NextVertex()) count++;
return count;
}
};
////////// class Face //////////
class Face {
private:
HEdge * he;
bool valid;
public:
// constructor
Face() : he(NULL), valid(true) { }
// access function
HEdge * HalfEdge() const { return he; }
HEdge * SetHalfEdge(HEdge * he) { return Face::he = he; }
// check for boundary face
bool IsBoundary() {
HEdge *curr = he;
do {
if (curr->Twin()->IsBoundary()) return true;
curr = curr->Next();
} while (curr != he);
return false;
}
bool SetValid(bool b) { return valid = b; }
bool IsValid() const { return valid;}
};
////////// class Mesh //////////
class Mesh {
public:
HEdgeList heList; // list of NON-boundary half edges
HEdgeList bheList; // list of boundary half egdes
VertexList vList; // list of vertices
FaceList fList; // list of faces
// constructor & destructors
Mesh() { }
~Mesh() { Clear(); }
// access functions
const HEdgeList Edges() const { return heList; }
const HEdgeList BoundaryEdges() const { return bheList; }
const VertexList Vertices() const { return vList; }
const FaceList Faces() const { return fList; }
// functions for loading obj files,
// you DO NOT need to understand and use them
void AddVertex(Vertex *v) { vList.push_back(v); }
void AddFace(int v1, int v2, int v3);
void Clear() {
size_t i;
for (i=0; i<heList.size(); i++) delete heList[i];
for (i=0; i<bheList.size(); i++) delete bheList[i];
for (i=0; i<vList.size(); i++) delete vList[i];
for (i=0; i<fList.size(); i++) delete fList[i];
heList.clear();
bheList.clear();
vList.clear();
fList.clear();
}
Vector3d MinCoord() const {
Vector3d minCoord;
for (size_t i=0; i<vList.size(); i++)
minCoord = minCoord.Min((vList[i])->Position());
return minCoord;
}
Vector3d MaxCoord() const {
Vector3d maxCoord;
for (size_t i=0; i<vList.size(); i++)
maxCoord = maxCoord.Max(vList[i]->Position());
return maxCoord;
}
bool LoadObjFile(const char * filename);
/************************************************************************/
/* please implement the following functions */
void DisplayMeshInfo();
void ComputeVertexNormals();
void ComputeVertexCurvatures();
void UmbrellaSmooth();
void ImplicitUmbrellaSmooth();
/************************************************************************/
// additional helper functions
// implement them if in needed
int CountBoundaryLoops();
int CountConnectedComponents();
};
// other helper functions
inline void SetPrevNext(HEdge *e1, HEdge *e2) { e1->SetNext(e2); e2->SetPrev(e1); }
inline void SetTwin(HEdge *e1, HEdge *e2) { e1->SetTwin(e2); e2->SetTwin(e1); }
inline void SetFace(Face *f, HEdge *e) { f->SetHalfEdge(e); e->SetFace(f); }
#endif // __MESH_H__