cursors.hh 8.94 KB
Newer Older
1
2
3
4
#pragma once

namespace polymesh
{
Philip Trettner's avatar
Philip Trettner committed
5
6
7
class Mesh;

template <typename PropT>
8
struct vertex_attribute;
Philip Trettner's avatar
Philip Trettner committed
9
template <typename PropT>
10
struct face_attribute;
Philip Trettner's avatar
Philip Trettner committed
11
template <typename PropT>
12
struct edge_attribute;
Philip Trettner's avatar
Philip Trettner committed
13
template <typename PropT>
14
struct halfedge_attribute;
15

Philip Trettner's avatar
Philip Trettner committed
16
17
18
19
20
21
struct vertex_handle;
struct face_handle;
struct edge_handle;
struct halfedge_handle;

struct face_vertex_ring;
22
23
24
25
26
27
28
29
30
struct face_edge_ring;
struct face_halfedge_ring;
struct face_face_ring;

struct vertex_halfedge_out_ring;
struct vertex_halfedge_in_ring;
struct vertex_face_ring;
struct vertex_edge_ring;
struct vertex_vertex_ring;
Philip Trettner's avatar
Philip Trettner committed
31

32
33
34
35
36
37
38
39
40
41
// ======================== INDICES ========================

struct face_index
{
    int value = -1;

    face_index() = default;
    explicit face_index(int idx) : value(idx) {}

    bool is_valid() const { return value >= 0; }
42
    bool is_invalid() const { return value < 0; }
43
44
45
46
    static face_index invalid() { return {}; }

    bool operator==(face_index const& rhs) const { return value == rhs.value; }
    bool operator!=(face_index const& rhs) const { return value != rhs.value; }
Philip Trettner's avatar
Philip Trettner committed
47
48

    template <typename PropT>
49
    PropT& operator[](face_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
50
    template <typename PropT>
51
    PropT const& operator[](face_attribute<PropT> const& prop) const;
52
53
54
55
56
57
58
59
60
61
};

struct vertex_index
{
    int value = -1;

    vertex_index() = default;
    explicit vertex_index(int idx) : value(idx) {}

    bool is_valid() const { return value >= 0; }
62
    bool is_invalid() const { return value < 0; }
63
64
65
66
    static vertex_index invalid() { return {}; }

    bool operator==(vertex_index const& rhs) const { return value == rhs.value; }
    bool operator!=(vertex_index const& rhs) const { return value != rhs.value; }
Philip Trettner's avatar
Philip Trettner committed
67
68

    template <typename PropT>
69
    PropT& operator[](vertex_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
70
    template <typename PropT>
71
    PropT const& operator[](vertex_attribute<PropT> const& prop) const;
72
73
74
75
76
77
78
79
80
81
};

struct edge_index
{
    int value = -1;

    edge_index() = default;
    explicit edge_index(int idx) : value(idx) {}

    bool is_valid() const { return value >= 0; }
82
    bool is_invalid() const { return value < 0; }
83
84
85
86
    static edge_index invalid() { return {}; }

    bool operator==(edge_index const& rhs) const { return value == rhs.value; }
    bool operator!=(edge_index const& rhs) const { return value != rhs.value; }
Philip Trettner's avatar
Philip Trettner committed
87
88

    template <typename PropT>
89
    PropT& operator[](edge_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
90
    template <typename PropT>
91
    PropT const& operator[](edge_attribute<PropT> const& prop) const;
92
93
94
95
96
97
98
99
100
101
};

struct halfedge_index
{
    int value = -1;

    halfedge_index() = default;
    explicit halfedge_index(int idx) : value(idx) {}

    bool is_valid() const { return value >= 0; }
102
    bool is_invalid() const { return value < 0; }
103
104
105
106
    static halfedge_index invalid() { return {}; }

    bool operator==(halfedge_index const& rhs) const { return value == rhs.value; }
    bool operator!=(halfedge_index const& rhs) const { return value != rhs.value; }
Philip Trettner's avatar
Philip Trettner committed
107
108

