-
Notifications
You must be signed in to change notification settings - Fork 0
/
dcel.h
192 lines (156 loc) · 4.29 KB
/
dcel.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
#pragma once
#include "pch.h"
namespace dcel {
// Forward classes
class edge;
class face;
class vertex;
class plane;
// Vertex pointer type
using vertex_ptr = std::shared_ptr<vertex>;
// Edge pointer type
using edge_ptr = std::shared_ptr<edge>;
// Face pointer type
using face_ptr = std::shared_ptr<face>;
// Plane pointer type
using plane_ptr = std::shared_ptr<plane>;
template <bool Const = false>
class face_iterator {
public:
/* Difference type */
using difference_type = std::size_t;
/** Value type */
using value_type = edge_ptr;
/* Pointer type */
using pointer =
std::conditional_t<Const, value_type const*, value_type*>;
/* Reference type */
using reference =
std::conditional_t<Const, value_type const&, value_type&>;
/*Iterator category */
using iterator_category = std::input_iterator_tag;
/* Default constructor == End iterator */
face_iterator() = default;
/** Construct from head of triangle and current edge */
explicit face_iterator(const edge_ptr& head, const edge_ptr& current)
: _head{ head }, _current{ current }
{
}
/* Dereference operator */
template <bool Const_ = Const>
std::enable_if_t<Const_, reference> operator*() const
{
return _current;
}
/* Dereference operator */
template <bool Const_ = Const>
std::enable_if_t<not Const_, reference> operator*()
{
return _current;
}
/* Equality operator */
auto operator==(const face_iterator& other) const -> bool
{
return _current == other._current;
}
/* Inequality operator */
auto operator!=(const face_iterator& other) const -> bool
{
return !(*this == other);
}
/* Increment operator */
auto operator++() -> face_iterator&
{
// Already at end
if (_current == nullptr) {
return *this;
}
// Get the next edge
_current = _current->next;
// If back at head, done iterating
if (_current == _head) {
_current = nullptr;
}
return *this;
}
private:
edge_ptr _head;
edge_ptr _current;
};
class vertex_attr
{
public:
glm::vec3 pos; // vertex position
glm::vec3 normal; // vertex normal
glm::vec2 uv; // texture coordinates
glm::vec2 tangent; // tangent
glm::vec2 bitangent; // bitanget
};
class vertex
{
public:
const bool is_boundary();
/* Set of all faces that share this interior node */
const std::vector<edge_ptr> wheel();
/* Edges in the wheel connected to the interior node */
const std::vector<edge_ptr> spoke();
vertex_attr attr; // vertex attributes
face_ptr face; // face the vertex belongs to
vertex_ptr parent; // parent node
edge_ptr edge; // one of the half-edges emantating from the vertex
size_t idx; // insertion index
std::vector<edge_ptr> edges; // list of edges with this vertex endpoint
// ABF++
float lambda_plan;
float lambda_len;
};
class edge
{
public:
const bool is_boundary();
vertex_ptr vert; // vertex at the end of the half-edge
edge_ptr pair; // oppositely oriented adjacent half-edge
face_ptr face; // face the half-edge borders
edge_ptr next; // next half-edge around the face
edge_ptr prev; // prev half-edge around the face
size_t idx; // insertion index
// ABF++
float alpha;
float alpha_sin;
float alpha_cos;
float phi;
float beta;
float weight;
};
class face
{
public:
/* Face edge iterator type */
using iterator = face_iterator<false>;
/* Face edge const iterator type */
using const_iterator = face_iterator<true>;
/* Returns an iterator over the edges of the face */
iterator begin() { return iterator{ head, head }; }
/* Returns the end iterator */
iterator end() { return iterator(); }
/* Returns an const iterator over the edges of the face */
const_iterator cbegin() const { return const_iterator{ head, head }; }
/* Returns the const end iterator */
const_iterator cend() const { return const_iterator(); }
/* Triangulate the face */
void triangulate(std::function<void(glm::vec3, glm::vec3, glm::vec3)> func);
face_ptr next; // next face
edge_ptr head; // one of the half-edges bordering the face
glm::vec3 faceNormal; // face normal
size_t idx; // insertion index
size_t vertexCount; // vertex count
// ABF++
float lambda_tri;
};
class plane
{
public:
glm::vec3 normal;
glm::vec3 centroid;
};
}