Developer Documentation
SmartHandles.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2019, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 
43 #pragma once
44 
45 
46 //== INCLUDES =================================================================
47 
48 #include "Handles.hh"
49 #include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
50 #include <OpenMesh/Core/System/OpenMeshDLLMacros.hh>
51 
52 
53 //== NAMESPACES ===============================================================
54 
55 namespace OpenMesh {
56 
57 //== FORWARD DECLARATION ======================================================
58 
59 struct SmartVertexHandle;
60 struct SmartHalfedgeHandle;
61 struct SmartEdgeHandle;
62 struct SmartFaceHandle;
63 
64 
65 //== CLASS DEFINITION =========================================================
66 
68 class OPENMESHDLLEXPORT SmartBaseHandle
69 {
70 public:
71  explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {}
72 
74  const PolyConnectivity* mesh() const { return mesh_; }
75 
76  // TODO: should operators ==, !=, < look at mesh_?
77 
78 private:
79  const PolyConnectivity* mesh_;
80 
81 };
82 
84 struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandle
85 {
86  explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {}
87 
89  SmartHalfedgeHandle out() const;
91  SmartHalfedgeHandle halfedge() const; // alias for out
93  SmartHalfedgeHandle in() const;
94 
102  PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
104  PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
105 
107  uint valence() const;
109  bool is_boundary() const;
111  bool is_manifold() const;
112 };
113 
114 struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle
115 {
116  explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {}
117 
119  SmartHalfedgeHandle next() const;
121  SmartHalfedgeHandle prev() const;
123  SmartHalfedgeHandle opp() const;
125  SmartVertexHandle to() const;
127  SmartVertexHandle from() const;
129  SmartEdgeHandle edge() const;
131  SmartFaceHandle face() const;
132 
134  bool is_boundary() const;
135 };
136 
137 struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle
138 {
139  explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {}
140 
142  SmartHalfedgeHandle halfedge(unsigned int _i) const;
144  SmartHalfedgeHandle h(unsigned int _i) const;
146  SmartHalfedgeHandle h0() const;
148  SmartHalfedgeHandle h1() const;
150  SmartVertexHandle vertex(unsigned int _i) const;
152  SmartVertexHandle v(unsigned int _i) const;
154  SmartVertexHandle v0() const;
156  SmartVertexHandle v1() const;
157 
159  bool is_boundary() const;
160 };
161 
162 struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle
163 {
164  explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {}
165 
167  SmartHalfedgeHandle halfedge() const;
168 
177 
179  uint valence() const;
181  bool is_boundary() const;
182 };
183 
184 
186 inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); }
188 inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); }
190 inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); }
192 inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); }
193 
195 inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); }
197 inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); }
199 inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); }
201 inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); }
202 
203 
204 // helper to convert Handle Types to Smarthandle Types
205 template <typename HandleT>
206 struct SmartHandle;
207 
208 template <> struct SmartHandle<VertexHandle> { using type = SmartVertexHandle; };
209 template <> struct SmartHandle<HalfedgeHandle> { using type = SmartHalfedgeHandle; };
210 template <> struct SmartHandle<EdgeHandle> { using type = SmartEdgeHandle; };
211 template <> struct SmartHandle<FaceHandle> { using type = SmartFaceHandle; };
212 
213 
215 {
216  assert(mesh() != nullptr);
217  return make_smart(mesh()->halfedge_handle(*this), mesh());
218 }
219 
221 {
222  return out();
223 }
224 
226 {
227  return out().opp();
228 }
229 
230 inline uint SmartVertexHandle::valence() const
231 {
232  assert(mesh() != nullptr);
233  return mesh()->valence(*this);
234 }
235 
237 {
238  assert(mesh() != nullptr);
239  return mesh()->is_boundary(*this);
240 }
241 
243 {
244  assert(mesh() != nullptr);
245  return mesh()->is_manifold(*this);
246 }
247 
249 {
250  assert(mesh() != nullptr);
251  return make_smart(mesh()->next_halfedge_handle(*this), mesh());
252 }
253 
255 {
256  assert(mesh() != nullptr);
257  return make_smart(mesh()->prev_halfedge_handle(*this), mesh());
258 }
259 
261 {
262  assert(mesh() != nullptr);
263  return make_smart(mesh()->opposite_halfedge_handle(*this), mesh());
264 }
265 
267 {
268  assert(mesh() != nullptr);
269  return make_smart(mesh()->to_vertex_handle(*this), mesh());
270 }
271 
273 {
274  assert(mesh() != nullptr);
275  return make_smart(mesh()->from_vertex_handle(*this), mesh());
276 }
277 
279 {
280  assert(mesh() != nullptr);
281  return make_smart(mesh()->edge_handle(*this), mesh());
282 }
283 
285 {
286  assert(mesh() != nullptr);
287  return make_smart(mesh()->face_handle(*this), mesh());
288 }
289 
291 {
292  assert(mesh() != nullptr);
293  return mesh()->is_boundary(*this);
294 }
295 
296 inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const
297 {
298  assert(mesh() != nullptr);
299  return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
300 }
301 
302 inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const
303 {
304  return halfedge(_i);
305 }
306 
308 {
309  return h(0);
310 }
311 
313 {
314  return h(1);
315 }
316 
317 inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const
318 {
319  return halfedge(_i).from();
320 }
321 
322 inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const
323 {
324  return vertex(_i);
325 }
326 
328 {
329  return v(0);
330 }
331 
333 {
334  return v(1);
335 }
336 
337 inline bool SmartEdgeHandle::is_boundary() const
338 {
339  assert(mesh() != nullptr);
340  return mesh()->is_boundary(*this);
341 }
342 
344 {
345  assert(mesh() != nullptr);
346  return make_smart(mesh()->halfedge_handle(*this), mesh());
347 }
348 
349 inline uint SmartFaceHandle::valence() const
350 {
351  assert(mesh() != nullptr);
352  return mesh()->valence(*this);
353 }
354 
355 inline bool SmartFaceHandle::is_boundary() const
356 {
357  assert(mesh() != nullptr);
358  return mesh()->is_boundary(*this);
359 }
360 
361 
362 
363 //=============================================================================
364 } // namespace OpenMesh
365 //=============================================================================
366 
367 //=============================================================================
bool is_manifold() const
Returns true iff (the mesh at) the vertex is two-manifold ?
Handle for a edge entity.
Definition: Handles.hh:134
uint valence() const
Returns the valence of the face.
Handle for a face entity.
Definition: Handles.hh:141
bool is_boundary() const
Returns true iff the vertex is incident to a boundary halfedge.
bool is_boundary() const
Returns true iff the edge lies on the boundary (i.e. one of the halfedges is boundary) ...
SmartHalfedgeHandle next() const
Returns next halfedge handle.
SmartVertexHandle v(unsigned int _i) const
Shorthand for vertex()
const PolyConnectivity * mesh() const
Get the underlying mesh of this handle.
Definition: SmartHandles.hh:74
SmartEdgeHandle edge() const
Returns incident edge of halfedge.
Handle for a halfedge entity.
Definition: Handles.hh:127
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:69
SmartHalfedgeHandle halfedge(unsigned int _i) const
Returns one of the two halfedges of the edge.
SmartHalfedgeHandle halfedge() const
Returns one of the halfedges of the face.
Handle for a vertex entity.
Definition: Handles.hh:120
SmartHalfedgeHandle in() const
Returns an incoming halfedge.
SmartHalfedgeHandle prev() const
Returns previous halfedge handle.
SmartVertexHandle v0() const
Shorthand for vertex(0)
SmartVertexHandle v1() const
Shorthand for vertex(1)
SmartHalfedgeHandle h(unsigned int _i) const
Shorthand for halfedge()
Base class for all smart handle types.
Definition: SmartHandles.hh:68
SmartHalfedgeHandle opp() const
Returns opposite halfedge handle.
SmartVertexHandle from() const
Returns vertex at start of halfedge.
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
SmartHalfedgeHandle h0() const
Shorthand for halfedge(0)
Generic class for iterator ranges.
SmartHalfedgeHandle halfedge() const
Returns an outgoing halfedge.
bool is_boundary() const
Returns true iff the halfedge is on the boundary (i.e. it has no corresponding face) ...
SmartHalfedgeHandle h1() const
Shorthand for halfedge(1)
SmartVertexHandle to() const
Returns vertex pointed to by halfedge.
SmartHalfedgeHandle out() const
Returns an outgoing halfedge.
SmartVertexHandle vertex(unsigned int _i) const
Returns one of the two incident vertices of the edge.
uint valence() const
Returns valence of the vertex.
Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access t...
Definition: SmartHandles.hh:84
Connectivity Class for polygonal meshes.
bool is_boundary() const
Returns true iff the face lies at the boundary (i.e. one of the edges is boundary) ...
SmartFaceHandle face() const
Returns incident face of halfedge.