    template <typename PropT>
109
    PropT& operator[](halfedge_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
110
    template <typename PropT>
111
    PropT const& operator[](halfedge_attribute<PropT> const& prop) const;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
};

// ======================== HANDLES ========================

struct face_handle
{
    Mesh const* mesh;
    face_index idx;

    face_handle(Mesh const* mesh, face_index idx) : mesh(mesh), idx(idx) {}

    bool operator==(face_index const& rhs) const { return idx == rhs; }
    bool operator!=(face_index const& rhs) const { return idx != rhs; }
    bool operator==(face_handle const& rhs) const { return mesh == rhs.mesh && idx == rhs.idx; }
    bool operator!=(face_handle const& rhs) const { return mesh != rhs.mesh || idx != rhs.idx; }
127

Philip Trettner's avatar
Philip Trettner committed
128
    template <typename PropT>
129
    PropT& operator[](face_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
130
    template <typename PropT>
131
    PropT const& operator[](face_attribute<PropT> const& prop) const;
Philip Trettner's avatar
Philip Trettner committed
132

133
134
135
136
137
    bool is_valid() const { return idx.is_valid(); }     ///< valid idx (but could be deleted in some iterators)
    bool is_invalid() const { return !idx.is_valid(); }; ///< invalid idx
    bool is_removed() const;                             ///< marked for deletion (but valid idx)

    bool is_boundary() const; ///< true if this face lies at a boundary
Philip Trettner's avatar
Philip Trettner committed
138
139
140
141
142

    vertex_handle any_vertex() const;
    halfedge_handle any_halfedge() const;

    face_vertex_ring vertices() const;
143
144
    face_edge_ring edges() const;
    face_halfedge_ring halfedges() const;
145
    face_face_ring adjacent_faces() const; ///< includes invalid ones for boundaries!
146
147
148
149
150
151
152
153
154
155
156
157
158
};

struct vertex_handle
{
    Mesh const* mesh;
    vertex_index idx;

    vertex_handle(Mesh const* mesh, vertex_index idx) : mesh(mesh), idx(idx) {}

    bool operator==(vertex_index const& rhs) const { return idx == rhs; }
    bool operator!=(vertex_index const& rhs) const { return idx != rhs; }
    bool operator==(vertex_handle const& rhs) const { return mesh == rhs.mesh && idx == rhs.idx; }
    bool operator!=(vertex_handle const& rhs) const { return mesh != rhs.mesh || idx != rhs.idx; }
159

Philip Trettner's avatar
Philip Trettner committed
160
    template <typename PropT>
161
    PropT& operator[](vertex_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
162
    template <typename PropT>
163
    PropT const& operator[](vertex_attribute<PropT> const& prop) const;
Philip Trettner's avatar
Philip Trettner committed
164

165
166
167
168
169
170
    bool is_valid() const { return idx.is_valid(); }     ///< valid idx (but could be deleted in some iterators)
    bool is_invalid() const { return !idx.is_valid(); }; ///< invalid idx
    bool is_removed() const;                             ///< marked for deletion (but valid idx)

    bool is_isolated() const; ///< true if this vertex is not connected at all
    bool is_boundary() const; ///< true if this vertex lies at a boundary
Philip Trettner's avatar
Philip Trettner committed
171

172
173
174
175
176
    face_handle any_face() const;                  ///< invalid if at boundary
    face_handle any_valid_face() const;            ///< invalid if isolated
    halfedge_handle any_outgoing_halfedge() const; ///< invalid if isolated
    halfedge_handle any_incoming_halfedge() const; ///< invalid if isolated
    edge_handle any_edge() const;                  ///< invalid if isolated
177
178

    vertex_halfedge_in_ring incoming_halfedges() const;
179
    vertex_halfedge_out_ring outgoing_halfedges() const;
180
181
182
    vertex_edge_ring edges() const;
    vertex_face_ring faces() const; ///< includes invalid ones for boundaries!
    vertex_vertex_ring adjacent_vertices() const;
183
184
185
186
187
188
189
190
191
192
193
194
195
};

struct edge_handle
{
    Mesh const* mesh;
    edge_index idx;

