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 #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 
50 namespace OpenMesh {
51 
52 //== FORWARD DECLARATION ======================================================
53 
54 struct SmartVertexHandle;
55 struct SmartHalfedgeHandle;
56 struct SmartEdgeHandle;
57 struct SmartFaceHandle;
58 
59 
60 //== CLASS DEFINITION =========================================================
61 
63 class OPENMESHDLLEXPORT SmartBaseHandle
64 {
65 public:
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 
73 private:
74  const PolyConnectivity* mesh_;
75 
76 };
77 
79 template <typename HandleType>
81 {
82 public:
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 
100 template <typename HandleType>
102 {
103 public:
105  bool is_boundary() const;
106 };
107 
109 struct 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 
127  PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
129  PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
130 
132  uint valence() const;
134  bool is_manifold() const;
135 };
136 
137 struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle, SmartHandleStatusPredicates<SmartHalfedgeHandle>, SmartHandleBoundaryPredicate<SmartHalfedgeHandle>
138 {
139  explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {}
140 
142  SmartHalfedgeHandle next() const;
144  SmartHalfedgeHandle prev() const;
146  SmartHalfedgeHandle opp() const;
148  SmartVertexHandle to() const;
150  SmartVertexHandle from() const;
152  SmartEdgeHandle edge() const;
154  SmartFaceHandle face() const;
155 
158 };
159 
160 struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle, SmartHandleStatusPredicates<SmartEdgeHandle>, SmartHandleBoundaryPredicate<SmartEdgeHandle>
161 {
162  explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {}
163 
165  SmartHalfedgeHandle halfedge(unsigned int _i) const;
167  SmartHalfedgeHandle h(unsigned int _i) const;
169  SmartHalfedgeHandle h0() const;
171  SmartHalfedgeHandle h1() const;
173  SmartVertexHandle vertex(unsigned int _i) const;
175  SmartVertexHandle v(unsigned int _i) const;
177  SmartVertexHandle v0() const;
179  SmartVertexHandle v1() const;
180 };
181 
182 struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle, SmartHandleStatusPredicates<SmartFaceHandle>, SmartHandleBoundaryPredicate<SmartFaceHandle>
183 {
184  explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {}
185 
187  SmartHalfedgeHandle halfedge() const;
188 
197 
199  uint valence() const;
200 };
201 
202 
204 inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); }
206 inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); }
208 inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); }
210 inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); }
211 
213 inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); }
215 inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); }
217 inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); }
219 inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); }
220 
221 
222 // helper to convert Handle Types to Smarthandle Types
223 template <typename HandleT>
224 struct SmartHandle;
225 
226 template <> struct SmartHandle<VertexHandle> { using type = SmartVertexHandle; };
227 template <> struct SmartHandle<HalfedgeHandle> { using type = SmartHalfedgeHandle; };
228 template <> struct SmartHandle<EdgeHandle> { using type = SmartEdgeHandle; };
229 template <> struct SmartHandle<FaceHandle> { using type = SmartFaceHandle; };
230 
231 
232 template <typename HandleType>
234 {
235  const auto& handle = static_cast<const HandleType&>(*this);
236  assert(handle.mesh() != nullptr);
237  return handle.mesh()->status(handle).feature();
238 }
239 
240 template <typename HandleType>
242 {
243  const auto& handle = static_cast<const HandleType&>(*this);
244  assert(handle.mesh() != nullptr);
245  return handle.mesh()->status(handle).selected();
246 }
247 
248 template <typename HandleType>
250 {
251  const auto& handle = static_cast<const HandleType&>(*this);
252  assert(handle.mesh() != nullptr);
253  return handle.mesh()->status(handle).tagged();
254 }
255 
256 template <typename HandleType>
258 {
259  const auto& handle = static_cast<const HandleType&>(*this);
260  assert(handle.mesh() != nullptr);
261  return handle.mesh()->status(handle).tagged2();
262 }
263 
264 template <typename HandleType>
266 {
267  const auto& handle = static_cast<const HandleType&>(*this);
268  assert(handle.mesh() != nullptr);
269  return handle.mesh()->status(handle).locked();
270 }
271 
272 template <typename HandleType>
274 {
275  const auto& handle = static_cast<const HandleType&>(*this);
276  assert(handle.mesh() != nullptr);
277  return handle.mesh()->status(handle).hidden();
278 }
279 
280 template <typename HandleType>
282 {
283  const auto& handle = static_cast<const HandleType&>(*this);
284  assert(handle.mesh() != nullptr);
285  return handle.mesh()->status(handle).deleted();
286 }
287 
288 template <typename HandleType>
290 {
291  const auto& handle = static_cast<const HandleType&>(*this);
292  assert(handle.mesh() != nullptr);
293  return handle.mesh()->is_boundary(handle);
294 }
295 
297 {
298  assert(mesh() != nullptr);
299  return make_smart(mesh()->halfedge_handle(*this), mesh());
300 }
301 
303 {
304  return out();
305 }
306 
308 {
309  return out().opp();
310 }
311 
312 inline uint SmartVertexHandle::valence() const
313 {
314  assert(mesh() != nullptr);
315  return mesh()->valence(*this);
316 }
317 
319 {
320  assert(mesh() != nullptr);
321  return mesh()->is_manifold(*this);
322 }
323 
325 {
326  assert(mesh() != nullptr);
327  return make_smart(mesh()->next_halfedge_handle(*this), mesh());
328 }
329 
331 {
332  assert(mesh() != nullptr);
333  return make_smart(mesh()->prev_halfedge_handle(*this), mesh());
334 }
335 
337 {
338  assert(mesh() != nullptr);
339  return make_smart(mesh()->opposite_halfedge_handle(*this), mesh());
340 }
341 
343 {
344  assert(mesh() != nullptr);
345  return make_smart(mesh()->to_vertex_handle(*this), mesh());
346 }
347 
349 {
350  assert(mesh() != nullptr);
351  return make_smart(mesh()->from_vertex_handle(*this), mesh());
352 }
353 
355 {
356  assert(mesh() != nullptr);
357  return make_smart(mesh()->edge_handle(*this), mesh());
358 }
359 
361 {
362  assert(mesh() != nullptr);
363  return make_smart(mesh()->face_handle(*this), mesh());
364 }
365 
366 inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const
367 {
368  assert(mesh() != nullptr);
369  return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
370 }
371 
372 inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const
373 {
374  return halfedge(_i);
375 }
376 
378 {
379  return h(0);
380 }
381 
383 {
384  return h(1);
385 }
386 
387 inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const
388 {
389  return halfedge(_i).from();
390 }
391 
392 inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const
393 {
394  return vertex(_i);
395 }
396 
398 {
399  return v(0);
400 }
401 
403 {
404  return v(1);
405 }
406 
408 {
409  assert(mesh() != nullptr);
410  return make_smart(mesh()->halfedge_handle(*this), mesh());
411 }
412 
413 inline uint SmartFaceHandle::valence() const
414 {
415  assert(mesh() != nullptr);
416  return mesh()->valence(*this);
417 }
418 
419 //=============================================================================
420 } // namespace OpenMesh
421 //=============================================================================
422 
423 //=============================================================================
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
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:69
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.
Base class for all smart handle types that contains status related methods.
SmartHalfedgeHandle halfedge() const
Returns one of the halfedges of the face.
bool feature() const
Returns true iff the handle is marked as feature.
Handle for a vertex entity.
Definition: Handles.hh:120
bool tagged2() const
Returns true iff the handle is marked as tagged2.
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:63
SmartHalfedgeHandle opp() const
Returns opposite halfedge handle.
Base class for all smart handle types that contains status related methods.
Definition: SmartHandles.hh:80
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 selected() const
Returns true iff the handle is marked as selected.
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...
bool is_boundary() const
Returns true iff the handle is boundary.
bool tagged() const
Returns true iff the handle is marked as tagged.
Connectivity Class for polygonal meshes.
bool deleted() const
Returns true iff the handle is marked as deleted.
bool locked() const
Returns true iff the handle is marked as locked.
SmartFaceHandle face() const
Returns incident face of halfedge.
bool hidden() const
Returns true iff the handle is marked as hidden.