Developer Documentation
IteratorsT.hh
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, 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 //
47 // Iterators for PolyMesh/TriMesh
48 //
49 //=============================================================================
50 
51 
52 
53 //== INCLUDES =================================================================
54 
56 #include <OpenMesh/Core/Mesh/Status.hh>
57 #include <OpenMesh/Core/Mesh/SmartHandles.hh>
58 #include <cassert>
59 #include <cstddef>
60 #include <iterator>
61 
62 
63 //== NAMESPACES ===============================================================
64 
65 namespace OpenMesh {
66 namespace Iterators {
67 
68 
69 //== FORWARD DECLARATIONS =====================================================
70 
71 
72 template <class Mesh> class ConstVertexIterT;
73 template <class Mesh> class VertexIterT;
74 template <class Mesh> class ConstHalfedgeIterT;
75 template <class Mesh> class HalfedgeIterT;
76 template <class Mesh> class ConstEdgeIterT;
77 template <class Mesh> class EdgeIterT;
78 template <class Mesh> class ConstFaceIterT;
79 template <class Mesh> class FaceIterT;
80 
81 
82 template <class Mesh, class ValueHandle, class MemberOwner, bool (MemberOwner::*PrimitiveStatusMember)() const, size_t (MemberOwner::*PrimitiveCountMember)() const>
84  public:
85  //--- Typedefs ---
86 
87  typedef ValueHandle value_handle;
88  typedef value_handle value_type;
89  typedef std::bidirectional_iterator_tag iterator_category;
90  typedef std::ptrdiff_t difference_type;
91  typedef const Mesh* mesh_ptr;
92  typedef const Mesh& mesh_ref;
93  typedef decltype(make_smart(std::declval<ValueHandle>(), std::declval<Mesh>())) SmartHandle;
94  typedef const SmartHandle& reference;
95  typedef const SmartHandle* pointer;
96 
99  : hnd_(make_smart(ValueHandle(),nullptr)), skip_bits_(0)
100  {}
101 
103  GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false)
104  : hnd_(make_smart(_hnd, _mesh)), skip_bits_(0)
105  {
106  if (_skip) enable_skipping();
107  }
108 
110  reference operator*() const {
111  return hnd_;
112  }
113 
115  pointer operator->() const {
116  return &hnd_;
117  }
118 
124  OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
125  value_handle handle() const {
126  return hnd_;
127  }
128 
135  OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
136  operator value_handle() const {
137  return hnd_;
138  }
139 
141  bool operator==(const GenericIteratorT& _rhs) const {
142  return ((hnd_.mesh() == _rhs.hnd_.mesh()) && (hnd_ == _rhs.hnd_));
143  }
144 
146  bool operator!=(const GenericIteratorT& _rhs) const {
147  return !operator==(_rhs);
148  }
149 
152  hnd_.__increment();
153  if (skip_bits_)
154  skip_fwd();
155  return *this;
156  }
157 
160  GenericIteratorT cpy(*this);
161  ++(*this);
162  return cpy;
163  }
164 
165 #if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
166  template<class T = value_handle>
167  auto operator+=(int amount) ->
168  typename std::enable_if<
169  sizeof(decltype(std::declval<T>().__increment(amount))) >= 0,
170  GenericIteratorT&>::type {
171  static_assert(std::is_same<T, value_handle>::value,
172  "Template parameter must not deviate from default.");
173  if (skip_bits_)
174  throw std::logic_error("Skipping iterators do not support "
175  "random access.");
176  hnd_.__increment(amount);
177  return *this;
178  }
179 
180  template<class T = value_handle>
181  auto operator+(int rhs) ->
182  typename std::enable_if<
183  sizeof(decltype(std::declval<T>().__increment(rhs), void (), int {})) >= 0,
184  GenericIteratorT>::type {
185  static_assert(std::is_same<T, value_handle>::value,
186  "Template parameter must not deviate from default.");
187  if (skip_bits_)
188  throw std::logic_error("Skipping iterators do not support "
189  "random access.");
190  GenericIteratorT result = *this;
191  result.hnd_.__increment(rhs);
192  return result;
193  }
194 #endif
195 
198  hnd_.__decrement();
199  if (skip_bits_)
200  skip_bwd();
201  return *this;
202  }
203 
206  GenericIteratorT cpy(*this);
207  --(*this);
208  return cpy;
209  }
210 
213  if (hnd_.mesh() && (hnd_.mesh()->*PrimitiveStatusMember)()) {
214  Attributes::StatusInfo status;
215  status.set_deleted(true);
216  status.set_hidden(true);
217  skip_bits_ = status.bits();
218  skip_fwd();
219  } else
220  skip_bits_ = 0;
221  }
222 
225  skip_bits_ = 0;
226  }
227 
228  private:
229 
230  void skip_fwd() {
231  assert(hnd_.mesh() && skip_bits_);
232  while ((hnd_.idx() < (signed) (hnd_.mesh()->*PrimitiveCountMember)())
233  && (hnd_.mesh()->status(hnd_).bits() & skip_bits_))
234  hnd_.__increment();
235  }
236 
237  void skip_bwd() {
238  assert(hnd_.mesh() && skip_bits_);
239  while ((hnd_.idx() >= 0) && (hnd_.mesh()->status(hnd_).bits() & skip_bits_))
240  hnd_.__decrement();
241  }
242 
243  protected:
244  SmartHandle hnd_;
245  unsigned int skip_bits_;
246 };
247 
248 //=============================================================================
249 } // namespace Iterators
250 } // namespace OpenMesh
251 //=============================================================================
GenericIteratorT & operator--()
Standard pre-decrement operator.
Definition: IteratorsT.hh:197
bool operator==(const GenericIteratorT &_rhs) const
Are two iterators equal? Only valid if they refer to the same mesh!
Definition: IteratorsT.hh:141
bool operator!=(const GenericIteratorT &_rhs) const
Not equal?
Definition: IteratorsT.hh:146
value_handle handle() const
Get the handle of the item the iterator refers to.
Definition: IteratorsT.hh:125
pointer operator->() const
Standard pointer operator.
Definition: IteratorsT.hh:115
SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity *_mesh)
Creats a SmartVertexHandle from a VertexHandle and a Mesh.
void disable_skipping()
Turn on skipping: automatically skip deleted/hidden elements.
Definition: IteratorsT.hh:224
void set_hidden(bool _b)
set hidden
Definition: Status.hh:123
void set_deleted(bool _b)
set deleted
Definition: Status.hh:105
unsigned int bits() const
return whole status
Definition: Status.hh:151
GenericIteratorT operator--(int)
Standard post-decrement operator.
Definition: IteratorsT.hh:205
void enable_skipping()
Turn on skipping: automatically skip deleted/hidden elements.
Definition: IteratorsT.hh:212
GenericIteratorT operator++(int)
Standard post-increment operator.
Definition: IteratorsT.hh:159
GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false)
Construct with mesh and a target handle.
Definition: IteratorsT.hh:103
GenericIteratorT()
Default constructor.
Definition: IteratorsT.hh:98
reference operator*() const
Standard dereferencing operator.
Definition: IteratorsT.hh:110
GenericIteratorT & operator++()
Standard pre-increment operator.
Definition: IteratorsT.hh:151