Developer Documentation
SmartHandles.hh
1/* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2025, 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#ifndef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
43#error Do not include this directly, include instead PolyConnectivity.hh
44#endif//OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
45
46#include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
47
48//== NAMESPACES ===============================================================
49
50namespace OpenMesh {
51
52//== FORWARD DECLARATION ======================================================
53
54struct SmartVertexHandle;
55struct SmartHalfedgeHandle;
56struct SmartEdgeHandle;
57struct SmartFaceHandle;
58
59
60//== CLASS DEFINITION =========================================================
61
63class OPENMESHDLLEXPORT SmartBaseHandle
64{
65public:
66 explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {}
67
69 const PolyConnectivity* mesh() const { return mesh_; }
70
71 // TODO: should operators ==, !=, < look at mesh_?
72
73private:
74 const PolyConnectivity* mesh_;
75
76};
77
79template <typename HandleType>
81{
82public:
84 bool feature() const;
86 bool selected() const;
88 bool tagged() const;
90 bool tagged2() const;
92 bool locked() const;
94 bool hidden() const;
96 bool deleted() const;
97};
98
100template <typename HandleType>
102{
103public:
105 bool is_boundary() const;
106};
107
109struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandle, SmartHandleStatusPredicates<SmartVertexHandle>, SmartHandleBoundaryPredicate<SmartVertexHandle>
110{
111 explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {}
112
114 SmartHalfedgeHandle out() const;
116 SmartHalfedgeHandle halfedge() const; // alias for out
118 SmartHalfedgeHandle in() const;
119
139 PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
141 PolyConnectivity::ConstVertexIHalfedgeCWRange incoming_halfedges_cw() const;
143 PolyConnectivity::ConstVertexIHalfedgeCCWRange incoming_halfedges_ccw() const;
145 PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges(HalfedgeHandle _heh) const;
147 PolyConnectivity::ConstVertexIHalfedgeCWRange incoming_halfedges_cw(HalfedgeHandle _heh) const;
149 PolyConnectivity::ConstVertexIHalfedgeCCWRange incoming_halfedges_ccw(HalfedgeHandle _heh) const;
151 PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
153 PolyConnectivity::ConstVertexOHalfedgeCWRange outgoing_halfedges_cw() const;
155 PolyConnectivity::ConstVertexOHalfedgeCCWRange outgoing_halfedges_ccw() const;
157 PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges(HalfedgeHandle _heh) const;
159 PolyConnectivity::ConstVertexOHalfedgeCWRange outgoing_halfedges_cw(HalfedgeHandle _heh) const;
161 PolyConnectivity::ConstVertexOHalfedgeCCWRange outgoing_halfedges_ccw(HalfedgeHandle _heh) const;
162
164 uint valence() const;
166 bool is_manifold() const;
167};
168
169struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle, SmartHandleStatusPredicates<SmartHalfedgeHandle>, SmartHandleBoundaryPredicate<SmartHalfedgeHandle>
170{
171 explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {}
172
174 SmartHalfedgeHandle next() const;
176 SmartHalfedgeHandle prev() const;
178 SmartHalfedgeHandle opp() const;
180 SmartVertexHandle to() const;
182 SmartVertexHandle from() const;
184 SmartEdgeHandle edge() const;
186 SmartFaceHandle face() const;
187
194};
195
196struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle, SmartHandleStatusPredicates<SmartEdgeHandle>, SmartHandleBoundaryPredicate<SmartEdgeHandle>
197{
198 explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {}
199
201 SmartHalfedgeHandle halfedge(unsigned int _i) const;
203 SmartHalfedgeHandle h(unsigned int _i) const;
205 SmartHalfedgeHandle h0() const;
207 SmartHalfedgeHandle h1() const;
209 SmartVertexHandle vertex(unsigned int _i) const;
211 SmartVertexHandle v(unsigned int _i) const;
213 SmartVertexHandle v0() const;
215 SmartVertexHandle v1() const;
216
225};
226
227struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle, SmartHandleStatusPredicates<SmartFaceHandle>, SmartHandleBoundaryPredicate<SmartFaceHandle>
228{
229 explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {}
230
232 SmartHalfedgeHandle halfedge() const;
233
258
260 uint valence() const;
261};
262
263
265inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); }
267inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); }
269inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); }
271inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); }
272
274inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); }
276inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); }
278inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); }
280inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); }
281
282
283// helper to convert Handle Types to Smarthandle Types
284template <typename HandleT>
286
287template <> struct SmartHandle<VertexHandle> { using type = SmartVertexHandle; };
288template <> struct SmartHandle<HalfedgeHandle> { using type = SmartHalfedgeHandle; };
289template <> struct SmartHandle<EdgeHandle> { using type = SmartEdgeHandle; };
290template <> struct SmartHandle<FaceHandle> { using type = SmartFaceHandle; };
291
292
293template <typename HandleType>
295{
296 const auto& handle = static_cast<const HandleType&>(*this);
297 assert(handle.mesh() != nullptr);
298 return handle.mesh()->status(handle).feature();
299}
300
301template <typename HandleType>
303{
304 const auto& handle = static_cast<const HandleType&>(*this);
305 assert(handle.mesh() != nullptr);
306 return handle.mesh()->status(handle).selected();
307}
308
309template <typename HandleType>
311{
312 const auto& handle = static_cast<const HandleType&>(*this);
313 assert(handle.mesh() != nullptr);
314 return handle.mesh()->status(handle).tagged();
315}
316
317template <typename HandleType>
319{
320 const auto& handle = static_cast<const HandleType&>(*this);
321 assert(handle.mesh() != nullptr);
322 return handle.mesh()->status(handle).tagged2();
323}
324
325template <typename HandleType>
327{
328 const auto& handle = static_cast<const HandleType&>(*this);
329 assert(handle.mesh() != nullptr);
330 return handle.mesh()->status(handle).locked();
331}
332
333template <typename HandleType>
335{
336 const auto& handle = static_cast<const HandleType&>(*this);
337 assert(handle.mesh() != nullptr);
338 return handle.mesh()->status(handle).hidden();
339}
340
341template <typename HandleType>
343{
344 const auto& handle = static_cast<const HandleType&>(*this);
345 assert(handle.mesh() != nullptr);
346 return handle.mesh()->status(handle).deleted();
347}
348
349template <typename HandleType>
351{
352 const auto& handle = static_cast<const HandleType&>(*this);
353 assert(handle.mesh() != nullptr);
354 return handle.mesh()->is_boundary(handle);
355}
356
358{
359 assert(mesh() != nullptr);
360 return make_smart(mesh()->halfedge_handle(*this), mesh());
361}
362
364{
365 return out();
366}
367
369{
370 return out().opp();
371}
372
373inline uint SmartVertexHandle::valence() const
374{
375 assert(mesh() != nullptr);
376 return mesh()->valence(*this);
377}
378
380{
381 assert(mesh() != nullptr);
382 return mesh()->is_manifold(*this);
383}
384
386{
387 assert(mesh() != nullptr);
388 return make_smart(mesh()->next_halfedge_handle(*this), mesh());
389}
390
392{
393 assert(mesh() != nullptr);
394 return make_smart(mesh()->prev_halfedge_handle(*this), mesh());
395}
396
398{
399 assert(mesh() != nullptr);
400 return make_smart(mesh()->opposite_halfedge_handle(*this), mesh());
401}
402
404{
405 assert(mesh() != nullptr);
406 return make_smart(mesh()->to_vertex_handle(*this), mesh());
407}
408
410{
411 assert(mesh() != nullptr);
412 return make_smart(mesh()->from_vertex_handle(*this), mesh());
413}
414
416{
417 assert(mesh() != nullptr);
418 return make_smart(mesh()->edge_handle(*this), mesh());
419}
420
422{
423 assert(mesh() != nullptr);
424 return make_smart(mesh()->face_handle(*this), mesh());
425}
426
427inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i = 0) const
428{
429 assert(mesh() != nullptr);
430 return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
431}
432
433inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i = 0) const
434{
435 return halfedge(_i);
436}
437
439{
440 return h(0);
441}
442
444{
445 return h(1);
446}
447
448inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const
449{
450 return halfedge(_i).from();
451}
452
453inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const
454{
455 return vertex(_i);
456}
457
459{
460 return v(0);
461}
462
464{
465 return v(1);
466}
467
469{
470 assert(mesh() != nullptr);
471 return make_smart(mesh()->halfedge_handle(*this), mesh());
472}
473
474inline uint SmartFaceHandle::valence() const
475{
476 assert(mesh() != nullptr);
477 return mesh()->valence(*this);
478}
479
480//=============================================================================
481} // namespace OpenMesh
482//=============================================================================
483
484//=============================================================================
int idx() const
Get the underlying index of this handle.
Definition: Handles.hh:69
Generic class for iterator ranges.
Connectivity Class for polygonal meshes.
uint valence(VertexHandle _vh) const
Vertex valence.
bool is_manifold(VertexHandle _vh) const
Is (the mesh at) vertex _vh two-manifold ?
Base class for all smart handle types.
Definition: SmartHandles.hh:64
const PolyConnectivity * mesh() const
Get the underlying mesh of this handle.
Definition: SmartHandles.hh:69
Base class for all smart handle types that contains status related methods.
bool is_boundary() const
Returns true iff the handle is boundary.
Base class for all smart handle types that contains status related methods.
Definition: SmartHandles.hh:81
bool selected() const
Returns true iff the handle is marked as selected.
bool feature() const
Returns true iff the handle is marked as feature.
bool locked() const
Returns true iff the handle is marked as locked.
bool deleted() const
Returns true iff the handle is marked as deleted.
bool tagged() const
Returns true iff the handle is marked as tagged.
bool tagged2() const
Returns true iff the handle is marked as tagged2.
bool hidden() const
Returns true iff the handle is marked as hidden.
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
Handle for a edge entity.
Definition: Handles.hh:135
Handle for a face entity.
Definition: Handles.hh:142
Handle for a halfedge entity.
Definition: Handles.hh:128
SmartVertexHandle v(unsigned int _i) const
Shorthand for vertex()
SmartVertexHandle v1() const
Shorthand for vertex(1)
SmartHalfedgeHandle h(unsigned int _i) const
Shorthand for halfedge()
SmartHalfedgeHandle h1() const
Shorthand for halfedge(1)
SmartVertexHandle vertex(unsigned int _i) const
Returns one of the two incident vertices of the edge.
SmartVertexHandle v0() const
Shorthand for vertex(0)
SmartHalfedgeHandle halfedge(unsigned int _i) const
Returns one of the two halfedges of the edge.
SmartHalfedgeHandle h0() const
Shorthand for halfedge(0)
uint valence() const
Returns the valence of the face.
SmartHalfedgeHandle halfedge() const
Returns one of the halfedges of the face.
SmartFaceHandle face() const
Returns incident face of halfedge.
SmartVertexHandle from() const
Returns vertex at start of halfedge.
SmartHalfedgeHandle next() const
Returns next halfedge handle.
SmartHalfedgeHandle prev() const
Returns previous halfedge handle.
SmartEdgeHandle edge() const
Returns incident edge of halfedge.
SmartHalfedgeHandle opp() const
Returns opposite halfedge handle.
SmartVertexHandle to() const
Returns vertex pointed to by halfedge.
Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access t...
SmartHalfedgeHandle halfedge() const
Returns an outgoing halfedge.
SmartHalfedgeHandle out() const
Returns an outgoing halfedge.
bool is_manifold() const
Returns true iff (the mesh at) the vertex is two-manifold ?
SmartHalfedgeHandle in() const
Returns an incoming halfedge.
uint valence() const
Returns valence of the vertex.
Handle for a vertex entity.
Definition: Handles.hh:121