IteratorsT.hh 10.5 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/* ========================================================================= *
Jan Möbius's avatar
Jan Möbius committed
2
3
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
Jan Möbius's avatar
Typo  
Jan Möbius committed
5
 *           Department of Computer Graphics and Multimedia                  *
Jan Möbius's avatar
Jan Möbius committed
6
7
 *                          All rights reserved.                             *
 *                            www.openmesh.org                               *
Jan Möbius's avatar
Jan Möbius committed
8
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
9
10
11
 *---------------------------------------------------------------------------*
 * This file is part of OpenMesh.                                            *
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
12
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
13
14
15
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
Jan Möbius's avatar
Jan Möbius committed
16
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
17
18
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
Jan Möbius's avatar
Jan Möbius committed
19
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
20
21
22
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
Jan Möbius's avatar
Jan Möbius committed
23
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
24
25
26
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
27
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
28
29
30
31
32
33
34
35
36
37
38
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
40
 *                                                                           *
 * ========================================================================= */
41
42
43
44
45

/*===========================================================================*\
 *                                                                           *             
 *   $Revision$                                                         *
 *   $Date$                   *
Jan Möbius's avatar
Jan Möbius committed
46
47
 *                                                                           *
\*===========================================================================*/
48

Jan Möbius's avatar
Jan Möbius committed
49
50
#ifndef OPENMESH_ITERATORS_HH
#define OPENMESH_ITERATORS_HH
51

Jan Möbius's avatar
Jan Möbius committed
52
53
54
55
56
57
58
59
60
61
62
63
//=============================================================================
//
//  Iterators for PolyMesh/TriMesh
//
//=============================================================================



//== INCLUDES =================================================================

#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Mesh/Status.hh>
64
#include <cassert>
65
#include <cstddef>
Matthias Möller's avatar
Matthias Möller committed
66
#include <iterator>
Jan Möbius's avatar
Jan Möbius committed
67
68
69
70
71
72
73
74
75
76
77
78


//== NAMESPACES ===============================================================

namespace OpenMesh {
namespace Iterators {


//== FORWARD DECLARATIONS =====================================================


template <class Mesh> class ConstVertexIterT;
79
template <class Mesh> class VertexIterT;
Jan Möbius's avatar
Jan Möbius committed
80
template <class Mesh> class ConstHalfedgeIterT;
81
template <class Mesh> class HalfedgeIterT;
Jan Möbius's avatar
Jan Möbius committed
82
template <class Mesh> class ConstEdgeIterT;
83
template <class Mesh> class EdgeIterT;
Jan Möbius's avatar
Jan Möbius committed
84
template <class Mesh> class ConstFaceIterT;
85
template <class Mesh> class FaceIterT;
Jan Möbius's avatar
Jan Möbius committed
86
87


88
template <class Mesh, class ValueHandle, class MemberOwner, bool (MemberOwner::*PrimitiveStatusMember)() const, size_t (MemberOwner::*PrimitiveCountMember)() const>
89
class GenericIteratorT {
90
    public:
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
        //--- Typedefs ---

        typedef ValueHandle                     value_handle;
        typedef value_handle                    value_type;
        typedef std::bidirectional_iterator_tag iterator_category;
        typedef std::ptrdiff_t                  difference_type;
        typedef const value_type&               reference;
        typedef const value_type*               pointer;
        typedef const Mesh*                     mesh_ptr;
        typedef const Mesh&                     mesh_ref;

        /// Default constructor.
        GenericIteratorT()
        : mesh_(0), skip_bits_(0)
        {}

        /// Construct with mesh and a target handle.
        GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false)
        : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0)
        {
            if (_skip) enable_skipping();
        }

        /// Standard dereferencing operator.
        reference operator*() const {
            return hnd_;
        }

