summaryrefslogtreecommitdiff
path: root/include/gudhi_patches/CGAL/Triangulation_ds_full_cell.h
blob: 541a6a857cec444d99b600368f32e669cc233d50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
// Author(s)    : Samuel Hornus

#ifndef CGAL_TRIANGULATION_DS_FULL_CELL_H
#define CGAL_TRIANGULATION_DS_FULL_CELL_H

#include <CGAL/TDS_full_cell_default_storage_policy.h>
#include <CGAL/TDS_full_cell_mirror_storage_policy.h>
#include <CGAL/internal/Triangulation/Dummy_TDS.h>
#include <CGAL/Dimension.h>
#include <CGAL/Default.h>
#include <CGAL/array.h>

namespace CGAL {

template< class TDS = void, typename FullCellStoragePolicy = Default >
class Triangulation_ds_full_cell
{
    typedef typename Default::Get<FullCellStoragePolicy, TDS_full_cell_default_storage_policy>::type
                                                   Storage_policy;
    typedef Triangulation_ds_full_cell<TDS>        Self;
    typedef typename TDS::Maximal_dimension        Maximal_dimension;

public:
    typedef TDS                                    Triangulation_data_structure;
    typedef typename TDS::Face                     Face;
    typedef typename TDS::Vertex_handle            Vertex_handle; /* Concept */
    typedef typename TDS::Vertex_const_handle      Vertex_const_handle;
    typedef typename TDS::Full_cell_handle         Full_cell_handle; /* Concept */
    typedef typename TDS::Full_cell_const_handle   Full_cell_const_handle;
    typedef typename TDS::Full_cell_data           TDS_data; /* data that the TDS wants to be stored here */
    template< typename TDS2 >
    struct Rebind_TDS /* Concept */
    {
        typedef Triangulation_ds_full_cell<TDS2, FullCellStoragePolicy> Other;
    };

private: // STORAGE
    typedef TFC_data< Vertex_handle, Full_cell_handle,
                      Maximal_dimension, Storage_policy >   Combinatorics;
    friend struct TFC_data< Vertex_handle, Full_cell_handle,
                      Maximal_dimension, Storage_policy >;
    // array of vertices
    typedef typename Combinatorics::Vertex_handle_array     Vertex_handle_array;
    // neighbor simplices
    typedef typename Combinatorics::Full_cell_handle_array    Full_cell_handle_array;

    // NOT DOCUMENTED...
    typename Combinatorics::Xor_type xor_of_vertices(const int cur_dim) const
    {
        return combinatorics_.xor_of_vertices(cur_dim);
    }

public:
    typedef typename Vertex_handle_array::const_iterator    Vertex_handle_const_iterator;
    typedef Vertex_handle_const_iterator    Vertex_handle_iterator; /* Concept */

    Triangulation_ds_full_cell(const int dmax) /* Concept */
    : combinatorics_(dmax), tds_data_()
    {
        CGAL_assertion( dmax > 0 );
        for( int i = 0; i <= dmax; ++i )
        {
            set_neighbor(i, Full_cell_handle());
            set_vertex(i, Vertex_handle());
            set_mirror_index(i, -1);
        }
    }

    Triangulation_ds_full_cell(const Triangulation_ds_full_cell & s) /* Concept */
    : combinatorics_(s.combinatorics_), tds_data_(s.tds_data_)
    {}

    ~Triangulation_ds_full_cell() {}

    int maximal_dimension() const /* Concept */
    {
        return static_cast<int>(vertices().size() - 1);
    }

    Vertex_handle_const_iterator vertices_begin() const /* Concept */
    {
        return vertices().begin();
    }

    Vertex_handle_const_iterator vertices_end() const /* Concept */
    {
        return vertices().end();
    }

    Vertex_handle vertex(const int i) const /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        return vertices()[i];
    }