    edge_handle(Mesh const* mesh, edge_index idx) : mesh(mesh), idx(idx) {}

    bool operator==(edge_index const& rhs) const { return idx == rhs; }
    bool operator!=(edge_index const& rhs) const { return idx != rhs; }
    bool operator==(edge_handle const& rhs) const { return mesh == rhs.mesh && idx == rhs.idx; }
    bool operator!=(edge_handle const& rhs) const { return mesh != rhs.mesh || idx != rhs.idx; }
196

Philip Trettner's avatar
Philip Trettner committed
197
    template <typename PropT>
198
    PropT& operator[](edge_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
199
    template <typename PropT>
200
    PropT const& operator[](edge_attribute<PropT> const& prop) const;
Philip Trettner's avatar
Philip Trettner committed
201

202
203
204
205
206
207
    bool is_valid() const { return idx.is_valid(); }     ///< valid idx (but could be deleted in some iterators)
    bool is_invalid() const { return !idx.is_valid(); }; ///< invalid idx
    bool is_removed() const;                             ///< marked for deletion (but valid idx)

    bool is_isolated() const; ///< true if this edge has no faces
    bool is_boundary() const; ///< true if this edge is a boundary
Philip Trettner's avatar
Philip Trettner committed
208
209
210

    halfedge_handle halfedgeA() const;
    halfedge_handle halfedgeB() const;
211
212
    vertex_handle vertexA() const;
    vertex_handle vertexB() const;
213
214
    face_handle faceA() const; ///< can be invalid if boundary
    face_handle faceB() const; ///< can be invalid if boundary
215
216
217
218
219
220
221
222
223
224
225
226
227
};

struct halfedge_handle
{
    Mesh const* mesh;
    halfedge_index idx;

    halfedge_handle(Mesh const* mesh, halfedge_index idx) : mesh(mesh), idx(idx) {}

    bool operator==(halfedge_index const& rhs) const { return idx == rhs; }
    bool operator!=(halfedge_index const& rhs) const { return idx != rhs; }
    bool operator==(halfedge_handle const& rhs) const { return mesh == rhs.mesh && idx == rhs.idx; }
    bool operator!=(halfedge_handle const& rhs) const { return mesh != rhs.mesh || idx != rhs.idx; }
Philip Trettner's avatar
Philip Trettner committed
228

Philip Trettner's avatar
Philip Trettner committed
229
    template <typename PropT>
230
    PropT& operator[](halfedge_attribute<PropT>& prop) const;
Philip Trettner's avatar
Philip Trettner committed
231
    template <typename PropT>
232
    PropT const& operator[](halfedge_attribute<PropT> const& prop) const;
Philip Trettner's avatar
Philip Trettner committed
233

234
235
236
237
238
    bool is_valid() const { return idx.is_valid(); }     ///< valid idx (but could be deleted in some iterators)
    bool is_invalid() const { return !idx.is_valid(); }; ///< invalid idx
    bool is_removed() const;                             ///< marked for deletion (but valid idx)

    bool is_boundary() const; ///< true if this half-edge is a boundary (CAUTION: its opposite might not be)
239

Philip Trettner's avatar
Philip Trettner committed
240
241
    vertex_handle vertex_to() const;
    vertex_handle vertex_from() const;
242
    edge_handle edge() const;
243
    face_handle face() const; ///< invalid if boundary
Philip Trettner's avatar
Philip Trettner committed
244
245
246
    halfedge_handle next() const;
    halfedge_handle prev() const;
    halfedge_handle opposite() const;
247
    face_handle opposite_face() const; ///< invalid if opposite boundary
248
249
};
}