        /// Standard pointer operator.
        pointer operator->() const {
            return &hnd_;
        }

124
125
126
127
128
        /**
         * \brief Get the handle of the item the iterator refers to.
         * \deprecated 
         * This function clutters your code. Use dereferencing operators -> and * instead.
         */
129
        OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
130
131
132
133
        value_handle handle() const {
            return hnd_;
        }

134
135
136
137
138
139
        /**
         * \brief Cast to the handle of the item the iterator refers to.
         * \deprecated
         * Implicit casts of iterators are unsafe. Use dereferencing operators
         * -> and * instead.
         */
140
        OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
        operator value_handle() const {
            return hnd_;
        }

        /// Are two iterators equal? Only valid if they refer to the same mesh!
        bool operator==(const GenericIteratorT& _rhs) const {
            return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_));
        }

        /// Not equal?
        bool operator!=(const GenericIteratorT& _rhs) const {
            return !operator==(_rhs);
        }

        /// Standard pre-increment operator
        GenericIteratorT& operator++() {
            hnd_.__increment();
            if (skip_bits_)
                skip_fwd();
            return *this;
        }

163
164
165
166
167
168
169
        /// Standard post-increment operator
        GenericIteratorT operator++(int) {
            GenericIteratorT cpy(*this);
            ++(*this);
            return cpy;
        }

170
#if ((defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        template<class T = value_handle>
        auto operator+=(int amount) ->
            typename std::enable_if<
                sizeof(decltype(std::declval<T>().__increment(amount))) >= 0,
                GenericIteratorT&>::type {
            static_assert(std::is_same<T, value_handle>::value,
                    "Template parameter must not deviate from default.");
            if (skip_bits_)
                throw std::logic_error("Skipping iterators do not support "
                        "random access.");
            hnd_.__increment(amount);
            return *this;
        }

        template<class T = value_handle>
        auto operator+(int rhs) ->
            typename std::enable_if<
                sizeof(decltype(std::declval<T>().__increment(rhs), void (), int {})) >= 0,
                GenericIteratorT>::type {
            static_assert(std::is_same<T, value_handle>::value,
                    "Template parameter must not deviate from default.");
            if (skip_bits_)
                throw std::logic_error("Skipping iterators do not support "
                        "random access.");
            GenericIteratorT result = *this;
            result.hnd_.__increment(rhs);
            return result;
        }
#endif

201
202
203
204
205
206
207
208
        /// Standard pre-decrement operator
        GenericIteratorT& operator--() {
            hnd_.__decrement();
            if (skip_bits_)
                skip_bwd();
            return *this;
        }

209
210
211
212
213
214
215
        /// Standard post-decrement operator
        GenericIteratorT operator--(int) {
            GenericIteratorT cpy(*this);
            --(*this);
            return cpy;
        }

216
217
        /// Turn on skipping: automatically skip deleted/hidden elements
        void enable_skipping() {
218
            if (mesh_ && (mesh_->*PrimitiveStatusMember)()) {
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
                Attributes::StatusInfo status;
                status.set_deleted(true);
                status.set_hidden(true);
                skip_bits_ = status.bits();
                skip_fwd();
            } else
                skip_bits_ = 0;
        }

        /// Turn on skipping: automatically skip deleted/hidden elements
        void disable_skipping() {
            skip_bits_ = 0;
        }

    private:

        void skip_fwd() {
            assert(mesh_ && skip_bits_);
237
            while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)())
238
239
240
241
242
243
244
245
246
247
248
249
250
251
                    && (mesh_->status(hnd_).bits() & skip_bits_))
                hnd_.__increment();
        }

        void skip_bwd() {
            assert(mesh_ && skip_bits_);
            while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_))
                hnd_.__decrement();
        }

    protected:
        mesh_ptr mesh_;
        value_handle hnd_;
        unsigned int skip_bits_;
Jan Möbius's avatar
Jan Möbius committed
252
253
254
255
256
257
258
259
};

//=============================================================================
} // namespace Iterators
} // namespace OpenMesh
//=============================================================================
#endif 
//=============================================================================