    Full_cell_handle neighbor(const int i) const /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        return neighbors()[i];
    }

    int mirror_index(const int i) const /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        return combinatorics_.mirror_index(i);
    }

    // Advanced...
    Vertex_handle mirror_vertex(const int i, const int cur_dim) const /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        return combinatorics_.mirror_vertex(i, cur_dim);
    }

    int index(Full_cell_const_handle s) const /* Concept */
    {
        // WE ASSUME THE FULL CELL WE ARE LOOKING FOR INDEED EXISTS !
        CGAL_precondition(has_neighbor(s));
        int index(0);
        while( neighbor(index) != s )
            ++index;
        return index;
    }

    int index(Vertex_const_handle v) const /* Concept */
    {
        // WE ASSUME THE VERTEX WE ARE LOOKING FOR INDEED EXISTS !
        CGAL_precondition(has_vertex(v));
        int index(0);
        while( vertex(index) != v )
            ++index;
        return index;
    }

    void set_vertex(const int i, Vertex_handle v) /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        vertices()[i] = v;
    }

    void set_neighbor(const int i, Full_cell_handle s) /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        neighbors()[i] = s;
    }

    void set_mirror_index(const int i, const int index) /* Concept */
    {
        CGAL_precondition(0<=i && i<=maximal_dimension());
        combinatorics_.set_mirror_index(i, index);
    }

    bool has_vertex(Vertex_const_handle v) const /* Concept */
    {
        int index;
        return has_vertex(v, index);
    }

    bool has_vertex(Vertex_const_handle v, int & index) const /* Concept */
    {
        const int d = maximal_dimension();
        index = 0;
        while( (index <= d) && (vertex(index) != v) )
            ++index;
        return (index <= d);
    }

    bool has_neighbor(Full_cell_const_handle s) const /* Concept */
    {
        int index;
        return has_neighbor(s, index);
    }

    bool has_neighbor(Full_cell_const_handle s, int & index) const /* Concept */
    {
        const int d = maximal_dimension();
        index = 0;
        while( (index <= d) && (neighbor(index) != s) )
            ++index;
        return (index <= d);
    }

    void swap_vertices(const int d1, const int d2) /* Concept */
    {
        CGAL_precondition(0 <= d1 && d1<=maximal_dimension());
        CGAL_precondition(0 <= d2 && d2<=maximal_dimension());
        combinatorics_.swap_vertices(d1, d2);
    }

    const TDS_data & tds_data() const { return tds_data_; } /* Concept */
    TDS_data & tds_data() { return tds_data_; } /* Concept */

    void*   for_compact_container() const { return combinatorics_.for_compact_container(); }
    void* & for_compact_container() { return combinatorics_.for_compact_container(); }

    bool is_valid(bool verbose = false, int = 0) const /* Concept */
    {
        const int d = maximal_dimension();
        int i(0);
        // test that the non-null Vertex_handles come first, before all null ones
        while( i <= d && vertex(i) != Vertex_handle() ) ++i;
        while( i <= d && vertex(i) == Vertex_handle() ) ++i;
        if( i <= d )
        {
            if( verbose ) CGAL_warning_msg(false, "full cell has garbage handles to vertices.");
            return false;
        }
        for( i = 0; i <= d; ++i )
        {
            if( Vertex_handle() == vertex(i) )
                break; // there are no more vertices
            Full_cell_handle n(neighbor(i));
            if( Full_cell_handle() != n )
            {
                int mirror_idx(mirror_index(i));
                if( n->neighbor(mirror_idx) == Full_cell_handle() )
                {
                    if( verbose ) CGAL_warning_msg(false, "neighbor has no back-neighbor.");
                    return false;
                }
                if( &(*(n->neighbor(mirror_idx))) != this )
                {
                    if( verbose ) CGAL_warning_msg(false, "neighbor does not point back to correct full cell.");
                    return false;
                }
            }
        }
        return true;
    }

private:
    // access to data members:
    Full_cell_handle_array & neighbors() {return combinatorics_.neighbors_; }
    const Full_cell_handle_array & neighbors() const {return combinatorics_.neighbors_; }
    Vertex_handle_array & vertices() {return combinatorics_.vertices_; }
    const Vertex_handle_array & vertices() const {return combinatorics_.vertices_; }

    // DATA MEMBERS
    Combinatorics       combinatorics_;
    mutable TDS_data    tds_data_;
};

// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:

template < typename TDS, typename SSP >
std::ostream &
operator<<(std::ostream & O, const Triangulation_ds_full_cell<TDS,SSP> &) /* Concept */
{
    /*if( is_ascii(O) )
    {
        // os << '\n';
    }
    else {}*/
    return O;
}

template < typename TDS, typename SSP >
std::istream &
operator>>(std::istream & I, Triangulation_ds_full_cell<TDS,SSP> &) /* Concept */
{
    /*if( is_ascii(I) )
    {}
    else {}*/
    return I;
}

// Special case: specialization when template parameter is void.

// we must declare it for each possible full_cell storage policy because :
// (GCC error:) default template arguments may not be used in partial specializations
template< typename StoragePolicy >
class Triangulation_ds_full_cell<void, StoragePolicy>
{
public:
    typedef internal::Triangulation::Dummy_TDS  TDS;
    typedef TDS                                 Triangulation_data_structure;
    typedef TDS::Vertex_handle                  Vertex_handle;
    typedef TDS::Vertex_const_handle            Vertex_const_handle;
    typedef TDS::Full_cell_handle               Full_cell_handle;
    typedef TDS::Full_cell_const_handle         Full_cell_const_handle;
    typedef TDS::Vertex_handle_const_iterator   Vertex_handle_const_iterator;
    typedef TDS::Full_cell_data                 TDS_data;
    template <typename TDS2>
    struct Rebind_TDS
    {
        typedef Triangulation_ds_full_cell<TDS2, StoragePolicy> Other;
    };
    Vertex_handle_const_iterator vertices_begin();
    Vertex_handle_const_iterator vertices_end();
};

} //namespace CGAL

#endif // CGAL_TRIANGULATION_DS_FULL_CELL_H