-
Notifications
You must be signed in to change notification settings - Fork 0
/
vertex.h
293 lines (238 loc) · 7.87 KB
/
vertex.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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#ifndef __vertex_h
#define __vertex_h
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#pragma warning(disable:4710) // function not inlined
#pragma warning(disable:4702) // unreachable code
#pragma warning(disable:4514) // unreferenced inline function has been removed
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
//using namespace std;
#include <vector>
#include <set>
#include "vec3.h"
#include "triangle.h"
using namespace std;
class Mesh;
// Used to store an edge -- two vertices which have only one
// triangle in common form an edge of the mesh.
struct border
{
int vert1;
int vert2;
int triIndex;
// We need operator< because it's used by the STL's set<> to determine equality
// (if (not a<b) and (not b>a) then a is equal to b)
bool operator<(const border& b) const
{
int v1, v2, b1, b2;
// make sure the smaller vert index is always first.
if (vert1 < vert2) {
v1 = vert1; v2 = vert2;
} else {
v1 = vert2; v2 = vert1;
}
if (b.vert1 < b.vert2) {
b1 = b.vert1; b2 = b.vert2;
} else {
b1 = b.vert2; b2 = b.vert1;
}
if (v1 < b1) return true;
if (v1 > b1) return false;
return (v2 < b2); // v1 == b1
}
};
// A vertex has both a position and a normal
class vertex
{
public:
// Constructors and Destructors
vertex() :
_myVertex(0.0, 0.0, 0.0), _vertexNormal(0.0, 0.0, 0.0),
_bActive(false), _cost(0), _minCostNeighbor(-1),
_index(-1), _QTriArea(0)
{
initQuadric();
};
vertex(float x1, float y1, float z1) :
_myVertex(x1, y1, z1), _vertexNormal(0.0, 0.0, 0.0),
_bActive(true), _cost(0), _minCostNeighbor(-1),
_index(-1), _QTriArea(0)
{
initQuadric();
};
vertex(float av[3]):
_myVertex(av), _vertexNormal(0.0, 0.0, 0.0),
_bActive(true), _cost(0), _minCostNeighbor(-1),
_index(-1), _QTriArea(0)
{
initQuadric();
};
vertex(float av[3], float vn[3]):
_myVertex(av), _vertexNormal(vn),
_bActive(true),_cost(0), _minCostNeighbor(-1),
_index(-1), _QTriArea(0)
{
initQuadric();
};
// copy ctor
vertex(const vertex& v) : _myVertex(v._myVertex), _vertexNormal(v._vertexNormal),
_vertNeighbors(v._vertNeighbors), _triNeighbors(v._triNeighbors),
_bActive(v._bActive), _cost(v._cost),
_minCostNeighbor(v._minCostNeighbor),
_index(v._index), _QTriArea(v._QTriArea)
{
// copy quadric
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
_Q[i][j] = v._Q[i][j];
}
}
};
// destructor
~vertex() {_vertNeighbors.erase(_vertNeighbors.begin(), _vertNeighbors.end());
_triNeighbors.erase(_triNeighbors.begin(), _triNeighbors.end());};
// Assignment operator
vertex& operator=(const vertex& v)
{
if (this == &v) return *this; // check for assignment to self
_myVertex =v._myVertex;
_vertexNormal = v._vertexNormal;
_vertNeighbors = v._vertNeighbors;
_triNeighbors = v._triNeighbors;
_bActive = v._bActive;
_cost = v._cost;
_minCostNeighbor = v._minCostNeighbor;
_index = v._index;
_QTriArea = v._QTriArea;
// copy quadric
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
_Q[i][j] = v._Q[i][j];
}
}
return *this;
};
// Assignment operator
vertex& operator=(const float av[3])
{
_myVertex.x=av[0];_myVertex.y=av[1];_myVertex.z=av[2];
// erase the list of neighboring vertices, faces
// since we're copying from an array of floats
_vertNeighbors.erase(_vertNeighbors.begin(), _vertNeighbors.end());
_triNeighbors.erase(_triNeighbors.begin(), _triNeighbors.end());
_cost = 0;
_minCostNeighbor = -1;
_index = -1;
_QTriArea = 0;
initQuadric();
return *this;
};
// Comparision operators
bool operator==(const vertex& v) {return (_myVertex == v._myVertex && _vertexNormal == v._vertexNormal);};
bool operator!=(const vertex& v) {return (_myVertex != v._myVertex || _vertexNormal != v._vertexNormal);};
// Input and Output
friend std::ostream& operator<<(std::ostream& , const vertex& );
// friend istream&
// operator>>(istream& is, vertex& vi);
// NOTE: a better solution would be to return a reference
const float* getArrayVerts() const {
_v[0]=_myVertex.x;
_v[1]=_myVertex.y;
_v[2]=_myVertex.z;
return _v;}
const float* getArrayVertNorms() const {
_vn[0]=_vertexNormal.x;
_vn[1]=_vertexNormal.y;
_vn[2]=_vertexNormal.z;
return _vn;}
// a vertex neighbor is connected by an edge
void addVertNeighbor(int v)
{
_vertNeighbors.insert(v);
}
// remove a vertex which is no longer connected by an edge
unsigned removeVertNeighbor(int v) {return _vertNeighbors.erase(v);}
// a triangle neighbor is a triangle which uses this vertex
void addTriNeighbor(int t)
{
_triNeighbors.insert(t);
}
// remove triangle if it no longer uses this vertex
unsigned removeTriNeighbor(int t) {return _triNeighbors.erase(t);}
Vec3& getXYZ() {return _myVertex;};
const Vec3& getXYZ() const {return _myVertex;};
// if a vertex is removed, we set a flag
bool isActive() const {return _bActive;};
void setActive(bool b) {_bActive = b;};
const set<int>& getVertNeighbors() const {return _vertNeighbors;}
set<int>& getVertNeighbors() {return _vertNeighbors;}
const set<int>& getTriNeighbors() const {return _triNeighbors;}
set<int>& getTriNeighbors() {return _triNeighbors;}
bool hasVertNeighbor(int v) const {return (_vertNeighbors.find(v) != _vertNeighbors.end());}
bool hasTriNeighbor(int t) const {return (_triNeighbors.find(t) != _triNeighbors.end());}
// edge remove costs are used in mesh simplification
double edgeRemoveCost() {return _cost;};
void setEdgeRemoveCost(double f) {_cost = f;};
int minCostEdgeVert() const {return _minCostNeighbor;};
void setMinCostEdgeVert(int i) {_minCostNeighbor = i;}
double getCost() const {return _cost;}
// operator< & operator> are used to order vertices by edge removal costs
bool operator<(const vertex& v) const {return (_cost < v._cost);}
bool operator>(const vertex& v) const {return (_cost > v._cost);}
int getIndex() const {return _index;}
void setIndex(int i) {_index = i;}
// Used for Garland & Heckbert's quadric edge collapse cost (used for mesh simplifications/progressive meshes)
void calcQuadric(Mesh& m, bool bUseTriArea); // calculate the 4x4 Quadric matrix
void getQuadric(double Qret[4][4])
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
Qret[i][j] = _Q[i][j];
}
}
}
void setQuadric(double Qnew[4][4])
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
_Q[i][j] = Qnew[i][j];
}
}
}
bool isBorder(Mesh& m); // is this vertex on the border
// (i.e. is there an edge which uses this vertex which
// is only used for one triangle?)
// Used for Gouraud shading
void setVertNomal(const Vec3& vn) {_vertexNormal = vn;};
double getQuadricSummedTriArea() {return _QTriArea;};
void setQuadricSummedTriArea(double newArea) {_QTriArea = newArea;};
// Is the current vertex on an edge? If so, get edge information.
// This is used to put constraints on the border so that the mesh
// edges aren't "eaten away" by the mesh simplification.
void getAllBorderEdges(set<border> &borderSet, Mesh& m);
private:
Vec3 _myVertex; // X, Y, Z position of this vertex
Vec3 _vertexNormal; // vertex normal, used for Gouraud shading
set<int> _vertNeighbors; // connected to this vertex via an edge
set<int> _triNeighbors; // triangles of which this vertex is a part
bool _bActive; // false if vertex has been removed
double _cost; // cost of removing this vertex from Progressive Mesh
int _minCostNeighbor; // index of vertex at other end of the min. cost edge
int _index;
mutable float _v[3];
mutable float _vn[3];
double _Q[4][4]; // Used for Quadric error cost.
double _QTriArea; // summed area of triangles used to computer quadrics
// Used for Garland & Heckbert's quadric edge collapse cost (used for mesh simplifications/progressive meshes)
void initQuadric()
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
_Q[i][j] = -1;
}
}
}
};
#endif // #ifndef __vertex_h